Add a test for certificate types parsing. Change-Id: Icddd39ae183f981f78a65427a4dda34449ca389a Reviewed-on: https://boringssl-review.googlesource.com/1111 Reviewed-by: Adam Langley <agl@google.com>
diff --git a/ssl/test/bssl_shim.cc b/ssl/test/bssl_shim.cc index d0117da..72be47e 100644 --- a/ssl/test/bssl_shim.cc +++ b/ssl/test/bssl_shim.cc
@@ -28,35 +28,37 @@ int select_certificate_callback(const struct ssl_early_callback_ctx *ctx) { early_callback_called = 1; - if (expected_server_name) { - const unsigned char *extension_data; - size_t extension_len; - CBS extension, server_name_list, host_name; - uint8_t name_type; + if (!expected_server_name) { + return 1; + } - if (!SSL_early_callback_ctx_extension_get(ctx, TLSEXT_TYPE_server_name, - &extension_data, - &extension_len)) { - fprintf(stderr, "Could not find server_name extension."); - return -1; - } + const uint8_t *extension_data; + size_t extension_len; + CBS extension, server_name_list, host_name; + uint8_t name_type; - CBS_init(&extension, extension_data, extension_len); - if (!CBS_get_u16_length_prefixed(&extension, &server_name_list) || - CBS_len(&extension) != 0 || - !CBS_get_u8(&server_name_list, &name_type) || - name_type != TLSEXT_NAMETYPE_host_name || - !CBS_get_u16_length_prefixed(&server_name_list, &host_name) || - CBS_len(&server_name_list) != 0) { - fprintf(stderr, "Could not decode server_name extension."); - return -1; - } + if (!SSL_early_callback_ctx_extension_get(ctx, TLSEXT_TYPE_server_name, + &extension_data, + &extension_len)) { + fprintf(stderr, "Could not find server_name extension.\n"); + return -1; + } - if (CBS_len(&host_name) != strlen(expected_server_name) || - memcmp(expected_server_name, - CBS_data(&host_name), CBS_len(&host_name)) != 0) { - fprintf(stderr, "Server name mismatch."); - } + CBS_init(&extension, extension_data, extension_len); + if (!CBS_get_u16_length_prefixed(&extension, &server_name_list) || + CBS_len(&extension) != 0 || + !CBS_get_u8(&server_name_list, &name_type) || + name_type != TLSEXT_NAMETYPE_host_name || + !CBS_get_u16_length_prefixed(&server_name_list, &host_name) || + CBS_len(&server_name_list) != 0) { + fprintf(stderr, "Could not decode server_name extension.\n"); + return -1; + } + + if (CBS_len(&host_name) != strlen(expected_server_name) || + memcmp(expected_server_name, + CBS_data(&host_name), CBS_len(&host_name)) != 0) { + fprintf(stderr, "Server name mismatch.\n"); } return 1; @@ -117,6 +119,7 @@ int main(int argc, char **argv) { int i, is_server, ret; + const char *expected_certificate_types = NULL; if (argc < 2) { fprintf(stderr, "Usage: %s (client|server) [flags...]\n", argv[0]); @@ -170,6 +173,14 @@ return 1; } expected_server_name = argv[i]; + } else if (strcmp(argv[i], "-expect-certificate-types") == 0) { + i++; + if (i >= argc) { + fprintf(stderr, "Missing parameter\n"); + return 1; + } + // Conveniently, 00 is not a certificate type. + expected_certificate_types = argv[i]; } else { fprintf(stderr, "Unknown argument: %s\n", argv[i]); return 1; @@ -202,6 +213,19 @@ } } + if (expected_certificate_types) { + uint8_t *certificate_types; + int num_certificate_types = + SSL_get0_certificate_types(ssl, &certificate_types); + if (num_certificate_types != (int)strlen(expected_certificate_types) || + memcmp(certificate_types, + expected_certificate_types, + num_certificate_types) != 0) { + fprintf(stderr, "certificate types mismatch\n"); + return 2; + } + } + for (;;) { uint8_t buf[512]; int n = SSL_read(ssl, buf, sizeof(buf));
diff --git a/ssl/test/runner/common.go b/ssl/test/runner/common.go index df7cacf..dca3e9d 100644 --- a/ssl/test/runner/common.go +++ b/ssl/test/runner/common.go
@@ -105,15 +105,15 @@ // Certificate types (for certificateRequestMsg) const ( - certTypeRSASign = 1 // A certificate containing an RSA key - certTypeDSSSign = 2 // A certificate containing a DSA key - certTypeRSAFixedDH = 3 // A certificate containing a static DH key - certTypeDSSFixedDH = 4 // A certificate containing a static DH key + CertTypeRSASign = 1 // A certificate containing an RSA key + CertTypeDSSSign = 2 // A certificate containing a DSA key + CertTypeRSAFixedDH = 3 // A certificate containing a static DH key + CertTypeDSSFixedDH = 4 // A certificate containing a static DH key // See RFC4492 sections 3 and 5.5. - certTypeECDSASign = 64 // A certificate containing an ECDSA-capable public key, signed with ECDSA. - certTypeRSAFixedECDH = 65 // A certificate containing an ECDH-capable public key, signed with RSA. - certTypeECDSAFixedECDH = 66 // A certificate containing an ECDH-capable public key, signed with ECDSA. + CertTypeECDSASign = 64 // A certificate containing an ECDSA-capable public key, signed with ECDSA. + CertTypeRSAFixedECDH = 65 // A certificate containing an ECDH-capable public key, signed with RSA. + CertTypeECDSAFixedECDH = 66 // A certificate containing an ECDH-capable public key, signed with ECDSA. // Rest of these are reserved by the TLS spec ) @@ -251,6 +251,10 @@ // by the policy in ClientAuth. ClientCAs *x509.CertPool + // ClientCertificateTypes defines the set of allowed client certificate + // types. The default is CertTypeRSASign and CertTypeECDSASign. + ClientCertificateTypes []byte + // InsecureSkipVerify controls whether a client verifies the // server's certificate chain and host name. // If InsecureSkipVerify is true, TLS accepts any certificate
diff --git a/ssl/test/runner/handshake_client.go b/ssl/test/runner/handshake_client.go index 220e489..890a8a0 100644 --- a/ssl/test/runner/handshake_client.go +++ b/ssl/test/runner/handshake_client.go
@@ -325,9 +325,9 @@ var rsaAvail, ecdsaAvail bool for _, certType := range certReq.certificateTypes { switch certType { - case certTypeRSASign: + case CertTypeRSASign: rsaAvail = true - case certTypeECDSASign: + case CertTypeECDSASign: ecdsaAvail = true } }
diff --git a/ssl/test/runner/handshake_server.go b/ssl/test/runner/handshake_server.go index 328c15f..a32c078 100644 --- a/ssl/test/runner/handshake_server.go +++ b/ssl/test/runner/handshake_server.go
@@ -337,10 +337,14 @@ if config.ClientAuth >= RequestClientCert { // Request a client certificate - certReq := new(certificateRequestMsg) - certReq.certificateTypes = []byte{ - byte(certTypeRSASign), - byte(certTypeECDSASign), + certReq := &certificateRequestMsg{ + certificateTypes: config.ClientCertificateTypes, + } + if certReq.certificateTypes == nil { + certReq.certificateTypes = []byte{ + byte(CertTypeRSASign), + byte(CertTypeECDSASign), + } } if c.vers >= VersionTLS12 { certReq.hasSignatureAndHash = true
diff --git a/ssl/test/runner/runner.go b/ssl/test/runner/runner.go index 96b52fa..7b1462a 100644 --- a/ssl/test/runner/runner.go +++ b/ssl/test/runner/runner.go
@@ -165,6 +165,22 @@ shouldFail: true, expectedLocalError: "remote error: error decoding message", }, + { + name: "ClientCertificateTypes", + config: Config{ + ClientAuth: RequestClientCert, + ClientCertificateTypes: []byte{ + CertTypeDSSSign, + CertTypeRSASign, + CertTypeECDSASign, + }, + }, + flags: []string{"-expect-certificate-types", string([]byte{ + CertTypeDSSSign, + CertTypeRSASign, + CertTypeECDSASign, + })}, + }, } func doExchange(tlsConn *Conn, messageLen int) error {