diff options
author | Dr. Stephen Henson <steve@openssl.org> | 2017-03-10 16:31:20 +0000 |
---|---|---|
committer | Dr. Stephen Henson <steve@openssl.org> | 2017-03-17 18:41:56 +0000 |
commit | 45615c5fac0aba7bd41be270c4bcf194bf1049f4 (patch) | |
tree | 39448b65ed8e3b80c6ec9a2f5211e08e9bbd85dc /ssl | |
parent | 32f661079d6a4bd5aa22921ed9cdbc3369ec40e8 (diff) |
Implement certificate_authorities extension
Reviewed-by: Rich Salz <rsalz@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/2918)
Diffstat (limited to 'ssl')
-rw-r--r-- | ssl/ssl_err.c | 2 | ||||
-rw-r--r-- | ssl/ssl_locl.h | 1 | ||||
-rw-r--r-- | ssl/statem/extensions.c | 56 | ||||
-rw-r--r-- | ssl/statem/statem_clnt.c | 2 |
4 files changed, 60 insertions, 1 deletions
diff --git a/ssl/ssl_err.c b/ssl/ssl_err.c index a7821ac4ac..c7e407fc27 100644 --- a/ssl/ssl_err.c +++ b/ssl/ssl_err.c @@ -282,6 +282,8 @@ static ERR_STRING_DATA SSL_str_functs[] = { {ERR_FUNC(SSL_F_TLS_CLIENT_KEY_EXCHANGE_POST_WORK), "tls_client_key_exchange_post_work"}, {ERR_FUNC(SSL_F_TLS_COLLECT_EXTENSIONS), "tls_collect_extensions"}, + {ERR_FUNC(SSL_F_TLS_CONSTRUCT_CERTIFICATE_AUTHORITIES), + "tls_construct_certificate_authorities"}, {ERR_FUNC(SSL_F_TLS_CONSTRUCT_CERTIFICATE_REQUEST), "tls_construct_certificate_request"}, {ERR_FUNC(SSL_F_TLS_CONSTRUCT_CERT_STATUS), "tls_construct_cert_status"}, diff --git a/ssl/ssl_locl.h b/ssl/ssl_locl.h index 9913548c88..f6eb03f4d9 100644 --- a/ssl/ssl_locl.h +++ b/ssl/ssl_locl.h @@ -1808,6 +1808,7 @@ typedef enum tlsext_index_en { TLSEXT_IDX_cookie, TLSEXT_IDX_cryptopro_bug, TLSEXT_IDX_early_data, + TLSEXT_IDX_certificate_authorities, TLSEXT_IDX_padding, TLSEXT_IDX_psk } TLSEXT_INDEX; diff --git a/ssl/statem/extensions.c b/ssl/statem/extensions.c index c4fc760b97..d0b15d576a 100644 --- a/ssl/statem/extensions.c +++ b/ssl/statem/extensions.c @@ -30,6 +30,13 @@ static int init_npn(SSL *s, unsigned int context); static int init_alpn(SSL *s, unsigned int context); static int final_alpn(SSL *s, unsigned int context, int sent, int *al); static int init_sig_algs(SSL *s, unsigned int context); +static int init_certificate_authorities(SSL *s, unsigned int context); +static int tls_construct_certificate_authorities(SSL *s, WPACKET *pkt, + unsigned int context, X509 *x, + size_t chainidx, int *al); +static int tls_parse_certificate_authorities(SSL *s, PACKET *pkt, + unsigned int context, X509 *x, + size_t chainidx, int *al); #ifndef OPENSSL_NO_SRP static int init_srp(SSL *s, unsigned int context); #endif @@ -289,6 +296,14 @@ static const EXTENSION_DEFINITION ext_defs[] = { final_early_data }, { + TLSEXT_TYPE_certificate_authorities, + EXT_CLIENT_HELLO | EXT_TLS1_3_CERTIFICATE_REQUEST | EXT_TLS1_3_ONLY, + init_certificate_authorities, + tls_parse_certificate_authorities, tls_parse_certificate_authorities, + tls_construct_certificate_authorities, + tls_construct_certificate_authorities, NULL, + }, + { /* Must be immediately before pre_shared_key */ TLSEXT_TYPE_padding, EXT_CLIENT_HELLO, @@ -966,6 +981,47 @@ static int final_ems(SSL *s, unsigned int context, int sent, int *al) return 1; } +static int init_certificate_authorities(SSL *s, unsigned int context) +{ + sk_X509_NAME_pop_free(s->s3->tmp.ca_names, X509_NAME_free); + s->s3->tmp.ca_names = NULL; + return 1; +} + +static int tls_construct_certificate_authorities(SSL *s, WPACKET *pkt, + unsigned int context, X509 *x, + size_t chainidx, int *al) +{ + STACK_OF(X509_NAME) *ca_sk = SSL_get_client_CA_list(s); + + if (ca_sk == NULL || sk_X509_NAME_num(ca_sk) == 0) + return 1; + + if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_certificate_authorities) + || !WPACKET_start_sub_packet_u16(pkt) + || !construct_ca_names(s, pkt) + || !WPACKET_close(pkt)) { + SSLerr(SSL_F_TLS_CONSTRUCT_CERTIFICATE_AUTHORITIES, + ERR_R_INTERNAL_ERROR); + return 0; + } + + return 1; +} + +static int tls_parse_certificate_authorities(SSL *s, PACKET *pkt, + unsigned int context, X509 *x, + size_t chainidx, int *al) +{ + if (!parse_ca_names(s, pkt, al)) + return 0; + if (PACKET_remaining(pkt) != 0) { + *al = SSL_AD_DECODE_ERROR; + return 0; + } + return 1; +} + #ifndef OPENSSL_NO_SRTP static int init_srtp(SSL *s, unsigned int context) { diff --git a/ssl/statem/statem_clnt.c b/ssl/statem/statem_clnt.c index 4f547acdbb..d584bd72fe 100644 --- a/ssl/statem/statem_clnt.c +++ b/ssl/statem/statem_clnt.c @@ -2351,7 +2351,7 @@ MSG_PROCESS_RETURN tls_process_certificate_request(SSL *s, PACKET *pkt) } if (!PACKET_get_length_prefixed_2(pkt, &extensions)) { - SSLerr(SSL_F_TLS_PROCESS_CLIENT_CERTIFICATE, SSL_R_BAD_LENGTH); + SSLerr(SSL_F_TLS_PROCESS_CERTIFICATE_REQUEST, SSL_R_BAD_LENGTH); goto err; } if (!tls_collect_extensions(s, &extensions, |