Implement certificate_authorities extension
authorDr. Stephen Henson <steve@openssl.org>
Fri, 10 Mar 2017 16:31:20 +0000 (16:31 +0000)
committerDr. Stephen Henson <steve@openssl.org>
Fri, 17 Mar 2017 18:41:56 +0000 (18:41 +0000)
Reviewed-by: Rich Salz <rsalz@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/2918)

include/openssl/ssl.h
include/openssl/tls1.h
ssl/ssl_err.c
ssl/ssl_locl.h
ssl/statem/extensions.c
ssl/statem/statem_clnt.c

index bca7f29..1041e3c 100644 (file)
@@ -2336,6 +2336,7 @@ int ERR_load_SSL_strings(void);
 # define SSL_F_TLS_CHOOSE_SIGALG                          513
 # define SSL_F_TLS_CLIENT_KEY_EXCHANGE_POST_WORK          354
 # define SSL_F_TLS_COLLECT_EXTENSIONS                     435
+# define SSL_F_TLS_CONSTRUCT_CERTIFICATE_AUTHORITIES      542
 # define SSL_F_TLS_CONSTRUCT_CERTIFICATE_REQUEST          372
 # define SSL_F_TLS_CONSTRUCT_CERT_STATUS                  429
 # define SSL_F_TLS_CONSTRUCT_CERT_STATUS_BODY             494
index f2af3ab..38ad74c 100644 (file)
@@ -184,6 +184,7 @@ extern "C" {
 # define TLSEXT_TYPE_supported_versions          43
 # define TLSEXT_TYPE_cookie                      44
 # define TLSEXT_TYPE_psk_kex_modes               45
+# define TLSEXT_TYPE_certificate_authorities     47
 
 /* Temporary extension type */
 # define TLSEXT_TYPE_renegotiate                 0xff01
index a7821ac..c7e407f 100644 (file)
@@ -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"},
index 9913548..f6eb03f 100644 (file)
@@ -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;
index c4fc760..d0b15d5 100644 (file)
@@ -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
@@ -288,6 +295,14 @@ static const EXTENSION_DEFINITION ext_defs[] = {
         tls_construct_stoc_early_data, tls_construct_ctos_early_data,
         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,
@@ -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)
 {
index 4f547ac..d584bd7 100644 (file)
@@ -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,