diff options
author | Nikos Mavrogiannopoulos <nmav@redhat.com> | 2017-10-03 14:21:33 +0200 |
---|---|---|
committer | Nikos Mavrogiannopoulos <nmav@redhat.com> | 2017-11-16 14:24:35 +0100 |
commit | 287039749f565046e8cce50b892944c73836452f (patch) | |
tree | 64e52adf1b20dc079ba26ff8ab1caeebe089ef64 | |
parent | 0eb891d521277045767f5e2d5ab33c00102e3b22 (diff) | |
download | gnutls-287039749f565046e8cce50b892944c73836452f.tar.gz |
handshake: handle the certificate authorities extension
That is, when sending or receiving the certificate request message.
Signed-off-by: Nikos Mavrogiannopoulos <nmav@redhat.com>
-rw-r--r-- | lib/auth/cert.c | 16 | ||||
-rw-r--r-- | lib/auth/cert.h | 2 | ||||
-rw-r--r-- | lib/tls13/certificate_request.c | 54 |
3 files changed, 61 insertions, 11 deletions
diff --git a/lib/auth/cert.c b/lib/auth/cert.c index 744641ad24..0ec6fbee8f 100644 --- a/lib/auth/cert.c +++ b/lib/auth/cert.c @@ -196,13 +196,13 @@ static int cert_get_issuer_dn(gnutls_pcert_st * cert, gnutls_datum_t * odn) static int find_x509_client_cert(gnutls_session_t session, const gnutls_certificate_credentials_t cred, - uint8_t * _data, size_t _data_size, + const uint8_t * _data, size_t _data_size, const gnutls_pk_algorithm_t * pk_algos, int pk_algos_length, int *indx) { unsigned size; gnutls_datum_t odn = { NULL, 0 }, asked_dn; - uint8_t *data = _data; + const uint8_t *data = _data; ssize_t data_size = _data_size; unsigned i, j; int result, cert_pk; @@ -224,7 +224,7 @@ find_x509_client_cert(gnutls_session_t session, DECR_LENGTH_RET(data_size, size, 0); data += 2; - asked_dn.data = data; + asked_dn.data = (void*)data; asked_dn.size = size; _gnutls_dn_log("Peer requested CA", &asked_dn); @@ -279,7 +279,7 @@ find_x509_client_cert(gnutls_session_t session, * certificate request packet. */ static int -get_issuers_num(gnutls_session_t session, uint8_t * data, ssize_t data_size) +get_issuers_num(gnutls_session_t session, const uint8_t * data, ssize_t data_size) { int issuers_dn_len = 0, result; unsigned size; @@ -328,7 +328,7 @@ get_issuers_num(gnutls_session_t session, uint8_t * data, ssize_t data_size) static int get_issuers(gnutls_session_t session, gnutls_datum_t * issuers_dn, int issuers_len, - uint8_t * data, size_t data_size) + const uint8_t * data, size_t data_size) { int i; unsigned size; @@ -352,7 +352,7 @@ get_issuers(gnutls_session_t session, data += 2; - issuers_dn[i].data = data; + issuers_dn[i].data = (void*)data; issuers_dn[i].size = size; _gnutls_dn_log("Peer requested CA", &issuers_dn[i]); @@ -515,13 +515,13 @@ call_get_cert_callback(gnutls_session_t session, */ int _gnutls_select_client_cert(gnutls_session_t session, - uint8_t * _data, size_t _data_size, + const uint8_t * _data, size_t _data_size, gnutls_pk_algorithm_t * pk_algos, int pk_algos_length) { int result; int indx = -1; gnutls_certificate_credentials_t cred; - uint8_t *data = _data; + const uint8_t *data = _data; ssize_t data_size = _data_size; int issuers_dn_length; gnutls_datum_t *issuers_dn = NULL; diff --git a/lib/auth/cert.h b/lib/auth/cert.h index ab8e840c7c..279f43f239 100644 --- a/lib/auth/cert.h +++ b/lib/auth/cert.h @@ -132,7 +132,7 @@ int _gnutls_get_selected_cert(gnutls_session_t session, int _gnutls_select_client_cert(gnutls_session_t session, - uint8_t * _data, size_t _data_size, + const uint8_t * _data, size_t _data_size, gnutls_pk_algorithm_t * pk_algos, int pk_algos_length); int _gnutls_copy_certificate_auth_info(cert_auth_info_t info, gnutls_pcert_st * certs, size_t ncerts); diff --git a/lib/tls13/certificate_request.c b/lib/tls13/certificate_request.c index 428f03df57..3e5b831a4f 100644 --- a/lib/tls13/certificate_request.c +++ b/lib/tls13/certificate_request.c @@ -30,11 +30,16 @@ #include "algorithms.h" #include "auth/cert.h" +/* for tlist dereference */ +#include "x509/verify-high.h" + +#define EXTID_CERTIFICATE_AUTHORITIES 47 + typedef struct crt_req_ctx_st { gnutls_session_t session; gnutls_pk_algorithm_t pk_algos[MAX_ALGOS]; unsigned pk_algos_length; - uint8_t *rdn; + const uint8_t *rdn; /* pointer inside the message buffer */ unsigned rdn_size; } crt_req_ctx_st; @@ -91,6 +96,17 @@ int parse_cert_extension(void *_ctx, uint16_t tls_id, const uint8_t *data, int d ctx->pk_algos[ctx->pk_algos_length++] = se->pk; } + } else if (tls_id == EXTID_CERTIFICATE_AUTHORITIES) { + if (data_size < 3) { + return gnutls_assert_val(GNUTLS_E_TLS_PACKET_DECODING_ERROR); + } + + ret = _gnutls_read_uint16(data); + if (ret != data_size-2) + return gnutls_assert_val(GNUTLS_E_TLS_PACKET_DECODING_ERROR); + + ctx->rdn = data+2; + ctx->rdn_size = ret; } return 0; @@ -152,10 +168,37 @@ int _gnutls13_recv_certificate_request(gnutls_session_t session) cleanup: _gnutls_buffer_clear(&buf); - gnutls_free(ctx.rdn); return ret; } +static +int write_certificate_authorities(void *ctx, gnutls_buffer_st *buf) +{ + gnutls_session_t session = ctx; + gnutls_certificate_credentials_t cred; + + if (session->internals.ignore_rdn_sequence != 0) + return 0; + + cred = (gnutls_certificate_credentials_t) + _gnutls_get_cred(session, GNUTLS_CRD_CERTIFICATE); + if (cred == NULL) { + gnutls_assert(); + return GNUTLS_E_INSUFFICIENT_CREDENTIALS; + } + + if (cred->tlist->x509_rdn_sequence.size == 0) + return 0; + + return + _gnutls_buffer_append_data_prefix(buf, 16, + cred-> + tlist->x509_rdn_sequence. + data, + cred-> + tlist->x509_rdn_sequence. + size); +} int _gnutls13_send_certificate_request(gnutls_session_t session, unsigned again) { @@ -198,6 +241,13 @@ int _gnutls13_send_certificate_request(gnutls_session_t session, unsigned again) goto cleanup; } + ret = _gnutls_extv_append(&buf, EXTID_CERTIFICATE_AUTHORITIES, session, + write_certificate_authorities); + if (ret < 0) { + gnutls_assert(); + goto cleanup; + } + ret = _gnutls_extv_append_final(&buf, init_pos); if (ret < 0) { gnutls_assert(); |