static void server (void) { /* this must be called once in the program */ gnutls_global_init (); gnutls_global_set_log_function (tls_log_func); if (debug) gnutls_global_set_log_level (4711); gnutls_anon_allocate_server_credentials (&anoncred); if (debug) success ("Launched, generating DH parameters...\n"); generate_dh_params (); gnutls_anon_set_server_dh_params (anoncred, dh_params); client_len = sizeof (sa_cli); session = initialize_tls_session (); sd = accept (listen_sd, (SA *) & sa_cli, &client_len); if (debug) success ("server: connection from %s, port %d\n", inet_ntop (AF_INET, &sa_cli.sin_addr, topbuf, sizeof (topbuf)), ntohs (sa_cli.sin_port)); gnutls_transport_set_ptr (session, (gnutls_transport_ptr_t) sd); ret = gnutls_handshake (session); if (ret < 0) { close (sd); gnutls_deinit (session); fail ("server: Handshake has failed (%s)\n\n", gnutls_strerror (ret)); return; } 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); */ i = 0; 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) { 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); close (listen_sd); gnutls_anon_free_server_credentials (anoncred); gnutls_dh_params_deinit (dh_params); gnutls_global_deinit (); if (debug) success ("server: finished\n"); }
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; }
void doit (void) { int exit_code = EXIT_SUCCESS; /* Server stuff. */ gnutls_certificate_credentials_t serverx509cred; gnutls_session_t server; int sret = GNUTLS_E_AGAIN; /* Client stuff. */ gnutls_certificate_credentials_t clientx509cred; gnutls_session_t client; int cret = GNUTLS_E_AGAIN; /* General init. */ gnutls_global_init (); gnutls_global_set_log_function (tls_log_func); if (debug) gnutls_global_set_log_level (2); /* Init server */ gnutls_certificate_allocate_credentials (&serverx509cred); gnutls_certificate_set_x509_key_mem (serverx509cred, &server_cert, &server_key, GNUTLS_X509_FMT_PEM); gnutls_init (&server, GNUTLS_SERVER); gnutls_credentials_set (server, GNUTLS_CRD_CERTIFICATE, serverx509cred); gnutls_priority_set_direct (server, "NORMAL", NULL); gnutls_transport_set_push_function (server, server_push); gnutls_transport_set_pull_function (server, server_pull); gnutls_transport_set_ptr (server, (gnutls_transport_ptr_t)server); /* Init client */ gnutls_certificate_allocate_credentials (&clientx509cred); gnutls_init (&client, GNUTLS_CLIENT); gnutls_credentials_set (client, GNUTLS_CRD_CERTIFICATE, clientx509cred); gnutls_priority_set_direct (client, "NORMAL", NULL); gnutls_transport_set_push_function (client, client_push); gnutls_transport_set_pull_function (client, client_pull); gnutls_transport_set_ptr (client, (gnutls_transport_ptr_t)client); HANDSHAKE(client, server); sret = gnutls_rehandshake (server); if (debug) { tls_log_func (0, "gnutls_rehandshake (server)...\n"); tls_log_func (0, gnutls_strerror (sret)); tls_log_func (0, "\n"); } { ssize_t n; char b[1]; n = gnutls_record_recv (client, b, 1); if (n != GNUTLS_E_REHANDSHAKE) abort (); } HANDSHAKE(client, server); gnutls_bye (client, GNUTLS_SHUT_RDWR); gnutls_bye (server, GNUTLS_SHUT_RDWR); gnutls_deinit (client); gnutls_deinit (server); gnutls_certificate_free_credentials (serverx509cred); gnutls_certificate_free_credentials (clientx509cred); gnutls_global_deinit (); if (debug) { if (exit_code == 0) puts ("Self-test successful"); else puts ("Self-test failed"); } }
static void server(int sds[]) { int j; /* this must be called once in the program */ global_init(); gnutls_global_set_log_function(tls_log_func); if (debug) gnutls_global_set_log_level(5); if (debug) success("Launched, setting DH parameters...\n"); generate_dh_params(); for (j = 0; j < SESSIONS; j++) { int sd = sds[j]; if (j == 0) { gnutls_certificate_allocate_credentials(&pgp_cred); ret = gnutls_certificate_set_openpgp_key_mem2 (pgp_cred, &server_crt, &server_key, "auto", GNUTLS_OPENPGP_FMT_BASE64); } else { gnutls_certificate_free_credentials(pgp_cred); gnutls_certificate_allocate_credentials(&pgp_cred); ret = gnutls_certificate_set_openpgp_key_mem2 (pgp_cred, &cert2048, &key2048, "auto", GNUTLS_OPENPGP_FMT_BASE64); } if (ret < 0) { fail("Could not set server key files...\n"); goto end; } gnutls_certificate_set_dh_params(pgp_cred, dh_params); session = initialize_tls_session(); gnutls_transport_set_int(session, sd); ret = gnutls_handshake(session); if (ret < 0) { close(sd); gnutls_deinit(session); fail("server: Handshake %d has failed (%s)\n\n", j, gnutls_strerror(ret)); goto end; } if (debug) success("server: Handshake %d was completed\n", j); 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 */ if (debug) 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) { fail("server: Received corrupted data(%d). Closing...\n", ret); goto end; } 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); } end: gnutls_certificate_free_credentials(pgp_cred); gnutls_dh_params_deinit(dh_params); gnutls_global_deinit(); if (debug) success("server: finished\n"); }
static void ekg_gnutls_free_connection(struct ekg_gnutls_connection *conn) { gnutls_deinit(conn->session); gnutls_certificate_free_credentials(conn->cred); g_slice_free(struct ekg_gnutls_connection, conn); }
/** * 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; }
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. */ const int kx_prio[] = { GNUTLS_KX_ANON_DH, 0 }; gnutls_global_init(); gnutls_anon_allocate_client_credentials(&anoncred); /* Initialize TLS session */ gnutls_init(&session, GNUTLS_CLIENT); /* Use default priorities */ gnutls_set_default_priority(session); gnutls_kx_set_priority(session, kx_prio); /* 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); /* 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); gnutls_bye(session, GNUTLS_SHUT_RDWR); end: tcp_close(sd); gnutls_deinit(session); gnutls_anon_free_client_credentials(anoncred); gnutls_global_deinit(); return 0; }
void try_with_key_fail(const char *name, const char *client_prio, int server_err, int client_err, const gnutls_datum_t *serv_cert, const gnutls_datum_t *serv_key, const gnutls_datum_t *cli_cert, const gnutls_datum_t *cli_key) { 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; 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_certificate_allocate_credentials(&serverx509cred)>=0); 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)); assert(gnutls_init(&server, GNUTLS_SERVER)>=0); if (server_priority) assert(gnutls_priority_set_direct(server, server_priority, NULL) >= 0); else assert(gnutls_priority_set_direct(server, client_prio, NULL) >= 0); assert(gnutls_credentials_set(server, GNUTLS_CRD_CERTIFICATE, serverx509cred)>=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(&clientx509cred); if (ret < 0) exit(1); if (cli_cert) { gnutls_certificate_set_x509_key_mem(clientx509cred, cli_cert, cli_key, GNUTLS_X509_FMT_PEM); gnutls_certificate_server_set_request(server, GNUTLS_CERT_REQUIRE); } ret = gnutls_init(&client, GNUTLS_CLIENT); 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); } ret = gnutls_credentials_set(client, GNUTLS_CRD_CERTIFICATE, clientx509cred); if (ret < 0) exit(1); success("negotiating %s\n", name); HANDSHAKE_EXPECT(client, server, client_err, server_err); gnutls_deinit(client); gnutls_deinit(server); gnutls_certificate_free_credentials(serverx509cred); gnutls_certificate_free_credentials(clientx509cred); }
static void server(int fd) { int ret; char buffer[MAX_BUF + 1]; gnutls_session_t session; gnutls_certificate_credentials_t x509_cred; gnutls_datum_t skey; /* this must be called once in the program */ global_init(); memset(buffer, 0, sizeof(buffer)); if (debug) { gnutls_global_set_log_function(server_log_func); gnutls_global_set_log_level(4711); } assert(gnutls_certificate_allocate_credentials(&x509_cred)>=0); assert(gnutls_certificate_set_x509_key_mem(x509_cred, &server_cert, &server_key, GNUTLS_X509_FMT_PEM)>=0); assert(gnutls_init(&session, GNUTLS_SERVER)>=0); assert(gnutls_session_ticket_key_generate(&skey)>=0); assert(gnutls_session_ticket_enable_server(session, &skey) >= 0); gnutls_handshake_set_hook_function(session, GNUTLS_HANDSHAKE_NEW_SESSION_TICKET, GNUTLS_HOOK_POST, handshake_callback); /* avoid calling all the priority functions, since the defaults * are adequate. */ assert(gnutls_priority_set_direct(session, "NORMAL", NULL)>=0); gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, x509_cred); gnutls_transport_set_int(session, fd); do { ret = gnutls_handshake(session); } while (ret < 0 && gnutls_error_is_fatal(ret) == 0); if (ret < 0) { /* failure is expected here */ goto end; } if (debug) { success("server: Handshake was completed\n"); } if (debug) success("server: TLS version is: %s\n", gnutls_protocol_get_name (gnutls_protocol_get_version(session))); if (sent != 0) { fail("new session ticket was sent\n"); exit(1); } /* do not wait for the peer to close the connection. */ gnutls_bye(session, GNUTLS_SHUT_WR); end: close(fd); gnutls_deinit(session); gnutls_free(skey.data); gnutls_certificate_free_credentials(x509_cred); gnutls_global_deinit(); if (debug) success("server: finished\n"); }
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); }
static void server(int fd, unsigned do_fork) { int ret; gnutls_certificate_credentials_t x509_cred; gnutls_session_t session; /* this must be called once in the program */ global_init(); #if 0 if (debug) { side = "server"; gnutls_global_set_log_function(tls_log_func); gnutls_global_set_log_level(4711); } #endif 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_dtls_set_timeouts(session, 5 * 1000, 60 * 1000); gnutls_dtls_set_mtu(session, 400); /* avoid calling all the priority functions, since the defaults * are adequate. */ gnutls_priority_set_direct(session, "NONE:+VERS-DTLS1.2:+CIPHER-ALL:+MAC-ALL:+SIGN-ALL:+COMP-ALL:+ECDHE-ECDSA:+CURVE-ALL", NULL); 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) { 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))); if (do_fork) do_fork_stuff(session); else do_reflect_stuff(session); 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, unsigned do_fork) { int ret; gnutls_certificate_credentials_t x509_cred; gnutls_session_t session; /* Need to enable anonymous KX specifically. */ global_init(); if (debug) { side = "client"; gnutls_global_set_log_function(tls_log_func); gnutls_global_set_log_level(4711); } gnutls_certificate_allocate_credentials(&x509_cred); /* Initialize TLS session */ gnutls_init(&session, GNUTLS_CLIENT | GNUTLS_DATAGRAM); gnutls_dtls_set_mtu(session, 1500); gnutls_dtls_set_timeouts(session, 6 * 1000, 60 * 1000); //gnutls_transport_set_push_function(session, push); /* Use default priorities */ gnutls_priority_set_direct(session, "NONE:+VERS-DTLS-ALL:+CIPHER-ALL:+MAC-ALL:+SIGN-ALL:+COMP-ALL:+ECDHE-ECDSA:+CURVE-ALL", NULL); /* put the anonymous credentials to the current session */ gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, x509_cred); gnutls_transport_set_int(session, fd); /* Perform the TLS handshake */ do { ret = gnutls_handshake(session); } while (ret < 0 && gnutls_error_is_fatal(ret) == 0); if (ret < 0) { fail("client: Handshake failed\n"); gnutls_perror(ret); exit(1); } else { if (debug) success("client: Handshake was completed\n"); } if (do_fork) do_fork_stuff(session); else do_reflect_stuff(session); close(fd); gnutls_deinit(session); gnutls_certificate_free_credentials(x509_cred); gnutls_global_deinit(); exit(0); }
void doit(void) { int err, i; int sockets[2]; const char *srcdir; pid_t child; char pub_key_path[512], priv_key_path[512]; global_init(); srcdir = getenv("srcdir") ? getenv("srcdir") : "."; for (i = 0; i < 5; i++) { if (i <= 1) key_id = NULL; /* try using the master key */ else if (i == 2) key_id = "auto"; /* test auto */ else if (i >= 3) key_id = "f30fd423c143e7ba"; if (debug) { gnutls_global_set_log_level(5); gnutls_global_set_log_function(log_message); } err = socketpair(AF_UNIX, SOCK_STREAM, 0, sockets); if (err != 0) fail("socketpair %s\n", strerror(errno)); if (sizeof(pub_key_path) < strlen(srcdir) + strlen(pub_key_file) + 2) abort(); strcpy(pub_key_path, srcdir); strcat(pub_key_path, "/"); strcat(pub_key_path, pub_key_file); if (sizeof(priv_key_path) < strlen(srcdir) + strlen(priv_key_file) + 2) abort(); strcpy(priv_key_path, srcdir); strcat(priv_key_path, "/"); strcat(priv_key_path, priv_key_file); child = fork(); if (child == -1) fail("fork %s\n", strerror(errno)); if (child == 0) { /* Child process (client). */ gnutls_session_t session; gnutls_certificate_credentials_t cred; ssize_t sent; if (debug) printf("client process %i\n", getpid()); err = gnutls_init(&session, GNUTLS_CLIENT); if (err != 0) fail("client session %d\n", err); if (i == 0) /* we use the primary key which is RSA. Test the RSA ciphersuite */ gnutls_priority_set_direct(session, "NONE:+VERS-TLS1.0:+CIPHER-ALL:+MAC-ALL:+SIGN-ALL:+COMP-ALL:+RSA:+CTYPE-OPENPGP", NULL); else gnutls_priority_set_direct(session, "NONE:+VERS-TLS1.0:+CIPHER-ALL:+MAC-ALL:+SIGN-ALL:+COMP-ALL:+DHE-DSS:+DHE-RSA:+CTYPE-OPENPGP", NULL); gnutls_transport_set_int(session, sockets[0]); err = gnutls_certificate_allocate_credentials(&cred); if (err != 0) fail("client credentials %d\n", err); err = gnutls_certificate_set_openpgp_key_file2(cred, pub_key_path, priv_key_path, key_id, GNUTLS_OPENPGP_FMT_BASE64); if (err != 0) fail("client openpgp keys %s\n", gnutls_strerror(err)); check_loaded_key(cred); err = gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, cred); if (err != 0) fail("client credential_set %d\n", err); gnutls_dh_set_prime_bits(session, 1024); if (i == 4) gnutls_openpgp_send_cert(session, GNUTLS_OPENPGP_CERT_FINGERPRINT); err = gnutls_handshake(session); if (err != 0) fail("client handshake %s (%d) \n", gnutls_strerror(err), err); else if (debug) printf("client handshake successful\n"); sent = gnutls_record_send(session, message, sizeof(message)); if (sent != sizeof(message)) fail("client sent %li vs. %li\n", (long) sent, (long) sizeof(message)); err = gnutls_bye(session, GNUTLS_SHUT_RDWR); if (err != 0) fail("client bye %d\n", err); if (debug) printf("client done\n"); gnutls_deinit(session); gnutls_certificate_free_credentials(cred); gnutls_free(stored_cli_cert.data); gnutls_global_deinit(); return; } else { /* Parent process (server). */ gnutls_session_t session; gnutls_dh_params_t dh_params; gnutls_certificate_credentials_t cred; char greetings[sizeof(message) * 2]; ssize_t received; pid_t done; int status; const gnutls_datum_t p3 = { (void *) pkcs3, strlen(pkcs3) }; if (debug) printf("server process %i (child %i)\n", getpid(), child); err = gnutls_init(&session, GNUTLS_SERVER); if (err != 0) fail("server session %d\n", err); gnutls_priority_set_direct(session, "NONE:+VERS-TLS1.0:+CIPHER-ALL:+MAC-ALL:+SIGN-ALL:+COMP-ALL:+DHE-DSS:+DHE-RSA:+RSA:+CTYPE-OPENPGP", NULL); gnutls_transport_set_int(session, sockets[1]); err = gnutls_certificate_allocate_credentials(&cred); if (err != 0) fail("server credentials %d\n", err); err = gnutls_certificate_set_openpgp_key_file2(cred, pub_key_path, priv_key_path, key_id, GNUTLS_OPENPGP_FMT_BASE64); if (err != 0) fail("server openpgp keys %s\n", gnutls_strerror(err)); check_loaded_key(cred); err = gnutls_dh_params_init(&dh_params); if (err) fail("server DH params init %d\n", err); err = gnutls_dh_params_import_pkcs3(dh_params, &p3, GNUTLS_X509_FMT_PEM); if (err) fail("server DH params generate %d\n", err); gnutls_certificate_set_dh_params(cred, dh_params); err = gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, cred); if (err != 0) fail("server credential_set %d\n", err); gnutls_certificate_server_set_request(session, GNUTLS_CERT_REQUIRE); if (i == 4) gnutls_openpgp_set_recv_key_function (session, key_recv_func); err = gnutls_handshake(session); if (err != 0) fail("server handshake %s (%d) \n", gnutls_strerror(err), err); if (stored_cli_cert.data == NULL) { const gnutls_datum_t *d; unsigned int d_size; d = gnutls_certificate_get_peers(session, &d_size); if (d != NULL) { stored_cli_cert.data = gnutls_malloc(d[0].size); memcpy(stored_cli_cert.data, d[0].data, d[0].size); stored_cli_cert.size = d[0].size; } } received = gnutls_record_recv(session, greetings, sizeof(greetings)); if (received != sizeof(message) || memcmp(greetings, message, sizeof(message))) fail("server received %li vs. %li\n", (long) received, (long) sizeof(message)); err = gnutls_bye(session, GNUTLS_SHUT_RDWR); if (err != 0) fail("server bye %s (%d) \n", gnutls_strerror(err), err); if (debug) printf("server done\n"); gnutls_deinit(session); gnutls_certificate_free_credentials(cred); gnutls_dh_params_deinit(dh_params); done = wait(&status); if (done < 0) fail("wait %s\n", strerror(errno)); if (done != child) fail("who's that?! %d\n", done); check_wait_status(status); } } gnutls_free(stored_cli_cert.data); gnutls_global_deinit(); }
void doit (void) { /* Server stuff. */ gnutls_anon_server_credentials_t s_anoncred; const gnutls_datum_t p3 = { (char *) pkcs3, strlen (pkcs3) }; static gnutls_dh_params_t dh_params; gnutls_session_t server; int sret = GNUTLS_E_AGAIN; /* Client stuff. */ gnutls_anon_client_credentials_t c_anoncred; gnutls_session_t client; int n, cret = GNUTLS_E_AGAIN; /* Need to enable anonymous KX specifically. */ const int kx_prio[] = { GNUTLS_KX_ANON_DH, 0 }; char buffer[MAX_BUF + 1]; ssize_t ns; int ret; /* General init. */ gnutls_global_init (); gnutls_global_set_log_function (tls_log_func); if (debug) gnutls_global_set_log_level (4711); /* 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_set_default_priority (server); gnutls_kx_set_priority (server, kx_prio); 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); /* Init client */ gnutls_anon_allocate_client_credentials (&c_anoncred); gnutls_init (&client, GNUTLS_CLIENT); gnutls_set_default_priority (client); gnutls_kx_set_priority (client, kx_prio); 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); do { if (cret == GNUTLS_E_AGAIN) { if (debug) success ("loop invoking client:\n"); cret = gnutls_handshake (client); if (debug) success ("client %d: %s\n", cret, gnutls_strerror (cret)); } if (sret == GNUTLS_E_AGAIN) { if (debug) success ("loop invoking server:\n"); sret = gnutls_handshake (server); if (debug) success ("server %d: %s\n", sret, gnutls_strerror (sret)); } } while (cret == GNUTLS_E_AGAIN || sret == GNUTLS_E_AGAIN); if (debug) success ("Handshake established\n"); ns = gnutls_record_send (client, MSG, strlen (MSG)); if (debug) success ("client: sent %d\n", (int) ns); ret = gnutls_record_recv (server, buffer, MAX_BUF); if (ret == 0) fail ("server: didn't receive any data\n"); else if (ret < 0) fail ("server: error: %s\n", gnutls_strerror (ret)); else { if (debug) { printf ("server: received %d: ", ret); for (n = 0; n < ret; n++) fputc (buffer[n], stdout); fputs ("\n", stdout); } } ns = gnutls_record_send (server, MSG, strlen (MSG)); if (debug) success ("server: sent %d\n", (int) ns); ret = gnutls_record_recv (client, buffer, MAX_BUF); if (ret == 0) { fail ("client: Peer has closed the TLS connection\n"); } else if (ret < 0) { fail ("client: Error: %s\n", gnutls_strerror (ret)); } else { if (debug) { printf ("client: received %d: ", ret); for (n = 0; n < ret; n++) fputc (buffer[n], stdout); fputs ("\n", stdout); } } gnutls_bye (client, GNUTLS_SHUT_RDWR); gnutls_bye (server, GNUTLS_SHUT_RDWR); gnutls_deinit (client); gnutls_deinit (server); free (to_server); free (to_client); 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) { int ret; gnutls_certificate_credentials_t x509_cred; gnutls_session_t session; /* Need to enable anonymous KX specifically. */ gnutls_global_set_time_function(mytime); global_init(); if (debug) { gnutls_global_set_log_function(client_log_func); gnutls_global_set_log_level(7); } gnutls_certificate_allocate_credentials(&x509_cred); /* Initialize TLS session */ gnutls_init(&session, GNUTLS_CLIENT|GNUTLS_NO_TICKETS); /* Use default priorities */ gnutls_priority_set_direct(session, "NORMAL:-KX-ALL:+ECDHE-RSA", NULL); /* put the anonymous credentials to the current session */ gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, x509_cred); gnutls_transport_set_int(session, fd); /* Perform the TLS handshake */ do { ret = gnutls_handshake(session); } while (ret < 0 && gnutls_error_is_fatal(ret) == 0); if (ret == GNUTLS_E_UNSUPPORTED_SIGNATURE_ALGORITHM) { /* success */ goto end; } if (ret < 0) { fail("client: Handshake failed: %s\n", gnutls_strerror(ret)); terminate(); } else { if (debug) success("client: Handshake was completed\n"); } if (debug) success("client: TLS version is: %s\n", gnutls_protocol_get_name (gnutls_protocol_get_version(session))); gnutls_bye(session, GNUTLS_SHUT_WR); end: close(fd); gnutls_deinit(session); gnutls_certificate_free_credentials(x509_cred); gnutls_global_deinit(); }
int main (int argc, char **argv) { int ret; int ii, i, inp; char buffer[MAX_BUF + 1]; char *session_data = NULL; char *session_id = NULL; size_t session_data_size; size_t session_id_size = 0; int user_term = 0, retval = 0; socket_st hd; ssize_t bytes; set_program_name (argv[0]); cmd_parser (argc, argv); gnutls_global_set_log_function (tls_log_func); gnutls_global_set_log_level (OPT_VALUE_DEBUG); if ((ret = gnutls_global_init ()) < 0) { fprintf (stderr, "global_init: %s\n", gnutls_strerror (ret)); exit (1); } #ifdef ENABLE_PKCS11 pkcs11_common (); #endif if (hostname == NULL) { fprintf (stderr, "No hostname given\n"); exit (1); } sockets_init (); init_global_tls_stuff (); socket_open (&hd, hostname, service, udp); socket_connect (&hd); hd.session = init_tls_session (hostname); if (starttls) goto after_handshake; for (i = 0; i < 2; i++) { if (i == 1) { hd.session = init_tls_session (hostname); gnutls_session_set_data (hd.session, session_data, session_data_size); free (session_data); } ret = do_handshake (&hd); if (ret < 0) { fprintf (stderr, "*** Handshake has failed\n"); gnutls_perror (ret); gnutls_deinit (hd.session); return 1; } else { printf ("- Handshake was completed\n"); if (gnutls_session_is_resumed (hd.session) != 0) printf ("*** This is a resumed session\n"); } if (resume != 0 && i == 0) { gnutls_session_get_data (hd.session, NULL, &session_data_size); session_data = malloc (session_data_size); gnutls_session_get_data (hd.session, session_data, &session_data_size); gnutls_session_get_id (hd.session, NULL, &session_id_size); session_id = malloc (session_id_size); gnutls_session_get_id (hd.session, session_id, &session_id_size); printf ("- Disconnecting\n"); socket_bye (&hd); printf ("\n\n- Connecting again- trying to resume previous session\n"); socket_open (&hd, hostname, service, udp); socket_connect (&hd); } else { break; } } after_handshake: /* Warning! Do not touch this text string, it is used by external programs to search for when gnutls-cli has reached this point. */ printf ("\n- Simple Client Mode:\n\n"); if (rehandshake) { ret = do_handshake (&hd); if (ret < 0) { fprintf (stderr, "*** ReHandshake has failed\n"); gnutls_perror (ret); gnutls_deinit (hd.session); return 1; } else { printf ("- ReHandshake was completed\n"); } } #ifndef _WIN32 signal (SIGALRM, &starttls_alarm); #endif fflush (stdout); fflush (stderr); /* do not buffer */ #if !(defined _WIN32 || defined __WIN32__) setbuf (stdin, NULL); #endif setbuf (stdout, NULL); setbuf (stderr, NULL); for (;;) { if (starttls_alarmed && !hd.secure) { /* Warning! Do not touch this text string, it is used by external programs to search for when gnutls-cli has reached this point. */ fprintf (stderr, "*** Starting TLS handshake\n"); ret = do_handshake (&hd); if (ret < 0) { fprintf (stderr, "*** Handshake has failed\n"); user_term = 1; retval = 1; break; } } inp = check_net_or_keyboard_input(&hd); if (inp == IN_NET) { memset (buffer, 0, MAX_BUF + 1); ret = socket_recv (&hd, buffer, MAX_BUF); if (ret == 0) { printf ("- Peer has closed the GnuTLS connection\n"); break; } else if (handle_error (&hd, ret) < 0 && user_term == 0) { fprintf (stderr, "*** Server has terminated the connection abnormally.\n"); retval = 1; break; } else if (ret > 0) { if (verbose != 0) printf ("- Received[%d]: ", ret); for (ii = 0; ii < ret; ii++) { fputc (buffer[ii], stdout); } fflush (stdout); } if (user_term != 0) break; } if (inp == IN_KEYBOARD) { if ((bytes = read (fileno (stdin), buffer, MAX_BUF - 1)) <= 0) { if (hd.secure == 0) { /* Warning! Do not touch this text string, it is used by external programs to search for when gnutls-cli has reached this point. */ fprintf (stderr, "*** Starting TLS handshake\n"); ret = do_handshake (&hd); clearerr (stdin); if (ret < 0) { fprintf (stderr, "*** Handshake has failed\n"); user_term = 1; retval = 1; break; } } else { user_term = 1; break; } continue; } buffer[bytes] = 0; if (crlf != 0) { char *b = strchr (buffer, '\n'); if (b != NULL) { strcpy (b, "\r\n"); bytes++; } } ret = socket_send (&hd, buffer, bytes); if (ret > 0) { if (verbose != 0) printf ("- Sent: %d bytes\n", ret); } else handle_error (&hd, ret); } } if (user_term != 0) socket_bye (&hd); else gnutls_deinit (hd.session); #ifdef ENABLE_SRP if (srp_cred) gnutls_srp_free_client_credentials (srp_cred); #endif #ifdef ENABLE_PSK if (psk_cred) gnutls_psk_free_client_credentials (psk_cred); #endif gnutls_certificate_free_credentials (xcred); #ifdef ENABLE_ANON gnutls_anon_free_client_credentials (anon_cred); #endif gnutls_global_deinit (); return retval; }
void doit (void) { /* Server stuff. */ gnutls_anon_server_credentials_t s_anoncred; const gnutls_datum_t p3 = { (char *) 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 (); }
void doit(void) { /* Server stuff. */ gnutls_anon_server_credentials_t s_anoncred; const gnutls_datum_t p3 = { (unsigned char *) pkcs3, strlen(pkcs3) }; static gnutls_dh_params_t dh_params; gnutls_session_t server; int sret = GNUTLS_E_AGAIN; /* Client stuff. */ gnutls_anon_client_credentials_t c_anoncred; gnutls_session_t client; int cret = GNUTLS_E_AGAIN, i; /* Need to enable anonymous KX specifically. */ ssize_t ns; int ret, transferred = 0; /* General init. */ global_init(); gnutls_global_set_log_function(tls_log_func); if (debug) gnutls_global_set_log_level(4711); /* 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_priority_set_direct(server, "NONE:+VERS-TLS-ALL:+ARCFOUR-128:+MAC-ALL:+SIGN-ALL:+COMP-NULL:+ANON-DH", NULL); gnutls_credentials_set(server, GNUTLS_CRD_ANON, s_anoncred); gnutls_transport_set_push_function(server, server_push); gnutls_transport_set_pull_function(server, server_pull); gnutls_transport_set_ptr(server, server); /* Init client */ gnutls_anon_allocate_client_credentials(&c_anoncred); gnutls_init(&client, GNUTLS_CLIENT); gnutls_priority_set_direct(client, "NONE:+VERS-TLS-ALL:+CIPHER-ALL:+ARCFOUR-128:+MAC-ALL:+SIGN-ALL:+COMP-NULL:+ANON-DH", NULL); 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_ptr(client, client); memset(b1, 0, sizeof(b1)); HANDSHAKE(client, server); if (debug) success("Handshake established\n"); memset(b1, 1, MAX_BUF); /* try the maximum allowed */ ret = gnutls_record_send(client, b1, MAX_BUF); if (ret < 0) { fprintf(stderr, "Error sending %d bytes: %s\n", (int) MAX_BUF, gnutls_strerror(ret)); exit(1); } if (ret != MAX_BUF) { fprintf(stderr, "Couldn't send %d bytes\n", (int) MAX_BUF); exit(1); } ret = gnutls_record_recv(server, buffer, MAX_BUF); if (ret < 0) { fprintf(stderr, "Error receiving %d bytes: %s\n", (int) MAX_BUF, gnutls_strerror(ret)); exit(1); } if (ret != MAX_BUF) { fprintf(stderr, "Couldn't receive %d bytes, received %d\n", (int) MAX_BUF, ret); exit(1); } if (memcmp(b1, buffer, MAX_BUF) != 0) { fprintf(stderr, "Buffers do not match!\n"); exit(1); } /* Try sending various other sizes */ for (i = 1; i < 128; i++) { TRANSFER(client, server, b1, i, buffer, MAX_BUF); } if (debug) fputs("\n", stdout); gnutls_bye(client, GNUTLS_SHUT_RDWR); gnutls_bye(server, GNUTLS_SHUT_RDWR); 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(); }
SslSocket::~SslSocket() { TRACE("~SslSocket()"); gnutls_deinit(session_); }
static void client(int sds[]) { int ret, ii, j; gnutls_session_t session; char buffer[MAX_BUF + 1]; gnutls_certificate_credentials_t xcred; global_init(); gnutls_global_set_log_function(tls_log_func); if (debug) gnutls_global_set_log_level(9); gnutls_certificate_allocate_credentials(&xcred); /* sets the trusted cas file */ if (debug) success("Setting key files...\n"); ret = gnutls_certificate_set_openpgp_key_mem(xcred, &cert, &key, GNUTLS_OPENPGP_FMT_BASE64); if (ret < 0) { fail("Could not set key files...\n"); return; } for (j = 0; j < SESSIONS; j++) { int sd = sds[j]; /* Initialize TLS session */ gnutls_init(&session, GNUTLS_CLIENT); /* Use default priorities */ gnutls_priority_set_direct(session, "NORMAL:+CTYPE-OPENPGP:+DHE-DSS:+DHE-DSS:+SIGN-DSA-SHA1:+SIGN-DSA-SHA256", NULL); /* put the x509 credentials to the current session */ gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, xcred); gnutls_transport_set_int(session, sd); /* Perform the TLS handshake */ ret = gnutls_handshake(session); if (ret < 0) { fail("client: Handshake %d failed\n", j); gnutls_perror(ret); goto end; } else if (debug) { success("client: Handshake %d was completed\n", j); } if (debug) success("client: TLS version is: %s\n", gnutls_protocol_get_name (gnutls_protocol_get_version(session))); /* see the Getting peer's information example */ if (debug) print_info(session); 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_certificate_free_credentials(xcred); gnutls_global_deinit(); }
static int setup_dtls_connection(struct worker_st *ws) { int ret; gnutls_session_t session; gnutls_datum_t master = { ws->master_secret, sizeof(ws->master_secret) }; gnutls_datum_t sid = { ws->session_id, sizeof(ws->session_id) }; if (ws->req.selected_ciphersuite == NULL) { oclog(ws, LOG_ERR, "no DTLS ciphersuite negotiated"); return -1; } oclog(ws, LOG_DEBUG, "setting up DTLS connection"); /* DTLS cookie verified. * Initialize session. */ ret = gnutls_init(&session, GNUTLS_SERVER|GNUTLS_DATAGRAM|GNUTLS_NONBLOCK); if (ret < 0) { oclog(ws, LOG_ERR, "could not initialize TLS session: %s", gnutls_strerror(ret)); return -1; } ret = gnutls_priority_set_direct(session, ws->req. selected_ciphersuite->gnutls_name, NULL); if (ret < 0) { oclog(ws, LOG_ERR, "could not set TLS priority: %s", gnutls_strerror(ret)); goto fail; } ret = gnutls_session_set_premaster(session, GNUTLS_SERVER, ws->req. selected_ciphersuite->gnutls_version, GNUTLS_KX_RSA, ws->req. selected_ciphersuite->gnutls_cipher, ws->req. selected_ciphersuite->gnutls_mac, GNUTLS_COMP_NULL, &master, &sid); if (ret < 0) { oclog(ws, LOG_ERR, "could not set TLS premaster: %s", gnutls_strerror(ret)); goto fail; } ret = gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, ws->creds->xcred); if (ret < 0) { oclog(ws, LOG_ERR, "could not set TLS credentials: %s", gnutls_strerror(ret)); goto fail; } gnutls_transport_set_push_function(session, dtls_push); gnutls_transport_set_pull_function(session, dtls_pull); gnutls_transport_set_pull_timeout_function(session, dtls_pull_timeout); gnutls_transport_set_ptr(session, &ws->dtls_tptr); gnutls_session_set_ptr(session, ws); gnutls_certificate_server_set_request(session, GNUTLS_CERT_IGNORE); gnutls_handshake_set_timeout(session, GNUTLS_DEFAULT_HANDSHAKE_TIMEOUT); ws->udp_state = UP_HANDSHAKE; ws->dtls_session = session; return 0; fail: gnutls_deinit(session); return -1; }
int /* O - 0 on success, -1 on failure */ _httpTLSStart(http_t *http) /* I - Connection to server */ { char hostname[256], /* Hostname */ *hostptr; /* Pointer into hostname */ int status; /* Status of handshake */ gnutls_certificate_credentials_t *credentials; /* TLS credentials */ char priority_string[1024]; /* Priority string */ DEBUG_printf(("3_httpTLSStart(http=%p)", http)); if (tls_options < 0) { DEBUG_puts("4_httpTLSStart: Setting defaults."); _cupsSetDefaults(); DEBUG_printf(("4_httpTLSStart: tls_options=%x", tls_options)); } if (http->mode == _HTTP_MODE_SERVER && !tls_keypath) { DEBUG_puts("4_httpTLSStart: cupsSetServerCredentials not called."); http->error = errno = EINVAL; http->status = HTTP_STATUS_ERROR; _cupsSetError(IPP_STATUS_ERROR_INTERNAL, _("Server credentials not set."), 1); return (-1); } credentials = (gnutls_certificate_credentials_t *) malloc(sizeof(gnutls_certificate_credentials_t)); if (credentials == NULL) { DEBUG_printf(("8_httpStartTLS: Unable to allocate credentials: %s", strerror(errno))); http->error = errno; http->status = HTTP_STATUS_ERROR; _cupsSetHTTPError(HTTP_STATUS_ERROR); return (-1); } gnutls_certificate_allocate_credentials(credentials); status = gnutls_init(&http->tls, http->mode == _HTTP_MODE_CLIENT ? GNUTLS_CLIENT : GNUTLS_SERVER); if (!status) status = gnutls_set_default_priority(http->tls); if (status) { http->error = EIO; http->status = HTTP_STATUS_ERROR; DEBUG_printf(("4_httpTLSStart: Unable to initialize common TLS parameters: %s", gnutls_strerror(status))); _cupsSetError(IPP_STATUS_ERROR_CUPS_PKI, gnutls_strerror(status), 0); gnutls_deinit(http->tls); gnutls_certificate_free_credentials(*credentials); free(credentials); http->tls = NULL; return (-1); } if (http->mode == _HTTP_MODE_CLIENT) { /* * Client: get the hostname to use for TLS... */ if (httpAddrLocalhost(http->hostaddr)) { strlcpy(hostname, "localhost", sizeof(hostname)); } else { /* * Otherwise make sure the hostname we have does not end in a trailing dot. */ strlcpy(hostname, http->hostname, sizeof(hostname)); if ((hostptr = hostname + strlen(hostname) - 1) >= hostname && *hostptr == '.') *hostptr = '\0'; } status = gnutls_server_name_set(http->tls, GNUTLS_NAME_DNS, hostname, strlen(hostname)); } else { /* * Server: get certificate and private key... */ char crtfile[1024], /* Certificate file */ keyfile[1024]; /* Private key file */ int have_creds = 0; /* Have credentials? */ if (http->fields[HTTP_FIELD_HOST][0]) { /* * Use hostname for TLS upgrade... */ strlcpy(hostname, http->fields[HTTP_FIELD_HOST], sizeof(hostname)); } else { /* * Resolve hostname from connection address... */ http_addr_t addr; /* Connection address */ socklen_t addrlen; /* Length of address */ addrlen = sizeof(addr); if (getsockname(http->fd, (struct sockaddr *)&addr, &addrlen)) { DEBUG_printf(("4_httpTLSStart: Unable to get socket address: %s", strerror(errno))); hostname[0] = '\0'; } else if (httpAddrLocalhost(&addr)) hostname[0] = '\0'; else { httpAddrLookup(&addr, hostname, sizeof(hostname)); DEBUG_printf(("4_httpTLSStart: Resolved socket address to \"%s\".", hostname)); } } if (isdigit(hostname[0] & 255) || hostname[0] == '[') hostname[0] = '\0'; /* Don't allow numeric addresses */ if (hostname[0]) { http_gnutls_make_path(crtfile, sizeof(crtfile), tls_keypath, hostname, "crt"); http_gnutls_make_path(keyfile, sizeof(keyfile), tls_keypath, hostname, "key"); have_creds = !access(crtfile, 0) && !access(keyfile, 0); } else if (tls_common_name) { http_gnutls_make_path(crtfile, sizeof(crtfile), tls_keypath, tls_common_name, "crt"); http_gnutls_make_path(keyfile, sizeof(keyfile), tls_keypath, tls_common_name, "key"); have_creds = !access(crtfile, 0) && !access(keyfile, 0); } if (!have_creds && tls_auto_create && (hostname[0] || tls_common_name)) { DEBUG_printf(("4_httpTLSStart: Auto-create credentials for \"%s\".", hostname[0] ? hostname : tls_common_name)); if (!cupsMakeServerCredentials(tls_keypath, hostname[0] ? hostname : tls_common_name, 0, NULL, time(NULL) + 365 * 86400)) { DEBUG_puts("4_httpTLSStart: cupsMakeServerCredentials failed."); http->error = errno = EINVAL; http->status = HTTP_STATUS_ERROR; _cupsSetError(IPP_STATUS_ERROR_INTERNAL, _("Unable to create server credentials."), 1); return (-1); } } DEBUG_printf(("4_httpTLSStart: Using certificate \"%s\" and private key \"%s\".", crtfile, keyfile)); status = gnutls_certificate_set_x509_key_file(*credentials, crtfile, keyfile, GNUTLS_X509_FMT_PEM); } if (!status) status = gnutls_credentials_set(http->tls, GNUTLS_CRD_CERTIFICATE, *credentials); if (status) { http->error = EIO; http->status = HTTP_STATUS_ERROR; DEBUG_printf(("4_httpTLSStart: Unable to complete client/server setup: %s", gnutls_strerror(status))); _cupsSetError(IPP_STATUS_ERROR_CUPS_PKI, gnutls_strerror(status), 0); gnutls_deinit(http->tls); gnutls_certificate_free_credentials(*credentials); free(credentials); http->tls = NULL; return (-1); } strlcpy(priority_string, "NORMAL", sizeof(priority_string)); if (tls_options & _HTTP_TLS_DENY_TLS10) strlcat(priority_string, ":+VERS-TLS-ALL:-VERS-TLS1.0:-VERS-SSL3.0", sizeof(priority_string)); else if (tls_options & _HTTP_TLS_ALLOW_SSL3) strlcat(priority_string, ":+VERS-TLS-ALL", sizeof(priority_string)); else strlcat(priority_string, ":+VERS-TLS-ALL:-VERS-SSL3.0", sizeof(priority_string)); if (!(tls_options & _HTTP_TLS_ALLOW_RC4)) strlcat(priority_string, ":-ARCFOUR-128", sizeof(priority_string)); if (!(tls_options & _HTTP_TLS_ALLOW_DH)) strlcat(priority_string, ":!ANON-DH", sizeof(priority_string)); #ifdef HAVE_GNUTLS_PRIORITY_SET_DIRECT gnutls_priority_set_direct(http->tls, priority_string, NULL); #else gnutls_priority_t priority; /* Priority */ gnutls_priority_init(&priority, priority_string, NULL); gnutls_priority_set(http->tls, priority); gnutls_priority_deinit(priority); #endif /* HAVE_GNUTLS_PRIORITY_SET_DIRECT */ gnutls_transport_set_ptr(http->tls, (gnutls_transport_ptr_t)http); gnutls_transport_set_pull_function(http->tls, http_gnutls_read); #ifdef HAVE_GNUTLS_TRANSPORT_SET_PULL_TIMEOUT_FUNCTION gnutls_transport_set_pull_timeout_function(http->tls, (gnutls_pull_timeout_func)httpWait); #endif /* HAVE_GNUTLS_TRANSPORT_SET_PULL_TIMEOUT_FUNCTION */ gnutls_transport_set_push_function(http->tls, http_gnutls_write); while ((status = gnutls_handshake(http->tls)) != GNUTLS_E_SUCCESS) { DEBUG_printf(("5_httpStartTLS: gnutls_handshake returned %d (%s)", status, gnutls_strerror(status))); if (gnutls_error_is_fatal(status)) { http->error = EIO; http->status = HTTP_STATUS_ERROR; _cupsSetError(IPP_STATUS_ERROR_CUPS_PKI, gnutls_strerror(status), 0); gnutls_deinit(http->tls); gnutls_certificate_free_credentials(*credentials); free(credentials); http->tls = NULL; return (-1); } } http->tls_credentials = credentials; return (0); }
void SSLi_free(SSL_handle_t *session) { gnutls_deinit(*session); free(session); }
void doit () { int err; int sockets[2]; const char *srcdir; char *pub_key_path, *priv_key_path; pid_t child; gnutls_global_init (); srcdir = getenv ("srcdir") ? getenv ("srcdir") : "."; if (debug) { gnutls_global_set_log_level (10); gnutls_global_set_log_function (log_message); } err = socketpair (PF_UNIX, SOCK_STREAM, 0, sockets); if (err != 0) fail ("socketpair %s\n", strerror (errno)); pub_key_path = alloca (strlen (srcdir) + strlen (pub_key_file) + 2); strcpy (pub_key_path, srcdir); strcat (pub_key_path, "/"); strcat (pub_key_path, pub_key_file); priv_key_path = alloca (strlen (srcdir) + strlen (priv_key_file) + 2); strcpy (priv_key_path, srcdir); strcat (priv_key_path, "/"); strcat (priv_key_path, priv_key_file); child = fork (); if (child == -1) fail ("fork %s\n", strerror (errno)); if (child == 0) { /* Child process (client). */ gnutls_session_t session; gnutls_certificate_credentials_t cred; ssize_t sent; if (debug) printf ("client process %i\n", getpid ()); err = gnutls_init (&session, GNUTLS_CLIENT); if (err != 0) fail ("client session %d\n", err); gnutls_priority_set_direct (session, "NONE:+VERS-TLS1.2:+CIPHER-ALL:+MAC-ALL:+SIGN-ALL:+COMP-ALL:+DHE-DSS:+DHE-RSA:+CTYPE-OPENPGP", NULL); gnutls_transport_set_ptr (session, (gnutls_transport_ptr_t) (intptr_t) sockets[0]); err = gnutls_certificate_allocate_credentials (&cred); if (err != 0) fail ("client credentials %d\n", err); err = gnutls_certificate_set_openpgp_key_file2 (cred, pub_key_path, priv_key_path, key_id, GNUTLS_OPENPGP_FMT_BASE64); if (err != 0) fail ("client openpgp keys %d\n", err); err = gnutls_credentials_set (session, GNUTLS_CRD_CERTIFICATE, cred); if (err != 0) fail ("client credential_set %d\n", err); gnutls_dh_set_prime_bits (session, 1024); err = gnutls_handshake (session); if (err != 0) fail ("client handshake %s (%d) \n", gnutls_strerror(err), err); else if (debug) printf ("client handshake successful\n"); sent = gnutls_record_send (session, message, sizeof (message)); if (sent != sizeof (message)) fail ("client sent %li vs. %li\n", (long) sent, (long) sizeof (message)); err = gnutls_bye (session, GNUTLS_SHUT_RDWR); if (err != 0) fail ("client bye %d\n", err); if (debug) printf ("client done\n"); gnutls_deinit(session); gnutls_certificate_free_credentials (cred); } else { /* Parent process (server). */ gnutls_session_t session; gnutls_dh_params_t dh_params; gnutls_certificate_credentials_t cred; char greetings[sizeof (message) * 2]; ssize_t received; pid_t done; int status; const gnutls_datum_t p3 = { (char *) pkcs3, strlen (pkcs3) }; if (debug) printf ("server process %i (child %i)\n", getpid (), child); err = gnutls_init (&session, GNUTLS_SERVER); if (err != 0) fail ("server session %d\n", err); gnutls_priority_set_direct (session, "NONE:+VERS-TLS1.2:+CIPHER-ALL:+MAC-ALL:+SIGN-ALL:+COMP-ALL:+DHE-DSS:+DHE-RSA:+CTYPE-OPENPGP", NULL); gnutls_transport_set_ptr (session, (gnutls_transport_ptr_t) (intptr_t) sockets[1]); err = gnutls_certificate_allocate_credentials (&cred); if (err != 0) fail ("server credentials %d\n", err); err = gnutls_certificate_set_openpgp_key_file2 (cred, pub_key_path, priv_key_path, key_id, GNUTLS_OPENPGP_FMT_BASE64); if (err != 0) fail ("server openpgp keys %d\n", err); err = gnutls_dh_params_init (&dh_params); if (err) fail ("server DH params init %d\n", err); err = gnutls_dh_params_import_pkcs3 (dh_params, &p3, GNUTLS_X509_FMT_PEM); if (err) fail ("server DH params generate %d\n", err); gnutls_certificate_set_dh_params (cred, dh_params); err = gnutls_credentials_set (session, GNUTLS_CRD_CERTIFICATE, cred); if (err != 0) fail ("server credential_set %d\n", err); gnutls_certificate_server_set_request (session, GNUTLS_CERT_REQUIRE); err = gnutls_handshake (session); if (err != 0) fail ("server handshake %s (%d) \n", gnutls_strerror(err), err); received = gnutls_record_recv (session, greetings, sizeof (greetings)); if (received != sizeof (message) || memcmp (greetings, message, sizeof (message))) fail ("server received %li vs. %li\n", (long) received, (long) sizeof (message)); err = gnutls_bye (session, GNUTLS_SHUT_RDWR); if (err != 0) fail ("server bye %s (%d) \n", gnutls_strerror(err), err); if (debug) printf ("server done\n"); gnutls_deinit(session); gnutls_certificate_free_credentials (cred); gnutls_dh_params_deinit (dh_params); done = wait (&status); if (done < 0) fail ("wait %s\n", strerror (errno)); if (done != child) fail ("who's that?! %d\n", done); if (WIFEXITED (status)) { if (WEXITSTATUS (status) != 0) fail ("child exited with status %d\n", WEXITSTATUS (status)); } else if (WIFSIGNALED (status)) fail ("child stopped by signal %d\n", WTERMSIG (status)); else fail ("child failed: %d\n", status); } }
int main (int argc, char **argv) { int err, ret; int sd, i; gnutls_session_t state; char buffer[MAX_BUF + 1]; char portname[6]; struct addrinfo hints, *res, *ptr; cmd_parser(argc, argv); #ifndef _WIN32 signal (SIGPIPE, SIG_IGN); #endif sockets_init (); if (gnutls_global_init () < 0) { fprintf (stderr, "global state initialization error\n"); exit (1); } gnutls_global_set_log_function (tls_log_func); gnutls_global_set_log_level (debug); printf ("Resolving '%s'...\n", hostname); /* get server name */ memset (&hints, 0, sizeof (hints)); hints.ai_socktype = SOCK_STREAM; hints.ai_flags = 0; snprintf (portname, sizeof (portname), "%d", port); if ((err = getaddrinfo (hostname, portname, &hints, &res)) != 0) { fprintf (stderr, "Cannot resolve %s: %s\n", hostname, gai_strerror (err)); exit (1); } /* X509 stuff */ if (gnutls_certificate_allocate_credentials (&xcred) < 0) { /* space for 2 certificates */ fprintf (stderr, "memory error\n"); exit (1); } /* SRP stuff */ #ifdef ENABLE_SRP if (gnutls_srp_allocate_client_credentials (&srp_cred) < 0) { fprintf (stderr, "memory error\n"); exit (1); } #endif #ifdef ENABLE_ANON /* ANON stuff */ if (gnutls_anon_allocate_client_credentials (&anon_cred) < 0) { fprintf (stderr, "memory error\n"); exit (1); } #endif i = 0; do { if (tls_tests[i].test_name == NULL) break; /* finished */ /* if neither of SSL3 and TLSv1 are supported, exit */ if (i > 6 && tls1_1_ok == 0 && tls1_ok == 0 && ssl3_ok == 0) { fprintf (stderr, "\nServer does not support any of SSL 3.0, TLS 1.0 and TLS 1.1\n"); break; } sd = -1; for (ptr = res; ptr != NULL; ptr = ptr->ai_next) { sd = socket (ptr->ai_family, ptr->ai_socktype, ptr->ai_protocol); if (sd == -1) { continue; } getnameinfo (ptr->ai_addr, ptr->ai_addrlen, buffer, MAX_BUF, NULL, 0, NI_NUMERICHOST); if (tt == 0) { printf ("Connecting to '%s:%d'...\n", buffer, port); tt = 1; } if ((err = connect (sd, ptr->ai_addr, ptr->ai_addrlen)) != 0) { close (sd); sd = -1; continue; } else break; } ERR (err, "connect"); gnutls_init (&state, GNUTLS_CLIENT|GNUTLS_NO_EXTENSIONS); gnutls_transport_set_ptr (state, (gnutls_transport_ptr_t) gl_fd_to_handle (sd)); if (hostname && !isdigit(hostname[0]) && strchr(hostname, ':') == 0) gnutls_server_name_set (state, GNUTLS_NAME_DNS, hostname, strlen (hostname)); do { printf ("Checking %s...", tls_tests[i].test_name); fflush(stdout); ret = tls_tests[i].func (state); if (ret == TEST_SUCCEED) printf (" %s\n", tls_tests[i].suc_str); else if (ret == TEST_FAILED) printf (" %s\n", tls_tests[i].fail_str); else if (ret == TEST_UNSURE) printf (" %s\n", tls_tests[i].unsure_str); else if (ret == TEST_IGNORE) { printf (" N/A\n"); i++; } } while (ret == TEST_IGNORE && tls_tests[i].test_name != NULL); gnutls_deinit (state); shutdown (sd, SHUT_RDWR); /* no more receptions */ close (sd); i++; } while (1); freeaddrinfo (res); #ifdef ENABLE_SRP gnutls_srp_free_client_credentials (srp_cred); #endif gnutls_certificate_free_credentials (xcred); #ifdef ENABLE_ANON gnutls_anon_free_client_credentials (anon_cred); #endif gnutls_global_deinit (); return 0; }
int main (void) { int err, listen_sd; int sd, ret; struct sockaddr_in sa_serv; struct sockaddr_in sa_cli; int client_len; char topbuf[512]; gnutls_session_t session; char buffer[MAX_BUF + 1]; int optval = 1; /* to disallow usage of the blocking /dev/random */ gcry_control (GCRYCTL_ENABLE_QUICK_RANDOM, 0); /* this must be called once in the program */ gnutls_global_init (); gnutls_certificate_allocate_credentials (&x509_cred); gnutls_certificate_set_x509_trust_file (x509_cred, CAFILE, GNUTLS_X509_FMT_PEM); gnutls_certificate_set_x509_crl_file (x509_cred, CRLFILE, GNUTLS_X509_FMT_PEM); gnutls_certificate_set_x509_key_file (x509_cred, CERTFILE, KEYFILE, GNUTLS_X509_FMT_PEM); gnutls_psk_allocate_server_credentials (&psk_cred); gnutls_psk_set_server_credentials_function (psk_cred, pskfunc); generate_dh_params (); gnutls_priority_init (&priority_cache, "NORMAL:PSK", NULL); gnutls_certificate_set_dh_params (x509_cred, dh_params); /* Socket operations */ listen_sd = socket (AF_INET, SOCK_STREAM, 0); SOCKET_ERR (listen_sd, "socket"); memset (&sa_serv, '\0', sizeof (sa_serv)); sa_serv.sin_family = AF_INET; sa_serv.sin_addr.s_addr = INADDR_ANY; sa_serv.sin_port = htons (PORT); /* Server Port number */ setsockopt (listen_sd, SOL_SOCKET, SO_REUSEADDR, (void *) &optval, sizeof (int)); err = bind (listen_sd, (SA *) & sa_serv, sizeof (sa_serv)); SOCKET_ERR (err, "bind"); err = listen (listen_sd, 1024); SOCKET_ERR (err, "listen"); printf ("Server ready. Listening to port '%d'.\n\n", PORT); client_len = sizeof (sa_cli); for (;;) { session = initialize_tls_session (); sd = accept (listen_sd, (SA *) & sa_cli, &client_len); printf ("- connection from %s, port %d\n", inet_ntop (AF_INET, &sa_cli.sin_addr, topbuf, sizeof (topbuf)), ntohs (sa_cli.sin_port)); gnutls_transport_set_ptr (session, (gnutls_transport_ptr_t) sd); ret = gnutls_handshake (session); if (ret < 0) { close (sd); gnutls_deinit (session); fprintf (stderr, "*** Handshake has failed (%s)\n\n", gnutls_strerror (ret)); continue; } printf ("- 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) { printf ("\n- Peer has closed the GnuTLS connection\n"); break; } else if (ret < 0) { fprintf (stderr, "\n*** Received corrupted " "data(%d). Closing the connection.\n\n", ret); break; } else if (ret > 0) { /* echo data back to the client */ gnutls_record_send (session, buffer, strlen (buffer)); } } printf ("\n"); /* do not wait for the peer to close the connection. */ gnutls_bye (session, GNUTLS_SHUT_WR); close (sd); gnutls_deinit (session); } close (listen_sd); gnutls_certificate_free_credentials (x509_cred); gnutls_psk_free_server_credentials (psk_cred); gnutls_priority_deinit (priority_cache); gnutls_global_deinit (); return 0; }
/* * This function is called to shut down the SSL layer but keep the * socket open (CCC - Clear Command Channel) */ int Curl_gtls_shutdown(struct connectdata *conn, int sockindex) { ssize_t result; int retval = 0; struct SessionHandle *data = conn->data; int done = 0; char buf[120]; /* This has only been tested on the proftpd server, and the mod_tls code sends a close notify alert without waiting for a close notify alert in response. Thus we wait for a close notify alert from the server, but we do not send one. Let's hope other servers do the same... */ if(data->set.ftp_ccc == CURLFTPSSL_CCC_ACTIVE) gnutls_bye(conn->ssl[sockindex].session, GNUTLS_SHUT_WR); if(conn->ssl[sockindex].session) { while(!done) { int what = Curl_socket_ready(conn->sock[sockindex], CURL_SOCKET_BAD, SSL_SHUTDOWN_TIMEOUT); if(what > 0) { /* Something to read, let's do it and hope that it is the close notify alert from the server */ result = gnutls_record_recv(conn->ssl[sockindex].session, buf, sizeof(buf)); switch(result) { case 0: /* This is the expected response. There was no data but only the close notify alert */ done = 1; break; case GNUTLS_E_AGAIN: case GNUTLS_E_INTERRUPTED: infof(data, "GNUTLS_E_AGAIN || GNUTLS_E_INTERRUPTED\n"); break; default: retval = -1; done = 1; break; } } else if(0 == what) { /* timeout */ failf(data, "SSL shutdown timeout"); done = 1; break; } else { /* anything that gets here is fatally bad */ failf(data, "select/poll on SSL socket, errno: %d", SOCKERRNO); retval = -1; done = 1; } } gnutls_deinit(conn->ssl[sockindex].session); } gnutls_certificate_free_credentials(conn->ssl[sockindex].cred); #ifdef USE_TLS_SRP if(data->set.ssl.authtype == CURL_TLSAUTH_SRP && data->set.ssl.username != NULL) gnutls_srp_free_client_credentials(conn->ssl[sockindex].srp_client_cred); #endif conn->ssl[sockindex].cred = NULL; conn->ssl[sockindex].session = NULL; return retval; }
void tls_free(tls_t *tls) { gnutls_deinit(tls->session); gnutls_certificate_free_credentials(tls->cred); xmpp_free(tls->ctx, tls); }
void doit(void) { int exit_code = EXIT_SUCCESS; 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_datum_t data; char buf[128]; /* General init. */ global_init(); gnutls_global_set_log_function(tls_log_func); if (debug) gnutls_global_set_log_level(6); gnutls_global_set_time_function(mytime); /* Init server */ gnutls_certificate_allocate_credentials(&serverx509cred); gnutls_certificate_set_x509_key_mem(serverx509cred, &server_cert, &server_key, GNUTLS_X509_FMT_PEM); gnutls_init(&server, GNUTLS_SERVER); gnutls_credentials_set(server, GNUTLS_CRD_CERTIFICATE, serverx509cred); gnutls_set_default_priority(server); 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(&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_init(&client, GNUTLS_CLIENT|GNUTLS_ENABLE_FALSE_START); if (ret < 0) exit(1); ret = gnutls_credentials_set(client, GNUTLS_CRD_CERTIFICATE, clientx509cred); if (ret < 0) exit(1); gnutls_set_default_priority(client); gnutls_transport_set_push_function(client, client_push); gnutls_transport_set_pull_function(client, client_pull); gnutls_transport_set_ptr(client, client); memset(buf, 0, sizeof(buf)); ret = gnutls_session_set_data(client, buf, sizeof(buf)); if (ret != GNUTLS_E_DB_ERROR) { fail("unexpected error: %s\n", gnutls_strerror(ret)); } HANDSHAKE(client, server); /* try obtaining the resumption data. This should fail because * the handshake is not yet complete (due to false start) */ ret = gnutls_session_get_data2(client, &data); if (ret != GNUTLS_E_UNAVAILABLE_DURING_HANDSHAKE) { fail("unexpected error: %s\n", gnutls_strerror(ret)); } ret = gnutls_record_recv(client, buf, sizeof(buf)); if (ret < 0 && ret != GNUTLS_E_AGAIN) { fail("unexpected error: %s\n", gnutls_strerror(ret)); } ret = gnutls_session_get_data2(client, &data); if (ret != 0) { fail("unexpected error: %s\n", gnutls_strerror(ret)); } gnutls_free(data.data); gnutls_bye(client, GNUTLS_SHUT_RDWR); gnutls_bye(server, GNUTLS_SHUT_RDWR); gnutls_deinit(client); gnutls_deinit(server); gnutls_certificate_free_credentials(serverx509cred); gnutls_certificate_free_credentials(clientx509cred); gnutls_global_deinit(); if (debug > 0) { if (exit_code == 0) puts("Self-test successful"); else puts("Self-test failed"); } }