提交 f71c6e52 编写于 作者: D Dr. Stephen Henson

Add support for distinct certificate chains per key type and per SSL

structure.

Before this the only way to add a custom chain was in the parent SSL_CTX
(which is shared by all key types and SSL structures) or rely on auto
chain building (which is performed on each handshake) from the trust store.
上级 9ade64de
......@@ -4,6 +4,10 @@
Changes between 1.0.1 and 1.1.0 [xx XXX xxxx]
*) Enhance SSL/TLS certificate chain handling to support different
chains for each certificate instead of one chain in the parent SSL_CTX.
[Steve Henson]
*) Support for fixed DH ciphersuite client authentication: where both
server and client use DH certificates with common parameters.
[Steve Henson]
......
......@@ -3350,6 +3350,21 @@ long ssl3_ctrl(SSL *s, int cmd, long larg, void *parg)
#endif
#endif /* !OPENSSL_NO_TLSEXT */
case SSL_CTRL_CHAIN:
if (larg)
return ssl_cert_set1_chain(s->cert,
(STACK_OF (X509) *)parg);
else
return ssl_cert_set0_chain(s->cert,
(STACK_OF (X509) *)parg);
case SSL_CTRL_CHAIN_CERT:
if (larg)
return ssl_cert_add1_chain_cert(s->cert, (X509 *)parg);
else
return ssl_cert_add0_chain_cert(s->cert, (X509 *)parg);
default:
break;
}
......@@ -3642,6 +3657,20 @@ long ssl3_ctx_ctrl(SSL_CTX *ctx, int cmd, long larg, void *parg)
}
break;
case SSL_CTRL_CHAIN:
if (larg)
return ssl_cert_set1_chain(ctx->cert,
(STACK_OF (X509) *)parg);
else
return ssl_cert_set0_chain(ctx->cert,
(STACK_OF (X509) *)parg);
case SSL_CTRL_CHAIN_CERT:
if (larg)
return ssl_cert_add1_chain_cert(ctx->cert, (X509 *)parg);
else
return ssl_cert_add0_chain_cert(ctx->cert, (X509 *)parg);
default:
return(0);
}
......
......@@ -1615,6 +1615,9 @@ DECLARE_PEM_rw(SSL_SESSION, SSL_SESSION)
#define SSL_CTRL_GET_EXTRA_CHAIN_CERTS 82
#define SSL_CTRL_CLEAR_EXTRA_CHAIN_CERTS 83
#define SSL_CTRL_CHAIN 88
#define SSL_CTRL_CHAIN_CERT 89
#define DTLSv1_get_timeout(ssl, arg) \
SSL_ctrl(ssl,DTLS_CTRL_GET_TIMEOUT,0, (void *)arg)
#define DTLSv1_handle_timeout(ssl) \
......@@ -1656,6 +1659,24 @@ DECLARE_PEM_rw(SSL_SESSION, SSL_SESSION)
#define SSL_CTX_clear_extra_chain_certs(ctx) \
SSL_CTX_ctrl(ctx,SSL_CTRL_CLEAR_EXTRA_CHAIN_CERTS,0,NULL)
#define SSL_CTX_set0_chain(ctx,sk) \
SSL_CTX_ctrl(ctx,SSL_CTRL_CHAIN,0,(char *)sk)
#define SSL_CTX_set1_chain(ctx,sk) \
SSL_CTX_ctrl(ctx,SSL_CTRL_CHAIN,1,(char *)sk)
#define SSL_CTX_add0_chain_cert(ctx,x509) \
SSL_CTX_ctrl(ctx,SSL_CTRL_CHAIN_CERT,0,(char *)x509)
#define SSL_CTX_add1_chain_cert(ctx,x509) \
SSL_CTX_ctrl(ctx,SSL_CTRL_CHAIN_CERT,1,(char *)x509)
#define SSL_set0_chain(ctx,sk) \
SSL_ctrl(ctx,SSL_CTRL_CHAIN,0,(char *)sk)
#define SSL_set1_chain(ctx,sk) \
SSL_ctrl(ctx,SSL_CTRL_CHAIN,1,(char *)sk)
#define SSL_add0_chain_cert(ctx,x509) \
SSL_ctrl(ctx,SSL_CTRL_CHAIN_CERT,0,(char *)x509)
#define SSL_add1_chain_cert(ctx,x509) \
SSL_ctrl(ctx,SSL_CTRL_CHAIN_CERT,1,(char *)x509)
#ifndef OPENSSL_NO_BIO
BIO_METHOD *BIO_f_ssl(void);
BIO *BIO_new_ssl(SSL_CTX *ctx,int client);
......
......@@ -317,11 +317,23 @@ CERT *ssl_cert_dup(CERT *cert)
SSLerr(SSL_F_SSL_CERT_DUP, SSL_R_LIBRARY_BUG);
}
}
if (cpk->chain)
{
rpk->chain = sk_X509_dup(cpk->chain);
if (!rpk->chain)
{
SSLerr(SSL_F_SSL_CERT_DUP, ERR_R_MALLOC_FAILURE);
goto err;
}
for (i = 0; i < sk_X509_num(rpk->chain); i++)
{
X509 *x = sk_X509_value(rpk->chain, i);
CRYPTO_add(&x->references, 1, CRYPTO_LOCK_X509);
}
}
}
/* ret->extra_certs *should* exist, but currently the own certificate
* chain is held inside SSL_CTX */
ret->references=1;
/* Set digests to defaults. NB: we don't copy existing values as they
* will be set during handshake.
......@@ -353,6 +365,8 @@ err:
X509_free(rpk->x509);
if (rpk->privatekey != NULL)
EVP_PKEY_free(rpk->privatekey);
if (rpk->chain)
sk_X509_pop_free(rpk->chain, X509_free);
}
......@@ -397,6 +411,8 @@ void ssl_cert_free(CERT *c)
X509_free(cpk->x509);
if (cpk->privatekey != NULL)
EVP_PKEY_free(cpk->privatekey);
if (cpk->chain)
sk_X509_pop_free(cpk->chain, X509_free);
#if 0
if (c->pkeys[i].publickey != NULL)
EVP_PKEY_free(c->pkeys[i].publickey);
......@@ -433,6 +449,59 @@ int ssl_cert_inst(CERT **o)
return(1);
}
int ssl_cert_set0_chain(CERT *c, STACK_OF(X509) *chain)
{
CERT_PKEY *cpk = c->key;
if (!cpk)
return 0;
if (cpk->chain)
sk_X509_pop_free(cpk->chain, X509_free);
cpk->chain = chain;
return 1;
}
int ssl_cert_set1_chain(CERT *c, STACK_OF(X509) *chain)
{
STACK_OF(X509) *dchain;
X509 *x;
int i;
if (!chain)
return ssl_cert_set0_chain(c, NULL);
dchain = sk_X509_dup(chain);
if (!dchain)
return 0;
for (i = 0; i < sk_X509_num(dchain); i++)
{
x = sk_X509_value(dchain, i);
CRYPTO_add(&x->references, 1, CRYPTO_LOCK_X509);
}
if (!ssl_cert_set0_chain(c, dchain))
{
sk_X509_pop_free(dchain, X509_free);
return 0;
}
return 1;
}
int ssl_cert_add0_chain_cert(CERT *c, X509 *x)
{
CERT_PKEY *cpk = c->key;
if (!cpk)
return 0;
if (!cpk->chain)
cpk->chain = sk_X509_new_null();
if (!cpk->chain || !sk_X509_push(cpk->chain, x))
return 0;
return 1;
}
int ssl_cert_add1_chain_cert(CERT *c, X509 *x)
{
if (!ssl_cert_add0_chain_cert(c, x))
return 0;
CRYPTO_add(&x->references, 1, CRYPTO_LOCK_X509);
return 1;
}
SESS_CERT *ssl_sess_cert_new(void)
{
......@@ -884,13 +953,22 @@ int ssl_add_cert_chain(SSL *s, CERT_PKEY *cpk, unsigned long *l)
int i;
X509 *x;
STACK_OF(X509) *extra_certs;
if (cpk)
x = cpk->x509;
else
x = NULL;
if ((s->mode & SSL_MODE_NO_AUTO_CHAIN) || s->ctx->extra_certs)
/* If we have a certificate specific chain use it, else use
* parent ctx.
*/
if (cpk && cpk->chain)
extra_certs = cpk->chain;
else
extra_certs = s->ctx->extra_certs;
if ((s->mode & SSL_MODE_NO_AUTO_CHAIN) || extra_certs)
no_chain = 1;
else
no_chain = 0;
......@@ -933,10 +1011,9 @@ int ssl_add_cert_chain(SSL *s, CERT_PKEY *cpk, unsigned long *l)
X509_STORE_CTX_cleanup(&xs_ctx);
}
}
/* Thawte special :-) */
for (i=0; i<sk_X509_num(s->ctx->extra_certs); i++)
for (i=0; i<sk_X509_num(extra_certs); i++)
{
x=sk_X509_value(s->ctx->extra_certs,i);
x=sk_X509_value(extra_certs,i);
if (!ssl_add_cert_to_buf(buf, l, x))
return 0;
}
......
......@@ -472,6 +472,8 @@ typedef struct cert_pkey_st
EVP_PKEY *privatekey;
/* Digest to use when signing */
const EVP_MD *digest;
/* Chain for this certificate */
STACK_OF(X509) *chain;
} CERT_PKEY;
typedef struct cert_st
......@@ -824,6 +826,11 @@ void ssl_update_cache(SSL *s, int mode);
int ssl_cipher_get_evp(const SSL_SESSION *s,const EVP_CIPHER **enc,
const EVP_MD **md,int *mac_pkey_type,int *mac_secret_size, SSL_COMP **comp);
int ssl_get_handshake_digest(int i,long *mask,const EVP_MD **md);
int ssl_cert_set0_chain(CERT *c, STACK_OF(X509) *chain);
int ssl_cert_set1_chain(CERT *c, STACK_OF(X509) *chain);
int ssl_cert_add0_chain_cert(CERT *c, X509 *x);
int ssl_cert_add1_chain_cert(CERT *c, X509 *x);
int ssl_verify_cert_chain(SSL *s,STACK_OF(X509) *sk);
int ssl_add_cert_chain(SSL *s, CERT_PKEY *cpk, unsigned long *l);
int ssl_undefined_function(SSL *s);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册