Tidy/enhance certificate chain output code.
New function ssl_add_cert_chain which adds a certificate chain to SSL internal BUF_MEM. Use this function in ssl3_output_cert_chain and dtls1_output_cert_chain instead of partly duplicating code.
This commit is contained in:
parent
7568d15acd
commit
4379d0e457
6 changed files with 93 additions and 132 deletions
|
@ -992,70 +992,14 @@ int dtls1_send_change_cipher_spec(SSL *s, int a, int b)
|
|||
return(dtls1_do_write(s,SSL3_RT_CHANGE_CIPHER_SPEC));
|
||||
}
|
||||
|
||||
static int dtls1_add_cert_to_buf(BUF_MEM *buf, unsigned long *l, X509 *x)
|
||||
{
|
||||
int n;
|
||||
unsigned char *p;
|
||||
|
||||
n=i2d_X509(x,NULL);
|
||||
if (!BUF_MEM_grow_clean(buf,(int)(n+(*l)+3)))
|
||||
{
|
||||
SSLerr(SSL_F_DTLS1_ADD_CERT_TO_BUF,ERR_R_BUF_LIB);
|
||||
return 0;
|
||||
}
|
||||
p=(unsigned char *)&(buf->data[*l]);
|
||||
l2n3(n,p);
|
||||
i2d_X509(x,&p);
|
||||
*l+=n+3;
|
||||
|
||||
return 1;
|
||||
}
|
||||
unsigned long dtls1_output_cert_chain(SSL *s, X509 *x)
|
||||
{
|
||||
unsigned char *p;
|
||||
int i;
|
||||
unsigned long l= 3 + DTLS1_HM_HEADER_LENGTH;
|
||||
BUF_MEM *buf;
|
||||
BUF_MEM *buf=s->init_buf;
|
||||
|
||||
/* TLSv1 sends a chain with nothing in it, instead of an alert */
|
||||
buf=s->init_buf;
|
||||
if (!BUF_MEM_grow_clean(buf,10))
|
||||
{
|
||||
SSLerr(SSL_F_DTLS1_OUTPUT_CERT_CHAIN,ERR_R_BUF_LIB);
|
||||
return(0);
|
||||
}
|
||||
if (x != NULL)
|
||||
{
|
||||
X509_STORE_CTX xs_ctx;
|
||||
|
||||
if (!X509_STORE_CTX_init(&xs_ctx,s->ctx->cert_store,x,NULL))
|
||||
{
|
||||
SSLerr(SSL_F_DTLS1_OUTPUT_CERT_CHAIN,ERR_R_X509_LIB);
|
||||
return(0);
|
||||
}
|
||||
|
||||
X509_verify_cert(&xs_ctx);
|
||||
/* Don't leave errors in the queue */
|
||||
ERR_clear_error();
|
||||
for (i=0; i < sk_X509_num(xs_ctx.chain); i++)
|
||||
{
|
||||
x = sk_X509_value(xs_ctx.chain, i);
|
||||
|
||||
if (!dtls1_add_cert_to_buf(buf, &l, x))
|
||||
{
|
||||
X509_STORE_CTX_cleanup(&xs_ctx);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
X509_STORE_CTX_cleanup(&xs_ctx);
|
||||
}
|
||||
/* Thawte special :-) */
|
||||
for (i=0; i<sk_X509_num(s->ctx->extra_certs); i++)
|
||||
{
|
||||
x=sk_X509_value(s->ctx->extra_certs,i);
|
||||
if (!dtls1_add_cert_to_buf(buf, &l, x))
|
||||
return 0;
|
||||
}
|
||||
if (!ssl_add_cert_chain(s, x, &l))
|
||||
return 0;
|
||||
|
||||
l-= (3 + DTLS1_HM_HEADER_LENGTH);
|
||||
|
||||
|
|
|
@ -321,84 +321,14 @@ int ssl3_send_change_cipher_spec(SSL *s, int a, int b)
|
|||
return(ssl3_do_write(s,SSL3_RT_CHANGE_CIPHER_SPEC));
|
||||
}
|
||||
|
||||
static int ssl3_add_cert_to_buf(BUF_MEM *buf, unsigned long *l, X509 *x)
|
||||
{
|
||||
int n;
|
||||
unsigned char *p;
|
||||
|
||||
n=i2d_X509(x,NULL);
|
||||
if (!BUF_MEM_grow_clean(buf,(int)(n+(*l)+3)))
|
||||
{
|
||||
SSLerr(SSL_F_SSL3_ADD_CERT_TO_BUF,ERR_R_BUF_LIB);
|
||||
return(-1);
|
||||
}
|
||||
p=(unsigned char *)&(buf->data[*l]);
|
||||
l2n3(n,p);
|
||||
i2d_X509(x,&p);
|
||||
*l+=n+3;
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
unsigned long ssl3_output_cert_chain(SSL *s, X509 *x)
|
||||
{
|
||||
unsigned char *p;
|
||||
int i;
|
||||
unsigned long l=7;
|
||||
BUF_MEM *buf;
|
||||
int no_chain;
|
||||
BUF_MEM *buf = s->init_buf;
|
||||
|
||||
if ((s->mode & SSL_MODE_NO_AUTO_CHAIN) || s->ctx->extra_certs)
|
||||
no_chain = 1;
|
||||
else
|
||||
no_chain = 0;
|
||||
|
||||
/* TLSv1 sends a chain with nothing in it, instead of an alert */
|
||||
buf=s->init_buf;
|
||||
if (!BUF_MEM_grow_clean(buf,10))
|
||||
{
|
||||
SSLerr(SSL_F_SSL3_OUTPUT_CERT_CHAIN,ERR_R_BUF_LIB);
|
||||
return(0);
|
||||
}
|
||||
if (x != NULL)
|
||||
{
|
||||
if (no_chain)
|
||||
{
|
||||
if (ssl3_add_cert_to_buf(buf, &l, x))
|
||||
return(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
X509_STORE_CTX xs_ctx;
|
||||
|
||||
if (!X509_STORE_CTX_init(&xs_ctx,s->ctx->cert_store,x,NULL))
|
||||
{
|
||||
SSLerr(SSL_F_SSL3_OUTPUT_CERT_CHAIN,ERR_R_X509_LIB);
|
||||
return(0);
|
||||
}
|
||||
X509_verify_cert(&xs_ctx);
|
||||
/* Don't leave errors in the queue */
|
||||
ERR_clear_error();
|
||||
for (i=0; i < sk_X509_num(xs_ctx.chain); i++)
|
||||
{
|
||||
x = sk_X509_value(xs_ctx.chain, i);
|
||||
|
||||
if (ssl3_add_cert_to_buf(buf, &l, x))
|
||||
{
|
||||
X509_STORE_CTX_cleanup(&xs_ctx);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
X509_STORE_CTX_cleanup(&xs_ctx);
|
||||
}
|
||||
}
|
||||
/* Thawte special :-) */
|
||||
for (i=0; i<sk_X509_num(s->ctx->extra_certs); i++)
|
||||
{
|
||||
x=sk_X509_value(s->ctx->extra_certs,i);
|
||||
if (ssl3_add_cert_to_buf(buf, &l, x))
|
||||
return(0);
|
||||
}
|
||||
if (!ssl_add_cert_chain(s, x, &l))
|
||||
return 0;
|
||||
|
||||
l-=7;
|
||||
p=(unsigned char *)&(buf->data[4]);
|
||||
|
|
|
@ -2175,6 +2175,8 @@ void ERR_load_SSL_strings(void);
|
|||
#define SSL_F_SSL3_SETUP_WRITE_BUFFER 291
|
||||
#define SSL_F_SSL3_WRITE_BYTES 158
|
||||
#define SSL_F_SSL3_WRITE_PENDING 159
|
||||
#define SSL_F_SSL_ADD_CERT_CHAIN 316
|
||||
#define SSL_F_SSL_ADD_CERT_TO_BUF 317
|
||||
#define SSL_F_SSL_ADD_CLIENTHELLO_RENEGOTIATE_EXT 298
|
||||
#define SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT 277
|
||||
#define SSL_F_SSL_ADD_CLIENTHELLO_USE_SRTP_EXT 307
|
||||
|
|
|
@ -851,3 +851,85 @@ err:
|
|||
return ret;
|
||||
}
|
||||
|
||||
/* Add a certificate to a BUF_MEM structure */
|
||||
|
||||
static int ssl_add_cert_to_buf(BUF_MEM *buf, unsigned long *l, X509 *x)
|
||||
{
|
||||
int n;
|
||||
unsigned char *p;
|
||||
|
||||
n=i2d_X509(x,NULL);
|
||||
if (!BUF_MEM_grow_clean(buf,(int)(n+(*l)+3)))
|
||||
{
|
||||
SSLerr(SSL_F_SSL_ADD_CERT_TO_BUF,ERR_R_BUF_LIB);
|
||||
return 0;
|
||||
}
|
||||
p=(unsigned char *)&(buf->data[*l]);
|
||||
l2n3(n,p);
|
||||
i2d_X509(x,&p);
|
||||
*l+=n+3;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Add certificate chain to internal SSL BUF_MEM strcuture */
|
||||
int ssl_add_cert_chain(SSL *s, X509 *x, unsigned long *l)
|
||||
{
|
||||
BUF_MEM *buf = s->init_buf;
|
||||
int no_chain;
|
||||
int i;
|
||||
|
||||
if ((s->mode & SSL_MODE_NO_AUTO_CHAIN) || s->ctx->extra_certs)
|
||||
no_chain = 1;
|
||||
else
|
||||
no_chain = 0;
|
||||
|
||||
/* TLSv1 sends a chain with nothing in it, instead of an alert */
|
||||
if (!BUF_MEM_grow_clean(buf,10))
|
||||
{
|
||||
SSLerr(SSL_F_SSL_ADD_CERT_CHAIN,ERR_R_BUF_LIB);
|
||||
return 0;
|
||||
}
|
||||
if (x != NULL)
|
||||
{
|
||||
if (no_chain)
|
||||
{
|
||||
if (!ssl_add_cert_to_buf(buf, l, x))
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
X509_STORE_CTX xs_ctx;
|
||||
|
||||
if (!X509_STORE_CTX_init(&xs_ctx,s->ctx->cert_store,x,NULL))
|
||||
{
|
||||
SSLerr(SSL_F_SSL_ADD_CERT_CHAIN,ERR_R_X509_LIB);
|
||||
return(0);
|
||||
}
|
||||
X509_verify_cert(&xs_ctx);
|
||||
/* Don't leave errors in the queue */
|
||||
ERR_clear_error();
|
||||
for (i=0; i < sk_X509_num(xs_ctx.chain); i++)
|
||||
{
|
||||
x = sk_X509_value(xs_ctx.chain, i);
|
||||
|
||||
if (ssl_add_cert_to_buf(buf, l, x))
|
||||
{
|
||||
X509_STORE_CTX_cleanup(&xs_ctx);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
X509_STORE_CTX_cleanup(&xs_ctx);
|
||||
}
|
||||
}
|
||||
/* Thawte special :-) */
|
||||
for (i=0; i<sk_X509_num(s->ctx->extra_certs); i++)
|
||||
{
|
||||
x=sk_X509_value(s->ctx->extra_certs,i);
|
||||
if (!ssl_add_cert_to_buf(buf, l, x))
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
|
|
@ -180,6 +180,8 @@ static ERR_STRING_DATA SSL_str_functs[]=
|
|||
{ERR_FUNC(SSL_F_SSL3_SETUP_WRITE_BUFFER), "SSL3_SETUP_WRITE_BUFFER"},
|
||||
{ERR_FUNC(SSL_F_SSL3_WRITE_BYTES), "SSL3_WRITE_BYTES"},
|
||||
{ERR_FUNC(SSL_F_SSL3_WRITE_PENDING), "SSL3_WRITE_PENDING"},
|
||||
{ERR_FUNC(SSL_F_SSL_ADD_CERT_CHAIN), "SSL_ADD_CERT_CHAIN"},
|
||||
{ERR_FUNC(SSL_F_SSL_ADD_CERT_TO_BUF), "SSL_ADD_CERT_TO_BUF"},
|
||||
{ERR_FUNC(SSL_F_SSL_ADD_CLIENTHELLO_RENEGOTIATE_EXT), "SSL_ADD_CLIENTHELLO_RENEGOTIATE_EXT"},
|
||||
{ERR_FUNC(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT), "SSL_ADD_CLIENTHELLO_TLSEXT"},
|
||||
{ERR_FUNC(SSL_F_SSL_ADD_CLIENTHELLO_USE_SRTP_EXT), "SSL_ADD_CLIENTHELLO_USE_SRTP_EXT"},
|
||||
|
|
|
@ -825,6 +825,7 @@ 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_verify_cert_chain(SSL *s,STACK_OF(X509) *sk);
|
||||
int ssl_add_cert_chain(SSL *s, X509 *x, unsigned long *l);
|
||||
int ssl_undefined_function(SSL *s);
|
||||
int ssl_undefined_void_function(void);
|
||||
int ssl_undefined_const_function(const SSL *s);
|
||||
|
|
Loading…
Reference in a new issue