PR: 2103
[openssl.git] / crypto / x509 / x509_vfy.c
index 9ff66cff1323c6bd2a6ff66f604e6c15a57b3ac4..87ebf62525cad5e2579d6708a47859a2945b7e45 100644 (file)
@@ -679,7 +679,12 @@ static int check_revocation(X509_STORE_CTX *ctx)
        if (ctx->param->flags & X509_V_FLAG_CRL_CHECK_ALL)
                last = sk_X509_num(ctx->chain) - 1;
        else
+               {
+               /* If checking CRL paths this isn't the EE certificate */
+               if (ctx->parent)
+                       return 1;
                last = 0;
+               }
        for(i = 0; i <= last; i++)
                {
                ctx->error_depth = i;
@@ -1387,7 +1392,7 @@ static int check_crl(X509_STORE_CTX *ctx, X509_CRL *crl)
 
                        if (!(ctx->current_crl_score & CRL_SCORE_SAME_PATH))
                                {
-                               if (!check_crl_path(ctx, ctx->current_issuer))
+                               if (check_crl_path(ctx, ctx->current_issuer) <= 0)
                                        {
                                        ctx->error = X509_V_ERR_CRL_PATH_VALIDATION_ERROR;
                                        ok = ctx->verify_cb(0, ctx);
@@ -1609,7 +1614,12 @@ static int internal_verify(X509_STORE_CTX *ctx)
        while (n >= 0)
                {
                ctx->error_depth=n;
-               if (!xs->valid)
+
+               /* Skip signature check for self signed certificates unless
+                * explicitly asked for. It doesn't add any security and
+                * just wastes time.
+                */
+               if (!xs->valid && (xs != xi || (ctx->param->flags & X509_V_FLAG_CHECK_SS_SIGNATURE)))
                        {
                        if ((pkey=X509_get_pubkey(xi)) == NULL)
                                {
@@ -1619,13 +1629,6 @@ static int internal_verify(X509_STORE_CTX *ctx)
                                if (!ok) goto end;
                                }
                        else if (X509_verify(xs,pkey) <= 0)
-                               /* XXX  For the final trusted self-signed cert,
-                                * this is a waste of time.  That check should
-                                * optional so that e.g. 'openssl x509' can be
-                                * used to detect invalid self-signatures, but
-                                * we don't verify again and again in SSL
-                                * handshakes and the like once the cert has
-                                * been declared trusted. */
                                {
                                ctx->error=X509_V_ERR_CERT_SIGNATURE_FAILURE;
                                ctx->current_cert=xs;
@@ -1724,6 +1727,7 @@ int X509_cmp_time(const ASN1_TIME *ctm, time_t *cmp_time)
                        offset= -offset;
                }
        atm.type=ctm->type;
+       atm.flags = 0;
        atm.length=sizeof(buff2);
        atm.data=(unsigned char *)buff2;
 
@@ -1761,16 +1765,18 @@ ASN1_TIME *X509_time_adj_ex(ASN1_TIME *s,
                                int offset_day, long offset_sec, time_t *in_tm)
        {
        time_t t;
-       int type = -1;
 
        if (in_tm) t = *in_tm;
        else time(&t);
 
-       if (s) type = s->type;
-       if (type == V_ASN1_UTCTIME)
-               return ASN1_UTCTIME_adj(s,t, offset_day, offset_sec);
-       if (type == V_ASN1_GENERALIZEDTIME)
-               return ASN1_GENERALIZEDTIME_adj(s, t, offset_day, offset_sec);
+       if (s && !(s->flags & ASN1_STRING_FLAG_MSTRING))
+               {
+               if (s->type == V_ASN1_UTCTIME)
+                       return ASN1_UTCTIME_adj(s,t, offset_day, offset_sec);
+               if (s->type == V_ASN1_GENERALIZEDTIME)
+                       return ASN1_GENERALIZEDTIME_adj(s, t, offset_day,
+                                                               offset_sec);
+               }
        return ASN1_TIME_adj(s, t, offset_day, offset_sec);
        }
 
@@ -1874,6 +1880,21 @@ STACK_OF(X509) *X509_STORE_CTX_get1_chain(X509_STORE_CTX *ctx)
        return chain;
        }
 
+X509 *X509_STORE_CTX_get0_current_issuer(X509_STORE_CTX *ctx)
+       {
+       return ctx->current_issuer;
+       }
+
+X509_CRL *X509_STORE_CTX_get0_current_crl(X509_STORE_CTX *ctx)
+       {
+       return ctx->current_crl;
+       }
+
+X509_STORE_CTX *X509_STORE_CTX_get0_parent_ctx(X509_STORE_CTX *ctx)
+       {
+       return ctx->parent;
+       }
+
 void X509_STORE_CTX_set_cert(X509_STORE_CTX *ctx, X509 *x)
        {
        ctx->cert=x;