int CTlsSocket::Handshake(const CTlsSocket* pPrimarySocket, bool try_resume) { m_pOwner->LogMessage(MessageType::Debug_Verbose, _T("CTlsSocket::Handshake()")); wxASSERT(m_session); m_tlsState = TlsState::handshake; fz::native_string hostname; if (pPrimarySocket) { // Implicitly trust certificate of primary socket unsigned int cert_list_size; const gnutls_datum_t* const cert_list = gnutls_certificate_get_peers(pPrimarySocket->m_session, &cert_list_size); if (cert_list && cert_list_size) { delete [] m_implicitTrustedCert.data; m_implicitTrustedCert.data = new unsigned char[cert_list[0].size]; memcpy(m_implicitTrustedCert.data, cert_list[0].data, cert_list[0].size); m_implicitTrustedCert.size = cert_list[0].size; } if (try_resume) { if (!CopySessionData(pPrimarySocket)) return FZ_REPLY_ERROR; } hostname = pPrimarySocket->m_socket.GetPeerHost(); } else { hostname = m_socket.GetPeerHost(); } if (!hostname.empty() && fz::get_address_type(hostname) == fz::address_type::unknown) { auto const utf8 = fz::to_utf8(hostname); if (!utf8.empty()) { int res = gnutls_server_name_set(m_session, GNUTLS_NAME_DNS, utf8.c_str(), utf8.size()); if (res) { LogError(res, _T("gnutls_server_name_set"), MessageType::Debug_Warning ); } } } gnutls_handshake_set_hook_function(m_session, GNUTLS_HANDSHAKE_ANY, GNUTLS_HOOK_BOTH, &handshake_hook_func); return ContinueHandshake(); }
static void client(int fd, unsigned tickets) { int ret; gnutls_certificate_credentials_t x509_cred; gnutls_session_t session; char buf[64]; unsigned try = 0; gnutls_datum_t session_data = {NULL, 0}; global_init(); tickets_seen = 0; if (debug) { gnutls_global_set_log_function(client_log_func); gnutls_global_set_log_level(7); } assert(gnutls_certificate_allocate_credentials(&x509_cred)>=0); retry: /* Initialize TLS session */ assert(gnutls_init(&session, GNUTLS_CLIENT|GNUTLS_POST_HANDSHAKE_AUTH)>=0); gnutls_handshake_set_timeout(session, 20 * 1000); ret = gnutls_priority_set_direct(session, "NORMAL:-VERS-ALL:+VERS-TLS1.3:+VERS-TLS1.2:+VERS-TLS1.0", NULL); if (ret < 0) fail("cannot set TLS 1.3 priorities\n"); if (try == 0) { gnutls_session_set_ptr(session, &session_data); gnutls_handshake_set_hook_function(session, GNUTLS_HANDSHAKE_NEW_SESSION_TICKET, GNUTLS_HOOK_BOTH, ticket_callback); } else {
static void server(int fd) { int ret; gnutls_session_t session; gnutls_certificate_credentials_t x509_cred; /* this must be called once in the program */ global_init(); if (debug) { gnutls_global_set_log_function(server_log_func); gnutls_global_set_log_level(4711); } gnutls_certificate_allocate_credentials(&x509_cred); gnutls_certificate_set_x509_key_mem(x509_cred, &server_cert, &server_key, GNUTLS_X509_FMT_PEM); gnutls_init(&session, GNUTLS_SERVER|GNUTLS_DATAGRAM); gnutls_handshake_set_timeout(session, 20 * 1000); gnutls_handshake_set_hook_function(session, GNUTLS_HANDSHAKE_CLIENT_HELLO, GNUTLS_HOOK_POST, handshake_callback); assert(gnutls_priority_set_direct(session, "NORMAL:-VERS-ALL:+VERS-DTLS1.2", NULL)>= 0); gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, x509_cred); gnutls_transport_set_int(session, fd); do { ret = gnutls_handshake(session); } while (ret < 0 && gnutls_error_is_fatal(ret) == 0); if (ret < 0) { /* failure is expected here */ goto end; } if (debug) success("server: Handshake was completed\n"); if (debug) success("server: TLS version is: %s\n", gnutls_protocol_get_name (gnutls_protocol_get_version(session))); assert(found_server_name != 0); assert(found_status_req != 0); gnutls_bye(session, GNUTLS_SHUT_WR); end: close(fd); gnutls_deinit(session); gnutls_certificate_free_credentials(x509_cred); gnutls_global_deinit(); if (debug) success("server: finished\n"); }
void doit(void) { /* Server stuff. */ gnutls_certificate_credentials_t serverx509cred; gnutls_session_t server; int sret = GNUTLS_E_AGAIN; /* Client stuff. */ gnutls_certificate_credentials_t clientx509cred; gnutls_session_t client; int cret = GNUTLS_E_AGAIN; /* General init. */ global_init(); gnutls_global_set_log_function(tls_log_func); if (debug) gnutls_global_set_log_level(2); /* Init server */ gnutls_certificate_allocate_credentials(&serverx509cred); gnutls_certificate_set_x509_key_mem(serverx509cred, &server_cert, &server_key, GNUTLS_X509_FMT_PEM); gnutls_init(&server, GNUTLS_SERVER); gnutls_credentials_set(server, GNUTLS_CRD_CERTIFICATE, serverx509cred); gnutls_priority_set_direct(server, "NORMAL", NULL); gnutls_transport_set_push_function(server, server_push); gnutls_transport_set_pull_function(server, server_pull); gnutls_transport_set_ptr(server, server); gnutls_certificate_set_verify_function(serverx509cred, server_callback); gnutls_certificate_server_set_request(server, GNUTLS_CERT_REQUEST); gnutls_handshake_set_post_client_hello_function(server, post_client_hello_callback); gnutls_handshake_set_hook_function(server, GNUTLS_HANDSHAKE_ANY, GNUTLS_HOOK_POST, handshake_callback); /* Init client */ gnutls_certificate_allocate_credentials(&clientx509cred); gnutls_init(&client, GNUTLS_CLIENT); gnutls_credentials_set(client, GNUTLS_CRD_CERTIFICATE, clientx509cred); gnutls_priority_set_direct(client, "NORMAL", NULL); gnutls_transport_set_push_function(client, client_push); gnutls_transport_set_pull_function(client, client_pull); gnutls_transport_set_ptr(client, client); gnutls_certificate_set_verify_function(clientx509cred, client_callback); HANDSHAKE(client, server); gnutls_bye(client, GNUTLS_SHUT_RDWR); gnutls_bye(server, GNUTLS_SHUT_RDWR); gnutls_deinit(client); gnutls_deinit(server); gnutls_certificate_free_credentials(serverx509cred); gnutls_certificate_free_credentials(clientx509cred); gnutls_global_deinit(); if (pch_ok == 0) fail("Post client hello callback wasn't called\n"); if (server_ok == 0) fail("Server certificate verify callback wasn't called\n"); if (client_ok == 0) fail("Client certificate verify callback wasn't called\n"); }
/* Returns true if resumed */ static unsigned handshake(const char *prio, unsigned t, const gnutls_datum_t *sdata, gnutls_datum_t *ndata, gnutls_datum_t *skey, struct hsk_st *h) { int ret; /* Server stuff. */ gnutls_certificate_credentials_t serverx509cred; gnutls_session_t server; int sret = GNUTLS_E_AGAIN; /* Client stuff. */ gnutls_certificate_credentials_t clientx509cred; gnutls_session_t client; int cret = GNUTLS_E_AGAIN; char buf[128]; gnutls_global_set_log_function(tls_log_func); if (debug) gnutls_global_set_log_level(6); assert(gnutls_certificate_allocate_credentials(&serverx509cred)>=0); assert(gnutls_certificate_set_x509_key_mem(serverx509cred, &server_cert, &server_key, GNUTLS_X509_FMT_PEM)>=0); assert(gnutls_init(&server, GNUTLS_SERVER)>=0); gnutls_credentials_set(server, GNUTLS_CRD_CERTIFICATE, serverx509cred); assert(gnutls_priority_set_direct(server, prio, NULL)>=0); gnutls_transport_set_push_function(server, server_push); gnutls_transport_set_pull_function(server, server_pull); gnutls_transport_set_ptr(server, server); gnutls_session_set_ptr(server, h); gnutls_db_set_cache_expiration(server, t); assert(gnutls_session_ticket_enable_server(server, skey) >= 0); gnutls_handshake_set_hook_function(server, -1, GNUTLS_HOOK_POST, handshake_callback); assert(gnutls_certificate_allocate_credentials(&clientx509cred)>=0); assert(gnutls_certificate_set_x509_trust_mem(clientx509cred, &ca_cert, GNUTLS_X509_FMT_PEM)>=0); assert(gnutls_init(&client, GNUTLS_CLIENT)>=0); assert(gnutls_credentials_set(client, GNUTLS_CRD_CERTIFICATE, clientx509cred)>=0); assert(gnutls_priority_set_direct(client, prio, NULL)>=0); gnutls_transport_set_push_function(client, client_push); gnutls_transport_set_pull_function(client, client_pull); gnutls_transport_set_ptr(client, client); if (sdata) { assert(gnutls_session_set_data(client, sdata->data, sdata->size)>=0); } memset(buf, 0, sizeof(buf)); ret = gnutls_session_set_data(client, buf, sizeof(buf)); if (ret != GNUTLS_E_DB_ERROR) { fail("unexpected error: %s\n", gnutls_strerror(ret)); } HANDSHAKE(client, server); gnutls_record_recv(client, buf, sizeof(buf)); if (ndata) { ret = gnutls_session_get_data2(client, ndata); if (ret < 0) { fail("unexpected error: %s\n", gnutls_strerror(ret)); } } ret = gnutls_session_is_resumed(client); gnutls_deinit(server); gnutls_deinit(client); gnutls_certificate_free_credentials(serverx509cred); gnutls_certificate_free_credentials(clientx509cred); reset_buffers(); return ret; }
static void server(int fd, const char *prio) { int ret; char buffer[MAX_BUF + 1]; gnutls_session_t session; gnutls_certificate_credentials_t x509_cred; gnutls_datum_t skey; /* this must be called once in the program */ global_init(); memset(buffer, 0, sizeof(buffer)); if (debug) { gnutls_global_set_log_function(server_log_func); gnutls_global_set_log_level(4711); } assert(gnutls_certificate_allocate_credentials(&x509_cred)>=0); assert(gnutls_certificate_set_x509_key_mem(x509_cred, &server_cert, &server_key, GNUTLS_X509_FMT_PEM)>=0); assert(gnutls_init(&session, GNUTLS_SERVER)>=0); assert(gnutls_session_ticket_key_generate(&skey)>=0); assert(gnutls_session_ticket_enable_server(session, &skey) >= 0); gnutls_handshake_set_hook_function(session, GNUTLS_HANDSHAKE_NEW_SESSION_TICKET, GNUTLS_HOOK_POST, handshake_callback); /* avoid calling all the priority functions, since the defaults * are adequate. */ assert(gnutls_priority_set_direct(session, prio, NULL)>=0); gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, x509_cred); gnutls_transport_set_int(session, fd); do { ret = gnutls_handshake(session); } while (ret < 0 && gnutls_error_is_fatal(ret) == 0); if (ret < 0) { /* failure is expected here */ goto end; } if (debug) { success("server: Handshake was completed\n"); } if (debug) success("server: TLS version is: %s\n", gnutls_protocol_get_name (gnutls_protocol_get_version(session))); if (sent == 0) { fail("client: didn't send new sessiont ticket\n"); terminate(); } /* do not wait for the peer to close the connection. */ gnutls_bye(session, GNUTLS_SHUT_WR); end: close(fd); gnutls_deinit(session); gnutls_free(skey.data); gnutls_certificate_free_credentials(x509_cred); gnutls_global_deinit(); if (debug) success("server: finished\n"); }
static void client(int fd) { int ret; unsigned int status; gnutls_certificate_credentials_t x509_cred; gnutls_session_t session; /* Need to enable anonymous KX specifically. */ gnutls_global_set_time_function(mytime); global_init(); if (debug) { gnutls_global_set_log_function(client_log_func); gnutls_global_set_log_level(7); } gnutls_certificate_allocate_credentials(&x509_cred); /* Initialize TLS session */ gnutls_init(&session, GNUTLS_CLIENT); /* Use default priorities */ gnutls_priority_set_direct(session, "NORMAL:-KX-ALL:+ECDHE-RSA", NULL); gnutls_handshake_set_hook_function(session, GNUTLS_HANDSHAKE_CERTIFICATE_STATUS, GNUTLS_HOOK_POST, handshake_callback); /* put the anonymous credentials to the current session */ gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, x509_cred); gnutls_transport_set_int(session, fd); /* Perform the TLS handshake */ do { ret = gnutls_handshake(session); } while (ret < 0 && gnutls_error_is_fatal(ret) == 0); if (ret == GNUTLS_E_UNSUPPORTED_SIGNATURE_ALGORITHM) { /* success */ goto end; } if (ret < 0) { fail("client: Handshake failed: %s\n", gnutls_strerror(ret)); terminate(); } else { if (debug) success("client: Handshake was completed\n"); } if (debug) success("client: TLS version is: %s\n", gnutls_protocol_get_name (gnutls_protocol_get_version(session))); if (received == 1) { fail("client: received certificate status when we shouldn't.\n"); terminate(); } ret = gnutls_certificate_verify_peers2(session, &status); if (ret != GNUTLS_E_SUCCESS) { fail("client: Peer certificate validation failed: %s\n", gnutls_strerror(ret)); terminate(); } else { if (status & GNUTLS_CERT_MISSING_OCSP_STATUS) { success("client: Validation failed with GNUTLS_CERT_MISSING_OCSP_STATUS\n"); } else { fail("client: Validation status does not include GNUTLS_CERT_MISSING_OCSP_STATUS. Status is %d\n", status); terminate(); } } gnutls_bye(session, GNUTLS_SHUT_WR); end: close(fd); gnutls_deinit(session); gnutls_certificate_free_credentials(x509_cred); gnutls_global_deinit(); }