TLS client: Add signature_algorithms extension into ClientHello
[mech_eap.git] / src / tls / tlsv1_client_write.c
index c5a4d4e..e024371 100644 (file)
@@ -47,6 +47,7 @@ u8 * tls_send_client_hello(struct tlsv1_client *conn, size_t *out_len)
        u8 *hello, *end, *pos, *hs_length, *hs_start, *rhdr;
        struct os_time now;
        size_t len, i;
+       u8 *ext_start;
 
        wpa_printf(MSG_DEBUG, "TLSv1: Send ClientHello");
        *out_len = 0;
@@ -61,7 +62,7 @@ u8 * tls_send_client_hello(struct tlsv1_client *conn, size_t *out_len)
        wpa_hexdump(MSG_MSGDUMP, "TLSv1: client_random",
                    conn->client_random, TLS_RANDOM_LEN);
 
-       len = 100 + conn->num_cipher_suites * 2 + conn->client_hello_ext_len;
+       len = 150 + conn->num_cipher_suites * 2 + conn->client_hello_ext_len;
        hello = os_malloc(len);
        if (hello == NULL)
                return NULL;
@@ -101,12 +102,42 @@ u8 * tls_send_client_hello(struct tlsv1_client *conn, size_t *out_len)
        *pos++ = 1;
        *pos++ = TLS_COMPRESSION_NULL;
 
+       /* Extension */
+       ext_start = pos;
+       pos += 2;
+
+#ifdef CONFIG_TLSV12
+       if (conn->rl.tls_version >= TLS_VERSION_1_2) {
+               /*
+                * Add signature_algorithms extension since we support only
+                * SHA256 (and not the default SHA1) with TLSv1.2.
+                */
+               /* ExtensionsType extension_type = signature_algorithms(13) */
+               WPA_PUT_BE16(pos, TLS_EXT_SIGNATURE_ALGORITHMS);
+               pos += 2;
+               /* opaque extension_data<0..2^16-1> length */
+               WPA_PUT_BE16(pos, 4);
+               pos += 2;
+               /* supported_signature_algorithms<2..2^16-2> length */
+               WPA_PUT_BE16(pos, 2);
+               pos += 2;
+               /* supported_signature_algorithms */
+               *pos++ = TLS_HASH_ALG_SHA256;
+               *pos++ = TLS_SIGN_ALG_RSA;
+       }
+#endif /* CONFIG_TLSV12 */
+
        if (conn->client_hello_ext) {
                os_memcpy(pos, conn->client_hello_ext,
                          conn->client_hello_ext_len);
                pos += conn->client_hello_ext_len;
        }
 
+       if (pos == ext_start + 2)
+               pos -= 2; /* no extensions */
+       else
+               WPA_PUT_BE16(ext_start, pos - ext_start - 2);
+
        WPA_PUT_BE24(hs_length, pos - hs_length - 3);
        tls_verify_hash_add(&conn->verify, hs_start, pos - hs_start);