diff --git a/apps/cms.c b/apps/cms.c index 868de4e918d0a92a67420bcdbe1d033c60077051..b7382a4f1f4f1f374bc1407fb7b5482d6c9b4d2b 100644 --- a/apps/cms.c +++ b/apps/cms.c @@ -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; diff --git a/crypto/x509/x509_vfy.c b/crypto/x509/x509_vfy.c index 625af4fd9f8a79c75c80b0d5e836e7374943755e..22d520b88a3e0e4c8d5face4a107741439b1060f 100644 --- a/crypto/x509/x509_vfy.c +++ b/crypto/x509/x509_vfy.c @@ -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 diff --git a/crypto/x509v3/pcy_data.c b/crypto/x509v3/pcy_data.c index 614d2b493550790436833e950b880b98ca27450b..4711b1ee927b9d824ded08083e0b7be7a4e327f8 100644 --- a/crypto/x509v3/pcy_data.c +++ b/crypto/x509v3/pcy_data.c @@ -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; } diff --git a/crypto/x509v3/pcy_tree.c b/crypto/x509v3/pcy_tree.c index 4fda1d419af6da9488b7a952eedd60920265e8c1..aed0155c2afc2f8fea1120275a98add0032cf7a7 100644 --- a/crypto/x509v3/pcy_tree.c +++ b/crypto/x509v3/pcy_tree.c @@ -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)) { diff --git a/crypto/x509v3/v3_purp.c b/crypto/x509v3/v3_purp.c index ab923bb0d09f364c525cc4a2aad59c232557dab2..f5f8d1c176c657b4592629eaf9dd575e79c72c47 100644 --- a/crypto/x509v3/v3_purp.c +++ b/crypto/x509v3/v3_purp.c @@ -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 */ diff --git a/crypto/x509v3/x509v3.h b/crypto/x509v3/x509v3.h index 381ea1315be3b98fc83a3b3b72fb33845e78d430..7cc24348b1134ff58a276bbdd93fe9bedc35b887 100644 --- a/crypto/x509v3/x509v3.h +++ b/crypto/x509v3/x509v3.h @@ -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 diff --git a/doc/apps/verify.pod b/doc/apps/verify.pod index ff2629d2cf851733b4aa6c5704a4cf594137a74c..8c8cbaaf4d72be429a55d38f724510a6d33c129d 100644 --- a/doc/apps/verify.pod +++ b/doc/apps/verify.pod @@ -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>