bool ConnSSL_GetCipherInfo(CONNECTION *c, char *buf, size_t len) { #ifdef HAVE_LIBSSL char *nl; SSL *ssl = c->ssl_state.ssl; if (!ssl) return false; *buf = 0; SSL_CIPHER_description(SSL_get_current_cipher(ssl), buf, len); nl = strchr(buf, '\n'); if (nl) *nl = 0; return true; #endif #ifdef HAVE_LIBGNUTLS if (Conn_OPTION_ISSET(c, CONN_SSL)) { const char *name_cipher, *name_mac, *name_proto, *name_keyexchange; unsigned keysize; gnutls_session_t sess = c->ssl_state.gnutls_session; gnutls_cipher_algorithm_t cipher = gnutls_cipher_get(sess); name_cipher = gnutls_cipher_get_name(cipher); name_mac = gnutls_mac_get_name(gnutls_mac_get(sess)); keysize = gnutls_cipher_get_key_size(cipher) * 8; name_proto = gnutls_protocol_get_name(gnutls_protocol_get_version(sess)); name_keyexchange = gnutls_kx_get_name(gnutls_kx_get(sess)); return snprintf(buf, len, "%s-%s%15s Kx=%s Enc=%s(%u) Mac=%s", name_cipher, name_mac, name_proto, name_keyexchange, name_cipher, keysize, name_mac) > 0; } return false; #endif }
static void tls_print_session_info(const host_addr_t addr, uint16 port, gnutls_session session, bool incoming) { const char *proto, *cert, *kx, *ciph, *mac, *comp; g_return_if_fail(session); proto = gnutls_protocol_get_name(gnutls_protocol_get_version(session)); cert = gnutls_certificate_type_get_name( gnutls_certificate_type_get(session)); kx = gnutls_kx_get_name(gnutls_kx_get(session)); comp = gnutls_compression_get_name(gnutls_compression_get(session)); ciph = gnutls_cipher_get_name(gnutls_cipher_get(session)); mac = gnutls_mac_get_name(gnutls_mac_get (session)); g_debug( "TLS session info (%s):\n" " Host: %s\n" " Protocol: %s\n" " Certificate: %s\n" " Key Exchange: %s\n" " Cipher: %s\n" " MAC: %s\n" " Compression: %s", incoming ? "incoming" : "outgoing", host_addr_port_to_string(addr, port), NULL_STRING(proto), NULL_STRING(cert), NULL_STRING(kx), NULL_STRING(ciph), NULL_STRING(mac), NULL_STRING(comp) ); }
unsigned char * get_ssl_connection_cipher(struct socket *socket) { ssl_t *ssl = socket->ssl; struct string str; if (!init_string(&str)) return NULL; #ifdef USE_OPENSSL add_format_to_string(&str, "%ld-bit %s %s", SSL_get_cipher_bits(ssl, NULL), SSL_get_cipher_version(ssl), SSL_get_cipher_name(ssl)); #elif defined(CONFIG_GNUTLS) /* XXX: How to get other relevant parameters? */ add_format_to_string(&str, "%s - %s - %s - %s - %s (compr: %s)", gnutls_protocol_get_name(gnutls_protocol_get_version(*ssl)), gnutls_kx_get_name(gnutls_kx_get(*ssl)), gnutls_cipher_get_name(gnutls_cipher_get(*ssl)), gnutls_mac_get_name(gnutls_mac_get(*ssl)), gnutls_certificate_type_get_name(gnutls_certificate_type_get(*ssl)), gnutls_compression_get_name(gnutls_compression_get(*ssl))); #endif return str.source; }
const char *dtls_gnutls_get_cipher(struct conn *conn, char *dst) { struct dtls_gnutls_data * d; const char *comp, *cipher, *mac, *proto, *kxname, *auth; gnutls_kx_algorithm_t kx; gnutls_credentials_type_t cred; if (!conn->dtls_data){ sprintf(dst, "%s","None"); return dst; } d = (struct dtls_gnutls_data*)conn->dtls_data; if ( !d->session ){ sprintf(dst, "%s","None"); return dst; } kx = gnutls_kx_get(d->session); kxname = gnutls_kx_get_name(kx); cred = gnutls_auth_get_type(d->session); proto = gnutls_protocol_get_name(gnutls_protocol_get_version(d->session)); comp = gnutls_compression_get_name(gnutls_compression_get(d->session)); cipher = gnutls_cipher_get_name(gnutls_cipher_get(d->session)); mac = gnutls_mac_get_name(gnutls_mac_get(d->session)); sprintf(dst,"cipher: %s/%s/%s/%s/%s",proto,kxname,cipher,mac,comp); return dst; }
char * SSL_CIPHER_description (SSL_CIPHER * cipher, char *buf, int size) { char *tmpbuf; int tmpsize; int local_alloc; if (buf) { tmpbuf = buf; tmpsize = size; local_alloc = 0; } else { tmpbuf = (char *) malloc (128); tmpsize = 128; local_alloc = 1; } if (snprintf (tmpbuf, tmpsize, "%s %s %s %s", gnutls_protocol_get_name (cipher->version), gnutls_kx_get_name (cipher->kx), gnutls_cipher_get_name (cipher->cipher), gnutls_mac_get_name (cipher->mac)) == -1) { if (local_alloc) free (tmpbuf); return (char *) "Buffer too small"; } return tmpbuf; }
wxString CTlsSocket::GetKeyExchange() { wxString keyExchange = _("unknown"); const char* s = gnutls_kx_get_name( gnutls_kx_get( m_session ) ); if (s && *s) keyExchange = wxString(s, wxConvUTF8); return keyExchange; }
/* This function will log some details of the given session. */ static void logtlsinfo (gnutls_session_t session) { gnutls_credentials_type_t cred; const char *protocol = gnutls_protocol_get_name (gnutls_protocol_get_version (session)); gnutls_kx_algorithm_t kx = gnutls_kx_get (session); const char *keyexchange = gnutls_kx_get_name (kx); const char *certtype = gnutls_certificate_type_get_name (gnutls_certificate_type_get (session)); const char *cipher = gnutls_cipher_get_name (gnutls_cipher_get (session)); const char *mac = gnutls_mac_get_name (gnutls_mac_get (session)); const char *compression = gnutls_compression_get_name (gnutls_compression_get (session)); int resumedp = gnutls_session_is_resumed (session); /* This message can arguably belong to LOG_AUTH. */ syslog (LOG_INFO, "TLS handshake negotiated protocol `%s', " "key exchange `%s', certficate type `%s', cipher `%s', " "mac `%s', compression `%s', %s", protocol ? protocol : "N/A", keyexchange ? keyexchange : "N/A", certtype ? certtype : "N/A", cipher ? cipher : "N/A", mac ? mac : "N/A", compression ? compression : "N/A", resumedp ? "resumed session" : "session not resumed"); cred = gnutls_auth_get_type (session); switch (cred) { case GNUTLS_CRD_ANON: syslog (LOG_INFO | LOG_DAEMON, "TLS anonymous authentication with %d bit Diffie-Hellman", gnutls_dh_get_prime_bits (session)); break; case GNUTLS_CRD_CERTIFICATE: if (kx == GNUTLS_KX_DHE_RSA || kx == GNUTLS_KX_DHE_DSS) syslog (LOG_INFO | LOG_DAEMON, "TLS certificate authentication with %d bits " "ephemeral Diffie-Hellman", gnutls_dh_get_prime_bits (session)); logcertinfo (session); break; case GNUTLS_CRD_SRP: case GNUTLS_CRD_PSK: case GNUTLS_CRD_IA: default: syslog (LOG_ERR | LOG_DAEMON, "Unknown TLS authentication (%d)", cred); break; } }
const char * rb_ssl_get_cipher(rb_fde_t *F) { static char buf[1024]; snprintf(buf, sizeof(buf), "%s-%s-%s-%s", gnutls_protocol_get_name(gnutls_protocol_get_version(SSL_P(F))), gnutls_kx_get_name(gnutls_kx_get(SSL_P(F))), gnutls_cipher_get_name(gnutls_cipher_get(SSL_P(F))), gnutls_mac_get_name(gnutls_mac_get(SSL_P(F)))); return buf; }
/* This function will print some details of the * given session. */ int print_info (gnutls_session_t session) { const char *tmp; gnutls_credentials_type_t cred; gnutls_kx_algorithm_t kx; /* print the key exchange's algorithm name */ kx = gnutls_kx_get (session); tmp = gnutls_kx_get_name (kx); printf ("- Key Exchange: %s\n", tmp); /* Check the authentication type used and switch * to the appropriate. */ cred = gnutls_auth_get_type (session); switch (cred) { case GNUTLS_CRD_IA: printf ("- TLS/IA session\n"); break; #ifdef ENABLE_SRP case GNUTLS_CRD_SRP: printf ("- SRP session with username %s\n", gnutls_srp_server_get_username (session)); break; #endif case GNUTLS_CRD_PSK: /* This returns NULL in server side. */ if (gnutls_psk_client_get_hint (session) != NULL) printf ("- PSK authentication. PSK hint '%s'\n", gnutls_psk_client_get_hint (session)); /* This returns NULL in client side. */ if (gnutls_psk_server_get_username (session) != NULL) printf ("- PSK authentication. Connected as '%s'\n", gnutls_psk_server_get_username (session)); break; case GNUTLS_CRD_ANON: /* anonymous authentication */ printf ("- Anonymous DH using prime of %d bits\n", gnutls_dh_get_prime_bits (session)); break; case GNUTLS_CRD_CERTIFICATE: /* certificate authentication */ /* Check if we have been using ephemeral Diffie-Hellman. */ if (kx == GNUTLS_KX_DHE_RSA || kx == GNUTLS_KX_DHE_DSS) { printf ("\n- Ephemeral DH using prime of %d bits\n", gnutls_dh_get_prime_bits (session)); } /* if the certificate list is available, then * print some information about it. */ print_x509_certificate_info (session); } /* switch */ /* print the protocol's name (ie TLS 1.0) */ tmp = gnutls_protocol_get_name (gnutls_protocol_get_version (session)); printf ("- Protocol: %s\n", tmp); /* print the certificate type of the peer. * ie X.509 */ tmp = gnutls_certificate_type_get_name (gnutls_certificate_type_get (session)); printf ("- Certificate Type: %s\n", tmp); /* print the compression algorithm (if any) */ tmp = gnutls_compression_get_name (gnutls_compression_get (session)); printf ("- Compression: %s\n", tmp); /* print the name of the cipher used. * ie 3DES. */ tmp = gnutls_cipher_get_name (gnutls_cipher_get (session)); printf ("- Cipher: %s\n", tmp); /* Print the MAC algorithms name. * ie SHA1 */ tmp = gnutls_mac_get_name (gnutls_mac_get (session)); printf ("- MAC: %s\n", tmp); return 0; }
void gtlsGeneric::logSessionInfo(LogWrapperType _logwrapper, gnutls_session_t _session) { const char *tmp; gnutls_credentials_type_t cred; gnutls_kx_algorithm_t kx; // print the key exchange's algorithm name kx = gnutls_kx_get(_session); tmp = gnutls_kx_get_name(kx); BTG_NOTICE(_logwrapper, "- Key Exchange: " << tmp); // Check the authentication type used and switch // to the appropriate. cred = gnutls_auth_get_type(_session); switch (cred) { case GNUTLS_CRD_SRP: { BTG_NOTICE(_logwrapper, "- SRP session"); break; } case GNUTLS_CRD_ANON: { BTG_NOTICE(_logwrapper, "- Anonymous DH using prime of " << gnutls_dh_get_prime_bits (_session) << " bits"); break; } case GNUTLS_CRD_CERTIFICATE: { // Check if we have been using ephemeral Diffie Hellman. if (kx == GNUTLS_KX_DHE_RSA || kx == GNUTLS_KX_DHE_DSS) { BTG_NOTICE(_logwrapper, "- Ephemeral DH using prime of " << gnutls_dh_get_prime_bits(_session) << " bits"); } /* if the certificate list is available, then * print some information about it. */ gtlsGeneric::logX509CertificateInfo(_logwrapper, _session); break; } default: { BTG_NOTICE(_logwrapper, "Unknown cred."); } } /* print the protocol's name (ie TLS 1.0) */ tmp = gnutls_protocol_get_name(gnutls_protocol_get_version(_session)); BTG_NOTICE(_logwrapper, "- Protocol: " << tmp); /* print the certificate type of the peer. * ie X.509 */ tmp = gnutls_certificate_type_get_name(gnutls_certificate_type_get(_session)); BTG_NOTICE(_logwrapper, "- Certificate Type: " << tmp); /* print the compression algorithm (if any) */ tmp = gnutls_compression_get_name(gnutls_compression_get(_session)); BTG_NOTICE(_logwrapper, "- Compression: " << tmp); /* print the name of the cipher used. * ie 3DES. */ tmp = gnutls_cipher_get_name(gnutls_cipher_get(_session)); BTG_NOTICE(_logwrapper, "- Cipher: " << tmp); /* Print the MAC algorithms name. * ie SHA1 */ tmp = gnutls_mac_get_name(gnutls_mac_get(_session)); BTG_NOTICE(_logwrapper, "- MAC: " << tmp); }
void try_with_key_ks(const char *name, const char *client_prio, gnutls_kx_algorithm_t client_kx, gnutls_sign_algorithm_t server_sign_algo, gnutls_sign_algorithm_t client_sign_algo, const gnutls_datum_t *serv_cert, const gnutls_datum_t *serv_key, const gnutls_datum_t *client_cert, const gnutls_datum_t *client_key, unsigned cert_flags, unsigned exp_group, gnutls_certificate_type_t server_ctype, gnutls_certificate_type_t client_ctype) { int ret; char buffer[256]; /* Server stuff. */ gnutls_certificate_credentials_t server_cred; gnutls_anon_server_credentials_t s_anoncred; gnutls_dh_params_t dh_params; const gnutls_datum_t p3 = { (unsigned char *) pkcs3, strlen(pkcs3) }; gnutls_session_t server; int sret = GNUTLS_E_AGAIN; /* Client stuff. */ gnutls_certificate_credentials_t client_cred; gnutls_anon_client_credentials_t c_anoncred; gnutls_session_t client; int cret = GNUTLS_E_AGAIN, version; const char *err; /* General init. */ gnutls_global_set_log_function(tls_log_func); if (debug) gnutls_global_set_log_level(6); reset_buffers(); /* Init server */ assert(gnutls_anon_allocate_server_credentials(&s_anoncred)>=0); assert(gnutls_certificate_allocate_credentials(&server_cred)>=0); // Set server crt creds based on ctype switch (server_ctype) { case GNUTLS_CRT_X509: ret = gnutls_certificate_set_x509_key_mem(server_cred, serv_cert, serv_key, GNUTLS_X509_FMT_PEM); break; case GNUTLS_CRT_RAWPK: ret = gnutls_certificate_set_rawpk_key_mem(server_cred, serv_cert, serv_key, GNUTLS_X509_FMT_PEM, NULL, 0, NULL, 0, 0); break; default: ret = GNUTLS_E_UNSUPPORTED_CERTIFICATE_TYPE; } if (ret < 0) { fail("Could not set key/cert: %s\n", gnutls_strerror(ret)); } gnutls_dh_params_init(&dh_params); gnutls_dh_params_import_pkcs3(dh_params, &p3, GNUTLS_X509_FMT_PEM); gnutls_certificate_set_dh_params(server_cred, dh_params); gnutls_anon_set_server_dh_params(s_anoncred, dh_params); assert(gnutls_init(&server, GNUTLS_SERVER | GNUTLS_ENABLE_RAWPK)>=0); assert(gnutls_credentials_set(server, GNUTLS_CRD_CERTIFICATE, server_cred)>=0); assert(gnutls_credentials_set(server, GNUTLS_CRD_ANON, s_anoncred)>=0); if (server_priority) assert(gnutls_priority_set_direct(server, server_priority, NULL) >= 0); else assert(gnutls_priority_set_direct(server, "NORMAL:+VERS-SSL3.0:+ANON-ECDH:+ANON-DH:+ECDHE-RSA:+DHE-RSA:+RSA:+ECDHE-ECDSA:+CURVE-X25519:+SIGN-EDDSA-ED25519:+CTYPE-ALL", NULL)>=0); gnutls_transport_set_push_function(server, server_push); gnutls_transport_set_pull_function(server, server_pull); gnutls_transport_set_ptr(server, server); /* Init client */ ret = gnutls_certificate_allocate_credentials(&client_cred); if (ret < 0) exit(1); if (cert_flags == USE_CERT) { // Set client crt creds based on ctype switch (client_ctype) { case GNUTLS_CRT_X509: gnutls_certificate_set_x509_key_mem(client_cred, client_cert, client_key, GNUTLS_X509_FMT_PEM); break; case GNUTLS_CRT_RAWPK: gnutls_certificate_set_rawpk_key_mem(client_cred, client_cert, client_key, GNUTLS_X509_FMT_PEM, NULL, 0, NULL, 0, 0); break; default: fail("Illegal client certificate type given\n"); } gnutls_certificate_server_set_request(server, GNUTLS_CERT_REQUIRE); } else if (cert_flags == ASK_CERT) { gnutls_certificate_server_set_request(server, GNUTLS_CERT_REQUEST); } #if 0 ret = gnutls_certificate_set_x509_trust_mem(client_cred, &ca_cert, GNUTLS_X509_FMT_PEM); if (ret < 0) exit(1); #endif ret = gnutls_init(&client, GNUTLS_CLIENT | GNUTLS_ENABLE_RAWPK); if (ret < 0) exit(1); assert(gnutls_anon_allocate_client_credentials(&c_anoncred)>=0); assert(gnutls_credentials_set(client, GNUTLS_CRD_ANON, c_anoncred)>=0); ret = gnutls_credentials_set(client, GNUTLS_CRD_CERTIFICATE, client_cred); if (ret < 0) exit(1); gnutls_transport_set_push_function(client, client_push); gnutls_transport_set_pull_function(client, client_pull); gnutls_transport_set_ptr(client, client); ret = gnutls_priority_set_direct(client, client_prio, &err); if (ret < 0) { if (ret == GNUTLS_E_INVALID_REQUEST) fprintf(stderr, "Error in %s\n", err); exit(1); } success("negotiating %s\n", name); HANDSHAKE(client, server); if (gnutls_kx_get(client) != client_kx) { fail("%s: got unexpected key exchange algorithm: %s (expected %s)\n", name, gnutls_kx_get_name(gnutls_kx_get(client)), gnutls_kx_get_name(client_kx)); exit(1); } /* test signature algorithm match */ version = gnutls_protocol_get_version(client); if (version >= GNUTLS_TLS1_2) { ret = gnutls_sign_algorithm_get(server); if (ret != (int)server_sign_algo) { fail("%s: got unexpected server signature algorithm: %d/%s\n", name, ret, gnutls_sign_get_name(ret)); exit(1); } ret = gnutls_sign_algorithm_get_client(server); if (ret != (int)client_sign_algo) { fail("%s: got unexpected client signature algorithm: %d/%s\n", name, ret, gnutls_sign_get_name(ret)); exit(1); } ret = gnutls_sign_algorithm_get(client); if (ret != (int)server_sign_algo) { fail("%s: cl: got unexpected server signature algorithm: %d/%s\n", name, ret, gnutls_sign_get_name(ret)); exit(1); } ret = gnutls_sign_algorithm_get_client(client); if (ret != (int)client_sign_algo) { fail("%s: cl: got unexpected client signature algorithm: %d/%s\n", name, ret, gnutls_sign_get_name(ret)); exit(1); } } if (exp_group != 0) { ret = gnutls_group_get(server); if (ret != (int)exp_group) { fail("%s: got unexpected server group: %d/%s\n", name, ret, gnutls_group_get_name(ret)); } ret = gnutls_group_get(client); if (ret != (int)exp_group) { fail("%s: got unexpected client group: %d/%s\n", name, ret, gnutls_group_get_name(ret)); } } gnutls_record_send(server, MSG, strlen(MSG)); ret = gnutls_record_recv(client, buffer, sizeof(buffer)); if (ret == 0) { fail("client: Peer has closed the TLS connection\n"); exit(1); } else if (ret < 0) { fail("client: Error: %s\n", gnutls_strerror(ret)); exit(1); } if (ret != strlen(MSG) || memcmp(MSG, buffer, ret) != 0) { fail("client: Error in data received. Expected %d, got %d\n", (int)strlen(MSG), ret); exit(1); } gnutls_bye(client, GNUTLS_SHUT_RDWR); gnutls_bye(server, GNUTLS_SHUT_RDWR); gnutls_deinit(client); gnutls_deinit(server); gnutls_certificate_free_credentials(server_cred); gnutls_certificate_free_credentials(client_cred); gnutls_anon_free_server_credentials(s_anoncred); gnutls_anon_free_client_credentials(c_anoncred); gnutls_dh_params_deinit(dh_params); }
void dtls_try_with_key_mtu(const char *name, const char *client_prio, gnutls_kx_algorithm_t client_kx, gnutls_sign_algorithm_t server_sign_algo, gnutls_sign_algorithm_t client_sign_algo, const gnutls_datum_t *serv_cert, const gnutls_datum_t *serv_key, const gnutls_datum_t *client_cert, const gnutls_datum_t *client_key, unsigned cert_flags, unsigned smtu) { int ret; char buffer[256]; /* Server stuff. */ gnutls_certificate_credentials_t serverx509cred; gnutls_anon_server_credentials_t s_anoncred; gnutls_dh_params_t dh_params; const gnutls_datum_t p3 = { (unsigned char *) pkcs3, strlen(pkcs3) }; gnutls_session_t server; int sret = GNUTLS_E_AGAIN; /* Client stuff. */ gnutls_certificate_credentials_t clientx509cred; gnutls_anon_client_credentials_t c_anoncred; gnutls_session_t client; int cret = GNUTLS_E_AGAIN, version; /* General init. */ gnutls_global_set_log_function(tls_log_func); if (debug) gnutls_global_set_log_level(6); reset_buffers(); /* Init server */ gnutls_anon_allocate_server_credentials(&s_anoncred); gnutls_certificate_allocate_credentials(&serverx509cred); ret = gnutls_certificate_set_x509_key_mem(serverx509cred, serv_cert, serv_key, GNUTLS_X509_FMT_PEM); if (ret < 0) { fail("Could not set key/cert: %s\n", gnutls_strerror(ret)); } gnutls_dh_params_init(&dh_params); gnutls_dh_params_import_pkcs3(dh_params, &p3, GNUTLS_X509_FMT_PEM); gnutls_certificate_set_dh_params(serverx509cred, dh_params); gnutls_anon_set_server_dh_params(s_anoncred, dh_params); assert(gnutls_init(&server, GNUTLS_SERVER|GNUTLS_DATAGRAM|GNUTLS_NONBLOCK)>=0); assert(gnutls_credentials_set(server, GNUTLS_CRD_CERTIFICATE, serverx509cred)>=0); assert(gnutls_credentials_set(server, GNUTLS_CRD_ANON, s_anoncred)>=0); assert(gnutls_priority_set_direct(server, "NORMAL:+ANON-ECDH:+ANON-DH:+ECDHE-RSA:+DHE-RSA:+RSA:+ECDHE-ECDSA:+CURVE-X25519", NULL)>=0); 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, server); if (smtu) gnutls_dtls_set_mtu (server, smtu); /* Init client */ ret = gnutls_certificate_allocate_credentials(&clientx509cred); if (ret < 0) exit(1); if (cert_flags == USE_CERT) { ret = gnutls_certificate_set_x509_key_mem(clientx509cred, client_cert, client_key, GNUTLS_X509_FMT_PEM); if (ret < 0) { fail("Could not set key/cert: %s\n", gnutls_strerror(ret)); } gnutls_certificate_server_set_request(server, GNUTLS_CERT_REQUIRE); } else if (cert_flags == ASK_CERT) { gnutls_certificate_server_set_request(server, GNUTLS_CERT_REQUEST); } #if 0 ret = gnutls_certificate_set_x509_trust_mem(clientx509cred, &ca_cert, GNUTLS_X509_FMT_PEM); if (ret < 0) exit(1); #endif ret = gnutls_init(&client, GNUTLS_CLIENT|GNUTLS_DATAGRAM|GNUTLS_NONBLOCK); if (ret < 0) exit(1); assert(gnutls_anon_allocate_client_credentials(&c_anoncred)>=0); assert(gnutls_credentials_set(client, GNUTLS_CRD_ANON, c_anoncred)>=0); ret = gnutls_credentials_set(client, GNUTLS_CRD_CERTIFICATE, clientx509cred); if (ret < 0) exit(1); 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, client); if (smtu) gnutls_dtls_set_mtu (client, smtu); ret = gnutls_priority_set_direct(client, client_prio, NULL); if (ret < 0) { exit(1); } success("negotiating %s\n", name); HANDSHAKE_DTLS(client, server); if (gnutls_kx_get(client) != client_kx) { fail("%s: got unexpected key exchange algorithm: %s (expected %s)\n", name, gnutls_kx_get_name(gnutls_kx_get(client)), gnutls_kx_get_name(client_kx)); exit(1); } /* test signature algorithm match */ version = gnutls_protocol_get_version(client); if (version >= GNUTLS_DTLS1_2) { ret = gnutls_sign_algorithm_get(server); if (ret != (int)server_sign_algo) { fail("%s: got unexpected server signature algorithm: %d/%s\n", name, ret, gnutls_sign_get_name(ret)); exit(1); } ret = gnutls_sign_algorithm_get_client(server); if (ret != (int)client_sign_algo) { fail("%s: got unexpected client signature algorithm: %d/%s\n", name, ret, gnutls_sign_get_name(ret)); exit(1); } ret = gnutls_sign_algorithm_get(client); if (ret != (int)server_sign_algo) { fail("%s: cl: got unexpected server signature algorithm: %d/%s\n", name, ret, gnutls_sign_get_name(ret)); exit(1); } ret = gnutls_sign_algorithm_get_client(client); if (ret != (int)client_sign_algo) { fail("%s: cl: got unexpected client signature algorithm: %d/%s\n", name, ret, gnutls_sign_get_name(ret)); exit(1); } } gnutls_record_send(server, MSG, strlen(MSG)); ret = gnutls_record_recv(client, buffer, sizeof(buffer)); if (ret == 0) { fail("client: Peer has closed the TLS connection\n"); exit(1); } else if (ret < 0) { fail("client: Error: %s\n", gnutls_strerror(ret)); exit(1); } if (ret != strlen(MSG) || memcmp(MSG, buffer, ret) != 0) { fail("client: Error in data received. Expected %d, got %d\n", (int)strlen(MSG), ret); exit(1); } 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_anon_free_server_credentials(s_anoncred); gnutls_anon_free_client_credentials(c_anoncred); gnutls_dh_params_deinit(dh_params); }
/* 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; }
/** * tls_negotiate - Negotiate TLS connection * @param conn Connection to a server * @retval 0 Success * @retval -1 Error * * After TLS state has been initialized, attempt to negotiate TLS over the * wire, including certificate checks. */ static int tls_negotiate(struct Connection *conn) { struct TlsSockData *data = mutt_mem_calloc(1, sizeof(struct TlsSockData)); conn->sockdata = data; int err = gnutls_certificate_allocate_credentials(&data->xcred); if (err < 0) { FREE(&conn->sockdata); mutt_error("gnutls_certificate_allocate_credentials: %s", gnutls_strerror(err)); return -1; } gnutls_certificate_set_x509_trust_file(data->xcred, C_CertificateFile, GNUTLS_X509_FMT_PEM); /* ignore errors, maybe file doesn't exist yet */ if (C_SslCaCertificatesFile) { gnutls_certificate_set_x509_trust_file(data->xcred, C_SslCaCertificatesFile, GNUTLS_X509_FMT_PEM); } if (C_SslClientCert) { mutt_debug(LL_DEBUG2, "Using client certificate %s\n", C_SslClientCert); gnutls_certificate_set_x509_key_file(data->xcred, C_SslClientCert, C_SslClientCert, GNUTLS_X509_FMT_PEM); } #ifdef 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 err = gnutls_init(&data->state, GNUTLS_CLIENT); if (err) { mutt_error("gnutls_handshake: %s", gnutls_strerror(err)); goto fail; } /* set socket */ gnutls_transport_set_ptr(data->state, (gnutls_transport_ptr_t)(long) conn->fd); if (gnutls_server_name_set(data->state, GNUTLS_NAME_DNS, conn->account.host, mutt_str_strlen(conn->account.host))) { mutt_error(_("Warning: unable to set TLS SNI host name")); } if (tls_set_priority(data) < 0) { goto fail; } if (C_SslMinDhPrimeBits > 0) { gnutls_dh_set_prime_bits(data->state, C_SslMinDhPrimeBits); } /* 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_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)); } goto fail; } if (tls_check_certificate(conn) == 0) 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 (!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; }
/** * gnutls_session_get_desc: * @session: is a gnutls session * * This function returns a string describing the current session. * The string is null terminated and allocated using gnutls_malloc(). * * Returns: a description of the protocols and algorithms in the current session. * * Since: 3.1.10 **/ char *gnutls_session_get_desc(gnutls_session_t session) { gnutls_kx_algorithm_t kx; unsigned type; char kx_name[32]; char proto_name[32]; const char *curve_name = NULL; unsigned dh_bits = 0; unsigned mac_id; char *desc; kx = session->security_parameters.kx_algorithm; if (kx == GNUTLS_KX_ANON_ECDH || kx == GNUTLS_KX_ECDHE_PSK || kx == GNUTLS_KX_ECDHE_RSA || kx == GNUTLS_KX_ECDHE_ECDSA) { curve_name = gnutls_ecc_curve_get_name(gnutls_ecc_curve_get (session)); } else if (kx == GNUTLS_KX_ANON_DH || kx == GNUTLS_KX_DHE_PSK || kx == GNUTLS_KX_DHE_RSA || kx == GNUTLS_KX_DHE_DSS) { dh_bits = gnutls_dh_get_prime_bits(session); } if (curve_name != NULL) snprintf(kx_name, sizeof(kx_name), "%s-%s", gnutls_kx_get_name(kx), curve_name); else if (dh_bits != 0) snprintf(kx_name, sizeof(kx_name), "%s-%u", gnutls_kx_get_name(kx), dh_bits); else snprintf(kx_name, sizeof(kx_name), "%s", gnutls_kx_get_name(kx)); type = gnutls_certificate_type_get(session); if (type == GNUTLS_CRT_X509) snprintf(proto_name, sizeof(proto_name), "%s", gnutls_protocol_get_name(get_num_version (session))); else snprintf(proto_name, sizeof(proto_name), "%s-%s", gnutls_protocol_get_name(get_num_version (session)), gnutls_certificate_type_get_name(type)); gnutls_protocol_get_name(get_num_version(session)), desc = gnutls_malloc(DESC_SIZE); if (desc == NULL) return NULL; mac_id = gnutls_mac_get(session); if (mac_id == GNUTLS_MAC_AEAD) { /* no need to print */ snprintf(desc, DESC_SIZE, "(%s)-(%s)-(%s)", proto_name, kx_name, gnutls_cipher_get_name(gnutls_cipher_get(session))); } else { snprintf(desc, DESC_SIZE, "(%s)-(%s)-(%s)-(%s)", proto_name, kx_name, gnutls_cipher_get_name(gnutls_cipher_get(session)), gnutls_mac_get_name(mac_id)); } return desc; }
/** * gnutls_session_get_desc: * @session: is a gnutls session * * This function returns a string describing the current session. * The string is null terminated and allocated using gnutls_malloc(). * * If initial negotiation is not complete when this function is called, * %NULL will be returned. * * Returns: a description of the protocols and algorithms in the current session. * * Since: 3.1.10 **/ char *gnutls_session_get_desc(gnutls_session_t session) { gnutls_kx_algorithm_t kx; const char *kx_str; unsigned type; char kx_name[32]; char proto_name[32]; const char *curve_name = NULL; unsigned dh_bits = 0; unsigned mac_id; char *desc; if (session->internals.initial_negotiation_completed == 0) return NULL; kx = session->security_parameters.kx_algorithm; if (kx == GNUTLS_KX_ANON_ECDH || kx == GNUTLS_KX_ECDHE_PSK || kx == GNUTLS_KX_ECDHE_RSA || kx == GNUTLS_KX_ECDHE_ECDSA) { curve_name = gnutls_ecc_curve_get_name(gnutls_ecc_curve_get (session)); #if defined(ENABLE_DHE) || defined(ENABLE_ANON) } else if (kx == GNUTLS_KX_ANON_DH || kx == GNUTLS_KX_DHE_PSK || kx == GNUTLS_KX_DHE_RSA || kx == GNUTLS_KX_DHE_DSS) { dh_bits = gnutls_dh_get_prime_bits(session); #endif } kx_str = gnutls_kx_get_name(kx); if (kx_str) { if (curve_name != NULL) snprintf(kx_name, sizeof(kx_name), "%s-%s", kx_str, curve_name); else if (dh_bits != 0) snprintf(kx_name, sizeof(kx_name), "%s-%u", kx_str, dh_bits); else snprintf(kx_name, sizeof(kx_name), "%s", kx_str); } else { strcpy(kx_name, "NULL"); } type = gnutls_certificate_type_get(session); if (type == GNUTLS_CRT_X509) snprintf(proto_name, sizeof(proto_name), "%s", gnutls_protocol_get_name(get_num_version (session))); else snprintf(proto_name, sizeof(proto_name), "%s-%s", gnutls_protocol_get_name(get_num_version (session)), gnutls_certificate_type_get_name(type)); desc = gnutls_malloc(DESC_SIZE); if (desc == NULL) return NULL; mac_id = gnutls_mac_get(session); if (mac_id == GNUTLS_MAC_AEAD) { /* no need to print */ snprintf(desc, DESC_SIZE, "(%s)-(%s)-(%s)", proto_name, kx_name, gnutls_cipher_get_name(gnutls_cipher_get(session))); } else { snprintf(desc, DESC_SIZE, "(%s)-(%s)-(%s)-(%s)", proto_name, kx_name, gnutls_cipher_get_name(gnutls_cipher_get(session)), gnutls_mac_get_name(mac_id)); } return desc; }
static void main_texinfo (void) { { size_t i; const char *name; char id[2]; gnutls_kx_algorithm_t kx; gnutls_cipher_algorithm_t cipher; gnutls_mac_algorithm_t mac; gnutls_protocol_t version; printf ("@heading Ciphersuites\n"); printf ("@multitable @columnfractions .60 .20 .20\n"); printf("@headitem Ciphersuite name @tab TLS ID @tab Since\n"); for (i = 0; (name = gnutls_cipher_suite_info (i, id, &kx, &cipher, &mac, &version)); i++) { printf ("@item %s\n@tab 0x%02X 0x%02X\n@tab %s\n", escape_texi_string(name, buffer, sizeof(buffer)), (unsigned char) id[0], (unsigned char) id[1], gnutls_protocol_get_name (version)); } printf ("@end multitable\n"); } { const gnutls_certificate_type_t *p = gnutls_certificate_type_list (); printf ("\n\n@heading Certificate types\n"); printf ("@table @code\n"); for (; *p; p++) { printf ("@item %s\n", gnutls_certificate_type_get_name (*p)); } printf ("@end table\n"); } { const gnutls_protocol_t *p = gnutls_protocol_list (); printf ("\n@heading Protocols\n@table @code\n"); for (; *p; p++) { printf ("@item %s\n", gnutls_protocol_get_name (*p)); } printf ("@end table\n"); } { const gnutls_cipher_algorithm_t *p = gnutls_cipher_list (); printf ("\n@heading Ciphers\n@table @code\n"); for (; *p; p++) { printf ("@item %s\n", gnutls_cipher_get_name (*p)); } printf ("@end table\n"); } { const gnutls_mac_algorithm_t *p = gnutls_mac_list (); printf ("\n@heading MAC algorithms\n@table @code\n"); for (; *p; p++) { printf ("@item %s\n", gnutls_mac_get_name (*p)); } printf ("@end table\n"); } { const gnutls_kx_algorithm_t *p = gnutls_kx_list (); printf ("\n@heading Key exchange methods\n@table @code\n"); for (; *p; p++) { printf ("@item %s\n", gnutls_kx_get_name (*p)); } printf ("@end table\n"); } { const gnutls_pk_algorithm_t *p = gnutls_pk_list (); printf ("\n@heading Public key algorithms\n@table @code\n"); for (; *p; p++) { printf ("@item %s\n", gnutls_pk_get_name (*p)); } printf ("@end table\n"); } { const gnutls_sign_algorithm_t *p = gnutls_sign_list (); printf ("\n@heading Public key signature algorithms\n@table @code\n"); for (; *p; p++) { printf ("@item %s\n", gnutls_sign_get_name (*p)); } printf ("@end table\n"); } { const gnutls_ecc_curve_t *p = gnutls_ecc_curve_list (); printf ("\n@heading Elliptic curves\n@table @code\n"); for (; *p; p++) { printf ("@item %s\n", gnutls_ecc_curve_get_name (*p)); } printf ("@end table\n"); } { const gnutls_compression_method_t *p = gnutls_compression_list (); printf ("\n@heading Compression methods\n@table @code\n"); for (; *p; p++) { printf ("@item %s\n", gnutls_compression_get_name (*p)); } printf ("@end table\n"); } }
int print_info (gnutls_session_t session, const char *hostname, int insecure) { const char *tmp; gnutls_credentials_type_t cred; gnutls_kx_algorithm_t kx; /* print the key exchange's algorithm name */ kx = gnutls_kx_get (session); cred = gnutls_auth_get_type (session); switch (cred) { #ifdef ENABLE_ANON case GNUTLS_CRD_ANON: print_dh_info (session, "Anonymous "); break; #endif #ifdef ENABLE_SRP case GNUTLS_CRD_SRP: /* This should be only called in server * side. */ if (gnutls_srp_server_get_username (session) != NULL) printf ("- SRP authentication. Connected as '%s'\n", gnutls_srp_server_get_username (session)); break; #endif #ifdef ENABLE_PSK case GNUTLS_CRD_PSK: /* This returns NULL in server side. */ if (gnutls_psk_client_get_hint (session) != NULL) printf ("- PSK authentication. PSK hint '%s'\n", gnutls_psk_client_get_hint (session)); /* This returns NULL in client side. */ if (gnutls_psk_server_get_username (session) != NULL) printf ("- PSK authentication. Connected as '%s'\n", gnutls_psk_server_get_username (session)); if (kx == GNUTLS_KX_DHE_PSK) print_dh_info (session, "Ephemeral "); break; #endif case GNUTLS_CRD_IA: printf ("- TLS/IA authentication\n"); break; case GNUTLS_CRD_CERTIFICATE: { char dns[256]; size_t dns_size = sizeof (dns); unsigned int type; /* This fails in client side */ if (gnutls_server_name_get (session, dns, &dns_size, &type, 0) == 0) { printf ("- Given server name[%d]: %s\n", type, dns); } } if (kx == GNUTLS_KX_DHE_RSA || kx == GNUTLS_KX_DHE_DSS) print_dh_info (session, "Ephemeral "); print_cert_info (session, hostname, insecure); print_cert_vrfy (session); } tmp = SU (gnutls_protocol_get_name (gnutls_protocol_get_version (session))); printf ("- Version: %s\n", tmp); tmp = SU (gnutls_kx_get_name (kx)); printf ("- Key Exchange: %s\n", tmp); tmp = SU (gnutls_cipher_get_name (gnutls_cipher_get (session))); printf ("- Cipher: %s\n", tmp); tmp = SU (gnutls_mac_get_name (gnutls_mac_get (session))); printf ("- MAC: %s\n", tmp); tmp = SU (gnutls_compression_get_name (gnutls_compression_get (session))); printf ("- Compression: %s\n", tmp); if (verbose) { char id[32]; size_t id_size = sizeof (id); gnutls_session_get_id (session, id, &id_size); printf ("- Session ID: %s\n", raw_to_string (id, id_size)); } fflush (stdout); return 0; }
int print_info (gnutls_session_t session, int print_cert) { const char *tmp; gnutls_credentials_type_t cred; gnutls_kx_algorithm_t kx; unsigned char session_id[33]; size_t session_id_size = sizeof (session_id); /* print session ID */ gnutls_session_get_id (session, session_id, &session_id_size); printf ("- Session ID: %s\n", raw_to_string (session_id, session_id_size)); /* print the key exchange's algorithm name */ kx = gnutls_kx_get (session); cred = gnutls_auth_get_type (session); switch (cred) { #ifdef ENABLE_ANON case GNUTLS_CRD_ANON: if (kx == GNUTLS_KX_ANON_ECDH) print_ecdh_info (session, "Anonymous "); else print_dh_info (session, "Anonymous ", verbose); break; #endif #ifdef ENABLE_SRP case GNUTLS_CRD_SRP: /* This should be only called in server * side. */ if (gnutls_srp_server_get_username (session) != NULL) printf ("- SRP authentication. Connected as '%s'\n", gnutls_srp_server_get_username (session)); break; #endif #ifdef ENABLE_PSK case GNUTLS_CRD_PSK: /* This returns NULL in server side. */ if (gnutls_psk_client_get_hint (session) != NULL) printf ("- PSK authentication. PSK hint '%s'\n", gnutls_psk_client_get_hint (session)); /* This returns NULL in client side. */ if (gnutls_psk_server_get_username (session) != NULL) printf ("- PSK authentication. Connected as '%s'\n", gnutls_psk_server_get_username (session)); if (kx == GNUTLS_KX_DHE_PSK) print_dh_info (session, "Ephemeral ", verbose); if (kx == GNUTLS_KX_ECDHE_PSK) print_ecdh_info (session, "Ephemeral "); break; #endif case GNUTLS_CRD_IA: printf ("- TLS/IA authentication\n"); break; case GNUTLS_CRD_CERTIFICATE: { char dns[256]; size_t dns_size = sizeof (dns); unsigned int type; /* This fails in client side */ if (gnutls_server_name_get (session, dns, &dns_size, &type, 0) == 0) { printf ("- Given server name[%d]: %s\n", type, dns); } } print_cert_info (session, verbose?GNUTLS_CRT_PRINT_FULL:GNUTLS_CRT_PRINT_COMPACT, print_cert); if (kx == GNUTLS_KX_DHE_RSA || kx == GNUTLS_KX_DHE_DSS) print_dh_info (session, "Ephemeral ", verbose); else if (kx == GNUTLS_KX_ECDHE_RSA || kx == GNUTLS_KX_ECDHE_ECDSA) print_ecdh_info (session, "Ephemeral "); } tmp = SU (gnutls_protocol_get_name (gnutls_protocol_get_version (session))); printf ("- Version: %s\n", tmp); tmp = SU (gnutls_kx_get_name (kx)); printf ("- Key Exchange: %s\n", tmp); tmp = SU (gnutls_cipher_get_name (gnutls_cipher_get (session))); printf ("- Cipher: %s\n", tmp); tmp = SU (gnutls_mac_get_name (gnutls_mac_get (session))); printf ("- MAC: %s\n", tmp); tmp = SU (gnutls_compression_get_name (gnutls_compression_get (session))); printf ("- Compression: %s\n", tmp); if (verbose) { gnutls_datum_t cb; int rc; rc = gnutls_session_channel_binding (session, GNUTLS_CB_TLS_UNIQUE, &cb); if (rc) fprintf (stderr, "Channel binding error: %s\n", gnutls_strerror (rc)); else { size_t i; printf ("- Channel binding 'tls-unique': "); for (i = 0; i < cb.size; i++) printf ("%02x", cb.data[i]); printf ("\n"); } } /* Warning: Do not print anything more here. The 'Compression:' output MUST be the last non-verbose output. This is used by Emacs starttls.el code. */ fflush (stdout); return 0; }
/** * @brief Get info pertaining to a socket. * @naslfn{get_sock_info} * * This function is used to retrieve various information about an * active socket. It requires the NASL socket number and a string to * select the information to retrieve. * * Supported keywords are: * * - @a dport Return the destination port. This is an integer. NOTE: * Not yet implemented. * * - @a sport Return the source port. This is an integer. NOTE: Not * yet implemented. * * - @a encaps Return the encapsulation of the socket. Example * output: "TLScustom". * * - @a tls-proto Return a string with the actual TLS protocol in use. * n/a" is returned if no SSL/TLS session is active. Example * output: "TLSv1". * * - @a tls-kx Return a string describing the key exchange algorithm. * Example output: "RSA". * * - @a tls-certtype Return the type of the certificate in use by the * session. Example output: "X.509" * * - @a tls-cipher Return the cipher algorithm in use by the session; * Example output: "AES-256-CBC". * * - @a tls-mac Return the message authentication algorithms used by * the session. Example output: "SHA1". * * - @a tls-comp Return the compression algorithms in use by the * session. Example output: "DEFLATE". * * - @a tls-auth Return the peer's authentication type. Example * output: "CERT". * * - @a tls-cert Return the peer's certificates for an SSL or TLS * connection. This is an array of binary strings or NULL if no * certificate is known. * * @nasluparam * * - A NASL socket * * - A string keyword; see above. * * @naslnparam * * - @a asstring If true return a human readable string instead of * an integer. Used only with these keywords: encaps. * * @naslret An integer or a string or NULL on error. * * @param[in] lexic Lexical context of the NASL interpreter. * * @return A tree cell. */ tree_cell * nasl_get_sock_info (lex_ctxt * lexic) { int sock; int type; int err; const char *keyword, *s; tree_cell *retc; int as_string; int transport; gnutls_session_t tls_session; char *strval; int intval; sock = get_int_var_by_num (lexic, 0, -1); if (sock <= 0) { nasl_perror (lexic, "error: socket %d is not valid\n"); return NULL; } keyword = get_str_var_by_num (lexic, 1); if (!keyword || !((type = get_var_type_by_num (lexic, 1)) == VAR2_STRING || type == VAR2_DATA)) { nasl_perror (lexic, "error: second argument is not of type string\n"); return NULL; } as_string = !!get_int_local_var_by_name (lexic, "asstring", 0); transport = 0; strval = NULL; intval = 0; retc = FAKE_CELL; /* Dummy value to detect retc == NULL. */ { void *tmp = NULL; err = get_sock_infos (sock, &transport, &tmp); tls_session = tmp; } if (err) { nasl_perror (lexic, "error retrieving infos for socket %d: %s\n", sock, strerror (err)); retc = NULL; } else if (!strcmp (keyword, "encaps")) { if (as_string) strval = estrdup (get_encaps_name (transport)); else intval = transport; } else if (!strcmp (keyword, "tls-proto")) { if (!tls_session) s = "n/a"; else s = gnutls_protocol_get_name (gnutls_protocol_get_version (tls_session)); strval = estrdup (s?s:"[?]"); } else if (!strcmp (keyword, "tls-kx")) { if (!tls_session) s = "n/a"; else s = gnutls_kx_get_name (gnutls_kx_get (tls_session)); strval = estrdup (s?s:""); } else if (!strcmp (keyword, "tls-certtype")) { if (!tls_session) s = "n/a"; else s = gnutls_certificate_type_get_name (gnutls_certificate_type_get (tls_session)); strval = estrdup (s?s:""); } else if (!strcmp (keyword, "tls-cipher")) { if (!tls_session) s = "n/a"; else s = gnutls_cipher_get_name (gnutls_cipher_get (tls_session)); strval = estrdup (s?s:""); } else if (!strcmp (keyword, "tls-mac")) { if (!tls_session) s = "n/a"; else s = gnutls_mac_get_name (gnutls_mac_get (tls_session)); strval = estrdup (s?s:""); } else if (!strcmp (keyword, "tls-comp")) { if (!tls_session) s = "n/a"; else s = gnutls_compression_get_name (gnutls_compression_get (tls_session)); strval = estrdup (s?s:""); } else if (!strcmp (keyword, "tls-auth")) { if (!tls_session) s = "n/a"; else { switch (gnutls_auth_get_type (tls_session)) { case GNUTLS_CRD_ANON: s = "ANON"; break; case GNUTLS_CRD_CERTIFICATE: s = "CERT"; break; case GNUTLS_CRD_PSK: s = "PSK"; break; case GNUTLS_CRD_SRP: s = "SRP"; break; default: s = "[?]"; break; } } strval = estrdup (s?s:""); } else if (!strcmp (keyword, "tls-cert")) { /* We only support X.509 for now. GNUTLS also allows for OpenPGP, but we are not prepared for that. */ if (!tls_session || gnutls_certificate_type_get (tls_session) != GNUTLS_CRT_X509) s = "n/a"; else { const gnutls_datum_t *list; unsigned int nlist = 0; int i; nasl_array *a; anon_nasl_var v; list = gnutls_certificate_get_peers (tls_session, &nlist); if (!list) retc = NULL; /* No certificate or other error. */ else { retc = alloc_tree_cell (0, NULL); retc->type = DYN_ARRAY; retc->x.ref_val = a = emalloc (sizeof *a); for (i=0; i < nlist; i++) { memset (&v, 0, sizeof v); v.var_type = VAR2_DATA; v.v.v_str.s_val = list[i].data; v.v.v_str.s_siz = list[i].size; add_var_to_list (a, i, &v); } } } } else { nasl_perror (lexic, "unknown keyword '%s'\n", keyword); retc = NULL; } if (!retc) ; else if (retc != FAKE_CELL) ; /* Already allocated. */ else if (strval) { retc = alloc_typed_cell (CONST_STR); retc->x.str_val = strval; retc->size = strlen (strval); } else { retc = alloc_typed_cell (CONST_INT); retc->x.i_val = intval; } return retc; }
int connect_ssl(char *host, char *port, int reconnect, int use_sessionid, int use_ticket, int delay, const char *client_cert, const char *client_key) { struct addrinfo* addr; int err, s; char buffer[256]; gnutls_anon_client_credentials_t anoncred; gnutls_certificate_credentials_t xcred; gnutls_session_t session; char *session_data = NULL; size_t session_data_size = 0; char *session_id = NULL; size_t session_id_size = 0; char *session_id_hex = NULL; char *session_id_p = NULL; unsigned session_id_idx; const char *hex = "0123456789ABCDEF"; start("Initialize GNU TLS library"); if ((err = gnutls_global_init())) fail("Unable to initialize GNU TLS:\n%s", gnutls_strerror(err)); if ((err = gnutls_anon_allocate_client_credentials(&anoncred))) fail("Unable to allocate anonymous client credentials:\n%s", gnutls_strerror(err)); if ((err = gnutls_certificate_allocate_credentials(&xcred))) fail("Unable to allocate X509 credentials:\n%s", gnutls_strerror(err)); #ifdef DEBUG gnutls_global_set_log_function(debug); gnutls_global_set_log_level(10); #endif addr = solve(host, port); do { start("Initialize TLS session"); if ((err = gnutls_init(&session, GNUTLS_CLIENT))) fail("Unable to initialize the current session:\n%s", gnutls_strerror(err)); if ((err = gnutls_priority_set_direct(session, "PERFORMANCE:NORMAL:EXPORT", NULL))) fail("Unable to initialize cipher suites:\n%s", gnutls_strerror(err)); gnutls_dh_set_prime_bits(session, 512); if (client_cert == NULL) { if ((err = gnutls_credentials_set(session, GNUTLS_CRD_ANON, anoncred))) fail("Unable to set anonymous credentials for session:\n%s", gnutls_strerror(err)); } else { if ((err = gnutls_certificate_set_x509_key_file(xcred, client_cert, client_key, GNUTLS_X509_FMT_PEM))) { fail("failed to load x509 certificate from file %s or key from %s: %s",client_cert,client_key,gnutls_strerror(err)); } } if ((err = gnutls_credentials_set (session, GNUTLS_CRD_CERTIFICATE, xcred))) fail("Unable to set credentials for session:\n%s", gnutls_strerror(err)); if (use_ticket) { start("Enable use of session tickets (RFC 5077)"); if (gnutls_session_ticket_enable_client(session)) fail("Unable to enable session tickets:\n%s", gnutls_strerror(err)); } if (session_data) { start("Copy old session"); if ((err = gnutls_session_set_data(session, session_data, session_data_size))) fail("Unable to set session to previous one:\n%s", gnutls_strerror(err)); } s = connect_socket(addr, host, port); start("Start TLS renegotiation"); gnutls_transport_set_ptr(session, (gnutls_transport_ptr_t)(uintptr_t)s); if ((err = gnutls_handshake(session))) { fail("Unable to start TLS renegotiation:\n%s", gnutls_strerror(err)); } start("Check if session was reused"); if (!gnutls_session_is_resumed(session) && session_data) warn("No session was reused."); else if (gnutls_session_is_resumed(session) && !session_data) warn("Session was reused."); else if (gnutls_session_is_resumed(session)) end("SSL session correctly reused"); else end("SSL session was not used"); start("Get current session"); if (session_data) { free(session_data); session_data = NULL; } session_data_size = 8192; if ((err = gnutls_session_get_data(session, NULL, &session_data_size))) warn("No session available:\n%s", gnutls_strerror(err)); else { session_data = malloc(session_data_size); if (!session_data) fail("No memory available"); gnutls_session_get_data(session, session_data, &session_data_size); if ((err = gnutls_session_get_id( session, NULL, &session_id_size))) warn("No session id available:\n%s", gnutls_strerror(err)); session_id = malloc(session_id_size); if (!session_id) fail("No memory available"); else { if ((err = gnutls_session_get_id( session, session_id, &session_id_size))) warn("No session id available:\n%s", gnutls_strerror(err)); session_id_hex = malloc(session_id_size * 2 + 1); if (!session_id_hex) fail("No memory available"); else { for (session_id_p = session_id_hex, session_id_idx = 0; session_id_idx < session_id_size; ++session_id_idx) { *session_id_p++ = hex[ (session_id[session_id_idx] >> 4) & 0xf]; *session_id_p++ = hex[ session_id[session_id_idx] & 0xf]; } *session_id_p = '\0'; end("Session context:\nProtocol : %s\nCipher : %s\nKx : %s\nCompression : %s\nPSK : %s\nID : %s", gnutls_protocol_get_name( gnutls_protocol_get_version(session) ), gnutls_cipher_get_name( gnutls_cipher_get(session) ), gnutls_kx_get_name( gnutls_kx_get(session) ), gnutls_compression_get_name( gnutls_compression_get(session)), gnutls_psk_server_get_username(session), session_id_hex ); free(session_id_hex); } free(session_id); } } if (!use_sessionid && !use_ticket) { free(session_data); session_data = NULL; } start("Send HTTP GET"); err = snprintf(buffer, sizeof(buffer), "GET / HTTP/1.0\r\n" "Host: %s\r\n" "\r\n", host); if (err == -1 || err >= sizeof(buffer)) fail("Unable to build request to send"); if (gnutls_record_send(session, buffer, strlen(buffer)) < 0) fail("SSL write request failed:\n%s", gnutls_strerror(err)); start("Get HTTP answer"); if ((err = gnutls_record_recv(session, buffer, sizeof(buffer) - 1)) <= 0) fail("SSL read request failed:\n%s", gnutls_strerror(err)); buffer[err] = '\0'; if (strchr(buffer, '\r')) *strchr(buffer, '\r') = '\0'; end("%s", buffer); start("End TLS connection"); gnutls_bye(session, GNUTLS_SHUT_RDWR); close(s); gnutls_deinit (session); --reconnect; if (reconnect < 0) break; else { start("waiting %d seconds",delay); sleep(delay); } } while (1); if (session_data) free(session_data); gnutls_anon_free_client_credentials(anoncred); gnutls_global_deinit(); return 0; }
int main (void) { { size_t i; const char *name; char id[2]; gnutls_kx_algorithm_t kx; gnutls_cipher_algorithm_t cipher; gnutls_mac_algorithm_t mac; gnutls_protocol_t version; printf ("Available cipher suites:\n"); printf ("@multitable @columnfractions .60 .20 .20\n"); for (i = 0; (name = gnutls_cipher_suite_info (i, id, &kx, &cipher, &mac, &version)); i++) { printf ("@item %s\n@tab 0x%02x 0x%02x\n@tab %s\n", name, (unsigned char) id[0], (unsigned char) id[1], gnutls_protocol_get_name (version)); } printf ("@end multitable\n"); } { const gnutls_certificate_type_t *p = gnutls_certificate_type_list (); printf ("\n\nAvailable certificate types:\n@itemize\n"); for (; *p; p++) { printf ("@item %s\n", gnutls_certificate_type_get_name (*p)); } printf ("@end itemize\n"); } { const gnutls_protocol_t *p = gnutls_protocol_list (); printf ("\nAvailable protocols:\n@itemize\n"); for (; *p; p++) { printf ("@item %s\n", gnutls_protocol_get_name (*p)); } printf ("@end itemize\n"); } { const gnutls_cipher_algorithm_t *p = gnutls_cipher_list (); printf ("\nAvailable ciphers:\n@itemize\n"); for (; *p; p++) { printf ("@item %s\n", gnutls_cipher_get_name (*p)); } printf ("@end itemize\n"); } { const gnutls_mac_algorithm_t *p = gnutls_mac_list (); printf ("\nAvailable MAC algorithms:\n@itemize\n"); for (; *p; p++) { printf ("@item %s\n", gnutls_mac_get_name (*p)); } printf ("@end itemize\n"); } { const gnutls_kx_algorithm_t *p = gnutls_kx_list (); printf ("\nAvailable key exchange methods:\n@itemize\n"); for (; *p; p++) { printf ("@item %s\n", gnutls_kx_get_name (*p)); } printf ("@end itemize\n"); } { const gnutls_pk_algorithm_t *p = gnutls_pk_list (); printf ("\nAvailable public key algorithms:\n@itemize\n"); for (; *p; p++) { printf ("@item %s\n", gnutls_pk_get_name (*p)); } printf ("@end itemize\n"); } { const gnutls_sign_algorithm_t *p = gnutls_sign_list (); printf ("\nAvailable public key signature algorithms:\n@itemize\n"); for (; *p; p++) { printf ("@item %s\n", gnutls_sign_get_name (*p)); } printf ("@end itemize\n"); } { const gnutls_compression_method_t *p = gnutls_compression_list (); printf ("\nAvailable compression methods:\n@itemize\n"); for (; *p; p++) { printf ("@item %s\n", gnutls_compression_get_name (*p)); } printf ("@end itemize\n"); } }
void print_list (const char *priorities, int verbose) { size_t i; int ret; unsigned int idx; const char *name; const char *err; unsigned char id[2]; gnutls_kx_algorithm_t kx; gnutls_cipher_algorithm_t cipher; gnutls_mac_algorithm_t mac; gnutls_protocol_t version; gnutls_priority_t pcache; const unsigned int *list; if (priorities != NULL) { printf ("Cipher suites for %s\n", priorities); ret = gnutls_priority_init (&pcache, priorities, &err); if (ret < 0) { fprintf (stderr, "Syntax error at: %s\n", err); exit (1); } for (i = 0;; i++) { ret = gnutls_priority_get_cipher_suite_index (pcache, i, &idx); if (ret == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE) break; if (ret == GNUTLS_E_UNKNOWN_CIPHER_SUITE) continue; name = gnutls_cipher_suite_info (idx, id, NULL, NULL, NULL, &version); if (name != NULL) printf ("%-50s\t0x%02x, 0x%02x\t%s\n", name, (unsigned char) id[0], (unsigned char) id[1], gnutls_protocol_get_name (version)); } printf("\n"); { ret = gnutls_priority_certificate_type_list (pcache, &list); printf ("Certificate types: "); if (ret == 0) printf("none\n"); for (i = 0; i < (unsigned)ret; i++) { printf ("CTYPE-%s", gnutls_certificate_type_get_name (list[i])); if (i+1!=(unsigned)ret) printf (", "); else printf ("\n"); } } { ret = gnutls_priority_protocol_list (pcache, &list); printf ("Protocols: "); if (ret == 0) printf("none\n"); for (i = 0; i < (unsigned)ret; i++) { printf ("VERS-%s", gnutls_protocol_get_name (list[i])); if (i+1!=(unsigned)ret) printf (", "); else printf ("\n"); } } { ret = gnutls_priority_compression_list (pcache, &list); printf ("Compression: "); if (ret == 0) printf("none\n"); for (i = 0; i < (unsigned)ret; i++) { printf ("COMP-%s", gnutls_compression_get_name (list[i])); if (i+1!=(unsigned)ret) printf (", "); else printf ("\n"); } } { ret = gnutls_priority_ecc_curve_list (pcache, &list); printf ("Elliptic curves: "); if (ret == 0) printf("none\n"); for (i = 0; i < (unsigned)ret; i++) { printf ("CURVE-%s", gnutls_ecc_curve_get_name (list[i])); if (i+1!=(unsigned)ret) printf (", "); else printf ("\n"); } } { ret = gnutls_priority_sign_list (pcache, &list); printf ("PK-signatures: "); if (ret == 0) printf("none\n"); for (i = 0; i < (unsigned)ret; i++) { printf ("SIGN-%s", gnutls_sign_algorithm_get_name (list[i])); if (i+1!=(unsigned)ret) printf (", "); else printf ("\n"); } } return; } printf ("Cipher suites:\n"); for (i = 0; (name = gnutls_cipher_suite_info (i, id, &kx, &cipher, &mac, &version)); i++) { printf ("%-50s\t0x%02x, 0x%02x\t%s\n", name, (unsigned char) id[0], (unsigned char) id[1], gnutls_protocol_get_name (version)); if (verbose) printf ("\tKey exchange: %s\n\tCipher: %s\n\tMAC: %s\n\n", gnutls_kx_get_name (kx), gnutls_cipher_get_name (cipher), gnutls_mac_get_name (mac)); } printf("\n"); { const gnutls_certificate_type_t *p = gnutls_certificate_type_list (); printf ("Certificate types: "); for (; *p; p++) { printf ("CTYPE-%s", gnutls_certificate_type_get_name (*p)); if (*(p + 1)) printf (", "); else printf ("\n"); } } { const gnutls_protocol_t *p = gnutls_protocol_list (); printf ("Protocols: "); for (; *p; p++) { printf ("VERS-%s", gnutls_protocol_get_name (*p)); if (*(p + 1)) printf (", "); else printf ("\n"); } } { const gnutls_cipher_algorithm_t *p = gnutls_cipher_list (); printf ("Ciphers: "); for (; *p; p++) { printf ("%s", gnutls_cipher_get_name (*p)); if (*(p + 1)) printf (", "); else printf ("\n"); } } { const gnutls_mac_algorithm_t *p = gnutls_mac_list (); printf ("MACs: "); for (; *p; p++) { printf ("%s", gnutls_mac_get_name (*p)); if (*(p + 1)) printf (", "); else printf ("\n"); } } { const gnutls_kx_algorithm_t *p = gnutls_kx_list (); printf ("Key exchange algorithms: "); for (; *p; p++) { printf ("%s", gnutls_kx_get_name (*p)); if (*(p + 1)) printf (", "); else printf ("\n"); } } { const gnutls_compression_method_t *p = gnutls_compression_list (); printf ("Compression: "); for (; *p; p++) { printf ("COMP-%s", gnutls_compression_get_name (*p)); if (*(p + 1)) printf (", "); else printf ("\n"); } } { const gnutls_ecc_curve_t *p = gnutls_ecc_curve_list (); printf ("Elliptic curves: "); for (; *p; p++) { printf ("CURVE-%s", gnutls_ecc_curve_get_name (*p)); if (*(p + 1)) printf (", "); else printf ("\n"); } } { const gnutls_pk_algorithm_t *p = gnutls_pk_list (); printf ("Public Key Systems: "); for (; *p; p++) { printf ("%s", gnutls_pk_algorithm_get_name (*p)); if (*(p + 1)) printf (", "); else printf ("\n"); } } { const gnutls_sign_algorithm_t *p = gnutls_sign_list (); printf ("PK-signatures: "); for (; *p; p++) { printf ("SIGN-%s", gnutls_sign_algorithm_get_name (*p)); if (*(p + 1)) printf (", "); else printf ("\n"); } } }
void print_list (int verbose) { { size_t i; const char *name; char id[2]; gnutls_kx_algorithm_t kx; gnutls_cipher_algorithm_t cipher; gnutls_mac_algorithm_t mac; gnutls_protocol_t version; printf ("Cipher suites:\n"); for (i = 0; (name = gnutls_cipher_suite_info (i, id, &kx, &cipher, &mac, &version)); i++) { printf ("%-50s\t0x%02x, 0x%02x\t%s\n", name, (unsigned char) id[0], (unsigned char) id[1], gnutls_protocol_get_name (version)); if (verbose) printf ("\tKey exchange: %s\n\tCipher: %s\n\tMAC: %s\n\n", gnutls_kx_get_name (kx), gnutls_cipher_get_name (cipher), gnutls_mac_get_name (mac)); } } { const gnutls_certificate_type_t *p = gnutls_certificate_type_list (); printf ("Certificate types: "); for (; *p; p++) { printf ("%s", gnutls_certificate_type_get_name (*p)); if (*(p + 1)) printf (", "); else printf ("\n"); } } { const gnutls_protocol_t *p = gnutls_protocol_list (); printf ("Protocols: "); for (; *p; p++) { printf ("%s", gnutls_protocol_get_name (*p)); if (*(p + 1)) printf (", "); else printf ("\n"); } } { const gnutls_cipher_algorithm_t *p = gnutls_cipher_list (); printf ("Ciphers: "); for (; *p; p++) { printf ("%s", gnutls_cipher_get_name (*p)); if (*(p + 1)) printf (", "); else printf ("\n"); } } { const gnutls_mac_algorithm_t *p = gnutls_mac_list (); printf ("MACs: "); for (; *p; p++) { printf ("%s", gnutls_mac_get_name (*p)); if (*(p + 1)) printf (", "); else printf ("\n"); } } { const gnutls_kx_algorithm_t *p = gnutls_kx_list (); printf ("Key exchange algorithms: "); for (; *p; p++) { printf ("%s", gnutls_kx_get_name (*p)); if (*(p + 1)) printf (", "); else printf ("\n"); } } { const gnutls_compression_method_t *p = gnutls_compression_list (); printf ("Compression: "); for (; *p; p++) { printf ("%s", gnutls_compression_get_name (*p)); if (*(p + 1)) printf (", "); else printf ("\n"); } } { const gnutls_pk_algorithm_t *p = gnutls_pk_list (); printf ("Public Key Systems: "); for (; *p; p++) { printf ("%s", gnutls_pk_algorithm_get_name (*p)); if (*(p + 1)) printf (", "); else printf ("\n"); } } { const gnutls_sign_algorithm_t *p = gnutls_sign_list (); printf ("PK-signatures: "); for (; *p; p++) { printf ("%s", gnutls_sign_algorithm_get_name (*p)); if (*(p + 1)) printf (", "); else printf ("\n"); } } }