Convert CertificateRequest construction to WPACKET

Reviewed-by: Rich Salz <rsalz@openssl.org>
This commit is contained in:
Matt Caswell 2016-09-29 14:25:52 +01:00
parent 25849a8f8b
commit 28ff8ef3f7
3 changed files with 61 additions and 59 deletions

View File

@ -3708,15 +3708,13 @@ const SSL_CIPHER *ssl3_choose_cipher(SSL *s, STACK_OF(SSL_CIPHER) *clnt,
return (ret);
}
int ssl3_get_req_cert_type(SSL *s, unsigned char *p)
int ssl3_get_req_cert_type(SSL *s, WPACKET *pkt)
{
int ret = 0;
uint32_t alg_k, alg_a = 0;
/* If we have custom certificate types set, use them */
if (s->cert->ctypes) {
memcpy(p, s->cert->ctypes, s->cert->ctype_num);
return (int)s->cert->ctype_num;
return WPACKET_memcpy(pkt, s->cert->ctypes, s->cert->ctype_num);
}
/* Get mask of algorithms disabled by signature list */
ssl_set_sig_mask(&alg_a, s, SSL_SECOP_SIGALG_MASK);
@ -3724,45 +3722,43 @@ int ssl3_get_req_cert_type(SSL *s, unsigned char *p)
alg_k = s->s3->tmp.new_cipher->algorithm_mkey;
#ifndef OPENSSL_NO_GOST
if (s->version >= TLS1_VERSION) {
if (alg_k & SSL_kGOST) {
p[ret++] = TLS_CT_GOST01_SIGN;
p[ret++] = TLS_CT_GOST12_SIGN;
p[ret++] = TLS_CT_GOST12_512_SIGN;
return (ret);
}
}
if (s->version >= TLS1_VERSION && (alg_k & SSL_kGOST))
return WPACKET_put_bytes_u8(pkt, TLS_CT_GOST01_SIGN)
&& WPACKET_put_bytes_u8(pkt, TLS_CT_GOST12_SIGN)
&& WPACKET_put_bytes_u8(pkt, TLS_CT_GOST12_512_SIGN);
#endif
if ((s->version == SSL3_VERSION) && (alg_k & SSL_kDHE)) {
#ifndef OPENSSL_NO_DH
# ifndef OPENSSL_NO_RSA
p[ret++] = SSL3_CT_RSA_EPHEMERAL_DH;
if (!WPACKET_put_bytes_u8(pkt, SSL3_CT_RSA_EPHEMERAL_DH))
return 0;
# endif
# ifndef OPENSSL_NO_DSA
p[ret++] = SSL3_CT_DSS_EPHEMERAL_DH;
if (!WPACKET_put_bytes_u8(pkt, SSL3_CT_DSS_EPHEMERAL_DH))
return 0;
# endif
#endif /* !OPENSSL_NO_DH */
}
#ifndef OPENSSL_NO_RSA
if (!(alg_a & SSL_aRSA))
p[ret++] = SSL3_CT_RSA_SIGN;
if (!(alg_a & SSL_aRSA) && !WPACKET_put_bytes_u8(pkt, SSL3_CT_RSA_SIGN))
return 0;
#endif
#ifndef OPENSSL_NO_DSA
if (!(alg_a & SSL_aDSS))
p[ret++] = SSL3_CT_DSS_SIGN;
if (!(alg_a & SSL_aDSS) && !WPACKET_put_bytes_u8(pkt, SSL3_CT_DSS_SIGN))
return 0;
#endif
#ifndef OPENSSL_NO_EC
/*
* ECDSA certs can be used with RSA cipher suites too so we don't
* need to check for SSL_kECDH or SSL_kECDHE
*/
if (s->version >= TLS1_VERSION) {
if (!(alg_a & SSL_aECDSA))
p[ret++] = TLS_CT_ECDSA_SIGN;
}
if (s->version >= TLS1_VERSION
&& !(alg_a & SSL_aECDSA)
&& !WPACKET_put_bytes_u8(pkt, TLS_CT_ECDSA_SIGN))
return 0;
#endif
return (ret);
return 1;
}
static int ssl3_set_req_cert_type(CERT *c, const unsigned char *p, size_t len)

View File

@ -1873,7 +1873,7 @@ __owur int ssl3_do_write(SSL *s, int type);
int ssl3_send_alert(SSL *s, int level, int desc);
__owur int ssl3_generate_master_secret(SSL *s, unsigned char *out,
unsigned char *p, int len);
__owur int ssl3_get_req_cert_type(SSL *s, unsigned char *p);
__owur int ssl3_get_req_cert_type(SSL *s, WPACKET *pkt);
__owur int ssl3_num_ciphers(void);
__owur const SSL_CIPHER *ssl3_get_cipher(unsigned int u);
int ssl3_renegotiate(SSL *ssl);

View File

@ -1960,62 +1960,66 @@ int tls_construct_server_key_exchange(SSL *s)
int tls_construct_certificate_request(SSL *s)
{
unsigned char *p, *d;
int i, j, nl, off, n;
int i, nl;
STACK_OF(X509_NAME) *sk = NULL;
X509_NAME *name;
BUF_MEM *buf;
WPACKET pkt;
buf = s->init_buf;
if (!WPACKET_init(&pkt, s->init_buf)
|| !ssl_set_handshake_header2(s, &pkt,
SSL3_MT_CERTIFICATE_REQUEST)) {
SSLerr(SSL_F_TLS_CONSTRUCT_CERTIFICATE_REQUEST, ERR_R_INTERNAL_ERROR);
goto err;
}
d = p = ssl_handshake_start(s);
/* get the list of acceptable cert types */
p++;
n = ssl3_get_req_cert_type(s, p);
d[0] = n;
p += n;
n++;
if (!WPACKET_start_sub_packet_u8(&pkt)
|| !ssl3_get_req_cert_type(s, &pkt)
|| !WPACKET_close(&pkt)) {
SSLerr(SSL_F_TLS_CONSTRUCT_CERTIFICATE_REQUEST, ERR_R_INTERNAL_ERROR);
goto err;
}
if (SSL_USE_SIGALGS(s)) {
const unsigned char *psigs;
unsigned char *etmp = p;
nl = tls12_get_psigalgs(s, &psigs);
/* Skip over length for now */
p += 2;
nl = tls12_copy_sigalgs_old(s, p, psigs, nl);
/* Now fill in length */
s2n(nl, etmp);
p += nl;
n += nl + 2;
if (!WPACKET_start_sub_packet_u16(&pkt)
|| !tls12_copy_sigalgs(s, &pkt, psigs, nl)
|| !WPACKET_close(&pkt)) {
SSLerr(SSL_F_TLS_CONSTRUCT_CERTIFICATE_REQUEST,
ERR_R_INTERNAL_ERROR);
goto err;
}
}
off = n;
p += 2;
n += 2;
/* Start sub-packet for client CA list */
if (!WPACKET_start_sub_packet_u16(&pkt)) {
SSLerr(SSL_F_TLS_CONSTRUCT_CERTIFICATE_REQUEST, ERR_R_INTERNAL_ERROR);
goto err;
}
sk = SSL_get_client_CA_list(s);
nl = 0;
if (sk != NULL) {
for (i = 0; i < sk_X509_NAME_num(sk); i++) {
name = sk_X509_NAME_value(sk, i);
j = i2d_X509_NAME(name, NULL);
if (!BUF_MEM_grow_clean(buf, SSL_HM_HEADER_LENGTH(s) + n + j + 2)) {
SSLerr(SSL_F_TLS_CONSTRUCT_CERTIFICATE_REQUEST, ERR_R_BUF_LIB);
unsigned char *namebytes;
X509_NAME *name = sk_X509_NAME_value(sk, i);
int namelen;
if (name == NULL
|| (namelen = i2d_X509_NAME(name, NULL)) < 0
|| !WPACKET_sub_allocate_bytes_u16(&pkt, namelen,
&namebytes)
|| i2d_X509_NAME(name, &namebytes) != namelen) {
SSLerr(SSL_F_TLS_CONSTRUCT_CERTIFICATE_REQUEST,
ERR_R_INTERNAL_ERROR);
goto err;
}
p = ssl_handshake_start(s) + n;
s2n(j, p);
i2d_X509_NAME(name, &p);
n += 2 + j;
nl += 2 + j;
}
}
/* else no CA names */
p = ssl_handshake_start(s) + off;
s2n(nl, p);
if (!ssl_set_handshake_header(s, SSL3_MT_CERTIFICATE_REQUEST, n)) {
if (!WPACKET_close(&pkt)
|| !ssl_close_construct_packet(s, &pkt)) {
SSLerr(SSL_F_TLS_CONSTRUCT_CERTIFICATE_REQUEST, ERR_R_INTERNAL_ERROR);
goto err;
}
@ -2024,6 +2028,8 @@ int tls_construct_certificate_request(SSL *s)
return 1;
err:
WPACKET_cleanup(&pkt);
ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
ossl_statem_set_error(s);
return 0;
}