mirror of
https://github.com/openssl/openssl.git
synced 2025-04-06 20:20:50 +08:00
Move parsing and construction of CA names to separate functions
Reviewed-by: Rich Salz <rsalz@openssl.org> (Merged from https://github.com/openssl/openssl/pull/2918)
This commit is contained in:
parent
fa013b6524
commit
5d6cca05b0
@ -2174,6 +2174,7 @@ int ERR_load_SSL_strings(void);
|
||||
# define SSL_F_OSSL_STATEM_SERVER13_READ_TRANSITION 437
|
||||
# define SSL_F_OSSL_STATEM_SERVER_CONSTRUCT_MESSAGE 431
|
||||
# define SSL_F_OSSL_STATEM_SERVER_READ_TRANSITION 418
|
||||
# define SSL_F_PARSE_CA_NAMES 541
|
||||
# define SSL_F_PROCESS_KEY_SHARE_EXT 439
|
||||
# define SSL_F_READ_STATE_MACHINE 352
|
||||
# define SSL_F_SET_CLIENT_CIPHERSUITE 540
|
||||
|
@ -74,6 +74,7 @@ static ERR_STRING_DATA SSL_str_functs[] = {
|
||||
"ossl_statem_server_construct_message"},
|
||||
{ERR_FUNC(SSL_F_OSSL_STATEM_SERVER_READ_TRANSITION),
|
||||
"ossl_statem_server_read_transition"},
|
||||
{ERR_FUNC(SSL_F_PARSE_CA_NAMES), "parse_ca_names"},
|
||||
{ERR_FUNC(SSL_F_PROCESS_KEY_SHARE_EXT), "process_key_share_ext"},
|
||||
{ERR_FUNC(SSL_F_READ_STATE_MACHINE), "read_state_machine"},
|
||||
{ERR_FUNC(SSL_F_SET_CLIENT_CIPHERSUITE), "set_client_ciphersuite"},
|
||||
|
@ -65,7 +65,6 @@ static MSG_PROCESS_RETURN tls_process_encrypted_extensions(SSL *s, PACKET *pkt);
|
||||
|
||||
static ossl_inline int cert_req_allowed(SSL *s);
|
||||
static int key_exchange_expected(SSL *s);
|
||||
static int ca_dn_cmp(const X509_NAME *const *a, const X509_NAME *const *b);
|
||||
static int ssl_cipher_list_to_bytes(SSL *s, STACK_OF(SSL_CIPHER) *sk,
|
||||
WPACKET *pkt);
|
||||
|
||||
@ -2328,16 +2327,8 @@ MSG_PROCESS_RETURN tls_process_key_exchange(SSL *s, PACKET *pkt)
|
||||
MSG_PROCESS_RETURN tls_process_certificate_request(SSL *s, PACKET *pkt)
|
||||
{
|
||||
int ret = MSG_PROCESS_ERROR;
|
||||
unsigned int i, name_len;
|
||||
X509_NAME *xn = NULL;
|
||||
const unsigned char *namestart, *namebytes;
|
||||
STACK_OF(X509_NAME) *ca_sk = NULL;
|
||||
PACKET cadns;
|
||||
|
||||
if ((ca_sk = sk_X509_NAME_new(ca_dn_cmp)) == NULL) {
|
||||
SSLerr(SSL_F_TLS_PROCESS_CERTIFICATE_REQUEST, ERR_R_MALLOC_FAILURE);
|
||||
goto err;
|
||||
}
|
||||
int al = -1;
|
||||
unsigned int i;
|
||||
|
||||
if (SSL_IS_TLS13(s)) {
|
||||
PACKET reqctx;
|
||||
@ -2396,42 +2387,11 @@ MSG_PROCESS_RETURN tls_process_certificate_request(SSL *s, PACKET *pkt)
|
||||
}
|
||||
|
||||
/* get the CA RDNs */
|
||||
if (!PACKET_get_length_prefixed_2(pkt, &cadns)) {
|
||||
ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
|
||||
SSLerr(SSL_F_TLS_PROCESS_CERTIFICATE_REQUEST, SSL_R_LENGTH_MISMATCH);
|
||||
if (!parse_ca_names(s, pkt, &al)) {
|
||||
ssl3_send_alert(s, SSL3_AL_FATAL, al);
|
||||
goto err;
|
||||
}
|
||||
|
||||
while (PACKET_remaining(&cadns)) {
|
||||
if (!PACKET_get_net_2(&cadns, &name_len)
|
||||
|| !PACKET_get_bytes(&cadns, &namebytes, name_len)) {
|
||||
ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
|
||||
SSLerr(SSL_F_TLS_PROCESS_CERTIFICATE_REQUEST,
|
||||
SSL_R_LENGTH_MISMATCH);
|
||||
goto err;
|
||||
}
|
||||
|
||||
namestart = namebytes;
|
||||
|
||||
if ((xn = d2i_X509_NAME(NULL, (const unsigned char **)&namebytes,
|
||||
name_len)) == NULL) {
|
||||
ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
|
||||
SSLerr(SSL_F_TLS_PROCESS_CERTIFICATE_REQUEST, ERR_R_ASN1_LIB);
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (namebytes != (namestart + name_len)) {
|
||||
ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
|
||||
SSLerr(SSL_F_TLS_PROCESS_CERTIFICATE_REQUEST,
|
||||
SSL_R_CA_DN_LENGTH_MISMATCH);
|
||||
goto err;
|
||||
}
|
||||
if (!sk_X509_NAME_push(ca_sk, xn)) {
|
||||
SSLerr(SSL_F_TLS_PROCESS_CERTIFICATE_REQUEST, ERR_R_MALLOC_FAILURE);
|
||||
goto err;
|
||||
}
|
||||
xn = NULL;
|
||||
}
|
||||
/* TODO(TLS1.3) need to parse and process extensions, for now ignore */
|
||||
if (SSL_IS_TLS13(s)) {
|
||||
PACKET reqexts;
|
||||
@ -2452,25 +2412,15 @@ MSG_PROCESS_RETURN tls_process_certificate_request(SSL *s, PACKET *pkt)
|
||||
|
||||
/* we should setup a certificate to return.... */
|
||||
s->s3->tmp.cert_req = 1;
|
||||
sk_X509_NAME_pop_free(s->s3->tmp.ca_names, X509_NAME_free);
|
||||
s->s3->tmp.ca_names = ca_sk;
|
||||
ca_sk = NULL;
|
||||
|
||||
ret = MSG_PROCESS_CONTINUE_PROCESSING;
|
||||
goto done;
|
||||
err:
|
||||
ossl_statem_set_error(s);
|
||||
done:
|
||||
X509_NAME_free(xn);
|
||||
sk_X509_NAME_pop_free(ca_sk, X509_NAME_free);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int ca_dn_cmp(const X509_NAME *const *a, const X509_NAME *const *b)
|
||||
{
|
||||
return (X509_NAME_cmp(*a, *b));
|
||||
}
|
||||
|
||||
MSG_PROCESS_RETURN tls_process_new_session_ticket(SSL *s, PACKET *pkt)
|
||||
{
|
||||
int al = SSL_AD_DECODE_ERROR;
|
||||
|
@ -1907,3 +1907,98 @@ int create_synthetic_message_hash(SSL *s)
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int ca_dn_cmp(const X509_NAME *const *a, const X509_NAME *const *b)
|
||||
{
|
||||
return X509_NAME_cmp(*a, *b);
|
||||
}
|
||||
|
||||
int parse_ca_names(SSL *s, PACKET *pkt, int *al)
|
||||
{
|
||||
STACK_OF(X509_NAME) *ca_sk = sk_X509_NAME_new(ca_dn_cmp);
|
||||
X509_NAME *xn = NULL;
|
||||
PACKET cadns;
|
||||
|
||||
if (ca_sk == NULL) {
|
||||
SSLerr(SSL_F_PARSE_CA_NAMES, ERR_R_MALLOC_FAILURE);
|
||||
goto decerr;
|
||||
}
|
||||
/* get the CA RDNs */
|
||||
if (!PACKET_get_length_prefixed_2(pkt, &cadns)) {
|
||||
*al = SSL_AD_DECODE_ERROR;
|
||||
SSLerr(SSL_F_PARSE_CA_NAMES, SSL_R_LENGTH_MISMATCH);
|
||||
goto decerr;
|
||||
}
|
||||
|
||||
while (PACKET_remaining(&cadns)) {
|
||||
const unsigned char *namestart, *namebytes;
|
||||
unsigned int name_len;
|
||||
|
||||
if (!PACKET_get_net_2(&cadns, &name_len)
|
||||
|| !PACKET_get_bytes(&cadns, &namebytes, name_len)) {
|
||||
SSLerr(SSL_F_PARSE_CA_NAMES, SSL_R_LENGTH_MISMATCH);
|
||||
goto decerr;
|
||||
}
|
||||
|
||||
namestart = namebytes;
|
||||
if ((xn = d2i_X509_NAME(NULL, &namebytes, name_len)) == NULL) {
|
||||
SSLerr(SSL_F_PARSE_CA_NAMES, ERR_R_ASN1_LIB);
|
||||
goto decerr;
|
||||
}
|
||||
if (namebytes != (namestart + name_len)) {
|
||||
SSLerr(SSL_F_PARSE_CA_NAMES, SSL_R_CA_DN_LENGTH_MISMATCH);
|
||||
goto decerr;
|
||||
}
|
||||
|
||||
if (!sk_X509_NAME_push(ca_sk, xn)) {
|
||||
SSLerr(SSL_F_PARSE_CA_NAMES, ERR_R_MALLOC_FAILURE);
|
||||
*al = SSL_AD_INTERNAL_ERROR;
|
||||
goto err;
|
||||
}
|
||||
xn = NULL;
|
||||
}
|
||||
|
||||
sk_X509_NAME_pop_free(s->s3->tmp.ca_names, X509_NAME_free);
|
||||
s->s3->tmp.ca_names = ca_sk;
|
||||
|
||||
return 1;
|
||||
|
||||
decerr:
|
||||
*al = SSL_AD_DECODE_ERROR;
|
||||
err:
|
||||
sk_X509_NAME_pop_free(ca_sk, X509_NAME_free);
|
||||
X509_NAME_free(xn);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int construct_ca_names(SSL *s, WPACKET *pkt)
|
||||
{
|
||||
STACK_OF(X509_NAME) *ca_sk = SSL_get_client_CA_list(s);
|
||||
|
||||
/* Start sub-packet for client CA list */
|
||||
if (!WPACKET_start_sub_packet_u16(pkt))
|
||||
return 0;
|
||||
|
||||
if (ca_sk != NULL) {
|
||||
int i;
|
||||
|
||||
for (i = 0; i < sk_X509_NAME_num(ca_sk); i++) {
|
||||
unsigned char *namebytes;
|
||||
X509_NAME *name = sk_X509_NAME_value(ca_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) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!WPACKET_close(pkt))
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
@ -80,6 +80,9 @@ typedef int (*confunc_f) (SSL *s, WPACKET *pkt);
|
||||
int check_in_list(SSL *s, unsigned int group_id, const unsigned char *groups,
|
||||
size_t num_groups, int checkallow);
|
||||
int create_synthetic_message_hash(SSL *s);
|
||||
int parse_ca_names(SSL *s, PACKET *pkt, int *al);
|
||||
int construct_ca_names(SSL *s, WPACKET *pkt);
|
||||
|
||||
/*
|
||||
* TLS/DTLS client state machine functions
|
||||
*/
|
||||
|
@ -2499,9 +2499,6 @@ int tls_construct_server_key_exchange(SSL *s, WPACKET *pkt)
|
||||
|
||||
int tls_construct_certificate_request(SSL *s, WPACKET *pkt)
|
||||
{
|
||||
int i;
|
||||
STACK_OF(X509_NAME) *sk = NULL;
|
||||
|
||||
if (SSL_IS_TLS13(s)) {
|
||||
/* TODO(TLS1.3) for now send empty request context */
|
||||
if (!WPACKET_put_bytes_u8(pkt, 0)) {
|
||||
@ -2533,35 +2530,11 @@ int tls_construct_certificate_request(SSL *s, WPACKET *pkt)
|
||||
}
|
||||
}
|
||||
|
||||
/* Start sub-packet for client CA list */
|
||||
if (!WPACKET_start_sub_packet_u16(pkt)) {
|
||||
if (!construct_ca_names(s, pkt)) {
|
||||
SSLerr(SSL_F_TLS_CONSTRUCT_CERTIFICATE_REQUEST, ERR_R_INTERNAL_ERROR);
|
||||
goto err;
|
||||
}
|
||||
|
||||
sk = SSL_get_client_CA_list(s);
|
||||
if (sk != NULL) {
|
||||
for (i = 0; i < sk_X509_NAME_num(sk); i++) {
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* else no CA names */
|
||||
if (!WPACKET_close(pkt)) {
|
||||
SSLerr(SSL_F_TLS_CONSTRUCT_CERTIFICATE_REQUEST, ERR_R_INTERNAL_ERROR);
|
||||
goto err;
|
||||
}
|
||||
/*
|
||||
* TODO(TLS1.3) implement configurable certificate_extensions
|
||||
* For now just send zero length extensions.
|
||||
|
Loading…
x
Reference in New Issue
Block a user