New chain building flags.
New flags to build certificate chains. The can be used to rearrange the chain so all an application needs to do is add all certificates in arbitrary order and then build the chain to check and correct them. Add verify error code when building chain. (Imported from upstream's c5ea65b157e17743c881b9e348524b0281b3d39f)
This commit is contained in:
parent
5685363771
commit
f669c2d91a
@ -735,9 +735,13 @@ struct ssl_session_st
|
||||
|
||||
/* Flags for building certificate chains */
|
||||
/* Treat any existing certificates as untrusted CAs */
|
||||
#define SSL_BUILD_CHAIN_FLAG_UNTRUSTED 0x1
|
||||
#define SSL_BUILD_CHAIN_FLAG_UNTRUSTED 0x1
|
||||
/* Don't include root CA in chain */
|
||||
#define SSL_BUILD_CHAIN_FLAG_NO_ROOT 0x2
|
||||
#define SSL_BUILD_CHAIN_FLAG_NO_ROOT 0x2
|
||||
/* Just check certificates already there */
|
||||
#define SSL_BUILD_CHAIN_FLAG_CHECK 0x4
|
||||
/* Ignore verification errors */
|
||||
#define SSL_BUILD_CHAIN_FLAG_IGNORE_ERROR 0x8
|
||||
|
||||
/* Flags returned by SSL_check_chain */
|
||||
/* Certificate can be used with this session */
|
||||
|
@ -1337,37 +1337,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)
|
||||
{
|
||||
OPENSSL_PUT_ERROR(SSL, 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))
|
||||
{
|
||||
OPENSSL_PUT_ERROR(SSL, 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)
|
||||
{
|
||||
OPENSSL_PUT_ERROR(SSL, 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 */
|
||||
@ -1375,12 +1403,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)
|
||||
|
Loading…
Reference in New Issue
Block a user