X509 verification fixes.
authorDr. Stephen Henson <steve@openssl.org>
Sun, 13 Jul 2008 14:25:36 +0000 (14:25 +0000)
committerDr. Stephen Henson <steve@openssl.org>
Sun, 13 Jul 2008 14:25:36 +0000 (14:25 +0000)
Ignore self issued certificates when checking path length constraints.

Duplicate OIDs in policy tree in case they are allocated.

Use anyPolicy from certificate cache and not current tree level.

apps/cms.c
crypto/x509/x509_vfy.c
crypto/x509v3/pcy_data.c
crypto/x509v3/pcy_tree.c
crypto/x509v3/v3_purp.c
crypto/x509v3/x509v3.h
doc/apps/verify.pod

index 868de4e..b7382a4 100644 (file)
@@ -95,6 +95,8 @@ static CMS_ReceiptRequest *make_receipt_request(STACK_OF(STRING) *rr_to,
 #define SMIME_SIGN_RECEIPT     (15 | SMIME_IP | SMIME_OP)
 #define SMIME_VERIFY_RECEIPT   (16 | SMIME_IP)
 
+int verify_err = 0;
+
 int MAIN(int, char **);
 
 int MAIN(int argc, char **argv)
@@ -118,6 +120,7 @@ int MAIN(int argc, char **argv)
        BIO *in = NULL, *out = NULL, *indata = NULL, *rctin = NULL;
        int badarg = 0;
        int flags = CMS_DETACHED, noout = 0, print = 0;
+       int verify_retcode = 0;
        int rr_print = 0, rr_allorfirst = -1;
        STACK_OF(STRING) *rr_to = NULL, *rr_from = NULL;
        CMS_ReceiptRequest *rr = NULL;
@@ -167,6 +170,8 @@ int MAIN(int argc, char **argv)
                        operation = SMIME_RESIGN;
                else if (!strcmp (*args, "-verify"))
                        operation = SMIME_VERIFY;
+               else if (!strcmp (*args, "-verify_retcode"))
+                       verify_retcode = 1;
                else if (!strcmp(*args,"-verify_receipt"))
                        {
                        operation = SMIME_VERIFY_RECEIPT;
@@ -1077,6 +1082,8 @@ int MAIN(int argc, char **argv)
                else
                        {
                        BIO_printf(bio_err, "Verification failure\n");
+                       if (verify_retcode)
+                               ret = verify_err + 32;
                        goto end;
                        }
                if (signerfile)
@@ -1206,6 +1213,8 @@ static int cms_cb(int ok, X509_STORE_CTX *ctx)
 
        error = X509_STORE_CTX_get_error(ctx);
 
+       verify_err = error;
+
        if ((error != X509_V_ERR_NO_EXPLICIT_POLICY)
                && ((error != X509_V_OK) || (ok != 2)))
                return ok;
index 625af4f..22d520b 100644 (file)
@@ -396,7 +396,7 @@ static int check_chain_extensions(X509_STORE_CTX *ctx)
 #ifdef OPENSSL_NO_CHAIN_VERIFY
        return 1;
 #else
-       int i, ok=0, must_be_ca;
+       int i, ok=0, must_be_ca, plen = 0;
        X509 *x;
        int (*cb)(int xok,X509_STORE_CTX *xctx);
        int proxy_path_length = 0;
@@ -497,9 +497,10 @@ static int check_chain_extensions(X509_STORE_CTX *ctx)
                                if (!ok) goto end;
                                }
                        }
-               /* Check pathlen */
-               if ((i > 1) && (x->ex_pathlen != -1)
-                          && (i > (x->ex_pathlen + proxy_path_length + 1)))
+               /* Check pathlen if not self issued */
+               if ((i > 1) && !(x->ex_flags & EXFLAG_SI)
+                          && (x->ex_pathlen != -1)
+                          && (plen > (x->ex_pathlen + proxy_path_length + 1)))
                        {
                        ctx->error = X509_V_ERR_PATH_LENGTH_EXCEEDED;
                        ctx->error_depth = i;
@@ -507,6 +508,9 @@ static int check_chain_extensions(X509_STORE_CTX *ctx)
                        ok=cb(0,ctx);
                        if (!ok) goto end;
                        }
+               /* Increment path length if not self issued */
+               if (!(x->ex_flags & EXFLAG_SI))
+                       plen++;
                /* If this certificate is a proxy certificate, the next
                   certificate must be another proxy certificate or a EE
                   certificate.  If not, the next certificate must be a
index 614d2b4..4711b1e 100644 (file)
@@ -87,6 +87,12 @@ X509_POLICY_DATA *policy_data_new(POLICYINFO *policy, ASN1_OBJECT *id, int crit)
        X509_POLICY_DATA *ret;
        if (!policy && !id)
                return NULL;
+       if (id)
+               {
+               id = OBJ_dup(id);
+               if (!id)
+                       return NULL;
+               }
        ret = OPENSSL_malloc(sizeof(X509_POLICY_DATA));
        if (!ret)
                return NULL;
@@ -94,6 +100,8 @@ X509_POLICY_DATA *policy_data_new(POLICYINFO *policy, ASN1_OBJECT *id, int crit)
        if (!ret->expected_policy_set)
                {
                OPENSSL_free(ret);
+               if (id)
+                       ASN1_OBJECT_free(id);
                return NULL;
                }
 
index 4fda1d4..aed0155 100644 (file)
@@ -131,7 +131,7 @@ static int tree_init(X509_POLICY_TREE **ptree, STACK_OF(X509) *certs,
                if (explicit_policy > 0)
                        {
                        explicit_policy--;
-                       if (!(x->ex_flags & EXFLAG_SS)
+                       if (!(x->ex_flags & EXFLAG_SI)
                                && (cache->explicit_skip != -1)
                                && (cache->explicit_skip < explicit_policy))
                                explicit_policy = cache->explicit_skip;
@@ -197,7 +197,7 @@ static int tree_init(X509_POLICY_TREE **ptree, STACK_OF(X509) *certs,
                        /* Any matching allowed if certificate is self
                         * issued and not the last in the chain.
                         */
-                       if (!(x->ex_flags & EXFLAG_SS) || (i == 0))
+                       if (!(x->ex_flags & EXFLAG_SI) || (i == 0))
                                level->flags |= X509_V_FLAG_INHIBIT_ANY;
                        }
                else
@@ -310,7 +310,8 @@ static int tree_link_any(X509_POLICY_LEVEL *curr,
 
                if (data == NULL)
                        return 0;
-               data->qualifier_set = curr->anyPolicy->data->qualifier_set;
+               /* Curr may not have anyPolicy */
+               data->qualifier_set = cache->anyPolicy->qualifier_set;
                data->flags |= POLICY_DATA_FLAG_SHARED_QUALIFIERS;
                if (!level_add_node(curr, data, node, tree))
                        {
index ab923bb..f5f8d1c 100644 (file)
@@ -293,6 +293,7 @@ int X509_supported_extension(X509_EXTENSION *ex)
                NID_sbgp_ipAddrBlock,   /* 290 */
                NID_sbgp_autonomousSysNum, /* 291 */
 #endif
+               NID_policy_constraints, /* 401 */
                NID_proxyCertInfo       /* 663 */
        };
 
@@ -327,7 +328,7 @@ static void x509v3_cache_extensions(X509 *x)
 #endif
        /* Does subject name match issuer ? */
        if(!X509_NAME_cmp(X509_get_subject_name(x), X509_get_issuer_name(x)))
-                        x->ex_flags |= EXFLAG_SS;
+                        x->ex_flags |= EXFLAG_SI;
        /* V1 should mean no extensions ... */
        if(!X509_get_version(x)) x->ex_flags |= EXFLAG_V1;
        /* Handle basic constraints */
index 381ea13..7cc2434 100644 (file)
@@ -388,6 +388,8 @@ struct ISSUING_DIST_POINT_st
 #define EXFLAG_NSCERT          0x8
 
 #define EXFLAG_CA              0x10
+/* Really self issued not necessarily self signed */
+#define EXFLAG_SI              0x20
 #define EXFLAG_SS              0x20
 #define EXFLAG_V1              0x40
 #define EXFLAG_INVALID         0x80
index ff2629d..8c8cbaa 100644 (file)
@@ -171,7 +171,7 @@ of an untrusted certificate cannot be found.
 
 =item B<3 X509_V_ERR_UNABLE_TO_GET_CRL: unable to get certificate CRL>
 
-the CRL of a certificate could not be found. Unused.
+the CRL of a certificate could not be found.
 
 =item B<4 X509_V_ERR_UNABLE_TO_DECRYPT_CERT_SIGNATURE: unable to decrypt certificate's signature>
 
@@ -194,7 +194,7 @@ the signature of the certificate is invalid.
 
 =item B<8 X509_V_ERR_CRL_SIGNATURE_FAILURE: CRL signature failure>
 
-the signature of the certificate is invalid. Unused.
+the signature of the certificate is invalid.
 
 =item B<9 X509_V_ERR_CERT_NOT_YET_VALID: certificate is not yet valid>
 
@@ -206,11 +206,11 @@ the certificate has expired: that is the notAfter date is before the current tim
 
 =item B<11 X509_V_ERR_CRL_NOT_YET_VALID: CRL is not yet valid>
 
-the CRL is not yet valid. Unused.
+the CRL is not yet valid.
 
 =item B<12 X509_V_ERR_CRL_HAS_EXPIRED: CRL has expired>
 
-the CRL has expired. Unused.
+the CRL has expired.
 
 =item B<13 X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD: format error in certificate's notBefore field>
 
@@ -222,11 +222,11 @@ the certificate notAfter field contains an invalid time.
 
 =item B<15 X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD: format error in CRL's lastUpdate field>
 
-the CRL lastUpdate field contains an invalid time. Unused.
+the CRL lastUpdate field contains an invalid time.
 
 =item B<16 X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD: format error in CRL's nextUpdate field>
 
-the CRL nextUpdate field contains an invalid time. Unused.
+the CRL nextUpdate field contains an invalid time.
 
 =item B<17 X509_V_ERR_OUT_OF_MEM: out of memory>
 
@@ -258,7 +258,7 @@ the certificate chain length is greater than the supplied maximum depth. Unused.
 
 =item B<23 X509_V_ERR_CERT_REVOKED: certificate revoked>
 
-the certificate has been revoked. Unused.
+the certificate has been revoked.
 
 =item B<24 X509_V_ERR_INVALID_CA: invalid CA certificate>