diff options
author | Nikos Mavrogiannopoulos <nmav@redhat.com> | 2017-09-21 09:53:47 +0200 |
---|---|---|
committer | Nikos Mavrogiannopoulos <nmav@redhat.com> | 2017-11-14 15:00:32 +0100 |
commit | 2994e87afdbb50d9dc28d2003421303c22b1e385 (patch) | |
tree | 4206268d1fb52ee793fc4fcfda779e5cd4ceec9f | |
parent | ce632a8c3881c4d6212b4a19346e9d681c4f61f1 (diff) | |
download | gnutls-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.c | 6 | ||||
-rw-r--r-- | lib/tls13/certificate.c | 80 | ||||
-rw-r--r-- | lib/tls13/certificate.h | 2 | ||||
-rw-r--r-- | lib/tls13/certificate_request.c | 5 | ||||
-rw-r--r-- | lib/tls13/certificate_request.h | 1 |
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); |