]> git.ipfire.org Git - thirdparty/gnutls.git/commitdiff
handshake: handle the certificate authorities extension
authorNikos Mavrogiannopoulos <nmav@redhat.com>
Tue, 3 Oct 2017 12:21:33 +0000 (14:21 +0200)
committerNikos Mavrogiannopoulos <nmav@redhat.com>
Mon, 19 Feb 2018 14:29:35 +0000 (15:29 +0100)
That is, when sending or receiving the certificate request message.

Signed-off-by: Nikos Mavrogiannopoulos <nmav@redhat.com>
lib/auth/cert.c
lib/auth/cert.h
lib/tls13/certificate_request.c

index 744641ad243ca76fb9fd11ecbca852bb82cce510..0ec6fbee8f25cebe3c6ce97ac3956710c1577ca4 100644 (file)
@@ -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;
index ab8e840c7c0b2df5f8451538d2fc1ff22b4e463e..279f43f2395fd5f03d10f55be74d8332edc1b9ab 100644 (file)
@@ -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);
index 428f03df5733792f2819154a96b4c0f58f059d5b..3e5b831a4fd45bdcde7c2589c418ec07b6bb5f9a 100644 (file)
 #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();