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:
David Benjamin
2014-07-09 21:03:54 +00:00
committed by Adam Langley
parent 676d1e780e
commit 7b03051103
5 changed files with 87 additions and 39 deletions
+50 -26
View File
@@ -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));
+11 -7
View File
@@ -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
+2 -2
View File
@@ -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
}
}
+8 -4
View File
@@ -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
+16
View File
@@ -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 {