summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNikos Mavrogiannopoulos <nmav@redhat.com>2017-10-03 14:21:33 +0200
committerNikos Mavrogiannopoulos <nmav@redhat.com>2017-11-16 14:24:35 +0100
commit287039749f565046e8cce50b892944c73836452f (patch)
tree64e52adf1b20dc079ba26ff8ab1caeebe089ef64
parent0eb891d521277045767f5e2d5ab33c00102e3b22 (diff)
downloadgnutls-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.c16
-rw-r--r--lib/auth/cert.h2
-rw-r--r--lib/tls13/certificate_request.c54
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();