New certificate_authorities functions
[openssl.git] / ssl / statem / extensions.c
index f11f5e03b970a3cafc4a590903b179acb53ad8b3..22669dd565b2b20a16dedaf71e63a45274107098 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
@@ -159,8 +166,9 @@ static const EXTENSION_DEFINITION ext_defs[] = {
     },
     {
         TLSEXT_TYPE_signature_algorithms,
-        EXT_CLIENT_HELLO,
-        init_sig_algs, tls_parse_ctos_sig_algs, NULL, NULL,
+        EXT_CLIENT_HELLO | EXT_TLS1_3_CERTIFICATE_REQUEST,
+        init_sig_algs, tls_parse_ctos_sig_algs,
+        tls_parse_ctos_sig_algs, tls_construct_ctos_sig_algs,
         tls_construct_ctos_sig_algs, final_sig_algs
     },
 #ifndef OPENSSL_NO_OCSP
@@ -287,9 +295,16 @@ 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 */
-        /* TODO(TLS1.3): Fix me */
         TLSEXT_TYPE_padding,
         EXT_CLIENT_HELLO,
         NULL,
@@ -310,7 +325,7 @@ static const EXTENSION_DEFINITION ext_defs[] = {
  * Verify whether we are allowed to use the extension |type| in the current
  * |context|. Returns 1 to indicate the extension is allowed or unknown or 0 to
  * indicate the extension is not allowed. If returning 1 then |*found| is set to
- * 1 if we found a definition for the extension, and |*idx| is set to its index
+ * the definition for the extension we found.
  */
 static int verify_extension(SSL *s, unsigned int context, unsigned int type,
                             custom_ext_methods *meths, RAW_EXTENSION *rawexlist,
@@ -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.peer_ca_names, X509_NAME_free);
+    s->s3->tmp.peer_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)
 {
@@ -1186,11 +1242,18 @@ int tls_psk_do_binder(SSL *s, const EVP_MD *md, const unsigned char *msgstart,
          * ClientHello - which we don't want - so we need to take that bit off.
          */
         if (s->server) {
-            if (hdatalen < s->init_num + SSL3_HM_HEADER_LENGTH) {
+            PACKET hashprefix, msg;
+
+            /* Find how many bytes are left after the first two messages */
+            if (!PACKET_buf_init(&hashprefix, hdata, hdatalen)
+                    || !PACKET_forward(&hashprefix, 1)
+                    || !PACKET_get_length_prefixed_3(&hashprefix, &msg)
+                    || !PACKET_forward(&hashprefix, 1)
+                    || !PACKET_get_length_prefixed_3(&hashprefix, &msg)) {
                 SSLerr(SSL_F_TLS_PSK_DO_BINDER, ERR_R_INTERNAL_ERROR);
                 goto err;
             }
-            hdatalen -= s->init_num + SSL3_HM_HEADER_LENGTH;
+            hdatalen -= PACKET_remaining(&hashprefix);
         }
 
         if (EVP_DigestUpdate(mctx, hdata, hdatalen) <= 0) {