bool ssl_connect_wget (int fd) { static const int cert_type_priority[] = { GNUTLS_CRT_X509, GNUTLS_CRT_OPENPGP, 0 }; struct wgnutls_transport_context *ctx; gnutls_session session; int err; int allowed_protocols[4] = {0, 0, 0, 0}; gnutls_init (&session, GNUTLS_CLIENT); gnutls_set_default_priority (session); gnutls_certificate_type_set_priority (session, cert_type_priority); gnutls_credentials_set (session, GNUTLS_CRD_CERTIFICATE, credentials); #ifndef FD_TO_SOCKET # define FD_TO_SOCKET(X) (X) #endif gnutls_transport_set_ptr (session, (gnutls_transport_ptr) FD_TO_SOCKET (fd)); err = 0; switch (opt.secure_protocol) { case secure_protocol_auto: break; case secure_protocol_sslv2: case secure_protocol_sslv3: allowed_protocols[0] = GNUTLS_SSL3; err = gnutls_protocol_set_priority (session, allowed_protocols); break; case secure_protocol_tlsv1: allowed_protocols[0] = GNUTLS_TLS1_0; allowed_protocols[1] = GNUTLS_TLS1_1; allowed_protocols[2] = GNUTLS_TLS1_2; err = gnutls_protocol_set_priority (session, allowed_protocols); break; default: abort (); } if (err < 0) { logprintf (LOG_NOTQUIET, "GnuTLS: %s\n", gnutls_strerror (err)); gnutls_deinit (session); return false; } err = gnutls_handshake (session); if (err < 0) { logprintf (LOG_NOTQUIET, "GnuTLS: %s\n", gnutls_strerror (err)); gnutls_deinit (session); return false; } ctx = xnew0 (struct wgnutls_transport_context); ctx->session = session; fd_register_transport (fd, &wgnutls_transport, ctx); return true; }
static void server (int fd, const char* prio) { int ret; char buffer[MAX_BUF + 1]; gnutls_session_t session; /* this must be called once in the program */ gnutls_global_init (); memset(buffer, 0, sizeof(buffer)); 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_anon_allocate_server_credentials (&anoncred); session = initialize_tls_session (prio); gnutls_transport_set_ptr (session, (gnutls_transport_ptr_t) fd); do { ret = gnutls_handshake (session); } while (ret < 0 && gnutls_error_is_fatal(ret) == 0); if (ret < 0) { close (fd); gnutls_deinit (session); fail ("server: Handshake has failed (%s)\n\n", gnutls_strerror (ret)); terminate(); } 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))); close(fd); gnutls_deinit (session); gnutls_anon_free_server_credentials (anoncred); gnutls_certificate_free_credentials (x509_cred); gnutls_global_deinit (); if (debug) success ("server: finished\n"); }
static void server(int sd) { gnutls_certificate_credentials_t x509_cred; gnutls_session_t session; int ret; unsigned loops; /* this must be called once in the program */ global_init(); gnutls_global_set_log_function(tls_log_func); if (debug) gnutls_global_set_log_level(6); gnutls_certificate_allocate_credentials(&x509_cred); gnutls_certificate_set_x509_trust_mem(x509_cred, &ca3_cert, GNUTLS_X509_FMT_PEM); gnutls_certificate_set_x509_key_mem(x509_cred, &server_ca3_localhost_cert, &server_ca3_key, GNUTLS_X509_FMT_PEM); if (debug) success("Launched, generating DH parameters...\n"); gnutls_init(&session, GNUTLS_SERVER); /* avoid calling all the priority functions, since the defaults * are adequate. */ gnutls_priority_set_direct(session, "NORMAL", NULL); gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, x509_cred); gnutls_transport_set_int(session, sd); loops = 0; do { ret = gnutls_handshake(session); loops++; if (loops > 64) fail("Too many loops in the handshake!\n"); } while (ret == GNUTLS_E_INTERRUPTED || ret == GNUTLS_E_AGAIN || ret == GNUTLS_E_WARNING_ALERT_RECEIVED); if (ret >= 0) { fail("server: Handshake succeeded unexpectedly\n"); } close(sd); gnutls_deinit(session); gnutls_certificate_free_credentials(x509_cred); gnutls_global_deinit(); if (debug) success("server: finished\n"); }
u8 * tls_connection_handshake(void *ssl_ctx, struct tls_connection *conn, const u8 *in_data, size_t in_len, size_t *out_len) { u8 *out_data; int ret; if (in_data && in_len) { if (conn->pull_buf) { wpa_printf(MSG_DEBUG, "%s - %d bytes remaining in " "pull_buf", __func__, conn->pull_buf_len); free(conn->pull_buf); } conn->pull_buf = malloc(in_len); if (conn->pull_buf == NULL) return NULL; memcpy(conn->pull_buf, in_data, in_len); conn->pull_buf_offset = conn->pull_buf; conn->pull_buf_len = in_len; } ret = gnutls_handshake(conn->session); if (ret < 0) { switch (ret) { case GNUTLS_E_AGAIN: break; case GNUTLS_E_FATAL_ALERT_RECEIVED: wpa_printf(MSG_DEBUG, "%s - received fatal '%s' alert", __func__, gnutls_alert_get_name( gnutls_alert_get(conn->session))); conn->read_alerts++; /* continue */ default: wpa_printf(MSG_DEBUG, "%s - gnutls_handshake failed " "-> %s", __func__, gnutls_strerror(ret)); conn->failed++; } } else { wpa_printf(MSG_DEBUG, "TLS: Handshake completed successfully"); if (conn->verify_peer && tls_connection_verify_peer(conn)) { wpa_printf(MSG_INFO, "TLS: Peer certificate chain " "failed validation"); conn->failed++; return NULL; } conn->established = 1; if (conn->push_buf == NULL) { /* Need to return something to get final TLS ACK. */ conn->push_buf = malloc(1); } } out_data = conn->push_buf; *out_len = conn->push_buf_len; conn->push_buf = NULL; conn->push_buf_len = 0; return out_data; }
void TLSTransaction::init (TLSServer& server) { gnutls_init (&_session, GNUTLS_SERVER); gnutls_priority_set (_session, server._priorities); gnutls_credentials_set (_session, GNUTLS_CRD_CERTIFICATE, server._credentials); // Require client certificate. gnutls_certificate_server_set_request (_session, GNUTLS_CERT_REQUIRE); /* // Set maximum compatibility mode. This is only suggested on public // webservers that need to trade security for compatibility gnutls_session_enable_compatibility_mode (_session); */ struct sockaddr_in sa_cli = {0}; socklen_t client_len = sizeof sa_cli; do { _socket = accept (server._socket, (struct sockaddr *) &sa_cli, &client_len); } while (errno == EINTR); if (_socket < 0) throw std::string (::strerror (errno)); // Obtain client info. char topbuf[512]; _address = inet_ntop (AF_INET, &sa_cli.sin_addr, topbuf, sizeof (topbuf)); _port = ntohs (sa_cli.sin_port); if (_debug) std::cout << "s: INFO connection from " << _address << " port " << _port << "\n"; #if GNUTLS_VERSION_NUMBER >= 0x030109 gnutls_transport_set_int (_session, _socket); #else gnutls_transport_set_ptr (_session, (gnutls_transport_ptr_t) (long) _socket); #endif // Key exchange. int ret; do { ret = gnutls_handshake (_session); } while (ret < 0 && gnutls_error_is_fatal (ret) == 0); if (ret < 0) throw std::string ("Handshake has failed (") + gnutls_strerror (ret) + ")"; if (_debug) std::cout << "s: INFO Handshake was completed\n"; }
static void client(int fd) { int ret; gnutls_anon_client_credentials_t anoncred; gnutls_session_t session; /* Need to enable anonymous KX specifically. */ global_init(); if (debug) { gnutls_global_set_log_function(client_log_func); gnutls_global_set_log_level(4711); } gnutls_anon_allocate_client_credentials(&anoncred); /* Initialize TLS session */ gnutls_init(&session, GNUTLS_CLIENT | GNUTLS_DATAGRAM); gnutls_dtls_set_mtu(session, 1500); gnutls_handshake_set_timeout(session, 20 * 1000); /* Use default priorities */ gnutls_priority_set_direct(session, "NONE:+VERS-DTLS-ALL:+CIPHER-ALL:+MAC-ALL:+SIGN-ALL:+COMP-ALL:+ANON-ECDH:+CURVE-ALL", NULL); /* put the anonymous credentials to the current session */ gnutls_credentials_set(session, GNUTLS_CRD_ANON, anoncred); gnutls_transport_set_int(session, fd); gnutls_transport_set_push_function(session, push); /* Perform the TLS handshake */ do { ret = gnutls_handshake(session); } while (ret < 0 && gnutls_error_is_fatal(ret) == 0); if (ret < 0) { success("client: Handshake failed as expected\n"); gnutls_perror(ret); goto exit; } else { fail("client: Handshake completed unexpectedly\n"); goto exit; } exit: gnutls_deinit(session); gnutls_anon_free_client_credentials(anoncred); gnutls_global_deinit(); }
bool DTLS_Encrypt(NetworkAddress * destAddress, uint8_t * plainText, int plainTextLength, uint8_t * encryptedBuffer, int encryptedBufferLength, int * encryptedLength, void *context) { bool result = false; DTLS_Session * session = GetSession(destAddress); if (session) { if (session->SessionEstablished) { gnutls_transport_set_push_function(session->Session, EncryptCallBack); session->Buffer = encryptedBuffer; session->BufferLength = encryptedBufferLength; int written = gnutls_write(session->Session, plainText, plainTextLength); if (written >= 0) { *encryptedLength = encryptedBufferLength - session->BufferLength; result = (*encryptedLength > 0); } } else { session->UserContext = context; gnutls_transport_set_push_function(session->Session, SSLSendCallBack); session->SessionEstablished = (gnutls_handshake(session->Session) == GNUTLS_E_SUCCESS); if (session->SessionEstablished) Lwm2m_Info("DTLS Session established\n"); } } else { int index; for (index = 0;index < MAX_DTLS_SESSIONS; index++) { if (!sessions[index].Session) { SetupNewSession(index, destAddress, true); sessions[index].UserContext = context; gnutls_transport_set_push_function(sessions[index].Session, SSLSendCallBack); sessions[index].SessionEstablished = (gnutls_handshake(sessions[index].Session) == GNUTLS_E_SUCCESS); break; } } } return result; }
int dtls_try_handshake(struct openconnect_info *vpninfo) { int err = gnutls_handshake(vpninfo->dtls_ssl); if (!err) { #ifdef HAVE_GNUTLS_DTLS_SET_DATA_MTU /* Make sure GnuTLS's idea of the MTU is sufficient to take a full VPN MTU (with 1-byte header) in a data record. */ err = gnutls_dtls_set_data_mtu(vpninfo->dtls_ssl, vpninfo->ip_info.mtu + 1); if (err) { vpn_progress(vpninfo, PRG_ERR, _("Failed to set DTLS MTU: %s\n"), gnutls_strerror(err)); goto error; } #else /* If we don't have gnutls_dtls_set_data_mtu() then make sure we leave enough headroom by adding the worst-case overhead. We only support AES128-CBC and DES-CBC3-SHA anyway, so working out the worst case isn't hard. */ gnutls_dtls_set_mtu(vpninfo->dtls_ssl, vpninfo->ip_info.mtu + 1 /* packet + header */ + 13 /* DTLS header */ + 20 /* biggest supported MAC (SHA1) */ + 16 /* biggest supported IV (AES-128) */ + 16 /* max padding */); #endif vpninfo->dtls_state = DTLS_CONNECTED; vpn_progress(vpninfo, PRG_INFO, _("Established DTLS connection (using GnuTLS). Ciphersuite %s.\n"), vpninfo->dtls_cipher); vpninfo->dtls_times.last_rekey = vpninfo->dtls_times.last_rx = vpninfo->dtls_times.last_tx = time(NULL); /* XXX: For OpenSSL we explicitly prevent retransmits here. */ return 0; } if (err == GNUTLS_E_AGAIN) { if (time(NULL) < vpninfo->new_dtls_started + 12) return 0; vpn_progress(vpninfo, PRG_DEBUG, _("DTLS handshake timed out\n")); } vpn_progress(vpninfo, PRG_ERR, _("DTLS handshake failed: %s\n"), gnutls_strerror(err)); error: dtls_close(vpninfo); vpninfo->dtls_state = DTLS_SLEEPING; time(&vpninfo->new_dtls_started); return -EINVAL; }
int SSL_accept (SSL * ssl) { X509_STORE_CTX *store; int cert_list_size = 0; int err; int i, j; int x_priority[GNUTLS_MAX_ALGORITHM_NUM]; /* take options into account before accepting */ memset (x_priority, 0, sizeof (x_priority)); if (ssl->options & SSL_OP_NO_TLSv1) { for (i = 0, j = 0; i < GNUTLS_MAX_ALGORITHM_NUM && x_priority[i] != 0; i++, j++) { if (ssl->ctx->method->protocol_priority[j] == GNUTLS_TLS1) j++; else x_priority[i] = ssl->ctx->method->protocol_priority[j]; } if (i < GNUTLS_MAX_ALGORITHM_NUM) x_priority[i] = 0; gnutls_protocol_set_priority (ssl->gnutls_state, ssl->ctx->method->protocol_priority); } /* FIXME: dh params, do we want client cert? */ err = gnutls_handshake (ssl->gnutls_state); ssl->last_error = err; if (err < 0) { last_error = err; return 0; } store = (X509_STORE_CTX *) calloc (1, sizeof (X509_STORE_CTX)); store->ssl = ssl; store->cert_list = gnutls_certificate_get_peers (ssl->gnutls_state, &cert_list_size); if (ssl->verify_callback) { ssl->verify_callback (1 /*FIXME*/, store); } ssl->state = SSL_ST_OK; err = store->error; free (store); /* FIXME: deal with error from callback */ return 1; }
/* retry an interrupted GTLS operation * rgerhards, 2008-04-30 */ static rsRetVal doRetry(nsd_gtls_t *pNsd) { DEFiRet; int gnuRet; dbgprintf("GnuTLS requested retry of %d operation - executing\n", pNsd->rtryCall); /* We follow a common scheme here: first, we do the systen call and * then we check the result. So far, the result is checked after the * switch, because the result check is the same for all calls. Note that * this may change once we deal with the read and write calls (but * probably this becomes an issue only when we begin to work on TLS * for relp). -- rgerhards, 2008-04-30 */ switch(pNsd->rtryCall) { case gtlsRtry_handshake: gnuRet = gnutls_handshake(pNsd->sess); if(gnuRet == 0) { pNsd->rtryCall = gtlsRtry_None; /* we are done */ /* we got a handshake, now check authorization */ CHKiRet(gtlsChkPeerAuth(pNsd)); } break; case gtlsRtry_recv: dbgprintf("retrying gtls recv, nsd: %p\n", pNsd); CHKiRet(gtlsRecordRecv(pNsd)); pNsd->rtryCall = gtlsRtry_None; /* we are done */ gnuRet = 0; break; case gtlsRtry_None: default: assert(0); /* this shall not happen! */ dbgprintf("ERROR: pNsd->rtryCall invalid in nsdsel_gtls.c:%d\n", __LINE__); gnuRet = 0; /* if it happens, we have at least a defined behaviour... ;) */ break; } if(gnuRet == 0) { pNsd->rtryCall = gtlsRtry_None; /* we are done */ } else if(gnuRet != GNUTLS_E_AGAIN && gnuRet != GNUTLS_E_INTERRUPTED) { uchar *pErr = gtlsStrerror(gnuRet); errmsg.LogError(0, RS_RET_GNUTLS_ERR, "unexpected GnuTLS error %d in %s:%d: %s\n", gnuRet, __FILE__, __LINE__, pErr); \ free(pErr); pNsd->rtryCall = gtlsRtry_None; /* we are also done... ;) */ ABORT_FINALIZE(RS_RET_GNUTLS_ERR); } /* if we are interrupted once again (else case), we do not need to * change our status because we are already setup for retries. */ finalize_it: if(iRet != RS_RET_OK && iRet != RS_RET_CLOSED && iRet != RS_RET_RETRY) pNsd->bAbortConn = 1; /* request abort */ RETiRet; }
/** * Enables SSL for the given connection. * * @param connection The connection to enable SSL for. * * @return IDEVICE_E_SUCCESS on success, IDEVICE_E_INVALID_ARG when connection * is NULL or connection->ssl_data is non-NULL, or IDEVICE_E_SSL_ERROR when * SSL initialization, setup, or handshake fails. */ idevice_error_t idevice_connection_enable_ssl(idevice_connection_t connection) { if (!connection || connection->ssl_data) return IDEVICE_E_INVALID_ARG; idevice_error_t ret = IDEVICE_E_SSL_ERROR; uint32_t return_me = 0; ssl_data_t ssl_data_loc = (ssl_data_t)malloc(sizeof(struct ssl_data_private)); /* Set up GnuTLS... */ debug_info("enabling SSL mode"); errno = 0; gnutls_global_init(); gnutls_certificate_allocate_credentials(&ssl_data_loc->certificate); gnutls_certificate_client_set_retrieve_function (ssl_data_loc->certificate, internal_cert_callback); gnutls_init(&ssl_data_loc->session, GNUTLS_CLIENT); gnutls_priority_set_direct(ssl_data_loc->session, "NONE:+VERS-SSL3.0:+ANON-DH:+RSA:+AES-128-CBC:+AES-256-CBC:+SHA1:+MD5:+COMP-NULL", NULL); gnutls_credentials_set(ssl_data_loc->session, GNUTLS_CRD_CERTIFICATE, ssl_data_loc->certificate); gnutls_session_set_ptr(ssl_data_loc->session, ssl_data_loc); gnutls_x509_crt_init(&ssl_data_loc->root_cert); gnutls_x509_crt_init(&ssl_data_loc->host_cert); gnutls_x509_privkey_init(&ssl_data_loc->root_privkey); gnutls_x509_privkey_init(&ssl_data_loc->host_privkey); userpref_error_t uerr = userpref_get_keys_and_certs(ssl_data_loc->root_privkey, ssl_data_loc->root_cert, ssl_data_loc->host_privkey, ssl_data_loc->host_cert); if (uerr != USERPREF_E_SUCCESS) { debug_info("Error %d when loading keys and certificates! %d", uerr); } debug_info("GnuTLS step 1..."); gnutls_transport_set_ptr(ssl_data_loc->session, (gnutls_transport_ptr_t)connection); debug_info("GnuTLS step 2..."); gnutls_transport_set_push_function(ssl_data_loc->session, (gnutls_push_func) & internal_ssl_write); debug_info("GnuTLS step 3..."); gnutls_transport_set_pull_function(ssl_data_loc->session, (gnutls_pull_func) & internal_ssl_read); debug_info("GnuTLS step 4 -- now handshaking..."); if (errno) debug_info("WARN: errno says %s before handshake!", strerror(errno)); return_me = gnutls_handshake(ssl_data_loc->session); debug_info("GnuTLS handshake done..."); if (return_me != GNUTLS_E_SUCCESS) { internal_ssl_cleanup(ssl_data_loc); free(ssl_data_loc); debug_info("GnuTLS reported something wrong."); gnutls_perror(return_me); debug_info("oh.. errno says %s", strerror(errno)); } else { connection->ssl_data = ssl_data_loc; ret = IDEVICE_E_SUCCESS; debug_info("SSL mode enabled"); } return ret; }
/* Only to be called from wr_send() and wr_recv() ! */ static bool wr_handshake(wr_socket s) { int res = gnutls_handshake (s->tls_s); if (GNUTLS_E_SUCCESS == res) s->tls_connected = !0; else if (GNUTLS_E_AGAIN == res) MHD_socket_set_error_ (MHD_SCKT_EAGAIN_); else MHD_socket_set_error_ (MHD_SCKT_ECONNABORTED_); /* hard error */ return s->tls_connected; }
static gpointer server_thread (gpointer user_data) { int listener = GPOINTER_TO_INT (user_data), client; gnutls_certificate_credentials creds; gnutls_session_t session; struct sockaddr_in sin; int len; char buf[BUFSIZE]; int status; gnutls_certificate_allocate_credentials (&creds); if (gnutls_certificate_set_x509_key_file (creds, ssl_cert_file, ssl_key_file, GNUTLS_X509_FMT_PEM) != 0) { g_error ("Failed to set SSL certificate and key files " "(%s, %s).", ssl_cert_file, ssl_key_file); } gnutls_certificate_set_dh_params (creds, dh_params); /* Create a new session */ gnutls_init (&session, GNUTLS_SERVER); gnutls_set_default_priority (session); gnutls_credentials_set (session, GNUTLS_CRD_CERTIFICATE, creds); gnutls_dh_set_prime_bits (session, DH_BITS); /* Wait for client thread to connect */ len = sizeof (sin); client = accept (listener, (struct sockaddr *) &sin, (void *)&len); gnutls_transport_set_ptr (session, GINT_TO_POINTER (client)); /* Initial handshake */ status = gnutls_handshake (session); if (status < 0) g_error ("initial handshake failed: %d", status); /* Synchronous client test. */ server_read (session, buf, BUFSIZE); server_write (session, buf, BUFSIZE); /* Async client test. */ server_read (session, buf, BUFSIZE); server_write (session, buf, BUFSIZE); /* That's all, folks. */ gnutls_bye (session, GNUTLS_SHUT_WR); gnutls_deinit (session); close (client); gnutls_certificate_free_credentials (creds); return NULL; }
static int test_tls_session_time_out (gnutls_session_t session) { int ret; MHD_socket sd; struct sockaddr_in sa; sd = socket (AF_INET, SOCK_STREAM, 0); if (sd == -1) { fprintf (stderr, "Failed to create socket: %s\n", strerror (errno)); return -1; } memset (&sa, '\0', sizeof (struct sockaddr_in)); sa.sin_family = AF_INET; sa.sin_port = htons (DEAMON_TEST_PORT); sa.sin_addr.s_addr = htonl (INADDR_LOOPBACK); gnutls_transport_set_ptr (session, (gnutls_transport_ptr_t) (intptr_t) sd); ret = connect (sd, (struct sockaddr *) &sa, sizeof (struct sockaddr_in)); if (ret < 0) { fprintf (stderr, "Error: %s\n", MHD_E_FAILED_TO_CONNECT); close (sd); return -1; } ret = gnutls_handshake (session); if (ret < 0) { fprintf (stderr, "Handshake failed\n"); close (sd); return -1; } sleep (TIME_OUT + 1); /* check that server has closed the connection */ /* TODO better RST trigger */ if (send (sd, "", 1, 0) == 0) { fprintf (stderr, "Connection failed to time-out\n"); close (sd); return -1; } close (sd); return 0; }
void socket_thread_main(apr_thread_t *self, void *data) { int ret = 0; socket_thread_data_t *thread_data = (socket_thread_data_t*)data; gnutls_session_t session; apr_os_sock_t sock; if(tls_cert != NULL) { if(apr_os_sock_get(&sock, thread_data->socket) != APR_SUCCESS) { syslog(LOG_ERR, "Can't get raw socket for TLS use"); ret = -1; } else if((thread_data->tls_session=apr_pcalloc( thread_data->pool, sizeof(gnutls_session_t)))!=NULL) { session = initialize_tls_session (); gnutls_transport_set_ptr (session, (gnutls_transport_ptr_t) (sock)); do { ret = gnutls_handshake (session); } while (ret < 0 && gnutls_error_is_fatal (ret) == 0); if (ret < 0) { syslog(LOG_ERR, "handshake has failed (%s)\n\n", gnutls_strerror (ret)); } *(thread_data->tls_session) = session; } else { syslog(LOG_ERR, "memory allocation failure"); ret = -1; } } if(ret >= 0) { socket_thread_handle(thread_data); if(thread_data->tls_session != NULL) gnutls_bye(session, GNUTLS_SHUT_WR); } apr_socket_close(thread_data->socket); if(thread_data->tls_session != NULL) gnutls_deinit (session); apr_pool_destroy(thread_data->pool); syslog(LOG_INFO, "client connection closed"); }
int TLSSocket::handshake() { int ret ; do { ret = gnutls_handshake (session); } while (ret == GNUTLS_E_AGAIN || ret == GNUTLS_E_INTERRUPTED ); if (ret < 0) { gnutls_perror(ret); Socket::close(); } return ret; }
static int handshake (struct stream_data *data) { const int protocol_priority[] = { GNUTLS_TLS1, GNUTLS_SSL3, 0 }; const int kx_priority[] = { GNUTLS_KX_RSA, 0 }; const int cipher_priority[] = { GNUTLS_CIPHER_3DES_CBC, GNUTLS_CIPHER_ARCFOUR, 0}; const int comp_priority[] = { GNUTLS_COMP_ZLIB, GNUTLS_COMP_NULL, 0 }; const int mac_priority[] = { GNUTLS_MAC_SHA, GNUTLS_MAC_MD5, 0 }; int ret; #ifndef WIN32 gcry_control(GCRYCTL_SET_THREAD_CBS, &gcry_threads_pthread); #endif if (gnutls_global_init () != 0) return IKS_NOMEM; if (gnutls_certificate_allocate_credentials (&data->cred) < 0) return IKS_NOMEM; if (gnutls_init (&data->sess, GNUTLS_CLIENT) != 0) { gnutls_certificate_free_credentials (data->cred); return IKS_NOMEM; } gnutls_protocol_set_priority (data->sess, protocol_priority); gnutls_cipher_set_priority(data->sess, cipher_priority); gnutls_compression_set_priority(data->sess, comp_priority); gnutls_kx_set_priority(data->sess, kx_priority); gnutls_mac_set_priority(data->sess, mac_priority); gnutls_credentials_set (data->sess, GNUTLS_CRD_CERTIFICATE, data->cred); gnutls_transport_set_push_function (data->sess, (gnutls_push_func) tls_push); gnutls_transport_set_pull_function (data->sess, (gnutls_pull_func) tls_pull); gnutls_transport_set_ptr (data->sess, data->prs); ret = gnutls_handshake (data->sess); if (ret != 0) { gnutls_deinit (data->sess); gnutls_certificate_free_credentials (data->cred); return IKS_NET_TLSFAIL; } data->flags &= (~SF_TRY_SECURE); data->flags |= SF_SECURE; iks_send_header (data->prs, data->server); return IKS_OK; } // HAVE_GNUTLS
static void client(int fd, const char *prio) { int ret; gnutls_certificate_credentials_t x509_cred; gnutls_session_t session; global_init(); if (debug) { gnutls_global_set_log_function(client_log_func); gnutls_global_set_log_level(7); } gnutls_certificate_allocate_credentials(&x509_cred); assert(gnutls_init(&session, GNUTLS_CLIENT)>=0); 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) { 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))); gnutls_bye(session, GNUTLS_SHUT_WR); close(fd); gnutls_deinit(session); gnutls_certificate_free_credentials(x509_cred); gnutls_global_deinit(); }
int SSL_accept (SSL * ssl) { X509_STORE_CTX *store; int cert_list_size = 0; int err; char x_priority[256]; /* take options into account before connecting */ memset (x_priority, 0, sizeof (x_priority)); if (ssl->options & SSL_OP_NO_TLSv1) { snprintf(x_priority, sizeof(x_priority), "%s:-VERS-TLS1.0", ssl->ctx->method->priority_string); err = gnutls_priority_set_direct(ssl->gnutls_state, x_priority, NULL); if (err < 0) { last_error = err; return 0; } } /* FIXME: dh params, do we want client cert? */ err = gnutls_handshake (ssl->gnutls_state); ssl->last_error = err; if (err < 0) { last_error = err; return 0; } store = (X509_STORE_CTX *) calloc (1, sizeof (X509_STORE_CTX)); store->ssl = ssl; store->cert_list = gnutls_certificate_get_peers (ssl->gnutls_state, &cert_list_size); if (ssl->verify_callback) { ssl->verify_callback (1 /*FIXME*/, store); } ssl->state = SSL_ST_OK; err = store->error; free (store); /* FIXME: deal with error from callback */ return 1; }
static void client(int fd) { int ret; gnutls_certificate_credentials_t x509_cred; gnutls_session_t session; gnutls_certificate_allocate_credentials(&x509_cred); /* Initialize TLS session */ gnutls_init(&session, GNUTLS_CLIENT); /* Use default priorities */ assert(gnutls_priority_set_direct(session, "NORMAL:-VERS-ALL:+VERS-TLS1.2", NULL)>=0); 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 < 0) { fail("client: Handshake failed\n"); gnutls_perror(ret); exit(1); } 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))); gnutls_bye(session, GNUTLS_SHUT_WR); close(fd); gnutls_deinit(session); gnutls_certificate_free_credentials(x509_cred); gnutls_global_deinit(); }
static void client(int fd) { int ret; gnutls_certificate_credentials_t xcred; gnutls_session_t session; global_init(); if (debug) { gnutls_global_set_log_function(client_log_func); gnutls_global_set_log_level(4711); } gnutls_certificate_allocate_credentials(&xcred); /* Initialize TLS session */ gnutls_init(&session, GNUTLS_CLIENT); gnutls_handshake_set_timeout(session, 20 * 1000); /* Use default priorities */ gnutls_priority_set_direct(session, "NORMAL:-KX-ALL:+ECDHE-RSA:%COMPAT", NULL); gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, xcred); gnutls_transport_set_int(session, fd); gnutls_transport_set_push_function(session, odd_push); /* Perform the TLS handshake */ do { ret = gnutls_handshake(session); } while (ret < 0 && gnutls_error_is_fatal(ret) == 0); if (ret >= 0) { fail("client: Handshake succeeded!\n"); exit(1); } close(fd); gnutls_deinit(session); gnutls_certificate_free_credentials(xcred); gnutls_global_deinit(); }
void GnuTlsStream::handshake(const GnuTlsServer& server) { log_debug("gnutls_init(session, GNUTLS_SERVER)"); int ret = gnutls_init(&_session, GNUTLS_SERVER); if (ret != 0) throw GnuTlsException("gnutls_init", ret); log_debug("gnutls_set_default_priority"); ret = gnutls_set_default_priority(_session); if (ret != 0) throw GnuTlsException("gnutls_set_default_priority", ret); log_debug("gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, " << server.getCred() << ')'); ret = gnutls_credentials_set(_session, GNUTLS_CRD_CERTIFICATE, server.getCred()); if (ret != 0) throw GnuTlsException("gnutls_credentials_set", ret); log_debug("gnutls_dh_set_prime_bits(session, 1024)"); gnutls_dh_set_prime_bits(_session, 1024); _fdInfo.fd = getFd(); _fdInfo.timeout = getTimeout(); log_debug("gnutls_transport_set_ptr(ptr)"); gnutls_transport_set_ptr(_session, static_cast<gnutls_transport_ptr_t>(&_fdInfo)); log_debug("gnutls_transport_set_pull_function()"); gnutls_transport_set_pull_function(_session, pull_func); log_debug("gnutls_transport_set_push_function()"); gnutls_transport_set_push_function(_session, push_func); // non-blocking/with timeout _fdInfo.timeout = 10000; log_debug("gnutls_handshake"); ret = gnutls_handshake(_session); log_debug("gnutls_handshake => " << ret); if (ret != 0) throw GnuTlsException("gnutls_handshake", ret); _connected = true; _fdInfo.timeout = getTimeout(); log_debug("ssl-handshake was completed"); }
int do_handshake (gnutls_session session) { int ret, alert; do { ret = gnutls_handshake (session); } while (ret == GNUTLS_E_INTERRUPTED || ret == GNUTLS_E_AGAIN); handshake_output = ret; if (ret < 0 && verbose > 1) { if (ret == GNUTLS_E_WARNING_ALERT_RECEIVED || ret == GNUTLS_E_FATAL_ALERT_RECEIVED) { alert = gnutls_alert_get (session); printf ("\n"); printf ("*** Received alert [%d]: %s\n", alert, gnutls_alert_get_name (alert)); } } if (ret < 0) return TEST_FAILED; gnutls_session_get_data (session, NULL, &session_data_size); if (sfree != 0) { free (session_data); sfree = 0; } session_data = malloc (session_data_size); sfree = 1; if (session_data == NULL) { fprintf (stderr, "Memory error\n"); exit (1); } gnutls_session_get_data (session, session_data, &session_data_size); session_id_size = sizeof (session_id); gnutls_session_get_id (session, session_id, &session_id_size); return TEST_SUCCEED; }
static Eina_Bool _process_data(gnutls_session_t client, Ecore_Fd_Handler * fd_handler) { static int ret, lastret; static unsigned int count = 0; if (!done) { lastret = ret; ret = gnutls_handshake(client); count++; if (gnutls_record_get_direction(client)) ecore_main_fd_handler_active_set(fd_handler, ECORE_FD_WRITE); else ecore_main_fd_handler_active_set(fd_handler, ECORE_FD_READ); /* avoid printing messages infinity times */ if (lastret != ret && ret != 0 && ret != GNUTLS_E_AGAIN) { print("gnutls returned with: %s - %s", gnutls_strerror_name(ret), gnutls_strerror(ret)); if ((ret == GNUTLS_E_WARNING_ALERT_RECEIVED) || (ret == GNUTLS_E_FATAL_ALERT_RECEIVED)) print("Also received alert: %s", gnutls_alert_get_name (gnutls_alert_get(client))); print("last out: %s", SSL_GNUTLS_PRINT_HANDSHAKE_STATUS (gnutls_handshake_get_last_out(client))); print("last in: %s", SSL_GNUTLS_PRINT_HANDSHAKE_STATUS (gnutls_handshake_get_last_in(client))); } if (gnutls_error_is_fatal(ret)) { print("yarrr this be an error!"); exit(1); } } if (ret == GNUTLS_E_SUCCESS) { done = 1; //print("Handshake successful in %u handshake calls!", count); ecore_main_loop_quit(); } return ECORE_CALLBACK_RENEW; }
static void ssl_handshake(struct sockifo* ifo) { int rv = gnutls_handshake(ifo->ssl); if (rv == GNUTLS_E_SUCCESS) { ifo->state.poll = POLL_NORMAL; ifo->state.ssl = SSL_ACTIVE; if (ifo->state.ssl_verify_type == VERIFY_CA) { ssl_vfy_ca(ifo); } else if (ifo->state.ssl_verify_type == VERIFY_FP) { ssl_vfy_fp(ifo); } } else if (rv == GNUTLS_E_AGAIN || rv == GNUTLS_E_INTERRUPTED) { do_eagain(ifo, 1); } else { esock(ifo, gnutls_strerror(rv)); } }
int SSLi_nonblockaccept( SSL_handle_t *session, bool_t * isSSLReady ) { int error; do { error = gnutls_handshake(*session); } while(error < GNUTLS_E_SUCCESS && !gnutls_error_is_fatal(error)); if ( error < GNUTLS_E_SUCCESS ) { Log_warn("TLS handshake failed with error %i (%s).", error, gnutls_strerror(error)); } if(isSSLReady) *isSSLReady = true; return error; }
static gnutls_session_t new_tls_session(int sock) { int ret; gnutls_session_t session; const char *err; #if defined LIBGNUTLS_VERSION_MAJOR && LIBGNUTLS_VERSION_MAJOR >= 3 # define TLS_DH_STR "+ANON-ECDH:+ANON-DH" #else # define TLS_DH_STR "+ANON-DH" #endif #ifdef GNUTLS_SRP_ENABLED const char *pstring = "NORMAL:+SRP:+SRP-DSS:+SRP-RSA:" TLS_DH_STR; #else const char *pstring = "NORMAL:" TLS_DH_STR; #endif gnutls_init(&session, GNUTLS_SERVER); gnutls_set_default_priority(session); ret = gnutls_priority_set_direct(session, pstring, &err); if (ret < 0) { fprintf(stderr, "TLS priority syntax error at: %s\n", err); return NULL; } #ifdef GNUTLS_SRP_ENABLED gnutls_credentials_set(session, GNUTLS_CRD_SRP, srpcred); gnutls_certificate_server_set_request(session, GNUTLS_CERT_IGNORE); #endif gnutls_credentials_set(session, GNUTLS_CRD_ANON, anoncred); gnutls_transport_set_ptr(session, fd_to_ptr(sock)); gnutls_transport_set_pull_function(session, tls_pull); gnutls_transport_set_push_function(session, tls_push); ret = gnutls_handshake(session); if ( ret < 0 ) { fprintf(stderr, "GnuTLS handshake failed: %s.\n", gnutls_strerror(ret)); gnutls_alert_send_appropriate(session, ret); return NULL; } return session; }
sstream::sstream(const TCPServer *tcp, secure::server_t scontext, size_t size) : tcpstream(tcp, size) { ssl = __context::session((__context *)scontext); bio = NULL; server = true; if(!is_open() || !ssl) return; gnutls_transport_set_ptr((SSL)ssl, reinterpret_cast<gnutls_transport_ptr_t>( so)); int result = gnutls_handshake((SSL)ssl); if(result >= 0) bio = ssl; }
static int get_cert(socket_st *hd, const char *hostname, unsigned udp, int fd) { gnutls_certificate_credentials_t xcred; gnutls_session_t session; int ret; struct priv_st priv; priv.found = 0; priv.fd = fd; ret = gnutls_certificate_allocate_credentials(&xcred); if (ret < 0) { fprintf(stderr, "error[%d]: %s\n", __LINE__, gnutls_strerror(ret)); exit(1); } gnutls_certificate_set_verify_function(xcred, cert_callback); ret = gnutls_init(&session, (udp?GNUTLS_DATAGRAM:0)|GNUTLS_CLIENT); if (ret < 0) { fprintf(stderr, "error[%d]: %s\n", __LINE__, gnutls_strerror(ret)); exit(1); } gnutls_session_set_ptr(session, &priv); gnutls_transport_set_int(session, hd->fd); gnutls_set_default_priority(session); if (hostname && is_ip(hostname)==0) { gnutls_server_name_set(session, GNUTLS_NAME_DNS, hostname, strlen(hostname)); } gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, xcred); do { ret = gnutls_handshake(session); } while(ret == GNUTLS_E_INTERRUPTED || ret == GNUTLS_E_AGAIN || ret == GNUTLS_E_WARNING_ALERT_RECEIVED); /* we don't care on the result */ gnutls_deinit(session); gnutls_certificate_free_credentials(xcred); if (priv.found == 0) return -1; return 0; }
void sstream::open(const char *host, const char *service, size_t bufsize) { if(server) return; close(); tcpstream::open(host, service, bufsize); if(!is_open() || !ssl) return; gnutls_transport_set_ptr((SSL)ssl, reinterpret_cast<gnutls_transport_ptr_t>(so)); int result = gnutls_handshake((SSL)ssl); if(result >= 0) bio = ssl; }