]> git.ipfire.org Git - thirdparty/gnutls.git/commitdiff
handshake: introduced server side handshake [1/2]
authorNikos Mavrogiannopoulos <nmav@redhat.com>
Thu, 21 Sep 2017 07:53:47 +0000 (09:53 +0200)
committerNikos Mavrogiannopoulos <nmav@redhat.com>
Mon, 19 Feb 2018 14:29:34 +0000 (15:29 +0100)
That is, send certificate request and certificate in server side

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

index 90528c4c0021841d8def1c0c79d60e85b5d90de1..77cf9ffbed18c7311948d830dcfc9a8c84c858c9 100644 (file)
@@ -104,7 +104,7 @@ int _gnutls13_handshake_client(gnutls_session_t session)
                IMED_RET("recv finished", ret, 0);
                /* fall through */
        case STATE107:
-               ret = _gnutls13_send_certificate(session);
+               ret = _gnutls13_send_certificate(session, AGAIN(STATE107));
                STATE = STATE107;
                IMED_RET("send certificate", ret, 0);
                /* fall through */
@@ -207,12 +207,12 @@ int _gnutls13_handshake_server(gnutls_session_t session)
                IMED_RET("send encrypted extensions", ret, 0);
                /* fall through */
        case STATE102:
-               abort();
+               ret = _gnutls13_send_certificate_request(session, AGAIN(STATE102));
                STATE = STATE102;
                IMED_RET("send certificate request", ret, 0);
                /* fall through */
        case STATE103:
-               abort();
+               ret = _gnutls13_send_certificate(session, AGAIN(STATE103));
                STATE = STATE103;
                IMED_RET("send certificate", ret, 0);
                /* fall through */
index 8a010053019d7e8d7130f045c5f7f5bd92d2ae65..29c7de4590d61ae2cf1df3bb21c19c236b1884b8 100644 (file)
@@ -26,6 +26,7 @@
 #include "handshake.h"
 #include "tls13/certificate.h"
 #include "auth/cert.h"
+#include "mbuffers.h"
 
 static int parse_cert_extension(void *ctx, uint16_t tls_id, const uint8_t *data, int data_size);
 static int parse_cert_list(gnutls_session_t session, uint8_t * data, size_t data_size);
@@ -65,6 +66,81 @@ cleanup:
        return ret;
 }
 
+int _gnutls13_send_certificate(gnutls_session_t session, unsigned again)
+{
+       int ret;
+       gnutls_pcert_st *apr_cert_list;
+       gnutls_privkey_t apr_pkey;
+       int apr_cert_list_length;
+       mbuffer_st *bufel = NULL;
+       gnutls_buffer_st buf;
+       unsigned pos_mark;
+       unsigned i;
+
+       if (again == 0) {
+               _gnutls_buffer_init(&buf);
+
+               ret = _gnutls_get_selected_cert(session, &apr_cert_list,
+                                               &apr_cert_list_length, &apr_pkey);
+               if (ret < 0)
+                       return gnutls_assert_val(ret);
+
+               ret = _gnutls_buffer_append_prefix(&buf, 8, 0);
+               if (ret < 0)
+                       return gnutls_assert_val(ret);
+
+               /* mark total size */
+               pos_mark = buf.length;
+               ret = _gnutls_buffer_append_prefix(&buf, 24, 0);
+               if (ret < 0) {
+                       gnutls_assert();
+                       goto cleanup;
+               }
+
+               for (i=0;i<(unsigned)apr_cert_list_length;i++) {
+                       ret = _gnutls_buffer_append_data_prefix(&buf, 24,
+                                                               apr_cert_list[i].cert.data,
+                                                               apr_cert_list[i].cert.size);
+                       if (ret < 0) {
+                               gnutls_assert();
+                               goto cleanup;
+                       }
+
+                       /* no extensions for now */
+                       ret = _gnutls_buffer_append_prefix(&buf, 16, 0);
+                       if (ret < 0) {
+                               gnutls_assert();
+                               goto cleanup;
+                       }
+               }
+
+               _gnutls_write_uint24(buf.length-pos_mark-3, &buf.data[pos_mark]);
+
+               bufel = _gnutls_handshake_alloc(session, buf.length);
+               if (bufel == NULL) {
+                       gnutls_assert();
+                       ret = GNUTLS_E_MEMORY_ERROR;
+                       goto cleanup;
+               }
+
+               _mbuffer_set_udata_size(bufel, 0);
+               ret = _mbuffer_append_data(bufel, buf.data, buf.length);
+               if (ret < 0) {
+                       gnutls_assert();
+                       goto cleanup;
+               }
+
+               _gnutls_buffer_clear(&buf);
+       }
+
+       return _gnutls_send_handshake(session, bufel, GNUTLS_HANDSHAKE_CERTIFICATE_PKT);
+
+ cleanup:
+       _gnutls_buffer_clear(&buf);
+       _mbuffer_xfree(&bufel);
+       return ret;
+}
+
 static int parse_cert_extension(void *ctx, uint16_t tls_id, const uint8_t *data, int data_size)
 {
        /* ignore all extensions */
@@ -217,7 +293,3 @@ parse_cert_list(gnutls_session_t session, uint8_t * data, size_t data_size)
 
 }
 
-int _gnutls13_send_certificate(gnutls_session_t session)
-{
-       return 0;
-}
index 686e4ea8ae017746b8be8d42dcd076c12fe4a005..4d2a3237a81263293949edf978d55a02ef657fe4 100644 (file)
@@ -21,4 +21,4 @@
  */
 
 int _gnutls13_recv_certificate(gnutls_session_t session);
-int _gnutls13_send_certificate(gnutls_session_t session);
+int _gnutls13_send_certificate(gnutls_session_t session, unsigned again);
index 9ec7bd601038574650c118c7dd0038c5853a54f8..0afe8b155aca8786562e4c6e8b6ac93ae8a15e6b 100644 (file)
@@ -68,3 +68,8 @@ int _gnutls13_recv_certificate_request(gnutls_session_t session)
 
        return 0;
 }
+
+int _gnutls13_send_certificate_request(gnutls_session_t session, unsigned again)
+{
+       return 0;
+}
index 4a99221aad70a5c9265026b7230379ac07960cf0..78b4b4eb4127c60c216af9e09f0156bcbe7aecda 100644 (file)
@@ -21,3 +21,4 @@
  */
 
 int _gnutls13_recv_certificate_request(gnutls_session_t session);
+int _gnutls13_send_certificate_request(gnutls_session_t session, unsigned again);