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 <davidben@google.com>
diff --git a/crypto/err/ssl.errordata b/crypto/err/ssl.errordata
index 9045e9a..c25683e 100644
--- a/crypto/err/ssl.errordata
+++ b/crypto/err/ssl.errordata
@@ -157,7 +157,9 @@
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 8d105aa..52ed52c 100644
--- a/include/openssl/ssl.h
+++ b/include/openssl/ssl.h
@@ -2708,6 +2708,7 @@
#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 @@
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 @@
#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 c1db7ab..1c55ab3 100644
--- a/include/openssl/tls1.h
+++ b/include/openssl/tls1.h
@@ -160,14 +160,14 @@
#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 @@
#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 3fdc6e5..1ed0bdf 100644
--- a/ssl/ssl_stat.c
+++ b/ssl/ssl_stat.c
@@ -476,6 +476,9 @@
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 @@
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 b690c6f..8320b7e 100644
--- a/ssl/test/runner/alert.go
+++ b/ssl/test/runner/alert.go
@@ -43,6 +43,7 @@
alertUnsupportedExtension alert = 110
alertUnrecognizedName alert = 112
alertUnknownPSKIdentity alert = 115
+ alertCertificateRequired alert = 116
)
var alertText = map[alert]string{
@@ -73,6 +74,7 @@
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 7c2fd17..abadf3a 100644
--- a/ssl/test/runner/handshake_server.go
+++ b/ssl/test/runner/handshake_server.go
@@ -830,7 +830,7 @@
// 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 2a7f141..8ca3917 100644
--- a/ssl/test/runner/runner.go
+++ b/ssl/test/runner/runner.go
@@ -2950,6 +2950,12 @@
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 @@
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 e634790..3928ab7 100644
--- a/ssl/tls13_both.c
+++ b/ssl/tls13_both.c
@@ -178,7 +178,7 @@
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;
}