Rename the chain variable to chainidx
[openssl.git] / ssl / statem / extensions_clnt.c
index f291e5ff150e8d67dc4c9c8873737d23b76e474b..277e0624a4a698737eb07c6ecaa1970e2e4d5569 100644 (file)
@@ -12,7 +12,8 @@
 #include "../ssl_locl.h"
 #include "statem_locl.h"
 
-int tls_construct_ctos_renegotiate(SSL *s, WPACKET *pkt, int *al)
+int tls_construct_ctos_renegotiate(SSL *s, WPACKET *pkt, X509 *x,
+                                   size_t chainidx, int *al)
 {
     /* Add RI if renegotiating */
     if (!s->renegotiate)
@@ -30,7 +31,8 @@ int tls_construct_ctos_renegotiate(SSL *s, WPACKET *pkt, int *al)
     return 1;
 }
 
-int tls_construct_ctos_server_name(SSL *s, WPACKET *pkt, int *al)
+int tls_construct_ctos_server_name(SSL *s, WPACKET *pkt, X509 *x,
+                                   size_t chainidx, int *al)
 {
     if (s->tlsext_hostname == NULL)
         return 1;
@@ -54,7 +56,8 @@ int tls_construct_ctos_server_name(SSL *s, WPACKET *pkt, int *al)
 }
 
 #ifndef OPENSSL_NO_SRP
-int tls_construct_ctos_srp(SSL *s, WPACKET *pkt, int *al)
+int tls_construct_ctos_srp(SSL *s, WPACKET *pkt, X509 *x, size_t chainidx,
+                           int *al)
 {
     /* Add SRP username if there is one */
     if (s->srp_ctx.login == NULL)
@@ -105,7 +108,8 @@ static int use_ecc(SSL *s)
     return i < end;
 }
 
-int tls_construct_ctos_ec_pt_formats(SSL *s, WPACKET *pkt, int *al)
+int tls_construct_ctos_ec_pt_formats(SSL *s, WPACKET *pkt, X509 *x,
+                                     size_t chainidx, int *al)
 {
     const unsigned char *pformats;
     size_t num_formats;
@@ -128,8 +132,8 @@ int tls_construct_ctos_ec_pt_formats(SSL *s, WPACKET *pkt, int *al)
     return 1;
 }
 
-
-int tls_construct_ctos_supported_groups(SSL *s, WPACKET *pkt, int *al)
+int tls_construct_ctos_supported_groups(SSL *s, WPACKET *pkt, X509 *x,
+                                        size_t chainidx, int *al)
 {
     const unsigned char *pcurves = NULL, *pcurvestmp;
     size_t num_curves = 0, i;
@@ -178,7 +182,8 @@ int tls_construct_ctos_supported_groups(SSL *s, WPACKET *pkt, int *al)
 }
 #endif
 
-int tls_construct_ctos_session_ticket(SSL *s, WPACKET *pkt, int *al)
+int tls_construct_ctos_session_ticket(SSL *s, WPACKET *pkt, X509 *x,
+                                      size_t chainidx, int *al)
 {
     size_t ticklen;
 
@@ -217,7 +222,8 @@ int tls_construct_ctos_session_ticket(SSL *s, WPACKET *pkt, int *al)
     return 1;
 }
 
-int tls_construct_ctos_sig_algs(SSL *s, WPACKET *pkt, int *al)
+int tls_construct_ctos_sig_algs(SSL *s, WPACKET *pkt, X509 *x, size_t chainidx,
+                                int *al)
 {
     size_t salglen;
     const unsigned char *salg;
@@ -242,10 +248,15 @@ int tls_construct_ctos_sig_algs(SSL *s, WPACKET *pkt, int *al)
 }
 
 #ifndef OPENSSL_NO_OCSP
-int tls_construct_ctos_status_request(SSL *s, WPACKET *pkt, int *al)
+int tls_construct_ctos_status_request(SSL *s, WPACKET *pkt, X509 *x,
+                                      size_t chainidx, int *al)
 {
     int i;
 
+    /* This extension isn't defined for client Certificates */
+    if (x != NULL)
+        return 1;
+
     if (s->tlsext_status_type != TLSEXT_STATUSTYPE_ocsp)
         return 1;
 
@@ -304,7 +315,8 @@ int tls_construct_ctos_status_request(SSL *s, WPACKET *pkt, int *al)
 #endif
 
 #ifndef OPENSSL_NO_NEXTPROTONEG
-int tls_construct_ctos_npn(SSL *s, WPACKET *pkt, int *al)
+int tls_construct_ctos_npn(SSL *s, WPACKET *pkt, X509 *x, size_t chainidx,
+                           int *al)
 {
     if (s->ctx->next_proto_select_cb == NULL || s->s3->tmp.finish_md_len != 0)
         return 1;
@@ -323,7 +335,8 @@ int tls_construct_ctos_npn(SSL *s, WPACKET *pkt, int *al)
 }
 #endif
 
-int tls_construct_ctos_alpn(SSL *s, WPACKET *pkt, int *al)
+int tls_construct_ctos_alpn(SSL *s, WPACKET *pkt, X509 *x, size_t chainidx,
+                            int *al)
 {
     s->s3->alpn_sent = 0;
 
@@ -351,7 +364,8 @@ int tls_construct_ctos_alpn(SSL *s, WPACKET *pkt, int *al)
 
 
 #ifndef OPENSSL_NO_SRTP
-int tls_construct_ctos_use_srtp(SSL *s, WPACKET *pkt, int *al)
+int tls_construct_ctos_use_srtp(SSL *s, WPACKET *pkt, X509 *x, size_t chainidx,
+                                int *al)
 {
     STACK_OF(SRTP_PROTECTION_PROFILE) *clnt = SSL_get_srtp_profiles(s);
     int i, end;
@@ -390,7 +404,8 @@ int tls_construct_ctos_use_srtp(SSL *s, WPACKET *pkt, int *al)
 }
 #endif
 
-int tls_construct_ctos_etm(SSL *s, WPACKET *pkt, int *al)
+int tls_construct_ctos_etm(SSL *s, WPACKET *pkt, X509 *x, size_t chainidx,
+                           int *al)
 {
     if (s->options & SSL_OP_NO_ENCRYPT_THEN_MAC)
         return 1;
@@ -405,11 +420,16 @@ int tls_construct_ctos_etm(SSL *s, WPACKET *pkt, int *al)
 }
 
 #ifndef OPENSSL_NO_CT
-int tls_construct_ctos_sct(SSL *s, WPACKET *pkt, int *al)
+int tls_construct_ctos_sct(SSL *s, WPACKET *pkt, X509 *x, size_t chainidx,
+                           int *al)
 {
     if (s->ct_validation_callback == NULL)
         return 1;
 
+    /* Not defined for client Certificates */
+    if (x != NULL)
+        return 1;
+
     if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_signed_certificate_timestamp)
             || !WPACKET_put_bytes_u16(pkt, 0)) {
         SSLerr(SSL_F_TLS_CONSTRUCT_CTOS_SCT, ERR_R_INTERNAL_ERROR);
@@ -420,7 +440,8 @@ int tls_construct_ctos_sct(SSL *s, WPACKET *pkt, int *al)
 }
 #endif
 
-int tls_construct_ctos_ems(SSL *s, WPACKET *pkt, int *al)
+int tls_construct_ctos_ems(SSL *s, WPACKET *pkt, X509 *x, size_t chainidx,
+                           int *al)
 {
     if (!WPACKET_put_bytes_u16(pkt, TLSEXT_TYPE_extended_master_secret)
             || !WPACKET_put_bytes_u16(pkt, 0)) {
@@ -431,7 +452,8 @@ int tls_construct_ctos_ems(SSL *s, WPACKET *pkt, int *al)
     return 1;
 }
 
-int tls_construct_ctos_supported_versions(SSL *s, WPACKET *pkt, int *al)
+int tls_construct_ctos_supported_versions(SSL *s, WPACKET *pkt, X509 *x,
+                                          size_t chainidx, int *al)
 {
     int currv, min_version, max_version, reason;
 
@@ -477,8 +499,8 @@ int tls_construct_ctos_supported_versions(SSL *s, WPACKET *pkt, int *al)
     return 1;
 }
 
-
-int tls_construct_ctos_key_share(SSL *s, WPACKET *pkt, int *al)
+int tls_construct_ctos_key_share(SSL *s, WPACKET *pkt, X509 *x, size_t chainidx,
+                                 int *al)
 {
 #ifndef OPENSSL_NO_TLS1_3
     size_t i, sharessent = 0, num_curves = 0;
@@ -568,7 +590,8 @@ int tls_construct_ctos_key_share(SSL *s, WPACKET *pkt, int *al)
 #define F5_WORKAROUND_MIN_MSG_LEN   0xff
 #define F5_WORKAROUND_MAX_MSG_LEN   0x200
 
-int tls_construct_ctos_padding(SSL *s, WPACKET *pkt, int *al)
+int tls_construct_ctos_padding(SSL *s, WPACKET *pkt, X509 *x, size_t chainidx,
+                               int *al)
 {
     unsigned char *padbytes;
     size_t hlen;
@@ -614,7 +637,8 @@ int tls_construct_ctos_padding(SSL *s, WPACKET *pkt, int *al)
 /*
  * Parse the server's renegotiation binding and abort if it's not right
  */
-int tls_parse_stoc_renegotiate(SSL *s, PACKET *pkt, int *al)
+int tls_parse_stoc_renegotiate(SSL *s, PACKET *pkt, X509 *x, size_t chainidx,
+                               int *al)
 {
     size_t expected_len = s->s3->previous_client_finished_len
         + s->s3->previous_server_finished_len;
@@ -671,7 +695,8 @@ int tls_parse_stoc_renegotiate(SSL *s, PACKET *pkt, int *al)
     return 1;
 }
 
-int tls_parse_stoc_server_name(SSL *s, PACKET *pkt, int *al)
+int tls_parse_stoc_server_name(SSL *s, PACKET *pkt, X509 *x, size_t chainidx,
+                               int *al)
 {
     if (s->tlsext_hostname == NULL || PACKET_remaining(pkt) > 0) {
         *al = SSL_AD_UNRECOGNIZED_NAME;
@@ -694,7 +719,8 @@ int tls_parse_stoc_server_name(SSL *s, PACKET *pkt, int *al)
 }
 
 #ifndef OPENSSL_NO_EC
-int tls_parse_stoc_ec_pt_formats(SSL *s, PACKET *pkt, int *al)
+int tls_parse_stoc_ec_pt_formats(SSL *s, PACKET *pkt, X509 *x, size_t chainidx,
+                                 int *al)
 {
     unsigned int ecpointformatlist_length;
     PACKET ecptformatlist;
@@ -729,7 +755,8 @@ int tls_parse_stoc_ec_pt_formats(SSL *s, PACKET *pkt, int *al)
 }
 #endif
 
-int tls_parse_stoc_session_ticket(SSL *s, PACKET *pkt, int *al)
+int tls_parse_stoc_session_ticket(SSL *s, PACKET *pkt, X509 *x, size_t chainidx,
+                                  int *al)
 {
     if (s->tls_session_ticket_ext_cb != NULL &&
         !s->tls_session_ticket_ext_cb(s, PACKET_data(pkt),
@@ -750,17 +777,28 @@ int tls_parse_stoc_session_ticket(SSL *s, PACKET *pkt, int *al)
 }
 
 #ifndef OPENSSL_NO_OCSP
-int tls_parse_stoc_status_request(SSL *s, PACKET *pkt, int *al)
+int tls_parse_stoc_status_request(SSL *s, PACKET *pkt, X509 *x, size_t chainidx,
+                                  int *al)
 {
     /*
-     * MUST be empty and only sent if we've requested a status
-     * request message.
+     * MUST only be sent if we've requested a status
+     * request message. In TLS <= 1.2 it must also be empty.
      */
     if (s->tlsext_status_type == TLSEXT_STATUSTYPE_nothing
-            || PACKET_remaining(pkt) > 0) {
+            || (!SSL_IS_TLS13(s) && PACKET_remaining(pkt) > 0)) {
         *al = SSL_AD_UNSUPPORTED_EXTENSION;
         return 0;
     }
+
+    if (SSL_IS_TLS13(s)) {
+        /* We only know how to handle this if it's for the first Certificate in
+         * the chain. We ignore any other repsonses.
+         */
+        if (chainidx != 0)
+            return 1;
+        return tls_process_cert_status_body(s, pkt, al);
+    }
+
     /* Set flag to expect CertificateStatus message */
     s->tlsext_status_expected = 1;
 
@@ -770,7 +808,7 @@ int tls_parse_stoc_status_request(SSL *s, PACKET *pkt, int *al)
 
 
 #ifndef OPENSSL_NO_CT
-int tls_parse_stoc_sct(SSL *s, PACKET *pkt, int *al)
+int tls_parse_stoc_sct(SSL *s, PACKET *pkt, X509 *x, size_t chainidx, int *al)
 {
     /*
      * Only take it if we asked for it - i.e if there is no CT validation
@@ -823,7 +861,7 @@ static int ssl_next_proto_validate(PACKET *pkt)
     return 1;
 }
 
-int tls_parse_stoc_npn(SSL *s, PACKET *pkt, int *al)
+int tls_parse_stoc_npn(SSL *s, PACKET *pkt, X509 *x, size_t chainidx, int *al)
 {
     unsigned char *selected;
     unsigned char selected_len;
@@ -873,7 +911,7 @@ int tls_parse_stoc_npn(SSL *s, PACKET *pkt, int *al)
 }
 #endif
 
-int tls_parse_stoc_alpn(SSL *s, PACKET *pkt, int *al)
+int tls_parse_stoc_alpn(SSL *s, PACKET *pkt, X509 *x, size_t chainidx, int *al)
 {
     size_t len;
 
@@ -910,7 +948,8 @@ int tls_parse_stoc_alpn(SSL *s, PACKET *pkt, int *al)
 }
 
 #ifndef OPENSSL_NO_SRTP
-int tls_parse_stoc_use_srtp(SSL *s, PACKET *pkt, int *al)
+int tls_parse_stoc_use_srtp(SSL *s, PACKET *pkt, X509 *x, size_t chainidx,
+                            int *al)
 {
     unsigned int id, ct, mki;
     int i;
@@ -963,7 +1002,7 @@ int tls_parse_stoc_use_srtp(SSL *s, PACKET *pkt, int *al)
 }
 #endif
 
-int tls_parse_stoc_etm(SSL *s, PACKET *pkt, int *al)
+int tls_parse_stoc_etm(SSL *s, PACKET *pkt, X509 *x, size_t chainidx, int *al)
 {
     /* Ignore if inappropriate ciphersuite */
     if (!(s->options & SSL_OP_NO_ENCRYPT_THEN_MAC)
@@ -974,7 +1013,7 @@ int tls_parse_stoc_etm(SSL *s, PACKET *pkt, int *al)
     return 1;
 }
 
-int tls_parse_stoc_ems(SSL *s, PACKET *pkt, int *al)
+int tls_parse_stoc_ems(SSL *s, PACKET *pkt, X509 *x, size_t chainidx, int *al)
 {
     s->s3->flags |= TLS1_FLAGS_RECEIVED_EXTMS;
     if (!s->hit)
@@ -983,7 +1022,8 @@ int tls_parse_stoc_ems(SSL *s, PACKET *pkt, int *al)
     return 1;
 }
 
-int tls_parse_stoc_key_share(SSL *s, PACKET *pkt, int *al)
+int tls_parse_stoc_key_share(SSL *s, PACKET *pkt, X509 *x, size_t chainidx,
+                             int *al)
 {
 #ifndef OPENSSL_NO_TLS1_3
     unsigned int group_id;