summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorNikos Mavrogiannopoulos <nmav@redhat.com>2018-04-23 09:09:41 +0200
committerNikos Mavrogiannopoulos <nmav@redhat.com>2018-05-04 11:38:50 +0200
commita55d3f831e91ff7c358d1f634814724a0c0252e7 (patch)
tree59e1dbd0d69e32bb8c679e54c2f29d6dfd16aabd /lib
parentf4c44772bf7f0614719538e4fb0016e6e760c5e7 (diff)
downloadgnutls-a55d3f831e91ff7c358d1f634814724a0c0252e7.tar.gz
tls13/certificate_request: corrected check of duplicate signature algorithms
Made the check local when parsing a certificate request, as we may receive multiple requests when post-handshake authentication is in place. Furthermore check whether this extension has been received as this is a mandatory one. In addition handle a memory leak when multiple peer certificates are set. Signed-off-by: Nikos Mavrogiannopoulos <nmav@redhat.com>
Diffstat (limited to 'lib')
-rw-r--r--lib/gnutls_int.h1
-rw-r--r--lib/tls13/certificate.c9
-rw-r--r--lib/tls13/certificate_request.c9
3 files changed, 16 insertions, 3 deletions
diff --git a/lib/gnutls_int.h b/lib/gnutls_int.h
index cae9d7aec7..9c9fb1533a 100644
--- a/lib/gnutls_int.h
+++ b/lib/gnutls_int.h
@@ -1213,7 +1213,6 @@ typedef struct {
#define HSK_HRR_SENT (1<<3)
#define HSK_HRR_RECEIVED (1<<4)
#define HSK_CRT_REQ_SENT (1<<5)
-#define HSK_CRT_REQ_GOT_SIG_ALGO (1<<6)
#define HSK_KEY_UPDATE_ASKED (1<<7) /* flag is not used during handshake */
#define HSK_FALSE_START_USED (1<<8) /* TLS1.2 only */
#define HSK_HAVE_FFDHE (1<<9) /* whether the peer has advertized at least an FFDHE group */
diff --git a/lib/tls13/certificate.c b/lib/tls13/certificate.c
index b738897742..52c485aaa4 100644
--- a/lib/tls13/certificate.c
+++ b/lib/tls13/certificate.c
@@ -481,6 +481,15 @@ parse_cert_list(gnutls_session_t session, uint8_t * data, size_t data_size)
/* The OCSP entries match the certificate entries, although
* the contents of each OCSP entry may be NULL.
*/
+ for(j=0;j<info->ncerts;j++)
+ gnutls_free(info->raw_certificate_list[j].data);
+ gnutls_free(info->raw_certificate_list);
+
+ for(j=0;j<info->nocsp;j++)
+ gnutls_free(info->raw_ocsp_list[j].data);
+ gnutls_free(info->raw_ocsp_list);
+
+
info->raw_certificate_list = peer_certs;
info->ncerts = npeer_certs;
diff --git a/lib/tls13/certificate_request.c b/lib/tls13/certificate_request.c
index 293cc38dcf..09fb56d0bd 100644
--- a/lib/tls13/certificate_request.c
+++ b/lib/tls13/certificate_request.c
@@ -37,6 +37,7 @@
typedef struct crt_req_ctx_st {
gnutls_session_t session;
+ unsigned got_sig_algo;
gnutls_pk_algorithm_t pk_algos[MAX_ALGOS];
unsigned pk_algos_length;
const uint8_t *rdn; /* pointer inside the message buffer */
@@ -71,10 +72,10 @@ int parse_cert_extension(void *_ctx, unsigned tls_id, const uint8_t *data, unsig
/* signature algorithms; let's use it to decide the certificate to use */
unsigned i;
- if (session->internals.hsk_flags & HSK_CRT_REQ_GOT_SIG_ALGO)
+ if (ctx->got_sig_algo)
return gnutls_assert_val(GNUTLS_E_RECEIVED_ILLEGAL_EXTENSION);
- session->internals.hsk_flags |= HSK_CRT_REQ_GOT_SIG_ALGO;
+ ctx->got_sig_algo = 1;
if (data_size < 2)
return gnutls_assert_val(GNUTLS_E_TLS_PACKET_DECODING_ERROR);
@@ -167,6 +168,10 @@ int _gnutls13_recv_certificate_request_int(gnutls_session_t session, gnutls_buff
goto cleanup;
}
+ /* The "signature_algorithms" extension MUST be specified */
+ if (!ctx.got_sig_algo)
+ return gnutls_assert_val(GNUTLS_E_RECEIVED_ILLEGAL_EXTENSION);
+
session->internals.hsk_flags |= HSK_CRT_ASKED;
ret = _gnutls_select_client_cert(session, ctx.rdn, ctx.rdn_size,