X-Git-Url: https://git.openssl.org/gitweb/?p=openssl.git;a=blobdiff_plain;f=ssl%2Fssl_cert.c;h=2c66460fe43c490db26ae327d374035d3df1b93a;hp=47c8b8659f4c666d5cbc0b922f0a9bf4d62ddec6;hb=5693a30813a031d3921a016a870420e7eb93ec90;hpb=0f78819c8ccb7c526edbe90d5b619281366ce75c diff --git a/ssl/ssl_cert.c b/ssl/ssl_cert.c index 47c8b8659f..2c66460fe4 100644 --- a/ssl/ssl_cert.c +++ b/ssl/ssl_cert.c @@ -606,18 +606,20 @@ int ssl_cert_select_current(CERT *c, X509 *x) return 0; for (i = 0; i < SSL_PKEY_NUM; i++) { - if (c->pkeys[i].x509 == x) + CERT_PKEY *cpk = c->pkeys + i; + if (cpk->x509 == x && cpk->privatekey) { - c->key = &c->pkeys[i]; + c->key = cpk; return 1; } } for (i = 0; i < SSL_PKEY_NUM; i++) { - if (c->pkeys[i].x509 && !X509_cmp(c->pkeys[i].x509, x)) + CERT_PKEY *cpk = c->pkeys + i; + if (cpk->privatekey && cpk->x509 && !X509_cmp(cpk->x509, x)) { - c->key = &c->pkeys[i]; + c->key = cpk; return 1; } } @@ -641,9 +643,10 @@ int ssl_cert_set_current(CERT *c, long op) return 0; for (i = idx; i < SSL_PKEY_NUM; i++) { - if (c->pkeys[i].x509) + CERT_PKEY *cpk = c->key + i; + if (cpk->x509 && cpk->privatekey) { - c->key = &c->pkeys[i]; + c->key = cpk; return 1; } } @@ -1195,37 +1198,65 @@ int ssl_build_cert_chain(CERT *c, X509_STORE *chain_store, int flags) X509_STORE_CTX xs_ctx; STACK_OF(X509) *chain = NULL, *untrusted = NULL; X509 *x; - int i; + int i, rv = 0; if (!cpk->x509) { SSLerr(SSL_F_SSL_BUILD_CERT_CHAIN, SSL_R_NO_CERTIFICATE_SET); - return 0; + goto err; } + /* Rearranging and check the chain: add everything to a store */ + if (flags & SSL_BUILD_CHAIN_FLAG_CHECK) + { + chain_store = X509_STORE_new(); + if (!chain_store) + goto err; + for (i = 0; i < sk_X509_num(cpk->chain); i++) + { + x = sk_X509_value(cpk->chain, i); + if (!X509_STORE_add_cert(chain_store, x)) + goto err; + } + /* Add EE cert too: it might be self signed */ + if (!X509_STORE_add_cert(chain_store, cpk->x509)) + goto err; + } + else + { + if (c->chain_store) + chain_store = c->chain_store; - if (c->chain_store) - chain_store = c->chain_store; - - if (flags & SSL_BUILD_CHAIN_FLAG_UNTRUSTED) - untrusted = cpk->chain; + if (flags & SSL_BUILD_CHAIN_FLAG_UNTRUSTED) + untrusted = cpk->chain; + } if (!X509_STORE_CTX_init(&xs_ctx, chain_store, cpk->x509, untrusted)) { SSLerr(SSL_F_SSL_BUILD_CERT_CHAIN, ERR_R_X509_LIB); - return 0; + goto err; } /* Set suite B flags if needed */ X509_STORE_CTX_set_flags(&xs_ctx, c->cert_flags & SSL_CERT_FLAG_SUITEB_128_LOS); i = X509_verify_cert(&xs_ctx); + if (i <= 0 && flags & SSL_BUILD_CHAIN_FLAG_IGNORE_ERROR) + { + ERR_clear_error(); + i = 1; + } if (i > 0) chain = X509_STORE_CTX_get1_chain(&xs_ctx); - X509_STORE_CTX_cleanup(&xs_ctx); if (i <= 0) { SSLerr(SSL_F_SSL_BUILD_CERT_CHAIN, SSL_R_CERTIFICATE_VERIFY_FAILED); - return 0; + i = X509_STORE_CTX_get_error(&xs_ctx); + ERR_add_error_data(2, "Verify error:", + X509_verify_cert_error_string(i)); + + X509_STORE_CTX_cleanup(&xs_ctx); + goto err; } + X509_STORE_CTX_cleanup(&xs_ctx); if (cpk->chain) sk_X509_pop_free(cpk->chain, X509_free); /* Remove EE certificate from chain */ @@ -1233,12 +1264,25 @@ int ssl_build_cert_chain(CERT *c, X509_STORE *chain_store, int flags) X509_free(x); if (flags & SSL_BUILD_CHAIN_FLAG_NO_ROOT) { - x = sk_X509_pop(chain); - X509_free(x); + if (sk_X509_num(chain) > 0) + { + /* See if last cert is self signed */ + x = sk_X509_value(chain, sk_X509_num(chain) - 1); + X509_check_purpose(x, -1, 0); + if (x->ex_flags & EXFLAG_SS) + { + x = sk_X509_pop(chain); + X509_free(x); + } + } } cpk->chain = chain; + rv = 1; + err: + if (flags & SSL_BUILD_CHAIN_FLAG_CHECK) + X509_STORE_free(chain_store); - return 1; + return rv; } int ssl_cert_set_cert_store(CERT *c, X509_STORE *store, int chain, int ref)