From e970f63dc028e32df50fa7135e5e0334afa24d83 Mon Sep 17 00:00:00 2001 From: "Dr. Stephen Henson" Date: Thu, 27 Mar 2014 14:20:16 +0000 Subject: [PATCH] Update chain building function. Don't clear verification errors from the error queue unless SSL_BUILD_CHAIN_FLAG_CLEAR_ERROR is set. If errors occur during verification and SSL_BUILD_CHAIN_FLAG_IGNORE_ERROR is set return 2 so applications can issue warnings. (cherry picked from commit 2dd6976f6d02f98b30c376951ac38f780a86b3b5) --- doc/ssl/SSL_CTX_add1_chain_cert.pod | 12 +++++++++++- ssl/ssl.h | 2 ++ ssl/ssl_cert.c | 7 +++++-- 3 files changed, 18 insertions(+), 3 deletions(-) diff --git a/doc/ssl/SSL_CTX_add1_chain_cert.pod b/doc/ssl/SSL_CTX_add1_chain_cert.pod index b508a342a5..786f31e4f6 100644 --- a/doc/ssl/SSL_CTX_add1_chain_cert.pod +++ b/doc/ssl/SSL_CTX_add1_chain_cert.pod @@ -60,7 +60,9 @@ existing chain certificates as untrusted CAs, B to omit the root CA from the built chain, B to use all existing chain certificates only to build the chain (effectively sanity checking and rearranging them if necessary), the flag -B ignores any errors during verification. +B ignores any errors during verification: +if flag B is also set verification errors +are cleared from the error queue. Each of these functions operates on the I end entity (i.e. server or client) certificate. This is the last certificate loaded or @@ -113,6 +115,10 @@ For example an application can add any set of certificates using SSL_CTX_use_certificate_chain_file() then call SSL_CTX_build_cert_chain() with the option B to check and reorder them. +Applications can issue non fatal warnings when checking chains by setting +the flag B and checking the return +value. + Calling SSL_CTX_build_cert_chain() or SSL_build_cert_chain() is more efficient than the automatic chain building as it is only performed once. Automatic chain building is performed on each new session. @@ -126,6 +132,10 @@ SSL_set_current_cert() with B return 1 for success, 2 if no server certificate is used because the ciphersuites is anonymous and 0 for failure. +SSL_CTX_build_cert_chain() and SSL_build_cert_chain() return 1 for success +and 0 for failure. If the flag B and +a verification error occurs then 2 is returned. + All other functions return 1 for success and 0 for failure. =head1 SEE ALSO diff --git a/ssl/ssl.h b/ssl/ssl.h index c6cd6a9ca5..27dcb09aae 100644 --- a/ssl/ssl.h +++ b/ssl/ssl.h @@ -791,6 +791,8 @@ struct ssl_session_st #define SSL_BUILD_CHAIN_FLAG_CHECK 0x4 /* Ignore verification errors */ #define SSL_BUILD_CHAIN_FLAG_IGNORE_ERROR 0x8 +/* Clear verification errors from queue */ +#define SSL_BUILD_CHAIN_FLAG_CLEAR_ERROR 0x10 /* Flags returned by SSL_check_chain */ /* Certificate can be used with this session */ diff --git a/ssl/ssl_cert.c b/ssl/ssl_cert.c index 09ea611d8a..3ad0f8bca3 100644 --- a/ssl/ssl_cert.c +++ b/ssl/ssl_cert.c @@ -1247,8 +1247,10 @@ int ssl_build_cert_chain(CERT *c, X509_STORE *chain_store, int flags) i = X509_verify_cert(&xs_ctx); if (i <= 0 && flags & SSL_BUILD_CHAIN_FLAG_IGNORE_ERROR) { - ERR_clear_error(); + if (flags & SSL_BUILD_CHAIN_FLAG_CLEAR_ERROR) + ERR_clear_error(); i = 1; + rv = 2; } if (i > 0) chain = X509_STORE_CTX_get1_chain(&xs_ctx); @@ -1283,7 +1285,8 @@ int ssl_build_cert_chain(CERT *c, X509_STORE *chain_store, int flags) } } cpk->chain = chain; - rv = 1; + if (rv == 0) + rv = 1; err: if (flags & SSL_BUILD_CHAIN_FLAG_CHECK) X509_STORE_free(chain_store);