Commit e970f63d authored by Dr. Stephen Henson's avatar Dr. Stephen Henson
Browse files

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)
parent 7c5718be
Loading
Loading
Loading
Loading
+11 −1
Original line number Original line Diff line number Diff line
@@ -60,7 +60,9 @@ existing chain certificates as untrusted CAs, B<SSL_BUILD_CHAIN_FLAG_NO_ROOT>
to omit the root CA from the built chain, B<SSL_BUILD_CHAIN_FLAG_CHECK> to
to omit the root CA from the built chain, B<SSL_BUILD_CHAIN_FLAG_CHECK> to
use all existing chain certificates only to build the chain (effectively
use all existing chain certificates only to build the chain (effectively
sanity checking and rearranging them if necessary), the flag
sanity checking and rearranging them if necessary), the flag
B<SSL_BUILD_CHAIN_FLAG_IGNORE_ERROR> ignores any errors during verification.
B<SSL_BUILD_CHAIN_FLAG_IGNORE_ERROR> ignores any errors during verification:
if flag B<SSL_BUILD_CHAIN_FLAG_CLEAR_ERROR> is also set verification errors
are cleared from the error queue.


Each of these functions operates on the I<current> end entity
Each of these functions operates on the I<current> end entity
(i.e. server or client) certificate. This is the last certificate loaded or
(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()
SSL_CTX_use_certificate_chain_file() then call SSL_CTX_build_cert_chain()
with the option B<SSL_BUILD_CHAIN_FLAG_CHECK> to check and reorder them.
with the option B<SSL_BUILD_CHAIN_FLAG_CHECK> to check and reorder them.


Applications can issue non fatal warnings when checking chains by setting
the flag B<SSL_BUILD_CHAIN_FLAG_IGNORE_ERRORS> and checking the return
value.

Calling SSL_CTX_build_cert_chain() or SSL_build_cert_chain() is more
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.
efficient than the automatic chain building as it is only performed once.
Automatic chain building is performed on each new session.
Automatic chain building is performed on each new session.
@@ -126,6 +132,10 @@ SSL_set_current_cert() with B<SSL_CERT_SET_SERVER> return 1 for success, 2 if
no server certificate is used because the ciphersuites is anonymous and 0
no server certificate is used because the ciphersuites is anonymous and 0
for failure.
for failure.


SSL_CTX_build_cert_chain() and SSL_build_cert_chain() return 1 for success
and 0 for failure. If the flag B<SSL_BUILD_CHAIN_FLAG_IGNORE_ERROR> and
a verification error occurs then 2 is returned.

All other functions return 1 for success and 0 for failure.
All other functions return 1 for success and 0 for failure.


=head1 SEE ALSO
=head1 SEE ALSO
+2 −0
Original line number Original line Diff line number Diff line
@@ -791,6 +791,8 @@ struct ssl_session_st
#define SSL_BUILD_CHAIN_FLAG_CHECK		0x4
#define SSL_BUILD_CHAIN_FLAG_CHECK		0x4
/* Ignore verification errors */
/* Ignore verification errors */
#define SSL_BUILD_CHAIN_FLAG_IGNORE_ERROR	0x8
#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 */
/* Flags returned by SSL_check_chain */
/* Certificate can be used with this session */
/* Certificate can be used with this session */
+5 −2
Original line number Original line Diff line number Diff line
@@ -1247,8 +1247,10 @@ int ssl_build_cert_chain(CERT *c, X509_STORE *chain_store, int flags)
	i = X509_verify_cert(&xs_ctx);
	i = X509_verify_cert(&xs_ctx);
	if (i <= 0 && flags & SSL_BUILD_CHAIN_FLAG_IGNORE_ERROR)
	if (i <= 0 && flags & SSL_BUILD_CHAIN_FLAG_IGNORE_ERROR)
		{
		{
		if (flags & SSL_BUILD_CHAIN_FLAG_CLEAR_ERROR)
			ERR_clear_error();
			ERR_clear_error();
		i = 1;
		i = 1;
		rv = 2;
		}
		}
	if (i > 0)
	if (i > 0)
		chain = X509_STORE_CTX_get1_chain(&xs_ctx);
		chain = X509_STORE_CTX_get1_chain(&xs_ctx);
@@ -1283,6 +1285,7 @@ int ssl_build_cert_chain(CERT *c, X509_STORE *chain_store, int flags)
			}
			}
		}
		}
	cpk->chain = chain;
	cpk->chain = chain;
	if (rv == 0)
		rv = 1;
		rv = 1;
	err:
	err:
	if (flags & SSL_BUILD_CHAIN_FLAG_CHECK)
	if (flags & SSL_BUILD_CHAIN_FLAG_CHECK)