test_code_t test_record_padding (gnutls_session_t session) { int ret; sprintf (prio_str, INIT_STR BLOCK_CIPHERS ":" ALL_COMP ":" ALL_CERTTYPES ":+VERS-TLS1.0:" ALL_MACS ":" ALL_KX ":%s", rest); _gnutls_priority_set_direct (session, prio_str); gnutls_credentials_set (session, GNUTLS_CRD_CERTIFICATE, xcred); ret = do_handshake (session); if (ret == TEST_SUCCEED) { tls1_ok = 1; } else { strcat (rest, ":%COMPAT"); } return ret; }
test_code_t test_max_record_size (gnutls_session_t session) { int ret; ADD_ALL_CIPHERS (session); ADD_ALL_COMP (session); ADD_ALL_CERTTYPES (session); ADD_ALL_PROTOCOLS (session); ADD_ALL_MACS (session); ADD_ALL_KX (session); gnutls_credentials_set (session, GNUTLS_CRD_CERTIFICATE, xcred); gnutls_record_set_max_size (session, 512); ret = do_handshake (session); if (ret == TEST_FAILED) return ret; ret = gnutls_record_get_max_size (session); if (ret == 512) return TEST_SUCCEED; return TEST_FAILED; }
/* Prints the trusted server's CAs. This is only * if the server sends a certificate request packet. */ test_code_t test_server_cas (gnutls_session_t session) { int ret; if (verbose == 0) return TEST_IGNORE; sprintf (prio_str, INIT_STR ALL_CIPHERS ":" ALL_COMP ":" ALL_CERTTYPES ":%s:" ALL_MACS ":" ALL_KX ":%s", protocol_str, rest); _gnutls_priority_set_direct (session, prio_str); gnutls_credentials_set (session, GNUTLS_CRD_CERTIFICATE, xcred); gnutls_certificate_set_retrieve_function (xcred, cert_callback); ret = do_handshake (session); gnutls_certificate_set_retrieve_function (xcred, NULL); if (ret == TEST_FAILED) return ret; return TEST_SUCCEED; }
void InitSession(StreamSocket* user, bool me_server) { issl_session* session = &sessions[user->GetFd()]; gnutls_init(&session->sess, me_server ? GNUTLS_SERVER : GNUTLS_CLIENT); session->socket = user; #ifdef GNUTLS_NEW_PRIO_API gnutls_priority_set(session->sess, priority); #else gnutls_set_default_priority(session->sess); #endif gnutls_credentials_set(session->sess, GNUTLS_CRD_CERTIFICATE, x509_cred); gnutls_dh_set_prime_bits(session->sess, dh_bits); gnutls_transport_set_ptr(session->sess, reinterpret_cast<gnutls_transport_ptr_t>(session)); gnutls_transport_set_push_function(session->sess, gnutls_push_wrapper); gnutls_transport_set_pull_function(session->sess, gnutls_pull_wrapper); if (me_server) gnutls_certificate_server_set_request(session->sess, GNUTLS_CERT_REQUEST); // Request client certificate if any. Handshake(session, user); }
static tls_session * tlsg_session_new ( tls_ctx * ctx, int is_server ) { tlsg_ctx *c = (tlsg_ctx *)ctx; tlsg_session *session; session = ber_memcalloc ( 1, sizeof (*session) ); if ( !session ) return NULL; session->ctx = c; gnutls_init( &session->session, is_server ? GNUTLS_SERVER : GNUTLS_CLIENT ); #ifdef HAVE_CIPHERSUITES gnutls_priority_set( session->session, c->prios ); #else gnutls_set_default_priority( session->session ); if ( c->kx_list ) { gnutls_kx_set_priority( session->session, c->kx_list ); gnutls_cipher_set_priority( session->session, c->cipher_list ); gnutls_mac_set_priority( session->session, c->mac_list ); } #endif if ( c->cred ) gnutls_credentials_set( session->session, GNUTLS_CRD_CERTIFICATE, c->cred ); if ( is_server ) { int flag = 0; if ( c->lo->ldo_tls_require_cert ) { flag = GNUTLS_CERT_REQUEST; if ( c->lo->ldo_tls_require_cert == LDAP_OPT_X_TLS_DEMAND || c->lo->ldo_tls_require_cert == LDAP_OPT_X_TLS_HARD ) flag = GNUTLS_CERT_REQUIRE; gnutls_certificate_server_set_request( session->session, flag ); } } return (tls_session *)session; }
/** * Create wr_socket with TLS TCP underlying socket * @return created socket on success, WR_BAD otherwise */ static wr_socket wr_create_tls_sckt(void) { #ifdef HTTPS_SUPPORT wr_socket s = (wr_socket)malloc(sizeof(struct wr_socket_strc)); if (WR_BAD == s) return WR_BAD; s->t = wr_tls; s->tls_connected = 0; s->fd = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP); if (MHD_INVALID_SOCKET != s->fd) { if (GNUTLS_E_SUCCESS == gnutls_init (&(s->tls_s), GNUTLS_CLIENT)) { if (GNUTLS_E_SUCCESS == gnutls_set_default_priority (s->tls_s)) { if (GNUTLS_E_SUCCESS == gnutls_certificate_allocate_credentials (&(s->tls_crd))) { if (GNUTLS_E_SUCCESS == gnutls_credentials_set (s->tls_s, GNUTLS_CRD_CERTIFICATE, s->tls_crd)) { #if GNUTLS_VERSION_NUMBER+0 >= 0x030109 gnutls_transport_set_int (s->tls_s, (int)(s->fd)); #else /* GnuTLS before 3.1.9 */ gnutls_transport_set_ptr (s->tls_s, (gnutls_transport_ptr_t)(intptr_t)(s->fd)); #endif /* GnuTLS before 3.1.9 */ return s; } gnutls_certificate_free_credentials (s->tls_crd); } } gnutls_deinit (s->tls_s); } (void)MHD_socket_close_ (s->fd); } free(s); #endif /* HTTPS_SUPPORT */ return WR_BAD; }
test_code_t test_rsa_pms (gnutls_session_t session) { int ret; /* here we enable both SSL 3.0 and TLS 1.0 * and try to connect and use rsa authentication. * If the server is old, buggy and only supports * SSL 3.0 then the handshake will fail. */ sprintf (prio_str, INIT_STR ALL_CIPHERS ":" ALL_COMP ":" ALL_CERTTYPES ":%s:" ALL_MACS ":+RSA:%s", protocol_str, rest); _gnutls_priority_set_direct (session, prio_str); gnutls_credentials_set (session, GNUTLS_CRD_CERTIFICATE, xcred); ret = do_handshake (session); if (ret == TEST_FAILED) return TEST_FAILED; if (gnutls_protocol_get_version (session) == GNUTLS_TLS1) return TEST_SUCCEED; return TEST_UNSURE; }
test_code_t test_certificate (gnutls_session_t session) { int ret; if (verbose == 0) return TEST_IGNORE; sprintf (prio_str, INIT_STR ALL_CIPHERS ":" ALL_COMP ":" ALL_CERTTYPES ":%s:" ALL_MACS ":" ALL_KX ":%s", protocol_str, rest); _gnutls_priority_set_direct (session, prio_str); gnutls_credentials_set (session, GNUTLS_CRD_CERTIFICATE, xcred); ret = do_handshake (session); if (ret == TEST_FAILED) return ret; printf ("\n"); print_cert_info (session, hostname, 1); return TEST_SUCCEED; }
test_code_t test_export (gnutls_session session) { int ret; ADD_ALL_COMP (session); ADD_ALL_CERTTYPES (session); ADD_ALL_PROTOCOLS (session); ADD_ALL_MACS (session); ADD_KX (session, GNUTLS_KX_RSA_EXPORT); ADD_CIPHER (session, GNUTLS_CIPHER_ARCFOUR_40); gnutls_credentials_set (session, GNUTLS_CRD_CERTIFICATE, xcred); ret = do_handshake (session); if (ret == TEST_SUCCEED) { export_true = 1; gnutls_rsa_export_get_pubkey (session, &exp, &mod); } return ret; }
static void rb_ssl_tryconn(rb_fde_t *F, int status, void *data) { struct ssl_connect *sconn = data; if(status != RB_OK) { rb_ssl_connect_realcb(F, status, sconn); return; } F->type |= RB_FD_SSL; rb_settimeout(F, sconn->timeout, rb_ssl_tryconn_timeout_cb, sconn); F->ssl = rb_malloc(sizeof(gnutls_session_t)); gnutls_init(F->ssl, GNUTLS_CLIENT); gnutls_set_default_priority(SSL_P(F)); gnutls_credentials_set(SSL_P(F), GNUTLS_CRD_CERTIFICATE, x509); gnutls_dh_set_prime_bits(SSL_P(F), 1024); gnutls_transport_set_ptr(SSL_P(F), (gnutls_transport_ptr_t) (long int)F->fd); gnutls_priority_set(SSL_P(F), default_priority); do_ssl_handshake(F, rb_ssl_tryconn_cb, (void *)sconn); }
gnutls_session initialize_tls_session (int sd) { int ret; gnutls_session session; const int cert_type_priority[2] = { GNUTLS_CRT_X509,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, xcred); gnutls_transport_set_ptr (session, (gnutls_transport_ptr) GINT_TO_POINTER(sd)); ret = gnutls_handshake (session); if (ret < 0) { close (sd); gnutls_deinit (session); fprintf (stderr, "*** Handshake failed\n"); gnutls_perror (ret); return NULL; } verify_certificate(session); return session; }
static void test_failure(const char *name, const char *prio) { 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; gnutls_x509_crt_t *crts; unsigned int crts_size; unsigned i; gnutls_typed_vdata_st vdata[2]; gnutls_x509_privkey_t pkey; unsigned status; success("testing cert verification failure for %s\n", name); to_server_len = 0; to_client_len = 0; ret = gnutls_x509_crt_list_import2(&crts, &crts_size, &server_cert, GNUTLS_X509_FMT_PEM, GNUTLS_X509_CRT_LIST_FAIL_IF_UNSORTED); if (ret < 0) { fprintf(stderr, "error: %s\n", gnutls_strerror(ret)); exit(1); } ret = gnutls_x509_privkey_init(&pkey); if (ret < 0) { fprintf(stderr, "error: %s\n", gnutls_strerror(ret)); exit(1); } ret = gnutls_x509_privkey_import(pkey, &server_key, GNUTLS_X509_FMT_PEM); if (ret < 0) { fprintf(stderr, "error: %s\n", gnutls_strerror(ret)); exit(1); } /* Init server */ gnutls_certificate_allocate_credentials(&serverx509cred); gnutls_certificate_set_x509_key(serverx509cred, crts, crts_size, pkey); gnutls_x509_privkey_deinit(pkey); for (i=0;i<crts_size;i++) gnutls_x509_crt_deinit(crts[i]); gnutls_free(crts); gnutls_init(&server, GNUTLS_SERVER); 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_certificate_server_set_request(server, GNUTLS_CERT_REQUEST); /* Init client */ /* Init client */ ret = gnutls_certificate_allocate_credentials(&clientx509cred); if (ret < 0) exit(1); ret = gnutls_certificate_set_x509_trust_mem(clientx509cred, &ca_cert, GNUTLS_X509_FMT_PEM); if (ret < 0) exit(1); ret = gnutls_certificate_set_x509_key_mem(clientx509cred, &cli_cert, &cli_key, GNUTLS_X509_FMT_PEM); ret = gnutls_init(&client, GNUTLS_CLIENT); if (ret < 0) exit(1); ret = gnutls_credentials_set(client, GNUTLS_CRD_CERTIFICATE, clientx509cred); if (ret < 0) exit(1); 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); memset(vdata, 0, sizeof(vdata)); /* check with wrong hostname */ vdata[0].type = GNUTLS_DT_DNS_HOSTNAME; vdata[0].data = (void*)"localhost1"; vdata[1].type = GNUTLS_DT_KEY_PURPOSE_OID; vdata[1].data = (void*)GNUTLS_KP_TLS_WWW_SERVER; gnutls_session_set_verify_cert2(client, vdata, 2, 0); HANDSHAKE_EXPECT(client, server, GNUTLS_E_CERTIFICATE_VERIFICATION_ERROR, GNUTLS_E_AGAIN); status = gnutls_session_get_verify_cert_status(client); if (status == 0) { fail("should not have accepted!\n"); exit(1); } gnutls_deinit(client); gnutls_deinit(server); gnutls_certificate_free_credentials(serverx509cred); gnutls_certificate_free_credentials(clientx509cred); }
struct dtls_gnutls_data *dtls_gnutls_data_create(struct conn *conn,int config) { const char *errpos; int rc; gnutls_datum_t key; int bits; struct dtls_gnutls_data *d = malloc(sizeof(struct dtls_gnutls_data)); if (!d) return 0; gnutls_global_set_log_level(10); gnutls_global_set_log_function(dtls_log_cb); rc = gnutls_init(&d->session, config); if (rc < 0) { cw_log(LOG_ERR, "DTLS - Can't init session: %s", gnutls_strerror(rc)); dtls_gnutls_data_destroy(d); return 0; } gnutls_certificate_allocate_credentials(&d->x509_cred); /* Set credentials */ if (conn->dtls_cert_file && conn->dtls_key_file){ rc = gnutls_certificate_set_x509_key_file(d->x509_cred, conn->dtls_cert_file, conn->dtls_key_file, GNUTLS_X509_FMT_PEM); if (rc < 0) { cw_log(LOG_ERR, "DTLS - Can't set cert/key: %s", gnutls_strerror(rc)); dtls_gnutls_data_destroy(d); return 0; } } /* #if GNUTLS_VERSION_NUMBER >= 0x030100 bits = gnutls_sec_param_to_pk_bits(GNUTLS_PK_DH, GNUTLS_SEC_PARAM_INSECURE); #else */ bits = gnutls_sec_param_to_pk_bits(GNUTLS_PK_DH, GNUTLS_SEC_PARAM_LEGACY); /*#endif*/ /* Set ciphers */ /* rc = gnutls_priority_init(&d->priority_cache, conn->dtls_cipher, &errpos); if (rc < 0) { cw_log(LOG_ERR, "DTLS - Can't init ciphers '%s' at '%s' : %s", conn->dtls_cipher, errpos, gnutls_strerror(rc)); dtls_gnutls_data_destroy(d); return 0; } rc = gnutls_priority_set(d->session, d->priority_cache); if (rc < 0) { cw_log(LOG_ERR, "DTLS - Can't set priority: %s", gnutls_strerror(rc)); dtls_gnutls_data_destroy(d); return 0; } */ rc = gnutls_priority_set_direct(d->session,conn->dtls_cipher,&errpos); if (rc < 0) { cw_log(LOG_ERR, "DTLS - Can't init ciphers '%s' at '%s' : %s", conn->dtls_cipher, errpos, gnutls_strerror(rc)); dtls_gnutls_data_destroy(d); return 0; } rc = gnutls_credentials_set(d->session, GNUTLS_CRD_CERTIFICATE, d->x509_cred); if (rc < 0) { cw_log(LOG_ERR, "DTLS - Can't set x.509 credentials: %s", gnutls_strerror(rc)); dtls_gnutls_data_destroy(d); return 0; } gnutls_certificate_set_verify_function(d->x509_cred,verify_cert); gnutls_session_set_ptr(d->session, conn); gnutls_transport_set_ptr(d->session, conn); gnutls_transport_set_pull_function(d->session, dtls_gnutls_bio_read); gnutls_transport_set_push_function(d->session, dtls_gnutls_bio_write); gnutls_transport_set_pull_timeout_function(d->session, dtls_gnutls_bio_wait); #if GNUTLS_VERSION_NUMBER >= 0x030100 gnutls_handshake_set_timeout(d->session, GNUTLS_DEFAULT_HANDSHAKE_TIMEOUT); gnutls_dtls_set_data_mtu(d->session, conn->dtls_mtu); #endif gnutls_dtls_set_mtu(d->session, conn->dtls_mtu); return d; }
/* * This function is called after the TCP connect has completed. Setup the TLS * layer and do all necessary magic. */ CURLcode Curl_gtls_connect(struct connectdata *conn, int sockindex) { const int cert_type_priority[] = { GNUTLS_CRT_X509, 0 }; struct SessionHandle *data = conn->data; gnutls_session session; int rc; unsigned int cert_list_size; const gnutls_datum *chainp; unsigned int verify_status; gnutls_x509_crt x509_cert; char certbuf[256]; /* big enough? */ size_t size; unsigned int algo; unsigned int bits; time_t clock; const char *ptr; void *ssl_sessionid; size_t ssl_idsize; /* GnuTLS only supports TLSv1 (and SSLv3?) */ if(data->set.ssl.version == CURL_SSLVERSION_SSLv2) { failf(data, "GnuTLS does not support SSLv2"); return CURLE_SSL_CONNECT_ERROR; } /* allocate a cred struct */ rc = gnutls_certificate_allocate_credentials(&conn->ssl[sockindex].cred); if(rc < 0) { failf(data, "gnutls_cert_all_cred() failed: %s", gnutls_strerror(rc)); return CURLE_SSL_CONNECT_ERROR; } if(data->set.ssl.CAfile) { /* set the trusted CA cert bundle file */ gnutls_certificate_set_verify_flags(conn->ssl[sockindex].cred, GNUTLS_VERIFY_ALLOW_X509_V1_CA_CRT); rc = gnutls_certificate_set_x509_trust_file(conn->ssl[sockindex].cred, data->set.ssl.CAfile, GNUTLS_X509_FMT_PEM); if(rc < 0) { infof(data, "error reading ca cert file %s (%s)\n", data->set.ssl.CAfile, gnutls_strerror(rc)); if (data->set.ssl.verifypeer) return CURLE_SSL_CACERT_BADFILE; } else infof(data, "found %d certificates in %s\n", rc, data->set.ssl.CAfile); } /* Initialize TLS session as a client */ rc = gnutls_init(&conn->ssl[sockindex].session, GNUTLS_CLIENT); if(rc) { failf(data, "gnutls_init() failed: %d", rc); return CURLE_SSL_CONNECT_ERROR; } /* convenient assign */ session = conn->ssl[sockindex].session; /* Use default priorities */ rc = gnutls_set_default_priority(session); if(rc < 0) return CURLE_SSL_CONNECT_ERROR; /* Sets the priority on the certificate types supported by gnutls. Priority is higher for types specified before others. After specifying the types you want, you must append a 0. */ rc = gnutls_certificate_type_set_priority(session, cert_type_priority); if(rc < 0) return CURLE_SSL_CONNECT_ERROR; if(data->set.cert) { if( gnutls_certificate_set_x509_key_file( conn->ssl[sockindex].cred, data->set.cert, data->set.key != 0 ? data->set.key : data->set.cert, do_file_type(data->set.cert_type) ) ) { failf(data, "error reading X.509 key or certificate file"); return CURLE_SSL_CONNECT_ERROR; } } /* put the credentials to the current session */ rc = gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, conn->ssl[sockindex].cred); /* set the connection handle (file descriptor for the socket) */ gnutls_transport_set_ptr(session, (gnutls_transport_ptr)conn->sock[sockindex]); /* register callback functions to send and receive data. */ gnutls_transport_set_push_function(session, Curl_gtls_push); gnutls_transport_set_pull_function(session, Curl_gtls_pull); /* lowat must be set to zero when using custom push and pull functions. */ gnutls_transport_set_lowat(session, 0); /* This might be a reconnect, so we check for a session ID in the cache to speed up things */ if(!Curl_ssl_getsessionid(conn, &ssl_sessionid, &ssl_idsize)) { /* we got a session id, use it! */ gnutls_session_set_data(session, ssl_sessionid, ssl_idsize); /* Informational message */ infof (data, "SSL re-using session ID\n"); } rc = handshake(conn, session, sockindex, TRUE); if(rc) /* handshake() sets its own error message with failf() */ return rc; /* This function will return the peer's raw certificate (chain) as sent by the peer. These certificates are in raw format (DER encoded for X.509). In case of a X.509 then a certificate list may be present. The first certificate in the list is the peer's certificate, following the issuer's certificate, then the issuer's issuer etc. */ chainp = gnutls_certificate_get_peers(session, &cert_list_size); if(!chainp) { if(data->set.ssl.verifyhost) { failf(data, "failed to get server cert"); return CURLE_SSL_PEER_CERTIFICATE; } infof(data, "\t common name: WARNING couldn't obtain\n"); } /* This function will try to verify the peer's certificate and return its status (trusted, invalid etc.). The value of status should be one or more of the gnutls_certificate_status_t enumerated elements bitwise or'd. To avoid denial of service attacks some default upper limits regarding the certificate key size and chain size are set. To override them use gnutls_certificate_set_verify_limits(). */ rc = gnutls_certificate_verify_peers2(session, &verify_status); if (rc < 0) { failf(data, "server cert verify failed: %d", rc); return CURLE_SSL_CONNECT_ERROR; } /* verify_status is a bitmask of gnutls_certificate_status bits */ if(verify_status & GNUTLS_CERT_INVALID) { if (data->set.ssl.verifypeer) { failf(data, "server certificate verification failed. CAfile: %s", data->set.ssl.CAfile?data->set.ssl.CAfile:"none"); return CURLE_SSL_CACERT; } else infof(data, "\t server certificate verification FAILED\n"); } else infof(data, "\t server certificate verification OK\n"); /* initialize an X.509 certificate structure. */ gnutls_x509_crt_init(&x509_cert); /* convert the given DER or PEM encoded Certificate to the native gnutls_x509_crt_t format */ gnutls_x509_crt_import(x509_cert, chainp, GNUTLS_X509_FMT_DER); size=sizeof(certbuf); rc = gnutls_x509_crt_get_dn_by_oid(x509_cert, GNUTLS_OID_X520_COMMON_NAME, 0, /* the first and only one */ FALSE, certbuf, &size); if(rc) { infof(data, "error fetching CN from cert:%s\n", gnutls_strerror(rc)); } /* This function will check if the given certificate's subject matches the given hostname. This is a basic implementation of the matching described in RFC2818 (HTTPS), which takes into account wildcards, and the subject alternative name PKIX extension. Returns non zero on success, and zero on failure. */ rc = gnutls_x509_crt_check_hostname(x509_cert, conn->host.name); if(!rc) { if (data->set.ssl.verifyhost > 1) { failf(data, "SSL: certificate subject name (%s) does not match " "target host name '%s'", certbuf, conn->host.dispname); gnutls_x509_crt_deinit(x509_cert); return CURLE_SSL_PEER_CERTIFICATE; } else infof(data, "\t common name: %s (does not match '%s')\n", certbuf, conn->host.dispname); } else infof(data, "\t common name: %s (matched)\n", certbuf); /* Show: - ciphers used - subject - start date - expire date - common name - issuer */ /* public key algorithm's parameters */ algo = gnutls_x509_crt_get_pk_algorithm(x509_cert, &bits); infof(data, "\t certificate public key: %s\n", gnutls_pk_algorithm_get_name(algo)); /* version of the X.509 certificate. */ infof(data, "\t certificate version: #%d\n", gnutls_x509_crt_get_version(x509_cert)); size = sizeof(certbuf); gnutls_x509_crt_get_dn(x509_cert, certbuf, &size); infof(data, "\t subject: %s\n", certbuf); clock = gnutls_x509_crt_get_activation_time(x509_cert); showtime(data, "start date", clock); clock = gnutls_x509_crt_get_expiration_time(x509_cert); showtime(data, "expire date", clock); size = sizeof(certbuf); gnutls_x509_crt_get_issuer_dn(x509_cert, certbuf, &size); infof(data, "\t issuer: %s\n", certbuf); gnutls_x509_crt_deinit(x509_cert); /* compression algorithm (if any) */ ptr = gnutls_compression_get_name(gnutls_compression_get(session)); /* the *_get_name() says "NULL" if GNUTLS_COMP_NULL is returned */ infof(data, "\t compression: %s\n", ptr); /* the name of the cipher used. ie 3DES. */ ptr = gnutls_cipher_get_name(gnutls_cipher_get(session)); infof(data, "\t cipher: %s\n", ptr); /* the MAC algorithms name. ie SHA1 */ ptr = gnutls_mac_get_name(gnutls_mac_get(session)); infof(data, "\t MAC: %s\n", ptr); if(!ssl_sessionid) { /* this session was not previously in the cache, add it now */ /* get the session ID data size */ gnutls_session_get_data(session, NULL, &ssl_idsize); ssl_sessionid = malloc(ssl_idsize); /* get a buffer for it */ if(ssl_sessionid) { /* extract session ID to the allocated buffer */ gnutls_session_get_data(session, ssl_sessionid, &ssl_idsize); /* store this session id */ return Curl_ssl_addsessionid(conn, ssl_sessionid, ssl_idsize); } } return CURLE_OK; }
int main(void) { int ret, sd, ii; gnutls_session_t session; char buffer[MAX_BUF + 1]; const char *err; gnutls_certificate_credentials_t xcred; if (gnutls_check_version("3.1.4") == NULL) { fprintf(stderr, "GnuTLS 3.1.4 or later is required for this example\n"); exit(1); } /* for backwards compatibility with gnutls < 3.3.0 */ gnutls_global_init(); /* X509 stuff */ gnutls_certificate_allocate_credentials(&xcred); /* sets the trusted cas file */ gnutls_certificate_set_x509_trust_file(xcred, CAFILE, GNUTLS_X509_FMT_PEM); gnutls_certificate_set_verify_function(xcred, verify_certificate_callback); /* Initialize TLS session */ gnutls_init(&session, GNUTLS_CLIENT | GNUTLS_DATAGRAM); /* Use default priorities */ ret = gnutls_priority_set_direct(session, "NORMAL", &err); if (ret < 0) { if (ret == GNUTLS_E_INVALID_REQUEST) { fprintf(stderr, "Syntax error at: %s\n", err); } exit(1); } /* put the x509 credentials to the current session */ gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, xcred); gnutls_server_name_set(session, GNUTLS_NAME_DNS, "my_host_name", strlen("my_host_name")); /* connect to the peer */ sd = udp_connect(); gnutls_transport_set_int(session, sd); /* set the connection MTU */ gnutls_dtls_set_mtu(session, 1000); gnutls_handshake_set_timeout(session, GNUTLS_DEFAULT_HANDSHAKE_TIMEOUT); /* Perform the TLS handshake */ do { ret = gnutls_handshake(session); } while (ret == GNUTLS_E_INTERRUPTED || ret == GNUTLS_E_AGAIN); /* Note that DTLS may also receive GNUTLS_E_LARGE_PACKET */ if (ret < 0) { fprintf(stderr, "*** Handshake failed\n"); gnutls_perror(ret); goto end; } else { char *desc; desc = gnutls_session_get_desc(session); printf("- Session info: %s\n", desc); gnutls_free(desc); } gnutls_record_send(session, MSG, strlen(MSG)); ret = gnutls_record_recv(session, buffer, MAX_BUF); if (ret == 0) { printf("- Peer has closed the TLS connection\n"); goto end; } else if (ret < 0 && gnutls_error_is_fatal(ret) == 0) { fprintf(stderr, "*** Warning: %s\n", gnutls_strerror(ret)); } else if (ret < 0) { fprintf(stderr, "*** Error: %s\n", gnutls_strerror(ret)); goto end; } if (ret > 0) { printf("- Received %d bytes: ", ret); for (ii = 0; ii < ret; ii++) { fputc(buffer[ii], stdout); } fputs("\n", stdout); } /* It is suggested not to use GNUTLS_SHUT_RDWR in DTLS * connections because the peer's closure message might * be lost */ gnutls_bye(session, GNUTLS_SHUT_WR); end: udp_close(sd); gnutls_deinit(session); gnutls_certificate_free_credentials(xcred); gnutls_global_deinit(); return 0; }
int main (void) { int ret, sd, ii; gnutls_session_t session; char buffer[MAX_BUF + 1]; gnutls_anon_client_credentials_t anoncred; /* Need to enable anonymous KX specifically. */ gnutls_global_init (); gnutls_anon_allocate_client_credentials (&anoncred); /* Initialize TLS session */ gnutls_init (&session, GNUTLS_CLIENT); /* Use default priorities */ gnutls_priority_set_direct (session, "PERFORMANCE:+ANON-ECDH:+ANON-DH", NULL); /* put the anonymous credentials to the current session */ gnutls_credentials_set (session, GNUTLS_CRD_ANON, anoncred); /* connect to the peer */ sd = tcp_connect (); gnutls_transport_set_ptr (session, (gnutls_transport_ptr_t) sd); gnutls_handshake_set_timeout (session, GNUTLS_DEFAULT_HANDSHAKE_TIMEOUT); /* Perform the TLS handshake */ do { ret = gnutls_handshake (session); } while (ret < 0 && gnutls_error_is_fatal (ret) == 0); if (ret < 0) { fprintf (stderr, "*** Handshake failed\n"); gnutls_perror (ret); goto end; } else { printf ("- Handshake was completed\n"); } gnutls_record_send (session, MSG, strlen (MSG)); ret = gnutls_record_recv (session, buffer, MAX_BUF); if (ret == 0) { printf ("- Peer has closed the TLS connection\n"); goto end; } else if (ret < 0) { fprintf (stderr, "*** Error: %s\n", gnutls_strerror (ret)); goto end; } printf ("- Received %d bytes: ", ret); for (ii = 0; ii < ret; ii++) { fputc (buffer[ii], stdout); } fputs ("\n", stdout); gnutls_bye (session, GNUTLS_SHUT_RDWR); end: tcp_close (sd); gnutls_deinit (session); gnutls_anon_free_client_credentials (anoncred); gnutls_global_deinit (); return 0; }
static void client(int sds[], struct params_res *params) { int ret, ii; gnutls_session_t session; char buffer[MAX_BUF + 1]; gnutls_anon_client_credentials_t anoncred; /* Need to enable anonymous KX specifically. */ /* variables used in session resuming */ int t; gnutls_datum_t session_data; if (debug) { gnutls_global_set_log_function(tls_log_func); gnutls_global_set_log_level(3); } global_init(); gnutls_anon_allocate_client_credentials(&anoncred); for (t = 0; t < SESSIONS; t++) { int sd = sds[t]; /* Initialize TLS session */ gnutls_init(&session, GNUTLS_CLIENT | GNUTLS_DATAGRAM); /* Use default priorities */ if (params->enable_session_ticket_client) gnutls_priority_set_direct(session, "NONE:+VERS-DTLS1.0:+CIPHER-ALL:+MAC-ALL:+SIGN-ALL:+COMP-ALL:+ANON-DH", NULL); else gnutls_priority_set_direct(session, "NONE:+VERS-DTLS1.0:+CIPHER-ALL:+MAC-ALL:+SIGN-ALL:+COMP-ALL:+ANON-DH:%NO_TICKETS", NULL); /* put the anonymous credentials to the current session */ gnutls_credentials_set(session, GNUTLS_CRD_ANON, anoncred); if (t > 0) { /* if this is not the first time we connect */ gnutls_session_set_data(session, session_data.data, session_data.size); gnutls_free(session_data.data); } gnutls_transport_set_int(session, sd); /* Perform the TLS handshake */ gnutls_dtls_set_timeouts(session, 3*1000, 240 * 1000); do { ret = gnutls_handshake(session); } while (ret < 0 && gnutls_error_is_fatal(ret) == 0); if (ret < 0) { gnutls_perror(ret); fail("client: Handshake failed\n"); goto end; } else { if (debug) success ("client: Handshake was completed\n"); } if (t == 0) { /* the first time we connect */ /* get the session data size */ ret = gnutls_session_get_data2(session, &session_data); if (ret < 0) fail("Getting resume data failed\n"); } else { /* the second time we connect */ /* check if we actually resumed the previous session */ if (gnutls_session_is_resumed(session) != 0) { if (params->expect_resume) { if (debug) success ("- Previous session was resumed\n"); } else fail("- Previous session was resumed\n"); } else { if (params->expect_resume) { fail("*** Previous session was NOT resumed\n"); } else { if (debug) success ("*** Previous session was NOT resumed (expected)\n"); } } } gnutls_record_send(session, MSG, strlen(MSG)); ret = gnutls_record_recv(session, buffer, MAX_BUF); if (ret == 0) { if (debug) success ("client: Peer has closed the TLS connection\n"); goto end; } else if (ret < 0) { fail("client: Error: %s\n", gnutls_strerror(ret)); goto end; } if (debug) { printf("- Received %d bytes: ", ret); for (ii = 0; ii < ret; ii++) { fputc(buffer[ii], stdout); } fputs("\n", stdout); } gnutls_bye(session, GNUTLS_SHUT_RDWR); close(sd); gnutls_deinit(session); } end: gnutls_anon_free_client_credentials(anoncred); }
void client (void) { int ret, sd, ii; gnutls_session_t session; char buffer[MAX_BUF + 1]; gnutls_certificate_credentials_t xcred; gnutls_global_init (); gnutls_global_set_log_function (tls_log_func); gnutls_global_set_log_level (4711); gnutls_certificate_allocate_credentials (&xcred); /* sets the trusted cas file */ gnutls_certificate_set_x509_trust_mem (xcred, &ca, GNUTLS_X509_FMT_PEM); gnutls_certificate_set_x509_key_mem (xcred, &cert, &key, GNUTLS_X509_FMT_PEM); /* Initialize TLS session */ gnutls_init (&session, GNUTLS_CLIENT); /* Use default priorities */ gnutls_set_default_priority (session); /* put the x509 credentials to the current session */ gnutls_credentials_set (session, GNUTLS_CRD_CERTIFICATE, xcred); /* connect to the peer */ sd = tcp_connect (); gnutls_transport_set_ptr (session, (gnutls_transport_ptr_t) sd); /* Perform the TLS handshake */ ret = gnutls_handshake (session); if (ret < 0) { fail ("client: Handshake failed\n"); gnutls_perror (ret); goto end; } else { success ("client: Handshake was completed\n"); } success ("client: TLS version is: %s\n", gnutls_protocol_get_name (gnutls_protocol_get_version (session))); /* see the Getting peer's information example */ print_info(session); gnutls_record_send (session, MSG, strlen (MSG)); ret = gnutls_record_recv (session, buffer, MAX_BUF); if (ret == 0) { success ("client: Peer has closed the TLS connection\n"); goto end; } else if (ret < 0) { fail ("client: Error: %s\n", gnutls_strerror (ret)); goto end; } printf ("- Received %d bytes: ", ret); for (ii = 0; ii < ret; ii++) { fputc (buffer[ii], stdout); } fputs ("\n", stdout); gnutls_bye (session, GNUTLS_SHUT_RDWR); end: tcp_close (sd); gnutls_deinit (session); gnutls_certificate_free_credentials (xcred); gnutls_global_deinit (); }
static void server(int fd, int profile) { int ret; gnutls_session_t session; gnutls_anon_server_credentials_t anoncred; uint8_t km[MAX_KEY_MATERIAL]; char buf[2 * MAX_KEY_MATERIAL]; gnutls_datum_t cli_key, cli_salt, server_key, server_salt; /* 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_anon_allocate_server_credentials(&anoncred); gnutls_init(&session, GNUTLS_SERVER | GNUTLS_DATAGRAM); gnutls_heartbeat_enable(session, GNUTLS_HB_PEER_ALLOWED_TO_SEND); gnutls_dtls_set_mtu(session, 1500); /* avoid calling all the priority functions, since the defaults * are adequate. */ gnutls_priority_set_direct(session, "NONE:+VERS-DTLS1.0:+CIPHER-ALL:+MAC-ALL:+SIGN-ALL:+COMP-ALL:+ANON-ECDH:+CURVE-ALL", NULL); if (profile) ret = gnutls_srtp_set_profile_direct(session, "SRTP_AES128_CM_HMAC_SHA1_80", NULL); else ret = gnutls_srtp_set_profile_direct(session, "SRTP_NULL_HMAC_SHA1_80", NULL); if (ret < 0) { gnutls_perror(ret); exit(1); } gnutls_credentials_set(session, GNUTLS_CRD_ANON, anoncred); gnutls_transport_set_int(session, 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))); ret = gnutls_srtp_get_keys(session, km, sizeof(km), &cli_key, &cli_salt, &server_key, &server_salt); if (ret < 0) { gnutls_perror(ret); exit(1); } if (debug) { size_t size = sizeof(buf); gnutls_hex_encode(&cli_key, buf, &size); success("Client key: %s\n", buf); size = sizeof(buf); gnutls_hex_encode(&cli_salt, buf, &size); success("Client salt: %s\n", buf); size = sizeof(buf); gnutls_hex_encode(&server_key, buf, &size); success("Server key: %s\n", buf); size = sizeof(buf); gnutls_hex_encode(&server_salt, buf, &size); success("Server salt: %s\n", buf); } /* do not wait for the peer to close the connection. */ gnutls_bye(session, GNUTLS_SHUT_WR); close(fd); gnutls_deinit(session); gnutls_anon_free_server_credentials(anoncred); gnutls_global_deinit(); if (debug) success("server: finished\n"); }
/* tls_negotiate: After TLS state has been initialised, attempt to negotiate * TLS over the wire, including certificate checks. */ static int tls_negotiate (CONNECTION * conn) { tlssockdata *data; int err; size_t nproto = 0; /* number of tls/ssl protocols */ data = (tlssockdata *) safe_calloc (1, sizeof (tlssockdata)); conn->sockdata = data; err = gnutls_certificate_allocate_credentials (&data->xcred); if (err < 0) { FREE(&conn->sockdata); mutt_error ("gnutls_certificate_allocate_credentials: %s", gnutls_strerror(err)); mutt_sleep (2); return -1; } gnutls_certificate_set_x509_trust_file (data->xcred, SslCertFile, GNUTLS_X509_FMT_PEM); /* ignore errors, maybe file doesn't exist yet */ if (SslCACertFile) { gnutls_certificate_set_x509_trust_file (data->xcred, SslCACertFile, GNUTLS_X509_FMT_PEM); } if (SslClientCert) { dprint (2, (debugfile, "Using client certificate %s\n", SslClientCert)); gnutls_certificate_set_x509_key_file (data->xcred, SslClientCert, SslClientCert, GNUTLS_X509_FMT_PEM); } #if HAVE_DECL_GNUTLS_VERIFY_DISABLE_TIME_CHECKS /* disable checking certificate activation/expiration times in gnutls, we do the checks ourselves */ gnutls_certificate_set_verify_flags(data->xcred, GNUTLS_VERIFY_DISABLE_TIME_CHECKS); #endif if ((err = gnutls_init(&data->state, GNUTLS_CLIENT))) { mutt_error ("gnutls_handshake: %s", gnutls_strerror(err)); mutt_sleep (2); goto fail; } /* set socket */ gnutls_transport_set_ptr (data->state, (gnutls_transport_ptr)conn->fd); if (option(OPTTLSV1_2)) protocol_priority[nproto++] = GNUTLS_TLS1_2; if (option(OPTTLSV1_1)) protocol_priority[nproto++] = GNUTLS_TLS1_1; if (option(OPTTLSV1)) protocol_priority[nproto++] = GNUTLS_TLS1; if (option(OPTSSLV3)) protocol_priority[nproto++] = GNUTLS_SSL3; protocol_priority[nproto] = 0; /* disable TLS/SSL protocols as needed */ if (nproto == 0) { mutt_error (_("All available protocols for TLS/SSL connection disabled")); goto fail; } /* else use the list set above */ /* We use default priorities (see gnutls documentation), except for protocol version */ gnutls_set_default_priority (data->state); gnutls_protocol_set_priority (data->state, protocol_priority); if (SslDHPrimeBits > 0) { gnutls_dh_set_prime_bits (data->state, SslDHPrimeBits); } /* gnutls_set_cred (data->state, GNUTLS_ANON, NULL); */ gnutls_credentials_set (data->state, GNUTLS_CRD_CERTIFICATE, data->xcred); err = gnutls_handshake(data->state); while (err == GNUTLS_E_AGAIN || err == GNUTLS_E_INTERRUPTED) { err = gnutls_handshake(data->state); } if (err < 0) { if (err == GNUTLS_E_FATAL_ALERT_RECEIVED) { mutt_error("gnutls_handshake: %s(%s)", gnutls_strerror(err), gnutls_alert_get_name(gnutls_alert_get(data->state))); } else { mutt_error("gnutls_handshake: %s", gnutls_strerror(err)); } mutt_sleep (2); goto fail; } if (!tls_check_certificate(conn)) goto fail; /* set Security Strength Factor (SSF) for SASL */ /* NB: gnutls_cipher_get_key_size() returns key length in bytes */ conn->ssf = gnutls_cipher_get_key_size (gnutls_cipher_get (data->state)) * 8; tls_get_client_cert (conn); if (!option(OPTNOCURSES)) { mutt_message (_("SSL/TLS connection using %s (%s/%s/%s)"), gnutls_protocol_get_name (gnutls_protocol_get_version (data->state)), gnutls_kx_get_name (gnutls_kx_get (data->state)), gnutls_cipher_get_name (gnutls_cipher_get (data->state)), gnutls_mac_get_name (gnutls_mac_get (data->state))); mutt_sleep (0); } return 0; fail: gnutls_certificate_free_credentials (data->xcred); gnutls_deinit (data->state); FREE(&conn->sockdata); return -1; }
int tls_connection_set_params(void *tls_ctx, struct tls_connection *conn, const struct tls_connection_params *params) { int ret; if (conn == NULL || params == NULL) return -1; os_free(conn->subject_match); conn->subject_match = NULL; if (params->subject_match) { conn->subject_match = os_strdup(params->subject_match); if (conn->subject_match == NULL) return -1; } os_free(conn->altsubject_match); conn->altsubject_match = NULL; if (params->altsubject_match) { conn->altsubject_match = os_strdup(params->altsubject_match); if (conn->altsubject_match == NULL) return -1; } /* TODO: gnutls_certificate_set_verify_flags(xcred, flags); * to force peer validation(?) */ if (params->ca_cert) { conn->verify_peer = 1; ret = gnutls_certificate_set_x509_trust_file( conn->xcred, params->ca_cert, GNUTLS_X509_FMT_PEM); if (ret < 0) { wpa_printf(MSG_DEBUG, "Failed to read CA cert '%s' " "in PEM format: %s", params->ca_cert, gnutls_strerror(ret)); ret = gnutls_certificate_set_x509_trust_file( conn->xcred, params->ca_cert, GNUTLS_X509_FMT_DER); if (ret < 0) { wpa_printf(MSG_DEBUG, "Failed to read CA cert " "'%s' in DER format: %s", params->ca_cert, gnutls_strerror(ret)); return -1; } } } if (params->client_cert && params->private_key) { /* TODO: private_key_passwd? */ ret = gnutls_certificate_set_x509_key_file( conn->xcred, params->client_cert, params->private_key, GNUTLS_X509_FMT_PEM); if (ret < 0) { wpa_printf(MSG_DEBUG, "Failed to read client cert/key " "in PEM format: %s", gnutls_strerror(ret)); ret = gnutls_certificate_set_x509_key_file( conn->xcred, params->client_cert, params->private_key, GNUTLS_X509_FMT_DER); if (ret < 0) { wpa_printf(MSG_DEBUG, "Failed to read client " "cert/key in DER format: %s", gnutls_strerror(ret)); return ret; } } } else if (params->private_key) { int pkcs12_ok = 0; #ifdef PKCS12_FUNCS /* Try to load in PKCS#12 format */ #if LIBGNUTLS_VERSION_NUMBER >= 0x010302 ret = gnutls_certificate_set_x509_simple_pkcs12_file( conn->xcred, params->private_key, GNUTLS_X509_FMT_DER, params->private_key_passwd); if (ret != 0) { wpa_printf(MSG_DEBUG, "Failed to load private_key in " "PKCS#12 format: %s", gnutls_strerror(ret)); return -1; } else pkcs12_ok = 1; #endif /* LIBGNUTLS_VERSION_NUMBER >= 0x010302 */ #endif /* PKCS12_FUNCS */ if (!pkcs12_ok) { wpa_printf(MSG_DEBUG, "GnuTLS: PKCS#12 support not " "included"); return -1; } } conn->tls_ia = params->tls_ia; conn->params_set = 1; ret = gnutls_credentials_set(conn->session, GNUTLS_CRD_CERTIFICATE, conn->xcred); if (ret < 0) { wpa_printf(MSG_INFO, "Failed to configure credentials: %s", gnutls_strerror(ret)); } #ifdef GNUTLS_IA if (conn->iacred_cli) gnutls_ia_free_client_credentials(conn->iacred_cli); ret = gnutls_ia_allocate_client_credentials(&conn->iacred_cli); if (ret) { wpa_printf(MSG_DEBUG, "Failed to allocate IA credentials: %s", gnutls_strerror(ret)); return -1; } ret = gnutls_credentials_set(conn->session, GNUTLS_CRD_IA, conn->iacred_cli); if (ret) { wpa_printf(MSG_DEBUG, "Failed to configure IA credentials: %s", gnutls_strerror(ret)); gnutls_ia_free_client_credentials(conn->iacred_cli); conn->iacred_cli = NULL; return -1; } #endif /* GNUTLS_IE */ return ret; }
static void server(int fd) { int ret; gnutls_certificate_credentials_t xcred; char buffer[MAX_BUF + 1]; gnutls_session_t session; /* 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(&xcred); ret = gnutls_certificate_set_x509_key_mem(xcred, &server_cert, &server_key, GNUTLS_X509_FMT_PEM); if (ret < 0) exit(1); gnutls_init(&session, GNUTLS_SERVER); gnutls_handshake_set_timeout(session, 20 * 1000); /* avoid calling all the priority functions, since the defaults * are adequate. */ gnutls_priority_set_direct(session, "NORMAL:-KX-ALL:+ECDHE-RSA", NULL); gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, xcred); gnutls_transport_set_int(session, 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))); /* see the Getting peer's information example */ /* print_info(session); */ memset(buffer, 1, sizeof(buffer)); do { ret = gnutls_record_send(session, buffer, sizeof(buffer)-1); } while (ret == GNUTLS_E_AGAIN || ret == GNUTLS_E_INTERRUPTED); if (ret < 0) { close(fd); gnutls_deinit(session); fail("server: data sending has failed (%s)\n\n", gnutls_strerror(ret)); terminate(); } ret = gnutls_bye(session, GNUTLS_SHUT_RDWR); if (ret < 0) { fail("server: error in closing session: %s\n", gnutls_strerror(ret)); } close(fd); gnutls_deinit(session); gnutls_certificate_free_credentials(xcred); gnutls_global_deinit(); if (debug) success("server: finished\n"); }
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"); }
static void client(int fd) { 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); /* Initialize TLS session */ gnutls_init(&session, GNUTLS_CLIENT|GNUTLS_DATAGRAM); gnutls_handshake_set_timeout(session, 20 * 1000); 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); assert(gnutls_server_name_set(session, GNUTLS_NAME_DNS, HOSTNAME, strlen(HOSTNAME))>=0); /* 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)); } 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); end: close(fd); gnutls_deinit(session); gnutls_certificate_free_credentials(x509_cred); gnutls_global_deinit(); }
static void test_success2(const char *name, const char *prio) { 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; gnutls_x509_crt_t *crts; unsigned int crts_size; unsigned i; gnutls_x509_privkey_t pkey; unsigned status; success("testing cert verification success2 for %s\n", name); to_server_len = 0; to_client_len = 0; ret = gnutls_x509_crt_list_import2(&crts, &crts_size, &server_cert, GNUTLS_X509_FMT_PEM, GNUTLS_X509_CRT_LIST_FAIL_IF_UNSORTED); if (ret < 0) { fprintf(stderr, "error: %s\n", gnutls_strerror(ret)); exit(1); } ret = gnutls_x509_privkey_init(&pkey); if (ret < 0) { fprintf(stderr, "error: %s\n", gnutls_strerror(ret)); exit(1); } ret = gnutls_x509_privkey_import(pkey, &server_key, GNUTLS_X509_FMT_PEM); if (ret < 0) { fprintf(stderr, "error: %s\n", gnutls_strerror(ret)); exit(1); } /* Init server */ gnutls_certificate_allocate_credentials(&serverx509cred); gnutls_certificate_set_x509_key(serverx509cred, crts, crts_size, pkey); gnutls_x509_privkey_deinit(pkey); for (i=0;i<crts_size;i++) gnutls_x509_crt_deinit(crts[i]); gnutls_free(crts); gnutls_init(&server, GNUTLS_SERVER); 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_certificate_server_set_request(server, GNUTLS_CERT_REQUEST); /* Init client */ /* Init client */ ret = gnutls_certificate_allocate_credentials(&clientx509cred); if (ret < 0) exit(1); ret = gnutls_certificate_set_x509_trust_mem(clientx509cred, &ca_cert, GNUTLS_X509_FMT_PEM); if (ret < 0) exit(1); ret = gnutls_certificate_set_x509_key_mem(clientx509cred, &cli_cert, &cli_key, GNUTLS_X509_FMT_PEM); ret = gnutls_init(&client, GNUTLS_CLIENT); if (ret < 0) exit(1); ret = gnutls_credentials_set(client, GNUTLS_CRD_CERTIFICATE, clientx509cred); if (ret < 0) exit(1); 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); gnutls_session_set_verify_cert(client, "localhost", 0); HANDSHAKE(client, server); status = gnutls_session_get_verify_cert_status(client); if (status != 0) { fail("%s: should have accepted: %u!\n", __func__, status); exit(1); } gnutls_deinit(client); gnutls_deinit(server); gnutls_certificate_free_credentials(serverx509cred); gnutls_certificate_free_credentials(clientx509cred); }
static void client(int fd, int profile) { gnutls_session_t session; int ret; gnutls_anon_client_credentials_t anoncred; uint8_t km[MAX_KEY_MATERIAL]; char buf[2 * MAX_KEY_MATERIAL]; gnutls_datum_t cli_key, cli_salt, server_key, server_salt; /* 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_heartbeat_enable(session, GNUTLS_HB_PEER_ALLOWED_TO_SEND); gnutls_dtls_set_mtu(session, 1500); /* Use default priorities */ gnutls_priority_set_direct(session, "NONE:+VERS-DTLS1.0:+CIPHER-ALL:+MAC-ALL:+SIGN-ALL:+COMP-ALL:+ANON-ECDH:+CURVE-ALL", NULL); if (profile) ret = gnutls_srtp_set_profile_direct(session, "SRTP_AES128_CM_HMAC_SHA1_80", NULL); else ret = gnutls_srtp_set_profile_direct(session, "SRTP_NULL_HMAC_SHA1_80", NULL); if (ret < 0) { gnutls_perror(ret); exit(1); } /* put the anonymous credentials to the current session */ gnutls_credentials_set(session, GNUTLS_CRD_ANON, anoncred); 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: DTLS version is: %s\n", gnutls_protocol_get_name (gnutls_protocol_get_version(session))); ret = gnutls_srtp_get_keys(session, km, sizeof(km), &cli_key, &cli_salt, &server_key, &server_salt); if (ret < 0) { gnutls_perror(ret); exit(1); } if (debug) { size_t size = sizeof(buf); gnutls_hex_encode(&cli_key, buf, &size); success("Client key: %s\n", buf); size = sizeof(buf); gnutls_hex_encode(&cli_salt, buf, &size); success("Client salt: %s\n", buf); size = sizeof(buf); gnutls_hex_encode(&server_key, buf, &size); success("Server key: %s\n", buf); size = sizeof(buf); gnutls_hex_encode(&server_salt, buf, &size); success("Server salt: %s\n", buf); } gnutls_bye(session, GNUTLS_SHUT_WR); close(fd); gnutls_deinit(session); gnutls_anon_free_client_credentials(anoncred); gnutls_global_deinit(); }
int main (void) { int ret, sd, ii; gnutls_session_t session; char buffer[MAX_BUF + 1]; const char *err; gnutls_certificate_credentials_t xcred; gnutls_global_init (); /* X509 stuff */ gnutls_certificate_allocate_credentials (&xcred); /* sets the trusted cas file */ gnutls_certificate_set_x509_trust_file (xcred, CAFILE, GNUTLS_X509_FMT_PEM); /* Initialize TLS session */ gnutls_init (&session, GNUTLS_CLIENT|GNUTLS_DATAGRAM); /* Use default priorities */ ret = gnutls_priority_set_direct (session, "NORMAL", &err); if (ret < 0) { if (ret == GNUTLS_E_INVALID_REQUEST) { fprintf (stderr, "Syntax error at: %s\n", err); } exit (1); } /* put the x509 credentials to the current session */ gnutls_credentials_set (session, GNUTLS_CRD_CERTIFICATE, xcred); /* connect to the peer */ sd = udp_connect (); gnutls_transport_set_ptr (session, (gnutls_transport_ptr_t) sd); /* set the connection MTU */ gnutls_dtls_set_mtu (session, 1000); /* Perform the TLS handshake */ ret = gnutls_handshake (session); if (ret < 0) { fprintf (stderr, "*** Handshake failed\n"); gnutls_perror (ret); goto end; } else { printf ("- Handshake was completed\n"); } gnutls_record_send (session, MSG, strlen (MSG)); ret = gnutls_record_recv (session, buffer, MAX_BUF); if (ret == 0) { printf ("- Peer has closed the TLS connection\n"); goto end; } else if (ret < 0) { fprintf (stderr, "*** Error: %s\n", gnutls_strerror (ret)); goto end; } printf ("- Received %d bytes: ", ret); for (ii = 0; ii < ret; ii++) { fputc (buffer[ii], stdout); } fputs ("\n", stdout); /* It is suggested not to use GNUTLS_SHUT_RDWR in DTLS * connections because the peer's closure message might * be lost */ gnutls_bye (session, GNUTLS_SHUT_WR); end: udp_close (sd); gnutls_deinit (session); gnutls_certificate_free_credentials (xcred); gnutls_global_deinit (); return 0; }
void doit (void) { /* Server stuff. */ gnutls_anon_server_credentials_t s_anoncred; const gnutls_datum_t p3 = { (void *) pkcs3, strlen (pkcs3) }; static gnutls_dh_params_t dh_params; gnutls_session_t server; int sret, cret; /* Client stuff. */ gnutls_anon_client_credentials_t c_anoncred; gnutls_session_t client; /* Need to enable anonymous KX specifically. */ char buffer[MAX_BUF + 1]; ssize_t ns; int ret, transferred = 0, msglen; /* General init. */ gnutls_global_init (); gnutls_global_set_log_function (tls_log_func); if (debug) gnutls_global_set_log_level (99); /* Init server */ gnutls_anon_allocate_server_credentials (&s_anoncred); gnutls_dh_params_init (&dh_params); gnutls_dh_params_import_pkcs3 (dh_params, &p3, GNUTLS_X509_FMT_PEM); gnutls_anon_set_server_dh_params (s_anoncred, dh_params); gnutls_init (&server, GNUTLS_SERVER|GNUTLS_DATAGRAM|GNUTLS_NONBLOCK); ret = gnutls_priority_set_direct (server, "NONE:+VERS-DTLS1.0:+CIPHER-ALL:+MAC-ALL:+SIGN-ALL:+COMP-ALL:+ANON-DH", NULL); if (ret < 0) exit(1); gnutls_credentials_set (server, GNUTLS_CRD_ANON, s_anoncred); gnutls_dh_set_prime_bits (server, 1024); gnutls_transport_set_push_function (server, server_push); gnutls_transport_set_pull_function (server, server_pull); gnutls_transport_set_pull_timeout_function (server, server_pull_timeout_func); gnutls_transport_set_ptr (server, (gnutls_transport_ptr_t)server); /* Init client */ gnutls_anon_allocate_client_credentials (&c_anoncred); gnutls_init (&client, GNUTLS_CLIENT|GNUTLS_DATAGRAM|GNUTLS_NONBLOCK); cret = gnutls_priority_set_direct (client, "NONE:+VERS-DTLS1.0:+CIPHER-ALL:+MAC-ALL:+SIGN-ALL:+COMP-ALL:+ANON-DH", NULL); if (cret < 0) exit(1); gnutls_credentials_set (client, GNUTLS_CRD_ANON, c_anoncred); gnutls_transport_set_push_function (client, client_push); gnutls_transport_set_pull_function (client, client_pull); gnutls_transport_set_pull_timeout_function (client, client_pull_timeout_func); gnutls_transport_set_ptr (client, (gnutls_transport_ptr_t)client); handshake = 1; HANDSHAKE(client, server); handshake = 0; if (debug) success ("Handshake established\n"); do { ret = gnutls_record_send (client, MSG, strlen (MSG)); } while(ret == GNUTLS_E_AGAIN); //success ("client: sent %d\n", ns); msglen = strlen(MSG); TRANSFER(client, server, MSG, msglen, buffer, MAX_BUF); if (debug) fputs ("\n", stdout); gnutls_bye (client, GNUTLS_SHUT_WR); gnutls_bye (server, GNUTLS_SHUT_WR); gnutls_deinit (client); gnutls_deinit (server); gnutls_anon_free_client_credentials (c_anoncred); gnutls_anon_free_server_credentials (s_anoncred); gnutls_dh_params_deinit (dh_params); gnutls_global_deinit (); }
static void client(int fd, struct sockaddr *connect_addr, socklen_t connect_addrlen) { int ret; char buffer[MAX_BUF + 1]; 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", NULL); gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, xcred); gnutls_transport_set_fastopen(session, fd, connect_addr, connect_addrlen, 0); /* 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))); do { ret = gnutls_record_recv(session, buffer, sizeof(buffer)-1); } while (ret == GNUTLS_E_AGAIN || ret == GNUTLS_E_INTERRUPTED); if (ret == 0) { if (debug) success ("client: Peer has closed the TLS connection\n"); goto end; } else if (ret < 0) { fail("client: Error: %s\n", gnutls_strerror(ret)); exit(1); } ret = gnutls_bye(session, GNUTLS_SHUT_RDWR); if (ret < 0) { fail("server: error in closing session: %s\n", gnutls_strerror(ret)); } end: close(fd); gnutls_deinit(session); gnutls_certificate_free_credentials(xcred); gnutls_global_deinit(); }
static void server(int sds[], struct params_res *params) { gnutls_anon_server_credentials_t anoncred; static gnutls_datum_t session_ticket_key = { NULL, 0 }; int ret; size_t t; gnutls_session_t session; /* this must be called once in the program, it is mostly for the server. */ if (debug) { gnutls_global_set_log_function(tls_log_func); gnutls_global_set_log_level(3); } global_init(); gnutls_anon_allocate_server_credentials(&anoncred); if (debug) success("Launched, generating DH parameters...\n"); gnutls_anon_set_server_dh_params(anoncred, dh_params); if (params->enable_db) { wrap_db_init(); } if (params->enable_session_ticket_server) gnutls_session_ticket_key_generate(&session_ticket_key); for (t = 0; t < SESSIONS; t++) { int sd = sds[t]; gnutls_init(&session, GNUTLS_SERVER | GNUTLS_DATAGRAM); gnutls_priority_set_direct(session, "NONE:+VERS-DTLS1.0:+CIPHER-ALL:+MAC-ALL:+SIGN-ALL:+COMP-ALL:+ANON-DH", NULL); gnutls_credentials_set(session, GNUTLS_CRD_ANON, anoncred); gnutls_dh_set_prime_bits(session, DH_BITS); if (params->enable_db) { gnutls_db_set_retrieve_function(session, wrap_db_fetch); gnutls_db_set_remove_function(session, wrap_db_delete); gnutls_db_set_store_function(session, wrap_db_store); gnutls_db_set_ptr(session, NULL); } if (params->enable_session_ticket_server) gnutls_session_ticket_enable_server(session, &session_ticket_key); gnutls_transport_set_int(session, sd); gnutls_dtls_set_timeouts(session, 3*1000, 240 * 1000); do { ret = gnutls_handshake(session); } while (ret < 0 && (ret == GNUTLS_E_INTERRUPTED||ret == GNUTLS_E_AGAIN)); if (ret < 0) { close(sd); gnutls_deinit(session); kill(child, SIGTERM); fail("server: Handshake has failed (%s)\n\n", gnutls_strerror(ret)); return; } if (debug) success("server: Handshake was completed\n"); /* see the Getting peer's information example */ /* print_info(session); */ for (;;) { memset(buffer, 0, MAX_BUF + 1); ret = gnutls_record_recv(session, buffer, MAX_BUF); if (ret == 0) { if (debug) success ("server: Peer has closed the GnuTLS connection\n"); break; } else if (ret < 0) { kill(child, SIGTERM); fail("server: Received corrupted data(%d). Closing...\n", ret); break; } else if (ret > 0) { /* echo data back to the client */ gnutls_record_send(session, buffer, strlen(buffer)); } } /* do not wait for the peer to close the connection. */ gnutls_bye(session, GNUTLS_SHUT_WR); close(sd); gnutls_deinit(session); } if (params->enable_db) { wrap_db_deinit(); } gnutls_free(session_ticket_key.data); session_ticket_key.data = NULL; gnutls_anon_free_server_credentials(anoncred); if (debug) success("server: finished\n"); }