summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorDaiki Ueno <ueno@gnu.org>2019-03-06 03:35:09 +0000
committerDaiki Ueno <ueno@gnu.org>2019-03-06 03:35:09 +0000
commit89088e2274342b9deaa50a8b60cf9a0971fe543b (patch)
treeeb8cf6cfc501652ff88b7553313642a937527ec6 /lib
parent80295b4962dd2eadd0f91a7864c11bac469a5135 (diff)
parent2a0164bf28fa2d83a274f290ec9aeaa230fb74d8 (diff)
downloadgnutls-89088e2274342b9deaa50a8b60cf9a0971fe543b.tar.gz
Merge branch 'tmp-cert-req' into 'master'
TLS 1.3: utilize "certificate_required" alert Closes #715 See merge request gnutls/gnutls!946
Diffstat (limited to 'lib')
-rw-r--r--lib/alert.c6
-rw-r--r--lib/errors.c2
-rw-r--r--lib/includes/gnutls/gnutls.h.in3
-rw-r--r--lib/tls13/certificate.c9
4 files changed, 18 insertions, 2 deletions
diff --git a/lib/alert.c b/lib/alert.c
index a2d1725e6b..dd99c0fc52 100644
--- a/lib/alert.c
+++ b/lib/alert.c
@@ -84,6 +84,8 @@ static const gnutls_alert_entry sup_alerts[] = {
ALERT_ENTRY(GNUTLS_A_NO_APPLICATION_PROTOCOL,
N_
("No supported application protocol could be negotiated")),
+ ALERT_ENTRY(GNUTLS_A_CERTIFICATE_REQUIRED,
+ N_("Certificate is required")),
{0, NULL, NULL}
};
@@ -326,6 +328,10 @@ int gnutls_error_to_alert(int err, int *level)
ret = GNUTLS_A_UNRECOGNIZED_NAME;
_level = GNUTLS_AL_FATAL;
break;
+ case GNUTLS_E_CERTIFICATE_REQUIRED:
+ ret = GNUTLS_A_CERTIFICATE_REQUIRED;
+ _level = GNUTLS_AL_FATAL;
+ break;
default:
ret = GNUTLS_A_INTERNAL_ERROR;
_level = GNUTLS_AL_FATAL;
diff --git a/lib/errors.c b/lib/errors.c
index 520958b70c..0ce58043f6 100644
--- a/lib/errors.c
+++ b/lib/errors.c
@@ -93,6 +93,8 @@ static const gnutls_error_entry error_entries[] = {
GNUTLS_E_ERROR_IN_FINISHED_PACKET),
ERROR_ENTRY(N_("No certificate was found."),
GNUTLS_E_NO_CERTIFICATE_FOUND),
+ ERROR_ENTRY(N_("Certificate is required."),
+ GNUTLS_E_CERTIFICATE_REQUIRED),
ERROR_ENTRY(N_
("The given DSA key is incompatible with the selected TLS protocol."),
GNUTLS_E_INCOMPAT_DSA_KEY_WITH_TLS_PROTOCOL),
diff --git a/lib/includes/gnutls/gnutls.h.in b/lib/includes/gnutls/gnutls.h.in
index eb808e40b4..5187501a7c 100644
--- a/lib/includes/gnutls/gnutls.h.in
+++ b/lib/includes/gnutls/gnutls.h.in
@@ -526,6 +526,7 @@ typedef enum {
* recognized.
* @GNUTLS_A_UNKNOWN_PSK_IDENTITY: The SRP/PSK username is missing
* or not known.
+ * @GNUTLS_A_CERTIFICATE_REQUIRED: Certificate is required.
* @GNUTLS_A_NO_APPLICATION_PROTOCOL: The ALPN protocol requested is
* not supported by the peer.
*
@@ -562,6 +563,7 @@ typedef enum {
GNUTLS_A_CERTIFICATE_UNOBTAINABLE = 111,
GNUTLS_A_UNRECOGNIZED_NAME = 112,
GNUTLS_A_UNKNOWN_PSK_IDENTITY = 115,
+ GNUTLS_A_CERTIFICATE_REQUIRED = 116,
GNUTLS_A_NO_APPLICATION_PROTOCOL = 120,
GNUTLS_A_MAX = GNUTLS_A_NO_APPLICATION_PROTOCOL
} gnutls_alert_description_t;
@@ -3143,6 +3145,7 @@ void gnutls_fips140_set_mode(gnutls_fips_mode_t mode, unsigned flags);
#define GNUTLS_E_UNKNOWN_PK_ALGORITHM -80
#define GNUTLS_E_TOO_MANY_HANDSHAKE_PACKETS -81
#define GNUTLS_E_RECEIVED_DISALLOWED_NAME -82 /* GNUTLS_A_ILLEGAL_PARAMETER */
+#define GNUTLS_E_CERTIFICATE_REQUIRED -112 /* GNUTLS_A_CERTIFICATE_REQUIRED */
/* returned if you need to generate temporary RSA
* parameters. These are needed for export cipher suites.
diff --git a/lib/tls13/certificate.c b/lib/tls13/certificate.c
index 2560ca3427..91d0a7fe68 100644
--- a/lib/tls13/certificate.c
+++ b/lib/tls13/certificate.c
@@ -100,8 +100,13 @@ int _gnutls13_recv_certificate(gnutls_session_t session)
ret = parse_cert_list(session, buf.data, buf.length);
if (ret < 0) {
- if (ret == GNUTLS_E_NO_CERTIFICATE_FOUND && optional)
- ret = 0;
+ if (ret == GNUTLS_E_NO_CERTIFICATE_FOUND) {
+ if (optional)
+ ret = 0;
+ else if (session->security_parameters.entity ==
+ GNUTLS_SERVER)
+ ret = GNUTLS_E_CERTIFICATE_REQUIRED;
+ }
gnutls_assert();
goto cleanup;
}