summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNikos Mavrogiannopoulos <nmav@redhat.com>2017-09-21 09:53:47 +0200
committerNikos Mavrogiannopoulos <nmav@redhat.com>2017-11-14 15:00:32 +0100
commit2994e87afdbb50d9dc28d2003421303c22b1e385 (patch)
tree4206268d1fb52ee793fc4fcfda779e5cd4ceec9f
parentce632a8c3881c4d6212b4a19346e9d681c4f61f1 (diff)
downloadgnutls-2994e87afdbb50d9dc28d2003421303c22b1e385.tar.gz
handshake: introduced server side handshake [1/2]
That is, send certificate request and certificate in server side Signed-off-by: Nikos Mavrogiannopoulos <nmav@redhat.com>
-rw-r--r--lib/handshake-tls13.c6
-rw-r--r--lib/tls13/certificate.c80
-rw-r--r--lib/tls13/certificate.h2
-rw-r--r--lib/tls13/certificate_request.c5
-rw-r--r--lib/tls13/certificate_request.h1
5 files changed, 86 insertions, 8 deletions
diff --git a/lib/handshake-tls13.c b/lib/handshake-tls13.c
index 90528c4c00..77cf9ffbed 100644
--- a/lib/handshake-tls13.c
+++ b/lib/handshake-tls13.c
@@ -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 */
diff --git a/lib/tls13/certificate.c b/lib/tls13/certificate.c
index 8a01005301..29c7de4590 100644
--- a/lib/tls13/certificate.c
+++ b/lib/tls13/certificate.c
@@ -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;
-}
diff --git a/lib/tls13/certificate.h b/lib/tls13/certificate.h
index 686e4ea8ae..4d2a3237a8 100644
--- a/lib/tls13/certificate.h
+++ b/lib/tls13/certificate.h
@@ -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);
diff --git a/lib/tls13/certificate_request.c b/lib/tls13/certificate_request.c
index 9ec7bd6010..0afe8b155a 100644
--- a/lib/tls13/certificate_request.c
+++ b/lib/tls13/certificate_request.c
@@ -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;
+}
diff --git a/lib/tls13/certificate_request.h b/lib/tls13/certificate_request.h
index 4a99221aad..78b4b4eb41 100644
--- a/lib/tls13/certificate_request.h
+++ b/lib/tls13/certificate_request.h
@@ -21,3 +21,4 @@
*/
int _gnutls13_recv_certificate_request(gnutls_session_t session);
+int _gnutls13_send_certificate_request(gnutls_session_t session, unsigned again);