Loading CHANGES +10 −0 Original line number Diff line number Diff line Loading @@ -4,6 +4,16 @@ Changes between 1.0.1 and 1.0.2 [xx XXX xxxx] *) Fix OCSP checking. [Rob Stradling <rob.stradling@comodo.com> and Ben Laurie] *) Backport support for partial chain verification: if an intermediate certificate is explicitly trusted (using -addtrust option to x509 utility for example) the verification is sucessful even if the chain is not complete. The OCSP checking fix depends on this backport. [Steve Henson and Rob Stradling <rob.stradling@comodo.com>] *) Add -trusted_first option which attempts to find certificates in the trusted store even if an untrusted chain is also supplied. [Steve Henson] Loading apps/ocsp.c +5 −5 Original line number Diff line number Diff line Loading @@ -866,6 +866,8 @@ int MAIN(int argc, char **argv) goto end; } ret = 0; if (!noverify) { if (req && ((i = OCSP_check_nonce(req, bs)) <= 0)) Loading @@ -875,17 +877,17 @@ int MAIN(int argc, char **argv) else { BIO_printf(bio_err, "Nonce Verify error\n"); ret = 1; goto end; } } i = OCSP_basic_verify(bs, verify_other, store, verify_flags); if (i < 0) i = OCSP_basic_verify(bs, NULL, store, 0); if(i <= 0) { BIO_printf(bio_err, "Response Verify Failure\n"); ERR_print_errors(bio_err); ret = 1; } else BIO_printf(bio_err, "Response verify OK\n"); Loading @@ -893,9 +895,7 @@ int MAIN(int argc, char **argv) } if (!print_ocsp_summary(out, bs, req, reqnames, ids, nsec, maxage)) goto end; ret = 0; ret = 1; end: ERR_print_errors(bio_err); Loading crypto/ocsp/ocsp_vfy.c +66 −7 Original line number Diff line number Diff line Loading @@ -77,8 +77,10 @@ int OCSP_basic_verify(OCSP_BASICRESP *bs, STACK_OF(X509) *certs, { X509 *signer, *x; STACK_OF(X509) *chain = NULL; STACK_OF(X509) *tmpchain = NULL; X509_STORE *tmpstore = NULL; X509_STORE_CTX ctx; int i, ret = 0; int i, ret; ret = ocsp_find_signer(&signer, bs, certs, st, flags); if (!ret) { Loading @@ -86,7 +88,7 @@ int OCSP_basic_verify(OCSP_BASICRESP *bs, STACK_OF(X509) *certs, goto end; } if ((ret == 2) && (flags & OCSP_TRUSTOTHER)) flags |= OCSP_NOVERIFY; chain = certs; if (!(flags & OCSP_NOSIGS)) { EVP_PKEY *skey; Loading @@ -102,6 +104,60 @@ int OCSP_basic_verify(OCSP_BASICRESP *bs, STACK_OF(X509) *certs, if (!(flags & OCSP_NOVERIFY)) { int init_res; /* If we trust the signer, we don't need to build a chain. * (If the signer is a root certificate, X509_verify_cert() * would fail anyway!) */ if (chain == certs) goto verified_chain; /* If we trust some "other" certificates, mark them as * explicitly trusted (because some of them might be * Intermediate CA Certificates), put them in a store and * attempt to build a trusted chain. */ if ((flags & OCSP_TRUSTOTHER) && (certs != NULL)) { ASN1_OBJECT *objtmp = OBJ_nid2obj(NID_OCSP_sign); tmpstore = X509_STORE_new(); if (!tmpstore) { ret = -1; OCSPerr(OCSP_F_OCSP_BASIC_VERIFY, ERR_R_MALLOC_FAILURE); goto end; } for (i = 0; i < sk_X509_num(certs); i++) { X509 *xother = sk_X509_value(certs, i); X509_add1_trust_object(xother, objtmp); if (!X509_STORE_add_cert(tmpstore, xother)) { ret = -1; goto end; } } init_res = X509_STORE_CTX_init(&ctx, tmpstore, signer, NULL); if (!init_res) { ret = -1; OCSPerr(OCSP_F_OCSP_BASIC_VERIFY,ERR_R_X509_LIB); goto end; } X509_STORE_CTX_set_purpose(&ctx, X509_PURPOSE_OCSP_HELPER); ret = X509_verify_cert(&ctx); if (ret == 1) { chain = tmpchain = X509_STORE_CTX_get1_chain(&ctx); X509_STORE_CTX_cleanup(&ctx); goto verified_chain; } X509_STORE_CTX_cleanup(&ctx); } /* Attempt to build a chain up to a Root Certificate in the * trust store provided by the caller. */ if(flags & OCSP_NOCHAIN) init_res = X509_STORE_CTX_init(&ctx, st, signer, NULL); else Loading @@ -115,7 +171,7 @@ int OCSP_basic_verify(OCSP_BASICRESP *bs, STACK_OF(X509) *certs, X509_STORE_CTX_set_purpose(&ctx, X509_PURPOSE_OCSP_HELPER); ret = X509_verify_cert(&ctx); chain = X509_STORE_CTX_get1_chain(&ctx); chain = tmpchain = X509_STORE_CTX_get1_chain(&ctx); X509_STORE_CTX_cleanup(&ctx); if (ret <= 0) { Loading @@ -125,6 +181,8 @@ int OCSP_basic_verify(OCSP_BASICRESP *bs, STACK_OF(X509) *certs, X509_verify_cert_error_string(i)); goto end; } verified_chain: if(flags & OCSP_NOCHECKS) { ret = 1; Loading Loading @@ -155,7 +213,8 @@ int OCSP_basic_verify(OCSP_BASICRESP *bs, STACK_OF(X509) *certs, end: if(chain) sk_X509_pop_free(chain, X509_free); if(tmpchain) sk_X509_pop_free(tmpchain, X509_free); if(tmpstore) X509_STORE_free(tmpstore); return ret; } Loading crypto/x509/x509_trs.c +9 −0 Original line number Diff line number Diff line Loading @@ -114,6 +114,15 @@ int X509_check_trust(X509 *x, int id, int flags) X509_TRUST *pt; int idx; if(id == -1) return 1; /* We get this as a default value */ if (id == 0) { int rv; rv = obj_trust(NID_anyExtendedKeyUsage, x, 0); if (rv != X509_TRUST_UNTRUSTED) return rv; return trust_compat(NULL, x, 0); } idx = X509_TRUST_get_by_id(id); if(idx == -1) return default_trust(id, x, flags); pt = X509_TRUST_get0(idx); Loading crypto/x509/x509_vfy.c +33 −27 Original line number Diff line number Diff line Loading @@ -323,8 +323,13 @@ int X509_verify_cert(X509_STORE_CTX *ctx) /* we now have our chain, lets check it... */ /* Is last certificate looked up self signed? */ if (!ctx->check_issued(ctx,x,x)) i = check_trust(ctx); /* If explicitly rejected error */ if (i == X509_TRUST_REJECTED) goto end; /* If not explicitly trusted then indicate error */ if (i != X509_TRUST_TRUSTED) { if ((chain_ss == NULL) || !ctx->check_issued(ctx, x, chain_ss)) { Loading Loading @@ -362,12 +367,6 @@ int X509_verify_cert(X509_STORE_CTX *ctx) if (!ok) goto end; /* The chain extensions are OK: check trust */ if (param->trust > 0) ok = check_trust(ctx); if (!ok) goto end; /* We may as well copy down any DSA parameters that are required */ X509_get_pubkey_parameters(NULL,ctx->chain); Loading Loading @@ -658,28 +657,35 @@ static int check_name_constraints(X509_STORE_CTX *ctx) static int check_trust(X509_STORE_CTX *ctx) { #ifdef OPENSSL_NO_CHAIN_VERIFY return 1; #else int i, ok; X509 *x; X509 *x = NULL; int (*cb)(int xok,X509_STORE_CTX *xctx); cb=ctx->verify_cb; /* For now just check the last certificate in the chain */ i = sk_X509_num(ctx->chain) - 1; /* Check all trusted certificates in chain */ for (i = ctx->last_untrusted; i < sk_X509_num(ctx->chain); i++) { x = sk_X509_value(ctx->chain, i); ok = X509_check_trust(x, ctx->param->trust, 0); /* If explicitly trusted return trusted */ if (ok == X509_TRUST_TRUSTED) return 1; return X509_TRUST_TRUSTED; /* If explicitly rejected notify callback and reject if * not overridden. */ if (ok == X509_TRUST_REJECTED) { ctx->error_depth = i; ctx->current_cert = x; if (ok == X509_TRUST_REJECTED) ctx->error = X509_V_ERR_CERT_REJECTED; else ctx->error = X509_V_ERR_CERT_UNTRUSTED; ok = cb(0, ctx); return ok; #endif if (!ok) return X509_TRUST_REJECTED; } } /* If no trusted certs in chain at all return untrusted and * allow standard (no issuer cert) etc errors to be indicated. */ return X509_TRUST_UNTRUSTED; } static int check_revocation(X509_STORE_CTX *ctx) Loading Loading
CHANGES +10 −0 Original line number Diff line number Diff line Loading @@ -4,6 +4,16 @@ Changes between 1.0.1 and 1.0.2 [xx XXX xxxx] *) Fix OCSP checking. [Rob Stradling <rob.stradling@comodo.com> and Ben Laurie] *) Backport support for partial chain verification: if an intermediate certificate is explicitly trusted (using -addtrust option to x509 utility for example) the verification is sucessful even if the chain is not complete. The OCSP checking fix depends on this backport. [Steve Henson and Rob Stradling <rob.stradling@comodo.com>] *) Add -trusted_first option which attempts to find certificates in the trusted store even if an untrusted chain is also supplied. [Steve Henson] Loading
apps/ocsp.c +5 −5 Original line number Diff line number Diff line Loading @@ -866,6 +866,8 @@ int MAIN(int argc, char **argv) goto end; } ret = 0; if (!noverify) { if (req && ((i = OCSP_check_nonce(req, bs)) <= 0)) Loading @@ -875,17 +877,17 @@ int MAIN(int argc, char **argv) else { BIO_printf(bio_err, "Nonce Verify error\n"); ret = 1; goto end; } } i = OCSP_basic_verify(bs, verify_other, store, verify_flags); if (i < 0) i = OCSP_basic_verify(bs, NULL, store, 0); if(i <= 0) { BIO_printf(bio_err, "Response Verify Failure\n"); ERR_print_errors(bio_err); ret = 1; } else BIO_printf(bio_err, "Response verify OK\n"); Loading @@ -893,9 +895,7 @@ int MAIN(int argc, char **argv) } if (!print_ocsp_summary(out, bs, req, reqnames, ids, nsec, maxage)) goto end; ret = 0; ret = 1; end: ERR_print_errors(bio_err); Loading
crypto/ocsp/ocsp_vfy.c +66 −7 Original line number Diff line number Diff line Loading @@ -77,8 +77,10 @@ int OCSP_basic_verify(OCSP_BASICRESP *bs, STACK_OF(X509) *certs, { X509 *signer, *x; STACK_OF(X509) *chain = NULL; STACK_OF(X509) *tmpchain = NULL; X509_STORE *tmpstore = NULL; X509_STORE_CTX ctx; int i, ret = 0; int i, ret; ret = ocsp_find_signer(&signer, bs, certs, st, flags); if (!ret) { Loading @@ -86,7 +88,7 @@ int OCSP_basic_verify(OCSP_BASICRESP *bs, STACK_OF(X509) *certs, goto end; } if ((ret == 2) && (flags & OCSP_TRUSTOTHER)) flags |= OCSP_NOVERIFY; chain = certs; if (!(flags & OCSP_NOSIGS)) { EVP_PKEY *skey; Loading @@ -102,6 +104,60 @@ int OCSP_basic_verify(OCSP_BASICRESP *bs, STACK_OF(X509) *certs, if (!(flags & OCSP_NOVERIFY)) { int init_res; /* If we trust the signer, we don't need to build a chain. * (If the signer is a root certificate, X509_verify_cert() * would fail anyway!) */ if (chain == certs) goto verified_chain; /* If we trust some "other" certificates, mark them as * explicitly trusted (because some of them might be * Intermediate CA Certificates), put them in a store and * attempt to build a trusted chain. */ if ((flags & OCSP_TRUSTOTHER) && (certs != NULL)) { ASN1_OBJECT *objtmp = OBJ_nid2obj(NID_OCSP_sign); tmpstore = X509_STORE_new(); if (!tmpstore) { ret = -1; OCSPerr(OCSP_F_OCSP_BASIC_VERIFY, ERR_R_MALLOC_FAILURE); goto end; } for (i = 0; i < sk_X509_num(certs); i++) { X509 *xother = sk_X509_value(certs, i); X509_add1_trust_object(xother, objtmp); if (!X509_STORE_add_cert(tmpstore, xother)) { ret = -1; goto end; } } init_res = X509_STORE_CTX_init(&ctx, tmpstore, signer, NULL); if (!init_res) { ret = -1; OCSPerr(OCSP_F_OCSP_BASIC_VERIFY,ERR_R_X509_LIB); goto end; } X509_STORE_CTX_set_purpose(&ctx, X509_PURPOSE_OCSP_HELPER); ret = X509_verify_cert(&ctx); if (ret == 1) { chain = tmpchain = X509_STORE_CTX_get1_chain(&ctx); X509_STORE_CTX_cleanup(&ctx); goto verified_chain; } X509_STORE_CTX_cleanup(&ctx); } /* Attempt to build a chain up to a Root Certificate in the * trust store provided by the caller. */ if(flags & OCSP_NOCHAIN) init_res = X509_STORE_CTX_init(&ctx, st, signer, NULL); else Loading @@ -115,7 +171,7 @@ int OCSP_basic_verify(OCSP_BASICRESP *bs, STACK_OF(X509) *certs, X509_STORE_CTX_set_purpose(&ctx, X509_PURPOSE_OCSP_HELPER); ret = X509_verify_cert(&ctx); chain = X509_STORE_CTX_get1_chain(&ctx); chain = tmpchain = X509_STORE_CTX_get1_chain(&ctx); X509_STORE_CTX_cleanup(&ctx); if (ret <= 0) { Loading @@ -125,6 +181,8 @@ int OCSP_basic_verify(OCSP_BASICRESP *bs, STACK_OF(X509) *certs, X509_verify_cert_error_string(i)); goto end; } verified_chain: if(flags & OCSP_NOCHECKS) { ret = 1; Loading Loading @@ -155,7 +213,8 @@ int OCSP_basic_verify(OCSP_BASICRESP *bs, STACK_OF(X509) *certs, end: if(chain) sk_X509_pop_free(chain, X509_free); if(tmpchain) sk_X509_pop_free(tmpchain, X509_free); if(tmpstore) X509_STORE_free(tmpstore); return ret; } Loading
crypto/x509/x509_trs.c +9 −0 Original line number Diff line number Diff line Loading @@ -114,6 +114,15 @@ int X509_check_trust(X509 *x, int id, int flags) X509_TRUST *pt; int idx; if(id == -1) return 1; /* We get this as a default value */ if (id == 0) { int rv; rv = obj_trust(NID_anyExtendedKeyUsage, x, 0); if (rv != X509_TRUST_UNTRUSTED) return rv; return trust_compat(NULL, x, 0); } idx = X509_TRUST_get_by_id(id); if(idx == -1) return default_trust(id, x, flags); pt = X509_TRUST_get0(idx); Loading
crypto/x509/x509_vfy.c +33 −27 Original line number Diff line number Diff line Loading @@ -323,8 +323,13 @@ int X509_verify_cert(X509_STORE_CTX *ctx) /* we now have our chain, lets check it... */ /* Is last certificate looked up self signed? */ if (!ctx->check_issued(ctx,x,x)) i = check_trust(ctx); /* If explicitly rejected error */ if (i == X509_TRUST_REJECTED) goto end; /* If not explicitly trusted then indicate error */ if (i != X509_TRUST_TRUSTED) { if ((chain_ss == NULL) || !ctx->check_issued(ctx, x, chain_ss)) { Loading Loading @@ -362,12 +367,6 @@ int X509_verify_cert(X509_STORE_CTX *ctx) if (!ok) goto end; /* The chain extensions are OK: check trust */ if (param->trust > 0) ok = check_trust(ctx); if (!ok) goto end; /* We may as well copy down any DSA parameters that are required */ X509_get_pubkey_parameters(NULL,ctx->chain); Loading Loading @@ -658,28 +657,35 @@ static int check_name_constraints(X509_STORE_CTX *ctx) static int check_trust(X509_STORE_CTX *ctx) { #ifdef OPENSSL_NO_CHAIN_VERIFY return 1; #else int i, ok; X509 *x; X509 *x = NULL; int (*cb)(int xok,X509_STORE_CTX *xctx); cb=ctx->verify_cb; /* For now just check the last certificate in the chain */ i = sk_X509_num(ctx->chain) - 1; /* Check all trusted certificates in chain */ for (i = ctx->last_untrusted; i < sk_X509_num(ctx->chain); i++) { x = sk_X509_value(ctx->chain, i); ok = X509_check_trust(x, ctx->param->trust, 0); /* If explicitly trusted return trusted */ if (ok == X509_TRUST_TRUSTED) return 1; return X509_TRUST_TRUSTED; /* If explicitly rejected notify callback and reject if * not overridden. */ if (ok == X509_TRUST_REJECTED) { ctx->error_depth = i; ctx->current_cert = x; if (ok == X509_TRUST_REJECTED) ctx->error = X509_V_ERR_CERT_REJECTED; else ctx->error = X509_V_ERR_CERT_UNTRUSTED; ok = cb(0, ctx); return ok; #endif if (!ok) return X509_TRUST_REJECTED; } } /* If no trusted certs in chain at all return untrusted and * allow standard (no issuer cert) etc errors to be indicated. */ return X509_TRUST_UNTRUSTED; } static int check_revocation(X509_STORE_CTX *ctx) Loading