Added restrictions on the use of proxy certificates, as they may pose
[openssl.git] / crypto / x509 / x509_vfy.c
index ffc07cce6f1566f82cabfbacb64e2fe9ece25c1f..3da2490fea29934f4acb37e8355b31c7b48c3bd8 100644 (file)
@@ -102,7 +102,7 @@ int X509_verify_cert(X509_STORE_CTX *ctx)
        X509_VERIFY_PARAM *param = ctx->param;
        int depth,i,ok=0;
        int num;
-       int (*cb)();
+       int (*cb)(int ok,X509_STORE_CTX *ctx);
        STACK_OF(X509) *sktmp=NULL;
        if (ctx->cert == NULL)
                {
@@ -388,9 +388,10 @@ static int check_chain_extensions(X509_STORE_CTX *ctx)
 #else
        int i, ok=0, must_be_ca;
        X509 *x;
-       int (*cb)();
+       int (*cb)(int ok,X509_STORE_CTX *ctx);
        int proxy_path_length = 0;
        cb=ctx->verify_cb;
+       int allow_proxy_certs = !!(ctx->flags & X509_V_FLAG_ALLOW_PROXY_CERTS);
 
        /* must_be_ca can have 1 of 3 values:
           -1: we accept both CA and non-CA certificates, to allow direct
@@ -401,6 +402,12 @@ static int check_chain_extensions(X509_STORE_CTX *ctx)
               all certificates in the chain except the leaf certificate.
        */
        must_be_ca = -1;
+
+       /* A hack to keep people who don't want to modify their software
+          happy */
+       if (getenv("OPENSSL_ALLOW_PROXY_CERTS"))
+               allow_proxy_certs = 1;
+
        /* Check all untrusted certificates */
        for (i = 0; i < ctx->last_untrusted; i++)
                {
@@ -415,6 +422,14 @@ static int check_chain_extensions(X509_STORE_CTX *ctx)
                        ok=cb(0,ctx);
                        if (!ok) goto end;
                        }
+               if (!allow_proxy_certs && (x->ex_flags & EXFLAG_PROXY))
+                       {
+                       ctx->error = X509_V_ERR_PROXY_CERTIFICATES_NOT_ALLOWED;
+                       ctx->error_depth = i;
+                       ctx->current_cert = x;
+                       ok=cb(0,ctx);
+                       if (!ok) goto end;
+                       }
                ret = X509_check_ca(x);
                switch(must_be_ca)
                        {
@@ -515,7 +530,7 @@ static int check_trust(X509_STORE_CTX *ctx)
 #else
        int i, ok;
        X509 *x;
-       int (*cb)();
+       int (*cb)(int ok,X509_STORE_CTX *ctx);
        cb=ctx->verify_cb;
 /* For now just check the last certificate in the chain */
        i = sk_X509_num(ctx->chain) - 1;
@@ -925,7 +940,7 @@ static int internal_verify(X509_STORE_CTX *ctx)
        int ok=0,n;
        X509 *xs,*xi;
        EVP_PKEY *pkey=NULL;
-       int (*cb)();
+       int (*cb)(int ok,X509_STORE_CTX *ctx);
 
        cb=ctx->verify_cb;