diff options
author | Nikos Mavrogiannopoulos <nmav@redhat.com> | 2018-04-23 09:09:41 +0200 |
---|---|---|
committer | Nikos Mavrogiannopoulos <nmav@redhat.com> | 2018-05-04 11:38:50 +0200 |
commit | a55d3f831e91ff7c358d1f634814724a0c0252e7 (patch) | |
tree | 59e1dbd0d69e32bb8c679e54c2f29d6dfd16aabd /lib | |
parent | f4c44772bf7f0614719538e4fb0016e6e760c5e7 (diff) | |
download | gnutls-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.h | 1 | ||||
-rw-r--r-- | lib/tls13/certificate.c | 9 | ||||
-rw-r--r-- | lib/tls13/certificate_request.c | 9 |
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, |