From f5ea34f1252967ee5ad5ff90ad7a55bb52c8144a Mon Sep 17 00:00:00 2001 From: jsing <> Date: Fri, 11 Aug 2017 21:12:39 +0000 Subject: Sort by extension/function name. --- src/regress/lib/libssl/tlsext/tlsexttest.c | 1335 ++++++++++++++-------------- 1 file changed, 667 insertions(+), 668 deletions(-) (limited to 'src') diff --git a/src/regress/lib/libssl/tlsext/tlsexttest.c b/src/regress/lib/libssl/tlsext/tlsexttest.c index 4f9e6e29e2..df448924a3 100644 --- a/src/regress/lib/libssl/tlsext/tlsexttest.c +++ b/src/regress/lib/libssl/tlsext/tlsexttest.c @@ -1,4 +1,4 @@ -/* $OpenBSD: tlsexttest.c,v 1.5 2017/08/11 20:14:13 doug Exp $ */ +/* $OpenBSD: tlsexttest.c,v 1.6 2017/08/11 21:12:39 jsing Exp $ */ /* * Copyright (c) 2017 Joel Sing * @@ -73,290 +73,361 @@ do { \ } while(0) /* - * Renegotiation Indication - RFC 5746. + * Supported Elliptic Curves - RFC 4492 section 5.1.1. + * + * This extension is only used by the client. */ -static unsigned char tlsext_ri_prev_client[] = { - 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, - 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff, +static uint8_t tlsext_ec_clienthello_default[] = { + 0x00, 0x06, + 0x00, 0x1d, /* X25519 (29) */ + 0x00, 0x17, /* secp256r1 (23) */ + 0x00, 0x18 /* secp384r1 (24) */ }; -static unsigned char tlsext_ri_prev_server[] = { - 0xff, 0xee, 0xdd, 0xcc, 0xbb, 0xaa, 0x99, 0x88, - 0x77, 0x66, 0x55, 0x44, 0x33, 0x22, 0x11, 0x00, +static uint16_t tlsext_ec_clienthello_secp384r1_val[] = { + 0x0018 /* tls1_ec_nid2curve_id(NID_secp384r1) */ }; - -static unsigned char tlsext_ri_clienthello[] = { - 0x10, - 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, - 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff, +static uint8_t tlsext_ec_clienthello_secp384r1[] = { + 0x00, 0x02, + 0x00, 0x18 /* secp384r1 (24) */ }; -static unsigned char tlsext_ri_serverhello[] = { - 0x20, - 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, - 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff, - 0xff, 0xee, 0xdd, 0xcc, 0xbb, 0xaa, 0x99, 0x88, - 0x77, 0x66, 0x55, 0x44, 0x33, 0x22, 0x11, 0x00, +/* Example from RFC 4492 section 5.1.1 */ +static uint16_t tlsext_ec_clienthello_nistp192and224_val[] = { + 0x0013, /* tls1_ec_nid2curve_id(NID_X9_62_prime192v1) */ + 0x0015 /* tls1_ec_nid2curve_id(NID_secp224r1) */ +}; +static uint8_t tlsext_ec_clienthello_nistp192and224[] = { + 0x00, 0x04, + 0x00, 0x13, /* secp192r1 aka NIST P-192 */ + 0x00, 0x15 /* secp224r1 aka NIST P-224 */ }; static int -test_tlsext_ri_clienthello(void) +test_tlsext_ec_clienthello(void) { unsigned char *data = NULL; SSL_CTX *ssl_ctx = NULL; SSL *ssl = NULL; - int failure = 0; size_t dlen; - int alert; + int failure, alert; CBB cbb; CBS cbs; + failure = 1; + CBB_init(&cbb, 0); - if ((ssl_ctx = SSL_CTX_new(TLSv1_2_client_method())) == NULL) + if ((ssl_ctx = SSL_CTX_new(TLS_client_method())) == NULL) errx(1, "failed to create SSL_CTX"); if ((ssl = SSL_new(ssl_ctx)) == NULL) errx(1, "failed to create SSL"); - if (tlsext_ri_clienthello_needs(ssl)) { - fprintf(stderr, "FAIL: clienthello should not need RI\n"); - failure = 1; - goto done; + /* + * Default ciphers include EC so we need it by default. + */ + if (!tlsext_ec_clienthello_needs(ssl)) { + FAIL("clienthello should need Ellipticcurves for default " + "ciphers\n"); + goto err; } - if (!SSL_renegotiate(ssl)) { - fprintf(stderr, "FAIL: client failed to set renegotiate\n"); - failure = 1; - goto done; + /* + * Exclude cipher suites so we can test not including it. + */ + if (!SSL_set_cipher_list(ssl, "TLSv1.2:!ECDHE:!ECDSA")) { + FAIL("clienthello should be able to set cipher list\n"); + goto err; + } + if (tlsext_ec_clienthello_needs(ssl)) { + FAIL("clienthello should not need Ellipticcurves\n"); + goto err; } - if (!tlsext_ri_clienthello_needs(ssl)) { - fprintf(stderr, "FAIL: clienthello should need RI\n"); - failure = 1; - goto done; + /* + * Use libtls default for the rest of the testing + */ + if (!SSL_set_cipher_list(ssl, "TLSv1.2+AEAD+ECDHE")) { + FAIL("clienthello should be able to set cipher list\n"); + goto err; + } + if (!tlsext_ec_clienthello_needs(ssl)) { + FAIL("clienthello should need Ellipticcurves\n"); + goto err; } - memcpy(S3I(ssl)->previous_client_finished, tlsext_ri_prev_client, - sizeof(tlsext_ri_prev_client)); - S3I(ssl)->previous_client_finished_len = sizeof(tlsext_ri_prev_client); + /* + * Test with a session secp384r1. The default is used instead. + */ + if ((ssl->session = SSL_SESSION_new()) == NULL) + errx(1, "failed to create session"); - S3I(ssl)->renegotiate_seen = 0; + if ((SSI(ssl)->tlsext_supportedgroups = malloc(sizeof(uint16_t))) + == NULL) { + FAIL("client could not malloc\n"); + goto err; + } + SSI(ssl)->tlsext_supportedgroups[0] = tls1_ec_nid2curve_id(NID_secp384r1); + SSI(ssl)->tlsext_supportedgroups_length = 1; - if (!tlsext_ri_clienthello_build(ssl, &cbb)) { - fprintf(stderr, "FAIL: clienthello failed to build RI\n"); - failure = 1; - goto done; + if (!tlsext_ec_clienthello_needs(ssl)) { + FAIL("clienthello should need Ellipticcurves\n"); + goto err; + } + + if (!tlsext_ec_clienthello_build(ssl, &cbb)) { + FAIL("clienthello failed to build Ellipticcurves\n"); + goto err; } if (!CBB_finish(&cbb, &data, &dlen)) errx(1, "failed to finish CBB"); - if (dlen != sizeof(tlsext_ri_clienthello)) { - fprintf(stderr, "FAIL: got clienthello RI with length %zu, " - "want length %zu\n", dlen, sizeof(tlsext_ri_clienthello)); - failure = 1; - goto done; - } - - if (memcmp(data, tlsext_ri_clienthello, dlen) != 0) { - fprintf(stderr, "FAIL: clienthello RI differs:\n"); - fprintf(stderr, "received:\n"); - hexdump(data, dlen); - fprintf(stderr, "test data:\n"); - hexdump(tlsext_ri_clienthello, sizeof(tlsext_ri_clienthello)); - failure = 1; - goto done; + if (dlen != sizeof(tlsext_ec_clienthello_default)) { + FAIL("got clienthello Ellipticcurves with length %zu, " + "want length %zu\n", dlen, + sizeof(tlsext_ec_clienthello_default)); + compare_data(data, dlen, tlsext_ec_clienthello_default, + sizeof(tlsext_ec_clienthello_default)); + goto err; } - CBS_init(&cbs, tlsext_ri_clienthello, sizeof(tlsext_ri_clienthello)); - if (!tlsext_ri_clienthello_parse(ssl, &cbs, &alert)) { - fprintf(stderr, "FAIL: failed to parse clienthello RI\n"); - failure = 1; - goto done; + if (memcmp(data, tlsext_ec_clienthello_default, dlen) != 0) { + FAIL("clienthello Ellipticcurves differs:\n"); + compare_data(data, dlen, tlsext_ec_clienthello_default, + sizeof(tlsext_ec_clienthello_default)); + goto err; } - if (S3I(ssl)->renegotiate_seen != 1) { - fprintf(stderr, "FAIL: renegotiate seen not set\n"); - failure = 1; - goto done; - } - if (S3I(ssl)->send_connection_binding != 1) { - fprintf(stderr, "FAIL: send connection binding not set\n"); - failure = 1; - goto done; - } + /* + * Test parsing secp384r1 + */ + CBB_cleanup(&cbb); + CBB_init(&cbb, 0); + free(data); + data = NULL; - memset(S3I(ssl)->previous_client_finished, 0, - sizeof(S3I(ssl)->previous_client_finished)); + SSL_SESSION_free(ssl->session); + if ((ssl->session = SSL_SESSION_new()) == NULL) + errx(1, "failed to create session"); - S3I(ssl)->renegotiate_seen = 0; + CBS_init(&cbs, tlsext_ec_clienthello_secp384r1, + sizeof(tlsext_ec_clienthello_secp384r1)); + if (!tlsext_ec_clienthello_parse(ssl, &cbs, &alert)) { + FAIL("failed to parse clienthello Ellipticcurves\n"); + goto err; + } - CBS_init(&cbs, tlsext_ri_clienthello, sizeof(tlsext_ri_clienthello)); - if (tlsext_ri_clienthello_parse(ssl, &cbs, &alert)) { - fprintf(stderr, "FAIL: parsed invalid clienthello RI\n"); - failure = 1; - goto done; + if (SSI(ssl)->tlsext_supportedgroups_length != + sizeof(tlsext_ec_clienthello_secp384r1_val) / sizeof(uint16_t)) { + FAIL("no tlsext_ellipticcurves from clienthello " + "Ellipticcurves\n"); + goto err; } - if (S3I(ssl)->renegotiate_seen == 1) { - fprintf(stderr, "FAIL: renegotiate seen set\n"); - failure = 1; - goto done; + if (memcmp(SSI(ssl)->tlsext_supportedgroups, + tlsext_ec_clienthello_secp384r1_val, + sizeof(tlsext_ec_clienthello_secp384r1_val)) != 0) { + FAIL("clienthello had an incorrect Ellipticcurves " + "entry\n"); + compare_data2(SSI(ssl)->tlsext_supportedgroups, + SSI(ssl)->tlsext_supportedgroups_length * 2, + tlsext_ec_clienthello_secp384r1_val, + sizeof(tlsext_ec_clienthello_secp384r1_val)); + goto err; } - done: + /* + * Use a custom order. + */ CBB_cleanup(&cbb); - SSL_CTX_free(ssl_ctx); - SSL_free(ssl); - free(data); - - return (failure); -} - -static int -test_tlsext_ri_serverhello(void) -{ - unsigned char *data = NULL; - SSL_CTX *ssl_ctx = NULL; - SSL *ssl = NULL; - int failure = 0; - size_t dlen; - int alert; - CBB cbb; - CBS cbs; - CBB_init(&cbb, 0); - if ((ssl_ctx = SSL_CTX_new(TLS_server_method())) == NULL) - errx(1, "failed to create SSL_CTX"); - if ((ssl = SSL_new(ssl_ctx)) == NULL) - errx(1, "failed to create SSL"); + SSL_SESSION_free(ssl->session); + if ((ssl->session = SSL_SESSION_new()) == NULL) + errx(1, "failed to create session"); - if (tlsext_ri_serverhello_needs(ssl)) { - fprintf(stderr, "FAIL: serverhello should not need RI\n"); - failure = 1; - goto done; + if ((ssl->internal->tlsext_supportedgroups = malloc(sizeof(uint16_t) * 2)) == NULL) { + FAIL("client could not malloc\n"); + goto err; } + ssl->internal->tlsext_supportedgroups[0] = tls1_ec_nid2curve_id(NID_X9_62_prime192v1); + ssl->internal->tlsext_supportedgroups[1] = tls1_ec_nid2curve_id(NID_secp224r1); + ssl->internal->tlsext_supportedgroups_length = 2; - S3I(ssl)->send_connection_binding = 1; - - if (!tlsext_ri_serverhello_needs(ssl)) { - fprintf(stderr, "FAIL: serverhello should need RI\n"); - failure = 1; - goto done; + if (!tlsext_ec_clienthello_needs(ssl)) { + FAIL("clienthello should need Ellipticcurves\n"); + goto err; } - memcpy(S3I(ssl)->previous_client_finished, tlsext_ri_prev_client, - sizeof(tlsext_ri_prev_client)); - S3I(ssl)->previous_client_finished_len = sizeof(tlsext_ri_prev_client); - - memcpy(S3I(ssl)->previous_server_finished, tlsext_ri_prev_server, - sizeof(tlsext_ri_prev_server)); - S3I(ssl)->previous_server_finished_len = sizeof(tlsext_ri_prev_server); - - S3I(ssl)->renegotiate_seen = 0; - - if (!tlsext_ri_serverhello_build(ssl, &cbb)) { - fprintf(stderr, "FAIL: serverhello failed to build RI\n"); - failure = 1; - goto done; - } + if (!tlsext_ec_clienthello_build(ssl, &cbb)) { + FAIL("clienthello failed to build Ellipticcurves\n"); + goto err; + } if (!CBB_finish(&cbb, &data, &dlen)) errx(1, "failed to finish CBB"); - if (dlen != sizeof(tlsext_ri_serverhello)) { - fprintf(stderr, "FAIL: got serverhello RI with length %zu, " - "want length %zu\n", dlen, sizeof(tlsext_ri_serverhello)); - failure = 1; - goto done; + if (dlen != sizeof(tlsext_ec_clienthello_nistp192and224)) { + FAIL("got clienthello Ellipticcurves with length %zu, " + "want length %zu\n", dlen, + sizeof(tlsext_ec_clienthello_nistp192and224)); + fprintf(stderr, "received:\n"); + hexdump(data, dlen); + fprintf(stderr, "test data:\n"); + hexdump(tlsext_ec_clienthello_nistp192and224, + sizeof(tlsext_ec_clienthello_nistp192and224)); + goto err; } - if (memcmp(data, tlsext_ri_serverhello, dlen) != 0) { - fprintf(stderr, "FAIL: serverhello RI differs:\n"); + if (memcmp(data, tlsext_ec_clienthello_nistp192and224, dlen) != 0) { + FAIL("clienthello Ellipticcurves differs:\n"); fprintf(stderr, "received:\n"); hexdump(data, dlen); fprintf(stderr, "test data:\n"); - hexdump(tlsext_ri_serverhello, sizeof(tlsext_ri_serverhello)); - failure = 1; - goto done; + hexdump(tlsext_ec_clienthello_nistp192and224, + sizeof(tlsext_ec_clienthello_nistp192and224)); + goto err; } - CBS_init(&cbs, tlsext_ri_serverhello, sizeof(tlsext_ri_serverhello)); - if (!tlsext_ri_serverhello_parse(ssl, &cbs, &alert)) { - fprintf(stderr, "FAIL: failed to parse serverhello RI\n"); - failure = 1; - goto done; + /* + * Parse non-default curves to session. + */ + CBB_cleanup(&cbb); + CBB_init(&cbb, 0); + free(data); + data = NULL; + + SSL_SESSION_free(ssl->session); + if ((ssl->session = SSL_SESSION_new()) == NULL) + errx(1, "failed to create session"); + + /* Reset back to the default list. */ + free(ssl->internal->tlsext_supportedgroups); + ssl->internal->tlsext_supportedgroups = NULL; + ssl->internal->tlsext_supportedgroups_length = 0; + + CBS_init(&cbs, tlsext_ec_clienthello_nistp192and224, + sizeof(tlsext_ec_clienthello_nistp192and224)); + if (!tlsext_ec_clienthello_parse(ssl, &cbs, &alert)) { + FAIL("failed to parse clienthello Ellipticcurves\n"); + goto err; } - if (S3I(ssl)->renegotiate_seen != 1) { - fprintf(stderr, "FAIL: renegotiate seen not set\n"); - failure = 1; - goto done; + if (SSI(ssl)->tlsext_supportedgroups_length != + sizeof(tlsext_ec_clienthello_nistp192and224_val) / sizeof(uint16_t)) { + FAIL("no tlsext_ellipticcurves from clienthello " + "Ellipticcurves\n"); + goto err; } - if (S3I(ssl)->send_connection_binding != 1) { - fprintf(stderr, "FAIL: send connection binding not set\n"); - failure = 1; - goto done; + + if (memcmp(SSI(ssl)->tlsext_supportedgroups, + tlsext_ec_clienthello_nistp192and224_val, + sizeof(tlsext_ec_clienthello_nistp192and224_val)) != 0) { + FAIL("clienthello had an incorrect Ellipticcurves entry\n"); + compare_data2(SSI(ssl)->tlsext_supportedgroups, + SSI(ssl)->tlsext_supportedgroups_length * 2, + tlsext_ec_clienthello_nistp192and224_val, + sizeof(tlsext_ec_clienthello_nistp192and224_val)); + goto err; } - memset(S3I(ssl)->previous_client_finished, 0, - sizeof(S3I(ssl)->previous_client_finished)); - memset(S3I(ssl)->previous_server_finished, 0, - sizeof(S3I(ssl)->previous_server_finished)); + failure = 0; - S3I(ssl)->renegotiate_seen = 0; + err: + CBB_cleanup(&cbb); + SSL_CTX_free(ssl_ctx); + SSL_free(ssl); + free(data); - CBS_init(&cbs, tlsext_ri_serverhello, sizeof(tlsext_ri_serverhello)); - if (tlsext_ri_serverhello_parse(ssl, &cbs, &alert)) { - fprintf(stderr, "FAIL: parsed invalid serverhello RI\n"); - failure = 1; - goto done; + return (failure); +} + + +/* elliptic_curves is only used by the client so this doesn't test much. */ +static int +test_tlsext_ec_serverhello(void) +{ + SSL_CTX *ssl_ctx = NULL; + SSL *ssl = NULL; + int failure; + + failure = 1; + + if ((ssl_ctx = SSL_CTX_new(TLS_server_method())) == NULL) + errx(1, "failed to create SSL_CTX"); + if ((ssl = SSL_new(ssl_ctx)) == NULL) + errx(1, "failed to create SSL"); + + if (tlsext_ec_serverhello_needs(ssl)) { + FAIL("serverhello should not need elliptic_curves\n"); + goto err; } - if (S3I(ssl)->renegotiate_seen == 1) { - fprintf(stderr, "FAIL: renegotiate seen set\n"); - failure = 1; - goto done; + if ((ssl->session = SSL_SESSION_new()) == NULL) + errx(1, "failed to create session"); + + if (tlsext_ec_serverhello_needs(ssl)) { + FAIL("serverhello should not need elliptic_curves\n"); + goto err; } - done: - CBB_cleanup(&cbb); + failure = 0; + + err: SSL_CTX_free(ssl_ctx); SSL_free(ssl); - free(data); return (failure); + } /* - * Server Name Indication - RFC 6066, section 3. + * Supported Point Formats - RFC 4492 section 5.1.2. + * + * Examples are from the RFC. Both client and server have the same build and + * parse but the needs differ. */ -#define TEST_SNI_SERVERNAME "www.libressl.org" +static uint8_t tlsext_ecpf_hello_uncompressed_val[] = { + TLSEXT_ECPOINTFORMAT_uncompressed +}; +static uint8_t tlsext_ecpf_hello_uncompressed[] = { + 0x01, + 0x00 /* TLSEXT_ECPOINTFORMAT_uncompressed */ +}; -static unsigned char tlsext_sni_clienthello[] = { - 0x00, 0x13, 0x00, 0x00, 0x10, 0x77, 0x77, 0x77, - 0x2e, 0x6c, 0x69, 0x62, 0x72, 0x65, 0x73, 0x73, - 0x6c, 0x2e, 0x6f, 0x72, 0x67, +static uint8_t tlsext_ecpf_hello_prime[] = { + 0x01, + 0x01 /* TLSEXT_ECPOINTFORMAT_ansiX962_compressed_prime */ }; -static unsigned char tlsext_sni_serverhello[] = { +static uint8_t tlsext_ecpf_hello_prefer_order_val[] = { + TLSEXT_ECPOINTFORMAT_ansiX962_compressed_prime, + TLSEXT_ECPOINTFORMAT_uncompressed, + TLSEXT_ECPOINTFORMAT_ansiX962_compressed_char2 +}; +static uint8_t tlsext_ecpf_hello_prefer_order[] = { + 0x03, + 0x01, /* TLSEXT_ECPOINTFORMAT_ansiX962_compressed_prime */ + 0x00, /* TLSEXT_ECPOINTFORMAT_uncompressed */ + 0x02 /* TLSEXT_ECPOINTFORMAT_ansiX962_compressed_char2 */ }; static int -test_tlsext_sni_clienthello(void) +test_tlsext_ecpf_clienthello(void) { - unsigned char *data = NULL; + uint8_t *data = NULL; SSL_CTX *ssl_ctx = NULL; SSL *ssl = NULL; - int failure = 0; size_t dlen; - int alert; + int failure, alert; CBB cbb; CBS cbs; + failure = 1; + CBB_init(&cbb, 0); if ((ssl_ctx = SSL_CTX_new(TLS_client_method())) == NULL) @@ -364,297 +435,48 @@ test_tlsext_sni_clienthello(void) if ((ssl = SSL_new(ssl_ctx)) == NULL) errx(1, "failed to create SSL"); - if (tlsext_sni_clienthello_needs(ssl)) { - fprintf(stderr, "FAIL: clienthello should not need SNI\n"); - failure = 1; - goto done; - } - - if (!SSL_set_tlsext_host_name(ssl, TEST_SNI_SERVERNAME)) { - fprintf(stderr, "FAIL: client failed to set server name\n"); - failure = 1; - goto done; + /* + * Default ciphers include EC so we need it by default. + */ + if (!tlsext_ecpf_clienthello_needs(ssl)) { + FAIL("clienthello should need ECPointFormats for default " + "ciphers\n"); + goto err; } - if (!tlsext_sni_clienthello_needs(ssl)) { - fprintf(stderr, "FAIL: clienthello should need SNI\n"); - failure = 1; - goto done; + /* + * Exclude EC cipher suites so we can test not including it. + */ + if (!SSL_set_cipher_list(ssl, "ALL:!ECDHE:!ECDH")) { + FAIL("clienthello should be able to set cipher list\n"); + goto err; } - - if (!tlsext_sni_clienthello_build(ssl, &cbb)) { - fprintf(stderr, "FAIL: clienthello failed to build SNI\n"); - failure = 1; - goto done; + if (tlsext_ecpf_clienthello_needs(ssl)) { + FAIL("clienthello should not need ECPointFormats\n"); + goto err; } - if (!CBB_finish(&cbb, &data, &dlen)) - errx(1, "failed to finish CBB"); - - if (dlen != sizeof(tlsext_sni_clienthello)) { - fprintf(stderr, "FAIL: got clienthello SNI with length %zu, " - "want length %zu\n", dlen, sizeof(tlsext_sni_clienthello)); - failure = 1; - goto done; + /* + * Use libtls default for the rest of the testing + */ + if (!SSL_set_cipher_list(ssl, "TLSv1.2+AEAD+ECDHE")) { + FAIL("clienthello should be able to set cipher list\n"); + goto err; } - - if (memcmp(data, tlsext_sni_clienthello, dlen) != 0) { - fprintf(stderr, "FAIL: clienthello SNI differs:\n"); - fprintf(stderr, "received:\n"); - hexdump(data, dlen); - fprintf(stderr, "test data:\n"); - hexdump(tlsext_sni_clienthello, sizeof(tlsext_sni_clienthello)); - failure = 1; - goto done; + if (!tlsext_ecpf_clienthello_needs(ssl)) { + FAIL("clienthello should need ECPointFormats\n"); + goto err; } + /* + * The default ECPointFormats should only have uncompressed + */ if ((ssl->session = SSL_SESSION_new()) == NULL) errx(1, "failed to create session"); - ssl->internal->hit = 0; - - CBS_init(&cbs, tlsext_sni_clienthello, sizeof(tlsext_sni_clienthello)); - if (!tlsext_sni_clienthello_parse(ssl, &cbs, &alert)) { - fprintf(stderr, "FAIL: failed to parse clienthello SNI\n"); - failure = 1; - goto done; - } - - if (ssl->session->tlsext_hostname == NULL) { - fprintf(stderr, "FAIL: no tlsext_hostname from clienthello SNI\n"); - failure = 1; - goto done; - } - - if (strlen(ssl->session->tlsext_hostname) != strlen(TEST_SNI_SERVERNAME) || - strncmp(ssl->session->tlsext_hostname, TEST_SNI_SERVERNAME, - strlen(TEST_SNI_SERVERNAME)) != 0) { - fprintf(stderr, "FAIL: got tlsext_hostname `%s', want `%s'\n", - ssl->session->tlsext_hostname, TEST_SNI_SERVERNAME); - failure = 1; - goto done; - } - - ssl->internal->hit = 1; - - if ((ssl->session->tlsext_hostname = strdup("notthesame.libressl.org")) == - NULL) - errx(1, "failed to strdup tlsext_hostname"); - - CBS_init(&cbs, tlsext_sni_clienthello, sizeof(tlsext_sni_clienthello)); - if (tlsext_sni_clienthello_parse(ssl, &cbs, &alert)) { - fprintf(stderr, "FAIL: parsed clienthello with mismatched SNI\n"); - failure = 1; - goto done; - } - - done: - CBB_cleanup(&cbb); - SSL_CTX_free(ssl_ctx); - SSL_free(ssl); - free(data); - - return (failure); -} - -static int -test_tlsext_sni_serverhello(void) -{ - unsigned char *data = NULL; - SSL_CTX *ssl_ctx = NULL; - SSL *ssl = NULL; - int failure = 0; - size_t dlen; - int alert; - CBB cbb; - CBS cbs; - - CBB_init(&cbb, 0); - - if ((ssl_ctx = SSL_CTX_new(TLS_server_method())) == NULL) - errx(1, "failed to create SSL_CTX"); - if ((ssl = SSL_new(ssl_ctx)) == NULL) - errx(1, "failed to create SSL"); - - if ((ssl->session = SSL_SESSION_new()) == NULL) - errx(1, "failed to create session"); - - if (tlsext_sni_serverhello_needs(ssl)) { - fprintf(stderr, "FAIL: serverhello should not need SNI\n"); - failure = 1; - goto done; - } - - if (!SSL_set_tlsext_host_name(ssl, TEST_SNI_SERVERNAME)) { - fprintf(stderr, "FAIL: client failed to set server name\n"); - failure = 1; - goto done; - } - - if ((ssl->session->tlsext_hostname = strdup(TEST_SNI_SERVERNAME)) == - NULL) - errx(1, "failed to strdup tlsext_hostname"); - - if (!tlsext_sni_serverhello_needs(ssl)) { - fprintf(stderr, "FAIL: serverhello should need SNI\n"); - failure = 1; - goto done; - } - - if (!tlsext_sni_serverhello_build(ssl, &cbb)) { - fprintf(stderr, "FAIL: serverhello failed to build SNI\n"); - failure = 1; - goto done; - } - - if (!CBB_finish(&cbb, &data, &dlen)) - errx(1, "failed to finish CBB"); - - if (dlen != sizeof(tlsext_sni_serverhello)) { - fprintf(stderr, "FAIL: got serverhello SNI with length %zu, " - "want length %zu\n", dlen, sizeof(tlsext_sni_serverhello)); - failure = 1; - goto done; - } - - if (memcmp(data, tlsext_sni_serverhello, dlen) != 0) { - fprintf(stderr, "FAIL: serverhello SNI differs:\n"); - fprintf(stderr, "received:\n"); - hexdump(data, dlen); - fprintf(stderr, "test data:\n"); - hexdump(tlsext_sni_serverhello, sizeof(tlsext_sni_serverhello)); - failure = 1; - goto done; - } - - free(ssl->session->tlsext_hostname); - ssl->session->tlsext_hostname = NULL; - - CBS_init(&cbs, tlsext_sni_serverhello, sizeof(tlsext_sni_serverhello)); - if (!tlsext_sni_serverhello_parse(ssl, &cbs, &alert)) { - fprintf(stderr, "FAIL: failed to parse serverhello SNI\n"); - failure = 1; - goto done; - } - - if (ssl->session->tlsext_hostname == NULL) { - fprintf(stderr, "FAIL: no tlsext_hostname after serverhello SNI\n"); - failure = 1; - goto done; - } - - if (strlen(ssl->session->tlsext_hostname) != strlen(TEST_SNI_SERVERNAME) || - strncmp(ssl->session->tlsext_hostname, TEST_SNI_SERVERNAME, - strlen(TEST_SNI_SERVERNAME)) != 0) { - fprintf(stderr, "FAIL: got tlsext_hostname `%s', want `%s'\n", - ssl->session->tlsext_hostname, TEST_SNI_SERVERNAME); - failure = 1; - goto done; - } - - done: - CBB_cleanup(&cbb); - SSL_CTX_free(ssl_ctx); - SSL_free(ssl); - free(data); - - return (failure); -} - -/* - * ECPointFormats - RFC 4492 section 5.1.2 (Supported Point Formats). - * - * Examples are from the RFC. Both client and server have the same build and - * parse but the needs differ. - */ - -static uint8_t tlsext_ecpf_hello_uncompressed_val[] = { - TLSEXT_ECPOINTFORMAT_uncompressed -}; -static uint8_t tlsext_ecpf_hello_uncompressed[] = { - 0x01, - 0x00 /* TLSEXT_ECPOINTFORMAT_uncompressed */ -}; - -static uint8_t tlsext_ecpf_hello_prime[] = { - 0x01, - 0x01 /* TLSEXT_ECPOINTFORMAT_ansiX962_compressed_prime */ -}; - -static uint8_t tlsext_ecpf_hello_prefer_order_val[] = { - TLSEXT_ECPOINTFORMAT_ansiX962_compressed_prime, - TLSEXT_ECPOINTFORMAT_uncompressed, - TLSEXT_ECPOINTFORMAT_ansiX962_compressed_char2 -}; -static uint8_t tlsext_ecpf_hello_prefer_order[] = { - 0x03, - 0x01, /* TLSEXT_ECPOINTFORMAT_ansiX962_compressed_prime */ - 0x00, /* TLSEXT_ECPOINTFORMAT_uncompressed */ - 0x02 /* TLSEXT_ECPOINTFORMAT_ansiX962_compressed_char2 */ -}; - -static int -test_tlsext_ecpf_clienthello(void) -{ - uint8_t *data = NULL; - SSL_CTX *ssl_ctx = NULL; - SSL *ssl = NULL; - size_t dlen; - int failure, alert; - CBB cbb; - CBS cbs; - - failure = 1; - - CBB_init(&cbb, 0); - - if ((ssl_ctx = SSL_CTX_new(TLS_client_method())) == NULL) - errx(1, "failed to create SSL_CTX"); - if ((ssl = SSL_new(ssl_ctx)) == NULL) - errx(1, "failed to create SSL"); - - /* - * Default ciphers include EC so we need it by default. - */ - if (!tlsext_ecpf_clienthello_needs(ssl)) { - FAIL("clienthello should need ECPointFormats for default " - "ciphers\n"); - goto err; - } - - /* - * Exclude EC cipher suites so we can test not including it. - */ - if (!SSL_set_cipher_list(ssl, "ALL:!ECDHE:!ECDH")) { - FAIL("clienthello should be able to set cipher list\n"); - goto err; - } - if (tlsext_ecpf_clienthello_needs(ssl)) { - FAIL("clienthello should not need ECPointFormats\n"); - goto err; - } - - /* - * Use libtls default for the rest of the testing - */ - if (!SSL_set_cipher_list(ssl, "TLSv1.2+AEAD+ECDHE")) { - FAIL("clienthello should be able to set cipher list\n"); - goto err; - } - if (!tlsext_ecpf_clienthello_needs(ssl)) { - FAIL("clienthello should need ECPointFormats\n"); - goto err; - } - - /* - * The default ECPointFormats should only have uncompressed - */ - if ((ssl->session = SSL_SESSION_new()) == NULL) - errx(1, "failed to create session"); - - if (!tlsext_ecpf_clienthello_build(ssl, &cbb)) { - FAIL("clienthello failed to build ECPointFormats\n"); - goto err; + if (!tlsext_ecpf_clienthello_build(ssl, &cbb)) { + FAIL("clienthello failed to build ECPointFormats\n"); + goto err; } if (!CBB_finish(&cbb, &data, &dlen)) @@ -810,7 +632,6 @@ test_tlsext_ecpf_clienthello(void) return (failure); } - static int test_tlsext_ecpf_serverhello(void) { @@ -1011,269 +832,382 @@ test_tlsext_ecpf_serverhello(void) } /* - * ellliptic_curves - RFC 4492 section 5.1.1 (Supported Elliptic Curves). - * - * This extension is only used by the client. + * Renegotiation Indication - RFC 5746. */ -static uint8_t tlsext_ec_clienthello_default[] = { - 0x00, 0x06, - 0x00, 0x1d, /* X25519 (29) */ - 0x00, 0x17, /* secp256r1 (23) */ - 0x00, 0x18 /* secp384r1 (24) */ +static unsigned char tlsext_ri_prev_client[] = { + 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, + 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff, }; -static uint16_t tlsext_ec_clienthello_secp384r1_val[] = { - 0x0018 /* tls1_ec_nid2curve_id(NID_secp384r1) */ -}; -static uint8_t tlsext_ec_clienthello_secp384r1[] = { - 0x00, 0x02, - 0x00, 0x18 /* secp384r1 (24) */ +static unsigned char tlsext_ri_prev_server[] = { + 0xff, 0xee, 0xdd, 0xcc, 0xbb, 0xaa, 0x99, 0x88, + 0x77, 0x66, 0x55, 0x44, 0x33, 0x22, 0x11, 0x00, }; -/* Example from RFC 4492 section 5.1.1 */ -static uint16_t tlsext_ec_clienthello_nistp192and224_val[] = { - 0x0013, /* tls1_ec_nid2curve_id(NID_X9_62_prime192v1) */ - 0x0015 /* tls1_ec_nid2curve_id(NID_secp224r1) */ +static unsigned char tlsext_ri_clienthello[] = { + 0x10, + 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, + 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff, }; -static uint8_t tlsext_ec_clienthello_nistp192and224[] = { - 0x00, 0x04, - 0x00, 0x13, /* secp192r1 aka NIST P-192 */ - 0x00, 0x15 /* secp224r1 aka NIST P-224 */ + +static unsigned char tlsext_ri_serverhello[] = { + 0x20, + 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, + 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff, + 0xff, 0xee, 0xdd, 0xcc, 0xbb, 0xaa, 0x99, 0x88, + 0x77, 0x66, 0x55, 0x44, 0x33, 0x22, 0x11, 0x00, }; static int -test_tlsext_ec_clienthello(void) +test_tlsext_ri_clienthello(void) { unsigned char *data = NULL; SSL_CTX *ssl_ctx = NULL; SSL *ssl = NULL; + int failure = 0; size_t dlen; - int failure, alert; + int alert; CBB cbb; CBS cbs; - failure = 1; - CBB_init(&cbb, 0); - if ((ssl_ctx = SSL_CTX_new(TLS_client_method())) == NULL) + if ((ssl_ctx = SSL_CTX_new(TLSv1_2_client_method())) == NULL) errx(1, "failed to create SSL_CTX"); if ((ssl = SSL_new(ssl_ctx)) == NULL) errx(1, "failed to create SSL"); - /* - * Default ciphers include EC so we need it by default. - */ - if (!tlsext_ec_clienthello_needs(ssl)) { - FAIL("clienthello should need Ellipticcurves for default " - "ciphers\n"); - goto err; + if (tlsext_ri_clienthello_needs(ssl)) { + fprintf(stderr, "FAIL: clienthello should not need RI\n"); + failure = 1; + goto done; } - /* - * Exclude cipher suites so we can test not including it. - */ - if (!SSL_set_cipher_list(ssl, "TLSv1.2:!ECDHE:!ECDSA")) { - FAIL("clienthello should be able to set cipher list\n"); - goto err; - } - if (tlsext_ec_clienthello_needs(ssl)) { - FAIL("clienthello should not need Ellipticcurves\n"); - goto err; + if (!SSL_renegotiate(ssl)) { + fprintf(stderr, "FAIL: client failed to set renegotiate\n"); + failure = 1; + goto done; } - /* - * Use libtls default for the rest of the testing - */ - if (!SSL_set_cipher_list(ssl, "TLSv1.2+AEAD+ECDHE")) { - FAIL("clienthello should be able to set cipher list\n"); - goto err; + if (!tlsext_ri_clienthello_needs(ssl)) { + fprintf(stderr, "FAIL: clienthello should need RI\n"); + failure = 1; + goto done; } - if (!tlsext_ec_clienthello_needs(ssl)) { - FAIL("clienthello should need Ellipticcurves\n"); - goto err; + + memcpy(S3I(ssl)->previous_client_finished, tlsext_ri_prev_client, + sizeof(tlsext_ri_prev_client)); + S3I(ssl)->previous_client_finished_len = sizeof(tlsext_ri_prev_client); + + S3I(ssl)->renegotiate_seen = 0; + + if (!tlsext_ri_clienthello_build(ssl, &cbb)) { + fprintf(stderr, "FAIL: clienthello failed to build RI\n"); + failure = 1; + goto done; } - /* - * Test with a session secp384r1. The default is used instead. - */ - if ((ssl->session = SSL_SESSION_new()) == NULL) - errx(1, "failed to create session"); + if (!CBB_finish(&cbb, &data, &dlen)) + errx(1, "failed to finish CBB"); - if ((SSI(ssl)->tlsext_supportedgroups = malloc(sizeof(uint16_t))) - == NULL) { - FAIL("client could not malloc\n"); - goto err; + if (dlen != sizeof(tlsext_ri_clienthello)) { + fprintf(stderr, "FAIL: got clienthello RI with length %zu, " + "want length %zu\n", dlen, sizeof(tlsext_ri_clienthello)); + failure = 1; + goto done; } - SSI(ssl)->tlsext_supportedgroups[0] = tls1_ec_nid2curve_id(NID_secp384r1); - SSI(ssl)->tlsext_supportedgroups_length = 1; - if (!tlsext_ec_clienthello_needs(ssl)) { - FAIL("clienthello should need Ellipticcurves\n"); - goto err; + if (memcmp(data, tlsext_ri_clienthello, dlen) != 0) { + fprintf(stderr, "FAIL: clienthello RI differs:\n"); + fprintf(stderr, "received:\n"); + hexdump(data, dlen); + fprintf(stderr, "test data:\n"); + hexdump(tlsext_ri_clienthello, sizeof(tlsext_ri_clienthello)); + failure = 1; + goto done; } - if (!tlsext_ec_clienthello_build(ssl, &cbb)) { - FAIL("clienthello failed to build Ellipticcurves\n"); - goto err; + CBS_init(&cbs, tlsext_ri_clienthello, sizeof(tlsext_ri_clienthello)); + if (!tlsext_ri_clienthello_parse(ssl, &cbs, &alert)) { + fprintf(stderr, "FAIL: failed to parse clienthello RI\n"); + failure = 1; + goto done; } - if (!CBB_finish(&cbb, &data, &dlen)) - errx(1, "failed to finish CBB"); + if (S3I(ssl)->renegotiate_seen != 1) { + fprintf(stderr, "FAIL: renegotiate seen not set\n"); + failure = 1; + goto done; + } + if (S3I(ssl)->send_connection_binding != 1) { + fprintf(stderr, "FAIL: send connection binding not set\n"); + failure = 1; + goto done; + } - if (dlen != sizeof(tlsext_ec_clienthello_default)) { - FAIL("got clienthello Ellipticcurves with length %zu, " - "want length %zu\n", dlen, - sizeof(tlsext_ec_clienthello_default)); - compare_data(data, dlen, tlsext_ec_clienthello_default, - sizeof(tlsext_ec_clienthello_default)); - goto err; + memset(S3I(ssl)->previous_client_finished, 0, + sizeof(S3I(ssl)->previous_client_finished)); + + S3I(ssl)->renegotiate_seen = 0; + + CBS_init(&cbs, tlsext_ri_clienthello, sizeof(tlsext_ri_clienthello)); + if (tlsext_ri_clienthello_parse(ssl, &cbs, &alert)) { + fprintf(stderr, "FAIL: parsed invalid clienthello RI\n"); + failure = 1; + goto done; } - if (memcmp(data, tlsext_ec_clienthello_default, dlen) != 0) { - FAIL("clienthello Ellipticcurves differs:\n"); - compare_data(data, dlen, tlsext_ec_clienthello_default, - sizeof(tlsext_ec_clienthello_default)); - goto err; + if (S3I(ssl)->renegotiate_seen == 1) { + fprintf(stderr, "FAIL: renegotiate seen set\n"); + failure = 1; + goto done; } - /* - * Test parsing secp384r1 - */ + done: CBB_cleanup(&cbb); - CBB_init(&cbb, 0); + SSL_CTX_free(ssl_ctx); + SSL_free(ssl); free(data); - data = NULL; - SSL_SESSION_free(ssl->session); - if ((ssl->session = SSL_SESSION_new()) == NULL) - errx(1, "failed to create session"); + return (failure); +} - CBS_init(&cbs, tlsext_ec_clienthello_secp384r1, - sizeof(tlsext_ec_clienthello_secp384r1)); - if (!tlsext_ec_clienthello_parse(ssl, &cbs, &alert)) { - FAIL("failed to parse clienthello Ellipticcurves\n"); - goto err; +static int +test_tlsext_ri_serverhello(void) +{ + unsigned char *data = NULL; + SSL_CTX *ssl_ctx = NULL; + SSL *ssl = NULL; + int failure = 0; + size_t dlen; + int alert; + CBB cbb; + CBS cbs; + + CBB_init(&cbb, 0); + + if ((ssl_ctx = SSL_CTX_new(TLS_server_method())) == NULL) + errx(1, "failed to create SSL_CTX"); + if ((ssl = SSL_new(ssl_ctx)) == NULL) + errx(1, "failed to create SSL"); + + if (tlsext_ri_serverhello_needs(ssl)) { + fprintf(stderr, "FAIL: serverhello should not need RI\n"); + failure = 1; + goto done; } - if (SSI(ssl)->tlsext_supportedgroups_length != - sizeof(tlsext_ec_clienthello_secp384r1_val) / sizeof(uint16_t)) { - FAIL("no tlsext_ellipticcurves from clienthello " - "Ellipticcurves\n"); - goto err; + S3I(ssl)->send_connection_binding = 1; + + if (!tlsext_ri_serverhello_needs(ssl)) { + fprintf(stderr, "FAIL: serverhello should need RI\n"); + failure = 1; + goto done; } - if (memcmp(SSI(ssl)->tlsext_supportedgroups, - tlsext_ec_clienthello_secp384r1_val, - sizeof(tlsext_ec_clienthello_secp384r1_val)) != 0) { - FAIL("clienthello had an incorrect Ellipticcurves " - "entry\n"); - compare_data2(SSI(ssl)->tlsext_supportedgroups, - SSI(ssl)->tlsext_supportedgroups_length * 2, - tlsext_ec_clienthello_secp384r1_val, - sizeof(tlsext_ec_clienthello_secp384r1_val)); - goto err; + memcpy(S3I(ssl)->previous_client_finished, tlsext_ri_prev_client, + sizeof(tlsext_ri_prev_client)); + S3I(ssl)->previous_client_finished_len = sizeof(tlsext_ri_prev_client); + + memcpy(S3I(ssl)->previous_server_finished, tlsext_ri_prev_server, + sizeof(tlsext_ri_prev_server)); + S3I(ssl)->previous_server_finished_len = sizeof(tlsext_ri_prev_server); + + S3I(ssl)->renegotiate_seen = 0; + + if (!tlsext_ri_serverhello_build(ssl, &cbb)) { + fprintf(stderr, "FAIL: serverhello failed to build RI\n"); + failure = 1; + goto done; } - /* - * Use a custom order. - */ - CBB_cleanup(&cbb); + if (!CBB_finish(&cbb, &data, &dlen)) + errx(1, "failed to finish CBB"); + + if (dlen != sizeof(tlsext_ri_serverhello)) { + fprintf(stderr, "FAIL: got serverhello RI with length %zu, " + "want length %zu\n", dlen, sizeof(tlsext_ri_serverhello)); + failure = 1; + goto done; + } + + if (memcmp(data, tlsext_ri_serverhello, dlen) != 0) { + fprintf(stderr, "FAIL: serverhello RI differs:\n"); + fprintf(stderr, "received:\n"); + hexdump(data, dlen); + fprintf(stderr, "test data:\n"); + hexdump(tlsext_ri_serverhello, sizeof(tlsext_ri_serverhello)); + failure = 1; + goto done; + } + + CBS_init(&cbs, tlsext_ri_serverhello, sizeof(tlsext_ri_serverhello)); + if (!tlsext_ri_serverhello_parse(ssl, &cbs, &alert)) { + fprintf(stderr, "FAIL: failed to parse serverhello RI\n"); + failure = 1; + goto done; + } + + if (S3I(ssl)->renegotiate_seen != 1) { + fprintf(stderr, "FAIL: renegotiate seen not set\n"); + failure = 1; + goto done; + } + if (S3I(ssl)->send_connection_binding != 1) { + fprintf(stderr, "FAIL: send connection binding not set\n"); + failure = 1; + goto done; + } + + memset(S3I(ssl)->previous_client_finished, 0, + sizeof(S3I(ssl)->previous_client_finished)); + memset(S3I(ssl)->previous_server_finished, 0, + sizeof(S3I(ssl)->previous_server_finished)); + + S3I(ssl)->renegotiate_seen = 0; + + CBS_init(&cbs, tlsext_ri_serverhello, sizeof(tlsext_ri_serverhello)); + if (tlsext_ri_serverhello_parse(ssl, &cbs, &alert)) { + fprintf(stderr, "FAIL: parsed invalid serverhello RI\n"); + failure = 1; + goto done; + } + + if (S3I(ssl)->renegotiate_seen == 1) { + fprintf(stderr, "FAIL: renegotiate seen set\n"); + failure = 1; + goto done; + } + + done: + CBB_cleanup(&cbb); + SSL_CTX_free(ssl_ctx); + SSL_free(ssl); + free(data); + + return (failure); +} + +/* + * Server Name Indication - RFC 6066 section 3. + */ + +#define TEST_SNI_SERVERNAME "www.libressl.org" + +static unsigned char tlsext_sni_clienthello[] = { + 0x00, 0x13, 0x00, 0x00, 0x10, 0x77, 0x77, 0x77, + 0x2e, 0x6c, 0x69, 0x62, 0x72, 0x65, 0x73, 0x73, + 0x6c, 0x2e, 0x6f, 0x72, 0x67, +}; + +static unsigned char tlsext_sni_serverhello[] = { +}; + +static int +test_tlsext_sni_clienthello(void) +{ + unsigned char *data = NULL; + SSL_CTX *ssl_ctx = NULL; + SSL *ssl = NULL; + int failure = 0; + size_t dlen; + int alert; + CBB cbb; + CBS cbs; + CBB_init(&cbb, 0); - SSL_SESSION_free(ssl->session); - if ((ssl->session = SSL_SESSION_new()) == NULL) - errx(1, "failed to create session"); + if ((ssl_ctx = SSL_CTX_new(TLS_client_method())) == NULL) + errx(1, "failed to create SSL_CTX"); + if ((ssl = SSL_new(ssl_ctx)) == NULL) + errx(1, "failed to create SSL"); - if ((ssl->internal->tlsext_supportedgroups = malloc(sizeof(uint16_t) * 2)) == NULL) { - FAIL("client could not malloc\n"); - goto err; + if (tlsext_sni_clienthello_needs(ssl)) { + fprintf(stderr, "FAIL: clienthello should not need SNI\n"); + failure = 1; + goto done; } - ssl->internal->tlsext_supportedgroups[0] = tls1_ec_nid2curve_id(NID_X9_62_prime192v1); - ssl->internal->tlsext_supportedgroups[1] = tls1_ec_nid2curve_id(NID_secp224r1); - ssl->internal->tlsext_supportedgroups_length = 2; - if (!tlsext_ec_clienthello_needs(ssl)) { - FAIL("clienthello should need Ellipticcurves\n"); - goto err; + if (!SSL_set_tlsext_host_name(ssl, TEST_SNI_SERVERNAME)) { + fprintf(stderr, "FAIL: client failed to set server name\n"); + failure = 1; + goto done; } - if (!tlsext_ec_clienthello_build(ssl, &cbb)) { - FAIL("clienthello failed to build Ellipticcurves\n"); - goto err; + if (!tlsext_sni_clienthello_needs(ssl)) { + fprintf(stderr, "FAIL: clienthello should need SNI\n"); + failure = 1; + goto done; + } + + if (!tlsext_sni_clienthello_build(ssl, &cbb)) { + fprintf(stderr, "FAIL: clienthello failed to build SNI\n"); + failure = 1; + goto done; } if (!CBB_finish(&cbb, &data, &dlen)) errx(1, "failed to finish CBB"); - if (dlen != sizeof(tlsext_ec_clienthello_nistp192and224)) { - FAIL("got clienthello Ellipticcurves with length %zu, " - "want length %zu\n", dlen, - sizeof(tlsext_ec_clienthello_nistp192and224)); - fprintf(stderr, "received:\n"); - hexdump(data, dlen); - fprintf(stderr, "test data:\n"); - hexdump(tlsext_ec_clienthello_nistp192and224, - sizeof(tlsext_ec_clienthello_nistp192and224)); - goto err; + if (dlen != sizeof(tlsext_sni_clienthello)) { + fprintf(stderr, "FAIL: got clienthello SNI with length %zu, " + "want length %zu\n", dlen, sizeof(tlsext_sni_clienthello)); + failure = 1; + goto done; } - if (memcmp(data, tlsext_ec_clienthello_nistp192and224, dlen) != 0) { - FAIL("clienthello Ellipticcurves differs:\n"); + if (memcmp(data, tlsext_sni_clienthello, dlen) != 0) { + fprintf(stderr, "FAIL: clienthello SNI differs:\n"); fprintf(stderr, "received:\n"); hexdump(data, dlen); fprintf(stderr, "test data:\n"); - hexdump(tlsext_ec_clienthello_nistp192and224, - sizeof(tlsext_ec_clienthello_nistp192and224)); - goto err; + hexdump(tlsext_sni_clienthello, sizeof(tlsext_sni_clienthello)); + failure = 1; + goto done; } - /* - * Parse non-default curves to session. - */ - CBB_cleanup(&cbb); - CBB_init(&cbb, 0); - free(data); - data = NULL; - - SSL_SESSION_free(ssl->session); if ((ssl->session = SSL_SESSION_new()) == NULL) errx(1, "failed to create session"); - /* Reset back to the default list. */ - free(ssl->internal->tlsext_supportedgroups); - ssl->internal->tlsext_supportedgroups = NULL; - ssl->internal->tlsext_supportedgroups_length = 0; + ssl->internal->hit = 0; - CBS_init(&cbs, tlsext_ec_clienthello_nistp192and224, - sizeof(tlsext_ec_clienthello_nistp192and224)); - if (!tlsext_ec_clienthello_parse(ssl, &cbs, &alert)) { - FAIL("failed to parse clienthello Ellipticcurves\n"); - goto err; + CBS_init(&cbs, tlsext_sni_clienthello, sizeof(tlsext_sni_clienthello)); + if (!tlsext_sni_clienthello_parse(ssl, &cbs, &alert)) { + fprintf(stderr, "FAIL: failed to parse clienthello SNI\n"); + failure = 1; + goto done; } - if (SSI(ssl)->tlsext_supportedgroups_length != - sizeof(tlsext_ec_clienthello_nistp192and224_val) / sizeof(uint16_t)) { - FAIL("no tlsext_ellipticcurves from clienthello " - "Ellipticcurves\n"); - goto err; + if (ssl->session->tlsext_hostname == NULL) { + fprintf(stderr, "FAIL: no tlsext_hostname from clienthello SNI\n"); + failure = 1; + goto done; } - if (memcmp(SSI(ssl)->tlsext_supportedgroups, - tlsext_ec_clienthello_nistp192and224_val, - sizeof(tlsext_ec_clienthello_nistp192and224_val)) != 0) { - FAIL("clienthello had an incorrect Ellipticcurves entry\n"); - compare_data2(SSI(ssl)->tlsext_supportedgroups, - SSI(ssl)->tlsext_supportedgroups_length * 2, - tlsext_ec_clienthello_nistp192and224_val, - sizeof(tlsext_ec_clienthello_nistp192and224_val)); - goto err; + if (strlen(ssl->session->tlsext_hostname) != strlen(TEST_SNI_SERVERNAME) || + strncmp(ssl->session->tlsext_hostname, TEST_SNI_SERVERNAME, + strlen(TEST_SNI_SERVERNAME)) != 0) { + fprintf(stderr, "FAIL: got tlsext_hostname `%s', want `%s'\n", + ssl->session->tlsext_hostname, TEST_SNI_SERVERNAME); + failure = 1; + goto done; } - failure = 0; + ssl->internal->hit = 1; - err: + if ((ssl->session->tlsext_hostname = strdup("notthesame.libressl.org")) == + NULL) + errx(1, "failed to strdup tlsext_hostname"); + + CBS_init(&cbs, tlsext_sni_clienthello, sizeof(tlsext_sni_clienthello)); + if (tlsext_sni_clienthello_parse(ssl, &cbs, &alert)) { + fprintf(stderr, "FAIL: parsed clienthello with mismatched SNI\n"); + failure = 1; + goto done; + } + + done: CBB_cleanup(&cbb); SSL_CTX_free(ssl_ctx); SSL_free(ssl); @@ -1282,43 +1216,108 @@ test_tlsext_ec_clienthello(void) return (failure); } - -/* elliptic_curves is only used by the client so this doesn't test much. */ static int -test_tlsext_ec_serverhello(void) +test_tlsext_sni_serverhello(void) { + unsigned char *data = NULL; SSL_CTX *ssl_ctx = NULL; SSL *ssl = NULL; - int failure; + int failure = 0; + size_t dlen; + int alert; + CBB cbb; + CBS cbs; - failure = 1; + CBB_init(&cbb, 0); if ((ssl_ctx = SSL_CTX_new(TLS_server_method())) == NULL) errx(1, "failed to create SSL_CTX"); if ((ssl = SSL_new(ssl_ctx)) == NULL) errx(1, "failed to create SSL"); - if (tlsext_ec_serverhello_needs(ssl)) { - FAIL("serverhello should not need elliptic_curves\n"); - goto err; - } - if ((ssl->session = SSL_SESSION_new()) == NULL) errx(1, "failed to create session"); - if (tlsext_ec_serverhello_needs(ssl)) { - FAIL("serverhello should not need elliptic_curves\n"); - goto err; + if (tlsext_sni_serverhello_needs(ssl)) { + fprintf(stderr, "FAIL: serverhello should not need SNI\n"); + failure = 1; + goto done; } - failure = 0; + if (!SSL_set_tlsext_host_name(ssl, TEST_SNI_SERVERNAME)) { + fprintf(stderr, "FAIL: client failed to set server name\n"); + failure = 1; + goto done; + } - err: + if ((ssl->session->tlsext_hostname = strdup(TEST_SNI_SERVERNAME)) == + NULL) + errx(1, "failed to strdup tlsext_hostname"); + + if (!tlsext_sni_serverhello_needs(ssl)) { + fprintf(stderr, "FAIL: serverhello should need SNI\n"); + failure = 1; + goto done; + } + + if (!tlsext_sni_serverhello_build(ssl, &cbb)) { + fprintf(stderr, "FAIL: serverhello failed to build SNI\n"); + failure = 1; + goto done; + } + + if (!CBB_finish(&cbb, &data, &dlen)) + errx(1, "failed to finish CBB"); + + if (dlen != sizeof(tlsext_sni_serverhello)) { + fprintf(stderr, "FAIL: got serverhello SNI with length %zu, " + "want length %zu\n", dlen, sizeof(tlsext_sni_serverhello)); + failure = 1; + goto done; + } + + if (memcmp(data, tlsext_sni_serverhello, dlen) != 0) { + fprintf(stderr, "FAIL: serverhello SNI differs:\n"); + fprintf(stderr, "received:\n"); + hexdump(data, dlen); + fprintf(stderr, "test data:\n"); + hexdump(tlsext_sni_serverhello, sizeof(tlsext_sni_serverhello)); + failure = 1; + goto done; + } + + free(ssl->session->tlsext_hostname); + ssl->session->tlsext_hostname = NULL; + + CBS_init(&cbs, tlsext_sni_serverhello, sizeof(tlsext_sni_serverhello)); + if (!tlsext_sni_serverhello_parse(ssl, &cbs, &alert)) { + fprintf(stderr, "FAIL: failed to parse serverhello SNI\n"); + failure = 1; + goto done; + } + + if (ssl->session->tlsext_hostname == NULL) { + fprintf(stderr, "FAIL: no tlsext_hostname after serverhello SNI\n"); + failure = 1; + goto done; + } + + if (strlen(ssl->session->tlsext_hostname) != strlen(TEST_SNI_SERVERNAME) || + strncmp(ssl->session->tlsext_hostname, TEST_SNI_SERVERNAME, + strlen(TEST_SNI_SERVERNAME)) != 0) { + fprintf(stderr, "FAIL: got tlsext_hostname `%s', want `%s'\n", + ssl->session->tlsext_hostname, TEST_SNI_SERVERNAME); + failure = 1; + goto done; + } + + done: + CBB_cleanup(&cbb); SSL_CTX_free(ssl_ctx); SSL_free(ssl); + free(data); return (failure); - } int @@ -1328,17 +1327,17 @@ main(int argc, char **argv) SSL_library_init(); + failed |= test_tlsext_ec_clienthello(); + failed |= test_tlsext_ec_serverhello(); + + failed |= test_tlsext_ecpf_clienthello(); + failed |= test_tlsext_ecpf_serverhello(); + failed |= test_tlsext_ri_clienthello(); failed |= test_tlsext_ri_serverhello(); failed |= test_tlsext_sni_clienthello(); failed |= test_tlsext_sni_serverhello(); - failed |= test_tlsext_ecpf_clienthello(); - failed |= test_tlsext_ecpf_serverhello(); - - failed |= test_tlsext_ec_clienthello(); - failed |= test_tlsext_ec_serverhello(); - return (failed); } -- cgit v1.2.3-55-g6feb