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>
This commit is contained in:
committed by
Adam Langley
parent
676d1e780e
commit
7b03051103
+50
-26
@@ -28,35 +28,37 @@ int early_callback_called = 0;
|
||||
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 @@ err:
|
||||
|
||||
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 @@ int main(int argc, char **argv) {
|
||||
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 @@ int main(int argc, char **argv) {
|
||||
}
|
||||
}
|
||||
|
||||
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));
|
||||
|
||||
@@ -105,15 +105,15 @@ const (
|
||||
|
||||
// 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 @@ type Config struct {
|
||||
// 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
|
||||
|
||||
@@ -325,9 +325,9 @@ func (hs *clientHandshakeState) doFullHandshake() error {
|
||||
var rsaAvail, ecdsaAvail bool
|
||||
for _, certType := range certReq.certificateTypes {
|
||||
switch certType {
|
||||
case certTypeRSASign:
|
||||
case CertTypeRSASign:
|
||||
rsaAvail = true
|
||||
case certTypeECDSASign:
|
||||
case CertTypeECDSASign:
|
||||
ecdsaAvail = true
|
||||
}
|
||||
}
|
||||
|
||||
@@ -337,10 +337,14 @@ func (hs *serverHandshakeState) doFullHandshake() error {
|
||||
|
||||
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
|
||||
|
||||
@@ -165,6 +165,22 @@ var testCases = []testCase{
|
||||
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 {
|
||||
|
||||
Reference in New Issue
Block a user