/** * @param session the session we are giving a cert for * @param req_ca_dn NULL on server side * @param nreqs length of req_ca_dn, and thus 0 on server side * @param pk_algos NULL on server side * @param pk_algos_length 0 on server side * @param pcert list of certificates (to be set) * @param pcert_length length of pcert (to be set) * @param pkey the private key (to be set) */ static int sni_callback (gnutls_session_t session, const gnutls_datum_t* req_ca_dn, int nreqs, const gnutls_pk_algorithm_t* pk_algos, int pk_algos_length, gnutls_pcert_st** pcert, unsigned int *pcert_length, gnutls_privkey_t * pkey) { char name[256]; size_t name_len; struct Hosts *host; unsigned int type; name_len = sizeof (name); if (GNUTLS_E_SUCCESS != gnutls_server_name_get (session, name, &name_len, &type, 0 /* index */)) return -1; for (host = hosts; NULL != host; host = host->next) if (0 == strncmp (name, host->hostname, name_len)) break; if (NULL == host) { fprintf (stderr, "Need certificate for %.*s\n", (int) name_len, name); return -1; } #if 0 fprintf (stderr, "Returning certificate for %.*s\n", (int) name_len, name); #endif *pkey = host->key; *pcert_length = 1; *pcert = &host->pcrt; return 0; }
int SslSocket::onClientHello(gnutls_session_t session) { TRACE("onClientHello()"); SslSocket *socket = (SslSocket *)gnutls_session_get_ptr(session); // find SNI server const int MAX_HOST_LEN = 255; std::size_t dataLen = MAX_HOST_LEN; char sniName[MAX_HOST_LEN]; unsigned int sniType; int rv = gnutls_server_name_get(session, sniName, &dataLen, &sniType, 0); if (rv != 0) { TRACE("onClientHello(): gnutls_server_name_get() failed with (%d): %s", rv, gnutls_strerror(rv)); // failed to get SNI from client, so try getting default context then. if (SslContext *cx = socket->driver_->selectContext("")) { cx->bind(socket); return 0; } return GNUTLS_E_UNIMPLEMENTED_FEATURE; } if (sniType != GNUTLS_NAME_DNS) { TRACE("onClientHello(): Unknown SNI type: %d", sniType); return GNUTLS_E_UNIMPLEMENTED_FEATURE; } TRACE("onClientHello(): SNI Name: \"%s\"", sniName); if (SslContext *cx = socket->driver_->selectContext(sniName)) cx->bind(socket); else if (SslContext* cx = socket->driver_->selectContext("")) cx->bind(socket); 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; }
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; }
// server_session void server_session::get_server_name (void *data, size_t * data_length, unsigned int *type, unsigned int indx) const { RETWRAP (gnutls_server_name_get (s, data, data_length, type, indx)); }