From 1db9e1bc7a1b49057fb3e6b621652a322c8c04a4 Mon Sep 17 00:00:00 2001 From: David Benjamin Date: Fri, 7 Oct 2016 20:51:43 -0400 Subject: [PATCH] Add the certificate_required alert. This is part of TLS 1.3 draft 16 but isn't much of a wire format change, so go ahead and add it now. When rolling into Chromium, we'll want to add an entry to the error mapping. Change-Id: I8fd7f461dca83b725a31ae19ef96c890d603ce53 Reviewed-on: https://boringssl-review.googlesource.com/11563 Reviewed-by: David Benjamin --- crypto/err/ssl.errordata | 2 ++ include/openssl/ssl.h | 5 ++++- include/openssl/tls1.h | 17 +++++++++-------- ssl/ssl_stat.c | 7 +++++-- ssl/test/runner/alert.go | 2 ++ ssl/test/runner/handshake_server.go | 2 +- ssl/test/runner/runner.go | 13 ++++++++++--- ssl/tls13_both.c | 2 +- 8 files changed, 34 insertions(+), 16 deletions(-) diff --git a/crypto/err/ssl.errordata b/crypto/err/ssl.errordata index 9045e9a7..c25683ee 100644 --- a/crypto/err/ssl.errordata +++ b/crypto/err/ssl.errordata @@ -157,7 +157,9 @@ SSL,1048,TLSV1_ALERT_UNKNOWN_CA SSL,1090,TLSV1_ALERT_USER_CANCELLED SSL,1114,TLSV1_BAD_CERTIFICATE_HASH_VALUE SSL,1113,TLSV1_BAD_CERTIFICATE_STATUS_RESPONSE +SSL,1116,TLSV1_CERTIFICATE_REQUIRED SSL,1111,TLSV1_CERTIFICATE_UNOBTAINABLE +SSL,1115,TLSV1_UNKNOWN_PSK_IDENTITY SSL,1112,TLSV1_UNRECOGNIZED_NAME SSL,1110,TLSV1_UNSUPPORTED_EXTENSION SSL,217,TLS_PEER_DID_NOT_RESPOND_WITH_CERTIFICATE_LIST diff --git a/include/openssl/ssl.h b/include/openssl/ssl.h index 8d105aae..52ed52c2 100644 --- a/include/openssl/ssl.h +++ b/include/openssl/ssl.h @@ -2708,6 +2708,7 @@ OPENSSL_EXPORT const char *SSL_get_psk_identity(const SSL *ssl); #define SSL_AD_PROTOCOL_VERSION TLS1_AD_PROTOCOL_VERSION #define SSL_AD_INSUFFICIENT_SECURITY TLS1_AD_INSUFFICIENT_SECURITY #define SSL_AD_INTERNAL_ERROR TLS1_AD_INTERNAL_ERROR +#define SSL_AD_INAPPROPRIATE_FALLBACK SSL3_AD_INAPPROPRIATE_FALLBACK #define SSL_AD_USER_CANCELLED TLS1_AD_USER_CANCELLED #define SSL_AD_NO_RENEGOTIATION TLS1_AD_NO_RENEGOTIATION #define SSL_AD_MISSING_EXTENSION TLS1_AD_MISSING_EXTENSION @@ -2718,7 +2719,7 @@ OPENSSL_EXPORT const char *SSL_get_psk_identity(const SSL *ssl); TLS1_AD_BAD_CERTIFICATE_STATUS_RESPONSE #define SSL_AD_BAD_CERTIFICATE_HASH_VALUE TLS1_AD_BAD_CERTIFICATE_HASH_VALUE #define SSL_AD_UNKNOWN_PSK_IDENTITY TLS1_AD_UNKNOWN_PSK_IDENTITY -#define SSL_AD_INAPPROPRIATE_FALLBACK SSL3_AD_INAPPROPRIATE_FALLBACK +#define SSL_AD_CERTIFICATE_REQUIRED TLS1_AD_CERTIFICATE_REQUIRED /* SSL_alert_type_string_long returns a string description of |value| as an * alert type (warning or fatal). */ @@ -4764,5 +4765,7 @@ BORINGSSL_MAKE_DELETER(SSL_SESSION, SSL_SESSION_free) #define SSL_R_TLSV1_UNRECOGNIZED_NAME 1112 #define SSL_R_TLSV1_BAD_CERTIFICATE_STATUS_RESPONSE 1113 #define SSL_R_TLSV1_BAD_CERTIFICATE_HASH_VALUE 1114 +#define SSL_R_TLSV1_UNKNOWN_PSK_IDENTITY 1115 +#define SSL_R_TLSV1_CERTIFICATE_REQUIRED 1116 #endif /* OPENSSL_HEADER_SSL_H */ diff --git a/include/openssl/tls1.h b/include/openssl/tls1.h index c1db7abc..1c55ab39 100644 --- a/include/openssl/tls1.h +++ b/include/openssl/tls1.h @@ -160,14 +160,14 @@ extern "C" { #define TLS1_AD_END_OF_EARLY_DATA 1 #define TLS1_AD_DECRYPTION_FAILED 21 #define TLS1_AD_RECORD_OVERFLOW 22 -#define TLS1_AD_UNKNOWN_CA 48 /* fatal */ -#define TLS1_AD_ACCESS_DENIED 49 /* fatal */ -#define TLS1_AD_DECODE_ERROR 50 /* fatal */ +#define TLS1_AD_UNKNOWN_CA 48 +#define TLS1_AD_ACCESS_DENIED 49 +#define TLS1_AD_DECODE_ERROR 50 #define TLS1_AD_DECRYPT_ERROR 51 -#define TLS1_AD_EXPORT_RESTRICTION 60 /* fatal */ -#define TLS1_AD_PROTOCOL_VERSION 70 /* fatal */ -#define TLS1_AD_INSUFFICIENT_SECURITY 71 /* fatal */ -#define TLS1_AD_INTERNAL_ERROR 80 /* fatal */ +#define TLS1_AD_EXPORT_RESTRICTION 60 +#define TLS1_AD_PROTOCOL_VERSION 70 +#define TLS1_AD_INSUFFICIENT_SECURITY 71 +#define TLS1_AD_INTERNAL_ERROR 80 #define TLS1_AD_USER_CANCELLED 90 #define TLS1_AD_NO_RENEGOTIATION 100 #define TLS1_AD_MISSING_EXTENSION 109 @@ -177,7 +177,8 @@ extern "C" { #define TLS1_AD_UNRECOGNIZED_NAME 112 #define TLS1_AD_BAD_CERTIFICATE_STATUS_RESPONSE 113 #define TLS1_AD_BAD_CERTIFICATE_HASH_VALUE 114 -#define TLS1_AD_UNKNOWN_PSK_IDENTITY 115 /* fatal */ +#define TLS1_AD_UNKNOWN_PSK_IDENTITY 115 +#define TLS1_AD_CERTIFICATE_REQUIRED 116 /* ExtensionType values from RFC6066 */ #define TLSEXT_TYPE_server_name 0 diff --git a/ssl/ssl_stat.c b/ssl/ssl_stat.c index 3fdc6e59..1ed0bdf6 100644 --- a/ssl/ssl_stat.c +++ b/ssl/ssl_stat.c @@ -476,6 +476,9 @@ const char *SSL_alert_desc_string_long(int value) { case TLS1_AD_INTERNAL_ERROR: return "internal error"; + case SSL3_AD_INAPPROPRIATE_FALLBACK: + return "inappropriate fallback"; + case TLS1_AD_USER_CANCELLED: return "user canceled"; @@ -500,8 +503,8 @@ const char *SSL_alert_desc_string_long(int value) { case TLS1_AD_UNKNOWN_PSK_IDENTITY: return "unknown PSK identity"; - case SSL3_AD_INAPPROPRIATE_FALLBACK: - return "inappropriate fallback"; + case TLS1_AD_CERTIFICATE_REQUIRED: + return "certificate required"; default: return "unknown"; diff --git a/ssl/test/runner/alert.go b/ssl/test/runner/alert.go index b690c6f6..8320b7e5 100644 --- a/ssl/test/runner/alert.go +++ b/ssl/test/runner/alert.go @@ -43,6 +43,7 @@ const ( alertUnsupportedExtension alert = 110 alertUnrecognizedName alert = 112 alertUnknownPSKIdentity alert = 115 + alertCertificateRequired alert = 116 ) var alertText = map[alert]string{ @@ -73,6 +74,7 @@ var alertText = map[alert]string{ alertUnsupportedExtension: "unsupported extension", alertUnrecognizedName: "unrecognized name", alertUnknownPSKIdentity: "unknown PSK identity", + alertCertificateRequired: "certificate required", } func (e alert) String() string { diff --git a/ssl/test/runner/handshake_server.go b/ssl/test/runner/handshake_server.go index 7c2fd179..abadf3ad 100644 --- a/ssl/test/runner/handshake_server.go +++ b/ssl/test/runner/handshake_server.go @@ -830,7 +830,7 @@ Curves: // The client didn't actually send a certificate switch config.ClientAuth { case RequireAnyClientCert, RequireAndVerifyClientCert: - c.sendAlert(alertBadCertificate) + c.sendAlert(alertCertificateRequired) return errors.New("tls: client didn't provide a certificate") } } diff --git a/ssl/test/runner/runner.go b/ssl/test/runner/runner.go index 2a7f141f..8ca3917f 100644 --- a/ssl/test/runner/runner.go +++ b/ssl/test/runner/runner.go @@ -2950,6 +2950,12 @@ func addClientAuthTests() { resumeSession: true, }) + certificateRequired := "remote error: certificate required" + if ver.version < VersionTLS13 { + // Prior to TLS 1.3, the generic handshake_failure alert + // was used. + certificateRequired = "remote error: handshake failure" + } testCases = append(testCases, testCase{ testType: serverTest, name: "RequireAnyClientCertificate-" + ver.name, @@ -2957,9 +2963,10 @@ func addClientAuthTests() { MinVersion: ver.version, MaxVersion: ver.version, }, - flags: []string{"-require-any-client-certificate"}, - shouldFail: true, - expectedError: ":PEER_DID_NOT_RETURN_A_CERTIFICATE:", + flags: []string{"-require-any-client-certificate"}, + shouldFail: true, + expectedError: ":PEER_DID_NOT_RETURN_A_CERTIFICATE:", + expectedLocalError: certificateRequired, }) if ver.version != VersionSSL30 { diff --git a/ssl/tls13_both.c b/ssl/tls13_both.c index e634790a..3928ab79 100644 --- a/ssl/tls13_both.c +++ b/ssl/tls13_both.c @@ -178,7 +178,7 @@ int tls13_process_certificate(SSL *ssl, int allow_anonymous) { if (sk_X509_num(chain) == 0) { if (!allow_anonymous) { OPENSSL_PUT_ERROR(SSL, SSL_R_PEER_DID_NOT_RETURN_A_CERTIFICATE); - ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE); + ssl3_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_CERTIFICATE_REQUIRED); goto err; }