/** * ntfs_pkcs12_extract_rsa_key */ static ntfs_rsa_private_key ntfs_pkcs12_extract_rsa_key(u8 *pfx, int pfx_size, char *password, char *thumbprint, int thumbprint_size, NTFS_DF_TYPES *df_type) { int err, bag_index, flags; gnutls_datum_t dpfx, dkey; gnutls_pkcs12_t pkcs12 = NULL; gnutls_pkcs12_bag_t bag = NULL; gnutls_x509_privkey_t pkey = NULL; gnutls_x509_crt_t crt = NULL; ntfs_rsa_private_key rsa_key = NULL; char purpose_oid[100]; size_t purpose_oid_size = sizeof(purpose_oid); int oid_index; size_t tp_size = thumbprint_size; BOOL have_thumbprint = FALSE; *df_type = DF_TYPE_UNKNOWN; /* Create a pkcs12 structure. */ err = gnutls_pkcs12_init(&pkcs12); if (err) { ntfs_log_error("Failed to initialize PKCS#12 structure: %s\n", gnutls_strerror(err)); return NULL; } /* Convert the PFX file (DER format) to native pkcs12 format. */ dpfx.data = pfx; dpfx.size = pfx_size; err = gnutls_pkcs12_import(pkcs12, &dpfx, GNUTLS_X509_FMT_DER, 0); if (err) { ntfs_log_error("Failed to convert the PFX file from DER to " "native PKCS#12 format: %s\n", gnutls_strerror(err)); goto err; } /* * Verify that the password is correct and that the key file has not * been tampered with. Note if the password has zero length and the * verification fails, retry with password set to NULL. This is needed * to get passwordless .pfx files generated with Windows XP SP1 (and * probably earlier versions of Windows) to work. */ retry_verify: err = gnutls_pkcs12_verify_mac(pkcs12, password); if (err) { if (err == GNUTLS_E_MAC_VERIFY_FAILED && password && !strlen(password)) { password = NULL; goto retry_verify; } ntfs_log_error("Failed to verify the MAC: %s Is the " "password correct?\n", gnutls_strerror(err)); goto err; } for (bag_index = 0; ; bag_index++) { err = gnutls_pkcs12_bag_init(&bag); if (err) { ntfs_log_error("Failed to initialize PKCS#12 Bag " "structure: %s\n", gnutls_strerror(err)); goto err; } err = gnutls_pkcs12_get_bag(pkcs12, bag_index, bag); if (err) { if (err == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE) { err = 0; break; } ntfs_log_error("Failed to obtain Bag from PKCS#12 " "structure: %s\n", gnutls_strerror(err)); goto err; } check_again: err = gnutls_pkcs12_bag_get_count(bag); if (err < 0) { ntfs_log_error("Failed to obtain Bag count: %s\n", gnutls_strerror(err)); goto err; } err = gnutls_pkcs12_bag_get_type(bag, 0); if (err < 0) { ntfs_log_error("Failed to determine Bag type: %s\n", gnutls_strerror(err)); goto err; } flags = 0; switch (err) { case GNUTLS_BAG_PKCS8_KEY: flags = GNUTLS_PKCS_PLAIN; case GNUTLS_BAG_PKCS8_ENCRYPTED_KEY: err = gnutls_pkcs12_bag_get_data(bag, 0, &dkey); if (err < 0) { ntfs_log_error("Failed to obtain Bag data: " "%s\n", gnutls_strerror(err)); goto err; } err = gnutls_x509_privkey_init(&pkey); if (err) { ntfs_log_error("Failed to initialized " "private key structure: %s\n", gnutls_strerror(err)); goto err; } /* Decrypt the private key into GNU TLS format. */ err = gnutls_x509_privkey_import_pkcs8(pkey, &dkey, GNUTLS_X509_FMT_DER, password, flags); if (err) { ntfs_log_error("Failed to convert private " "key from DER to GNU TLS " "format: %s\n", gnutls_strerror(err)); goto err; } #if 0 /* * Export the key again, but unencrypted, and output it * to stderr. Note the output has an RSA header so to * compare to openssl pkcs12 -nodes -in myfile.pfx * output need to ignore the part of the key between * the first "MII..." up to the second "MII...". The * actual RSA private key begins at the second "MII..." * and in my testing at least was identical to openssl * output and was also identical both on big and little * endian so gnutls should be endianness safe. */ char *buf = malloc(8192); size_t bufsize = 8192; err = gnutls_x509_privkey_export_pkcs8(pkey, GNUTLS_X509_FMT_PEM, "", GNUTLS_PKCS_PLAIN, buf, &bufsize); if (err) { ntfs_log_error("eek1\n"); exit(1); } ntfs_log_error("%s\n", buf); free(buf); #endif /* Convert the private key to our internal format. */ rsa_key = ntfs_rsa_private_key_import_from_gnutls(pkey); if (!rsa_key) goto err; break; case GNUTLS_BAG_ENCRYPTED: err = gnutls_pkcs12_bag_decrypt(bag, password); if (err) { ntfs_log_error("Failed to decrypt Bag: %s\n", gnutls_strerror(err)); goto err; } goto check_again; case GNUTLS_BAG_CERTIFICATE: err = gnutls_pkcs12_bag_get_data(bag, 0, &dkey); if (err < 0) { ntfs_log_error("Failed to obtain Bag data: " "%s\n", gnutls_strerror(err)); goto err; } err = gnutls_x509_crt_init(&crt); if (err) { ntfs_log_error("Failed to initialize " "certificate structure: %s\n", gnutls_strerror(err)); goto err; } err = gnutls_x509_crt_import(crt, &dkey, GNUTLS_X509_FMT_DER); if (err) { ntfs_log_error("Failed to convert certificate " "from DER to GNU TLS format: " "%s\n", gnutls_strerror(err)); goto err; } oid_index = 0; /* * Search in the key purposes for an EFS * encryption purpose or an EFS recovery * purpose, and use the first one found. */ do { purpose_oid_size = sizeof(purpose_oid); err = gnutls_x509_crt_get_key_purpose_oid(crt, oid_index, purpose_oid, &purpose_oid_size, NULL); if (!err) { purpose_oid[purpose_oid_size - 1] = '\0'; if (!strcmp(purpose_oid, NTFS_EFS_CERT_PURPOSE_OID_DRF)) *df_type = DF_TYPE_DRF; else if (!strcmp(purpose_oid, NTFS_EFS_CERT_PURPOSE_OID_DDF)) *df_type = DF_TYPE_DDF; else oid_index++; } } while (!err && (*df_type == DF_TYPE_UNKNOWN)); if (*df_type == DF_TYPE_UNKNOWN) { /* End of list reached ? */ if (err == GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE) ntfs_log_error("Key does not have an " "EFS purpose OID\n"); else ntfs_log_error("Failed to get a key " "purpose OID : %s ", gnutls_strerror(err)); goto err; } /* Return the thumbprint to the caller. */ err = gnutls_x509_crt_get_fingerprint(crt, GNUTLS_DIG_SHA1, thumbprint, &tp_size); if (err) { ntfs_log_error("Failed to get thumbprint: " "%s\n", gnutls_strerror(err)); goto err; } if (tp_size != NTFS_SHA1_THUMBPRINT_SIZE) { ntfs_log_error("Invalid thumbprint size %zd. " "Should be %d.\n", tp_size, thumbprint_size); err = EINVAL; goto err; } have_thumbprint = TRUE; gnutls_x509_crt_deinit(crt); crt = NULL; break; default: /* We do not care about other types. */ break; } gnutls_pkcs12_bag_deinit(bag); } err: if (rsa_key && (err || *df_type == DF_TYPE_UNKNOWN || !have_thumbprint)) { if (!err) ntfs_log_error("Key type or thumbprint not found, " "aborting.\n"); ntfs_rsa_private_key_release(rsa_key); rsa_key = NULL; } if (crt) gnutls_x509_crt_deinit(crt); if (pkey) gnutls_x509_privkey_deinit(pkey); if (bag) gnutls_pkcs12_bag_deinit(bag); if (pkcs12) gnutls_pkcs12_deinit(pkcs12); return rsa_key; }
void doit (void) { int exit_val = 0; size_t i; int ret; /* The overloading of time() seems to work in linux (ELF?) * systems only. Disable it on windows. */ #ifdef _WIN32 exit(77); #endif ret = gnutls_global_init (); if (ret != 0) { fail ("%d: %s\n", ret, gnutls_strerror (ret)); exit (EXIT_FAILURE); } gnutls_global_set_time_function (mytime); gnutls_global_set_log_function (tls_log_func); if (debug) gnutls_global_set_log_level (4711); for (i = 0; chains[i].chain; i++) { unsigned int verify_status; gnutls_x509_crt_t certs[4]; gnutls_x509_crt_t ca; gnutls_datum_t tmp; size_t j; if (debug) printf ("Chain '%s' (%d)...\n", chains[i].name, (int) i); for (j = 0; chains[i].chain[j]; j++) { if (debug > 2) printf ("\tAdding certificate %d...", (int) j); ret = gnutls_x509_crt_init (&certs[j]); if (ret < 0) error (EXIT_FAILURE, 0, "gnutls_x509_crt_init[%d,%d]: %s", (int) i, (int) j, gnutls_strerror (ret)); tmp.data = (char *) chains[i].chain[j]; tmp.size = strlen (chains[i].chain[j]); ret = gnutls_x509_crt_import (certs[j], &tmp, GNUTLS_X509_FMT_PEM); if (debug > 2) printf ("done\n"); if (ret < 0) error (EXIT_FAILURE, 0, "gnutls_x509_crt_import[%d,%d]: %s", (int) i, (int) j, gnutls_strerror (ret)); gnutls_x509_crt_print (certs[j], GNUTLS_CRT_PRINT_ONELINE, &tmp); if (debug) printf ("\tCertificate %d: %.*s\n", (int) j, tmp.size, tmp.data); gnutls_free (tmp.data); } if (debug > 2) printf ("\tAdding CA certificate..."); ret = gnutls_x509_crt_init (&ca); if (ret < 0) error (EXIT_FAILURE, 0, "gnutls_x509_crt_init: %s", gnutls_strerror (ret)); tmp.data = (char *) *chains[i].ca; tmp.size = strlen (*chains[i].ca); ret = gnutls_x509_crt_import (ca, &tmp, GNUTLS_X509_FMT_PEM); if (ret < 0) error (EXIT_FAILURE, 0, "gnutls_x509_crt_import: %s", gnutls_strerror (ret)); if (debug > 2) printf ("done\n"); gnutls_x509_crt_print (ca, GNUTLS_CRT_PRINT_ONELINE, &tmp); if (debug) printf ("\tCA Certificate: %.*s\n", tmp.size, tmp.data); gnutls_free (tmp.data); if (debug) printf ("\tVerifying..."); ret = gnutls_x509_crt_list_verify (certs, j, &ca, 1, NULL, 0, chains[i].verify_flags, &verify_status); if (ret < 0) error (EXIT_FAILURE, 0, "gnutls_x509_crt_list_verify[%d,%d]: %s", (int) i, (int) j, gnutls_strerror (ret)); if (verify_status != chains[i].expected_verify_result) { fail ("chain[%s]: verify_status: %d expected: %d\n", chains[i].name, verify_status, chains[i].expected_verify_result); #if 0 j = 0; do { fprintf (stderr, "%s\n", chains[i].chain[j]); } while (chains[i].chain[++j] != NULL); #endif if (!debug) exit (1); } else if (debug) printf ("done\n"); if (debug) printf ("\tCleanup..."); gnutls_x509_crt_deinit (ca); for (j = 0; chains[i].chain[j]; j++) gnutls_x509_crt_deinit (certs[j]); if (debug) printf ("done\n\n\n"); } gnutls_global_deinit (); if (debug) printf ("Exit status...%d\n", exit_val); exit (exit_val); }
int tls_connection_decrypt(void *ssl_ctx, struct tls_connection *conn, const u8 *in_data, size_t in_len, u8 *out_data, size_t out_len) { ssize_t res; if (conn->pull_buf) { wpa_printf(MSG_DEBUG, "%s - %lu bytes remaining in " "pull_buf", __func__, (unsigned long) conn->pull_buf_len); os_free(conn->pull_buf); } conn->pull_buf = os_malloc(in_len); if (conn->pull_buf == NULL) return -1; os_memcpy(conn->pull_buf, in_data, in_len); conn->pull_buf_offset = conn->pull_buf; conn->pull_buf_len = in_len; #ifdef GNUTLS_IA if (conn->tls_ia) { res = gnutls_ia_recv(conn->session, (char *) out_data, out_len); if (out_len >= 12 && (res == GNUTLS_E_WARNING_IA_IPHF_RECEIVED || res == GNUTLS_E_WARNING_IA_FPHF_RECEIVED)) { int final = res == GNUTLS_E_WARNING_IA_FPHF_RECEIVED; wpa_printf(MSG_DEBUG, "%s: Received %sPhaseFinished", __func__, final ? "Final" : "Intermediate"); res = gnutls_ia_permute_inner_secret( conn->session, conn->session_keys_len, (char *) conn->session_keys); if (conn->session_keys) { os_memset(conn->session_keys, 0, conn->session_keys_len); os_free(conn->session_keys); } conn->session_keys = NULL; conn->session_keys_len = 0; if (res) { wpa_printf(MSG_DEBUG, "%s: Failed to permute " "inner secret: %s", __func__, gnutls_strerror(res)); return -1; } res = gnutls_ia_verify_endphase(conn->session, (char *) out_data); if (res == 0) { wpa_printf(MSG_DEBUG, "%s: Correct endphase " "checksum", __func__); } else { wpa_printf(MSG_INFO, "%s: Endphase " "verification failed: %s", __func__, gnutls_strerror(res)); return -1; } if (final) conn->final_phase_finished = 1; return 0; }
void doit(void) { #ifdef ENABLE_NON_SUITEB_CURVES const char *filename, *password = "******"; gnutls_pkcs12_t pkcs12; gnutls_datum_t data; gnutls_x509_crt_t *chain, *extras; unsigned int chain_size = 0, extras_size = 0, i; gnutls_x509_privkey_t pkey; int ret; ret = global_init(); if (ret < 0) fail("global_init failed %d\n", ret); gnutls_global_set_log_function(tls_log_func); if (debug) gnutls_global_set_log_level(2); ret = gnutls_pkcs12_init(&pkcs12); if (ret < 0) fail("initialization failed: %s\n", gnutls_strerror(ret)); filename = getenv("PKCS12_MANY_CERTS_FILE"); if (!filename) filename = "pkcs12-decode/pkcs12_5certs.p12"; if (debug) success ("Reading PKCS#12 blob from `%s' using password `%s'.\n", filename, password); ret = gnutls_load_file(filename, &data); if (ret < 0) fail("cannot open file"); ret = gnutls_pkcs12_import(pkcs12, &data, GNUTLS_X509_FMT_DER, 0); if (ret < 0) fail("pkcs12_import failed %d: %s\n", ret, gnutls_strerror(ret)); if (debug) success("Read file OK\n"); ret = gnutls_pkcs12_simple_parse(pkcs12, password, &pkey, &chain, &chain_size, &extras, &extras_size, NULL, 0); if (ret < 0) fail("pkcs12_simple_parse failed %d: %s\n", ret, gnutls_strerror(ret)); if (chain_size != 1) fail("chain size (%u) should have been 1\n", chain_size); if (extras_size != 4) fail("extras size (%u) should have been 4\n", extras_size); if (debug) { char dn[512]; size_t dn_size; dn_size = sizeof(dn); ret = gnutls_x509_crt_get_dn(chain[0], dn, &dn_size); if (ret < 0) fail("crt_get_dn failed %d: %s\n", ret, gnutls_strerror(ret)); success("dn: %s\n", dn); dn_size = sizeof(dn); ret = gnutls_x509_crt_get_issuer_dn(chain[0], dn, &dn_size); if (ret < 0) fail("crt_get_dn failed %d: %s\n", ret, gnutls_strerror(ret)); success("issuer dn: %s\n", dn); } gnutls_pkcs12_deinit(pkcs12); gnutls_x509_privkey_deinit(pkey); for (i = 0; i < chain_size; i++) gnutls_x509_crt_deinit(chain[i]); gnutls_free(chain); for (i = 0; i < extras_size; i++) gnutls_x509_crt_deinit(extras[i]); gnutls_free(extras); /* Try gnutls_x509_privkey_import2() */ ret = gnutls_x509_privkey_init(&pkey); if (ret < 0) fail("gnutls_x509_privkey_init failed %d: %s\n", ret, gnutls_strerror(ret)); ret = gnutls_x509_privkey_import2(pkey, &data, GNUTLS_X509_FMT_DER, password, 0); if (ret < 0) fail("gnutls_x509_privkey_import2 failed %d: %s\n", ret, gnutls_strerror(ret)); gnutls_x509_privkey_deinit(pkey); free(data.data); gnutls_global_deinit(); #else exit(77); #endif }
static void server_initiated_handshake(void) { /* 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; unsigned char buffer[64]; int cret = GNUTLS_E_AGAIN; size_t transferred = 0; success("testing server initiated re-handshake\n"); /* General init. */ 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:-VERS-TLS-ALL:+VERS-TLS1.3", NULL); 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_certificate_allocate_credentials(&clientx509cred); gnutls_init(&client, GNUTLS_CLIENT); gnutls_credentials_set(client, GNUTLS_CRD_CERTIFICATE, clientx509cred); gnutls_priority_set_direct(client, "NORMAL:+VERS-TLS1.3", NULL); gnutls_transport_set_push_function(client, client_push); gnutls_transport_set_pull_function(client, client_pull); gnutls_transport_set_ptr(client, client); HANDSHAKE(client, server); if (gnutls_protocol_get_version(client) != GNUTLS_TLS1_3) fail("TLS1.3 was not negotiated\n"); 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); /* in TLS1.2 we get REHANDSHAKE error, here nothing */ if (n != GNUTLS_E_AGAIN) { fail("error msg: %s\n", gnutls_strerror(n)); } } TRANSFER(client, server, "xxxx", 4, buffer, sizeof(buffer)); 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(); reset_buffers(); }
static void server(int fd, const char *prio, unsigned etm) { int ret; char buffer[MAX_BUF + 1]; gnutls_session_t session; gnutls_anon_server_credentials_t anoncred; gnutls_certificate_credentials_t x509_cred; unsigned to_send = sizeof(buffer)/4; /* 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); } gnutls_certificate_allocate_credentials(&x509_cred); gnutls_certificate_set_x509_key_mem(x509_cred, &server_cert, &server_key, GNUTLS_X509_FMT_PEM); gnutls_anon_allocate_server_credentials(&anoncred); gnutls_init(&session, GNUTLS_SERVER); /* avoid calling all the priority functions, since the defaults * are adequate. */ gnutls_priority_set_direct(session, prio, NULL); gnutls_credentials_set(session, GNUTLS_CRD_ANON, anoncred); 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 (etm != 0 && gnutls_session_etm_status(session) == 0) { fail("server: EtM was not negotiated with %s!\n", prio); exit(1); } else if (etm == 0 && gnutls_session_etm_status(session) != 0) { fail("server: EtM was negotiated with %s!\n", prio); exit(1); } 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))); do { do { ret = gnutls_record_send(session, buffer, sizeof(buffer)); } while (ret == GNUTLS_E_AGAIN || ret == GNUTLS_E_INTERRUPTED); if (ret < 0) { fail("Error sending %d byte packet: %s\n", to_send, gnutls_strerror(ret)); terminate(); } to_send++; } while (to_send < 64); to_send = -1; /* do not wait for the peer to close the connection. */ gnutls_bye(session, GNUTLS_SHUT_WR); close(fd); gnutls_deinit(session); gnutls_anon_free_server_credentials(anoncred); gnutls_certificate_free_credentials(x509_cred); gnutls_global_deinit(); if (debug) success("server: finished\n"); }
static void client(int fd) { int ret; char buffer[MAX_BUF + 1]; gnutls_anon_client_credentials_t anoncred; gnutls_session_t session; /* Need to enable anonymous KX specifically. */ global_init(); if (debug) { gnutls_global_set_log_function(client_log_func); gnutls_global_set_log_level(4711); } gnutls_anon_allocate_client_credentials(&anoncred); /* Initialize TLS session */ gnutls_init(&session, GNUTLS_CLIENT | GNUTLS_DATAGRAM); gnutls_dtls_set_mtu(session, 1500); gnutls_handshake_set_timeout(session, 20 * 1000); /* Use default priorities */ gnutls_priority_set_direct(session, "NONE:+VERS-DTLS-ALL:+CIPHER-ALL:+MAC-ALL:+SIGN-ALL:+COMP-ALL:+ANON-ECDH:+CURVE-ALL", NULL); /* put the anonymous credentials to the current session */ gnutls_credentials_set(session, GNUTLS_CRD_ANON, anoncred); gnutls_transport_set_int(session, fd); gnutls_transport_set_push_function(session, push); /* Perform the TLS handshake */ do { ret = gnutls_handshake(session); } while (ret < 0 && gnutls_error_is_fatal(ret) == 0); if (ret < 0) { fail("client: Handshake failed\n"); gnutls_perror(ret); exit(1); } else { if (debug) success("client: Handshake was completed\n"); } if (debug) success("client: TLS version is: %s\n", gnutls_protocol_get_name (gnutls_protocol_get_version(session))); do { ret = gnutls_record_recv(session, buffer, MAX_BUF); } while (ret == GNUTLS_E_AGAIN || ret == GNUTLS_E_INTERRUPTED); if (ret == 0) { if (debug) success ("client: Peer has closed the TLS connection\n"); goto end; } else if (ret < 0) { fail("client: Error: %s\n", gnutls_strerror(ret)); exit(1); } gnutls_bye(session, GNUTLS_SHUT_WR); end: close(fd); gnutls_deinit(session); gnutls_anon_free_client_credentials(anoncred); gnutls_global_deinit(); }
static void cipher_bench (int algo, int size) { int ret; gnutls_cipher_hd_t ctx; void *_key, *_iv; gnutls_datum_t key, iv; struct timespec start, stop; double secs; double data_size = 0; double dspeed, ddata; int blocksize = gnutls_cipher_get_block_size (algo); int keysize = gnutls_cipher_get_key_size (algo); char metric[16]; _key = malloc (keysize); if (_key == NULL) return; memset (_key, 0xf0, keysize); _iv = malloc (blocksize); if (_iv == NULL) return; memset (_iv, 0xf0, blocksize); iv.data = _iv; iv.size = blocksize; key.data = _key; key.size = keysize; printf ("Checking %s (%dkb payload)... ", gnutls_cipher_get_name (algo), size); fflush (stdout); must_finish = 0; alarm (5); gettime (&start); ret = gnutls_cipher_init (&ctx, algo, &key, &iv); if (ret < 0) { fprintf (stderr, "error: %s\n", gnutls_strerror (ret)); goto leave; } do { gnutls_cipher_encrypt (ctx, data, size * 1024); data_size += size * 1024; } while (must_finish == 0); gnutls_cipher_deinit (ctx); gettime (&stop); secs = (stop.tv_sec * 1000 + stop.tv_nsec / (1000 * 1000) - (start.tv_sec * 1000 + start.tv_nsec / (1000 * 1000))); secs /= 1000; value2human (data_size, secs, &ddata, &dspeed, metric); printf ("Encrypted %.2f %s in %.2f secs: ", ddata, metric, secs); printf ("%.2f %s/sec\n", dspeed, metric); leave: free (_key); free (_iv); }
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); gnutls_session_set_finished_function (server, server_finished_callback); /* 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); gnutls_session_set_finished_function (client, client_finished_callback); 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 int /* O - 1 on success, 0 on failure */ make_certificate(cupsd_client_t *con) /* I - Client connection */ { gnutls_x509_crt crt; /* Self-signed certificate */ gnutls_x509_privkey key; /* Encryption key */ cups_lang_t *language; /* Default language info */ cups_file_t *fp; /* Key/cert file */ unsigned char buffer[8192]; /* Buffer for x509 data */ size_t bytes; /* Number of bytes of data */ unsigned char serial[4]; /* Serial number buffer */ time_t curtime; /* Current time */ int result; /* Result of GNU TLS calls */ /* * Create the encryption key... */ cupsdLogMessage(CUPSD_LOG_INFO, "Generating SSL server key..."); gnutls_x509_privkey_init(&key); gnutls_x509_privkey_generate(key, GNUTLS_PK_RSA, 2048, 0); /* * Save it... */ bytes = sizeof(buffer); if ((result = gnutls_x509_privkey_export(key, GNUTLS_X509_FMT_PEM, buffer, &bytes)) < 0) { cupsdLogMessage(CUPSD_LOG_ERROR, "Unable to export SSL server key - %s", gnutls_strerror(result)); gnutls_x509_privkey_deinit(key); return (0); } else if ((fp = cupsFileOpen(ServerKey, "w")) != NULL) { cupsFileWrite(fp, (char *)buffer, bytes); cupsFileClose(fp); cupsdLogMessage(CUPSD_LOG_INFO, "Created SSL server key file \"%s\"...", ServerKey); } else { cupsdLogMessage(CUPSD_LOG_ERROR, "Unable to create SSL server key file \"%s\" - %s", ServerKey, strerror(errno)); gnutls_x509_privkey_deinit(key); return (0); } /* * Create the self-signed certificate... */ cupsdLogMessage(CUPSD_LOG_INFO, "Generating self-signed SSL certificate..."); language = cupsLangDefault(); curtime = time(NULL); serial[0] = curtime >> 24; serial[1] = curtime >> 16; serial[2] = curtime >> 8; serial[3] = curtime; gnutls_x509_crt_init(&crt); if (strlen(language->language) == 5) gnutls_x509_crt_set_dn_by_oid(crt, GNUTLS_OID_X520_COUNTRY_NAME, 0, language->language + 3, 2); else gnutls_x509_crt_set_dn_by_oid(crt, GNUTLS_OID_X520_COUNTRY_NAME, 0, "US", 2); gnutls_x509_crt_set_dn_by_oid(crt, GNUTLS_OID_X520_COMMON_NAME, 0, ServerName, strlen(ServerName)); gnutls_x509_crt_set_dn_by_oid(crt, GNUTLS_OID_X520_ORGANIZATION_NAME, 0, ServerName, strlen(ServerName)); gnutls_x509_crt_set_dn_by_oid(crt, GNUTLS_OID_X520_ORGANIZATIONAL_UNIT_NAME, 0, "Unknown", 7); gnutls_x509_crt_set_dn_by_oid(crt, GNUTLS_OID_X520_STATE_OR_PROVINCE_NAME, 0, "Unknown", 7); gnutls_x509_crt_set_dn_by_oid(crt, GNUTLS_OID_X520_LOCALITY_NAME, 0, "Unknown", 7); gnutls_x509_crt_set_dn_by_oid(crt, GNUTLS_OID_PKCS9_EMAIL, 0, ServerAdmin, strlen(ServerAdmin)); gnutls_x509_crt_set_key(crt, key); gnutls_x509_crt_set_serial(crt, serial, sizeof(serial)); gnutls_x509_crt_set_activation_time(crt, curtime); gnutls_x509_crt_set_expiration_time(crt, curtime + 10 * 365 * 86400); gnutls_x509_crt_set_ca_status(crt, 0); gnutls_x509_crt_set_subject_alternative_name(crt, GNUTLS_SAN_DNSNAME, ServerName); gnutls_x509_crt_set_key_purpose_oid(crt, GNUTLS_KP_TLS_WWW_SERVER, 0); gnutls_x509_crt_set_key_usage(crt, GNUTLS_KEY_KEY_ENCIPHERMENT); gnutls_x509_crt_set_version(crt, 3); bytes = sizeof(buffer); if (gnutls_x509_crt_get_key_id(crt, 0, buffer, &bytes) >= 0) gnutls_x509_crt_set_subject_key_id(crt, buffer, bytes); gnutls_x509_crt_sign(crt, crt, key); /* * Save it... */ bytes = sizeof(buffer); if ((result = gnutls_x509_crt_export(crt, GNUTLS_X509_FMT_PEM, buffer, &bytes)) < 0) cupsdLogMessage(CUPSD_LOG_ERROR, "Unable to export SSL server certificate - %s", gnutls_strerror(result)); else if ((fp = cupsFileOpen(ServerCertificate, "w")) != NULL) { cupsFileWrite(fp, (char *)buffer, bytes); cupsFileClose(fp); cupsdLogMessage(CUPSD_LOG_INFO, "Created SSL server certificate file \"%s\"...", ServerCertificate); } else cupsdLogMessage(CUPSD_LOG_ERROR, "Unable to create SSL server certificate file \"%s\" - %s", ServerCertificate, strerror(errno)); /* * Cleanup... */ gnutls_x509_crt_deinit(crt); gnutls_x509_privkey_deinit(key); return (1); }
int /* O - 1 on success, 0 on error */ cupsdStartTLS(cupsd_client_t *con) /* I - Client connection */ { int status; /* Error code */ gnutls_certificate_server_credentials *credentials; /* TLS credentials */ cupsdLogMessage(CUPSD_LOG_DEBUG, "[Client %d] Encrypting connection.", con->http.fd); /* * Verify that we have a certificate... */ if (access(ServerKey, 0) || access(ServerCertificate, 0)) { /* * Nope, make a self-signed certificate... */ if (!make_certificate(con)) return (0); } /* * Create the SSL object and perform the SSL handshake... */ credentials = (gnutls_certificate_server_credentials *) malloc(sizeof(gnutls_certificate_server_credentials)); if (credentials == NULL) { cupsdLogMessage(CUPSD_LOG_ERROR, "Unable to encrypt connection from %s - %s", con->http.hostname, strerror(errno)); return (0); } gnutls_certificate_allocate_credentials(credentials); gnutls_certificate_set_x509_key_file(*credentials, ServerCertificate, ServerKey, GNUTLS_X509_FMT_PEM); gnutls_init(&con->http.tls, GNUTLS_SERVER); gnutls_set_default_priority(con->http.tls); gnutls_credentials_set(con->http.tls, GNUTLS_CRD_CERTIFICATE, *credentials); gnutls_transport_set_ptr(con->http.tls, (gnutls_transport_ptr)HTTP(con)); gnutls_transport_set_pull_function(con->http.tls, _httpReadGNUTLS); gnutls_transport_set_push_function(con->http.tls, _httpWriteGNUTLS); while ((status = gnutls_handshake(con->http.tls)) != GNUTLS_E_SUCCESS) { if (gnutls_error_is_fatal(status)) { cupsdLogMessage(CUPSD_LOG_ERROR, "Unable to encrypt connection from %s - %s", con->http.hostname, gnutls_strerror(status)); gnutls_deinit(con->http.tls); gnutls_certificate_free_credentials(*credentials); con->http.tls = NULL; free(credentials); return (0); } } cupsdLogMessage(CUPSD_LOG_DEBUG, "Connection from %s now encrypted.", con->http.hostname); con->http.tls_credentials = credentials; return (1); }
TDSRET tds_ssl_init(TDSSOCKET *tds) { gnutls_session_t session; gnutls_certificate_credentials_t xcred; int ret; const char *tls_msg; xcred = NULL; session = NULL; tls_msg = "initializing tls"; if (!tls_initialized) { ret = 0; tds_mutex_lock(&tls_mutex); if (!tls_initialized) { tds_gcry_init(); ret = gnutls_global_init(); if (ret == 0) tls_initialized = 1; } tds_mutex_unlock(&tls_mutex); if (ret != 0) goto cleanup; } if (tds_write_dump && tls_initialized < 2) { gnutls_global_set_log_level(11); gnutls_global_set_log_function(tds_tls_log); tls_initialized = 2; } tls_msg = "allocating credentials"; ret = gnutls_certificate_allocate_credentials(&xcred); if (ret != 0) goto cleanup; if (!tds_dstr_isempty(&tds->login->cafile)) { tls_msg = "loading CA file"; if (strcasecmp(tds_dstr_cstr(&tds->login->cafile), "system") == 0) ret = gnutls_certificate_set_x509_system_trust(xcred); else ret = gnutls_certificate_set_x509_trust_file(xcred, tds_dstr_cstr(&tds->login->cafile), GNUTLS_X509_FMT_PEM); if (ret <= 0) goto cleanup; if (!tds_dstr_isempty(&tds->login->crlfile)) { tls_msg = "loading CRL file"; ret = gnutls_certificate_set_x509_crl_file(xcred, tds_dstr_cstr(&tds->login->crlfile), GNUTLS_X509_FMT_PEM); if (ret <= 0) goto cleanup; } gnutls_certificate_set_verify_function(xcred, tds_verify_certificate); } /* Initialize TLS session */ tls_msg = "initializing session"; ret = gnutls_init(&session, GNUTLS_CLIENT); if (ret != 0) goto cleanup; gnutls_transport_set_ptr(session, tds); gnutls_transport_set_pull_function(session, tds_pull_func_login); gnutls_transport_set_push_function(session, tds_push_func_login); /* NOTE: there functions return int however they cannot fail */ /* use default priorities... */ gnutls_set_default_priority(session); /* ... but overwrite some */ ret = gnutls_priority_set_direct (session, "NORMAL:%COMPAT:-VERS-SSL3.0", NULL); if (ret != 0) goto cleanup; /* mssql does not like padding too much */ #ifdef HAVE_GNUTLS_RECORD_DISABLE_PADDING gnutls_record_disable_padding(session); #endif /* put the anonymous credentials to the current session */ tls_msg = "setting credential"; ret = gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, xcred); if (ret != 0) goto cleanup; /* Perform the TLS handshake */ tls_msg = "handshake"; ret = gnutls_handshake (session); if (ret != 0) goto cleanup; tdsdump_log(TDS_DBG_INFO1, "handshake succeeded!!\n"); gnutls_transport_set_ptr(session, tds->conn); gnutls_transport_set_pull_function(session, tds_pull_func); gnutls_transport_set_push_function(session, tds_push_func); tds->conn->tls_session = session; tds->conn->tls_credentials = xcred; return TDS_SUCCESS; cleanup: if (session) gnutls_deinit(session); if (xcred) gnutls_certificate_free_credentials(xcred); tdsdump_log(TDS_DBG_ERROR, "%s failed: %s\n", tls_msg, gnutls_strerror (ret)); return TDS_FAIL; }
static int tds_verify_certificate(gnutls_session_t session) { unsigned int status; int ret; TDSSOCKET *tds = (TDSSOCKET *) gnutls_transport_get_ptr(session); #ifdef ENABLE_DEVELOPING unsigned int list_size; const gnutls_datum_t *cert_list; #endif if (!tds->login) return GNUTLS_E_CERTIFICATE_ERROR; ret = gnutls_certificate_verify_peers2(session, &status); if (ret < 0) { tdsdump_log(TDS_DBG_ERROR, "Error verifying certificate: %s\n", gnutls_strerror(ret)); return GNUTLS_E_CERTIFICATE_ERROR; } #ifdef ENABLE_DEVELOPING cert_list = gnutls_certificate_get_peers(session, &list_size); if (cert_list) { gnutls_x509_crt_t cert; gnutls_datum_t cinfo; char buf[8192]; size_t size; gnutls_x509_crt_init(&cert); gnutls_x509_crt_import(cert, &cert_list[0], GNUTLS_X509_FMT_DER); /* This is the preferred way of printing short information about * a certificate. */ size = sizeof(buf); ret = gnutls_x509_crt_export(cert, GNUTLS_X509_FMT_PEM, buf, &size); if (ret == 0) { FILE *f = fopen("cert.dat", "wb"); if (f) { fwrite(buf, size, 1, f); fclose(f); } } ret = gnutls_x509_crt_print(cert, GNUTLS_CRT_PRINT_ONELINE, &cinfo); if (ret == 0) { tdsdump_log(TDS_DBG_INFO1, "Certificate info: %s\n", cinfo.data); gnutls_free(cinfo.data); } gnutls_x509_crt_deinit(cert); } #endif /* Certificate is not trusted */ if (status != 0) { tdsdump_log(TDS_DBG_ERROR, "Certificate status: %u\n", status); return GNUTLS_E_CERTIFICATE_ERROR; } /* check hostname */ if (tds->login->check_ssl_hostname) { const gnutls_datum_t *cert_list; unsigned int list_size; gnutls_x509_crt_t cert; cert_list = gnutls_certificate_get_peers(session, &list_size); if (!cert_list) { tdsdump_log(TDS_DBG_ERROR, "Error getting TLS session peers\n"); return GNUTLS_E_CERTIFICATE_ERROR; } gnutls_x509_crt_init(&cert); gnutls_x509_crt_import(cert, &cert_list[0], GNUTLS_X509_FMT_DER); ret = gnutls_x509_crt_check_hostname(cert, tds_dstr_cstr(&tds->login->server_host_name)); gnutls_x509_crt_deinit(cert); if (!ret) { tdsdump_log(TDS_DBG_ERROR, "Certificate hostname does not match\n"); return GNUTLS_E_CERTIFICATE_ERROR; } } /* notify gnutls to continue handshake normally */ return 0; }
int ssl_open(http_t *client, char *msg) { int ret; char buf[256]; size_t len; const char *sn, *err; const gnutls_datum_t *cert_list; unsigned int cert_list_size = 0; gnutls_x509_crt_t cert; if (!client->ssl_enabled) return tcp_init(&client->tcp, msg); /* Initialize TLS session */ logit(LOG_INFO, "%s, initiating HTTPS ...", msg); gnutls_init(&client->ssl, GNUTLS_CLIENT); /* SSL SNI support: tell the servername we want to speak to */ http_get_remote_name(client, &sn); gnutls_session_set_ptr(client->ssl, (void *)sn); if (gnutls_server_name_set(client->ssl, GNUTLS_NAME_DNS, sn, strlen(sn))) return RC_HTTPS_SNI_ERROR; /* Use default priorities */ ret = gnutls_priority_set_direct(client->ssl, "NORMAL", &err); if (ret < 0) { if (ret == GNUTLS_E_INVALID_REQUEST) logit(LOG_ERR, "Syntax error at: %s", err); return RC_HTTPS_INVALID_REQUEST; } /* put the x509 credentials to the current session */ gnutls_credentials_set(client->ssl, GNUTLS_CRD_CERTIFICATE, xcred); /* connect to the peer */ tcp_set_port(&client->tcp, HTTPS_DEFAULT_PORT); DO(tcp_init(&client->tcp, msg)); /* Forward TCP socket to GnuTLS, the set_int() API is perhaps too new still ... since 3.1.9 */ // gnutls_transport_set_int(client->ssl, client->tcp.ip.socket); gnutls_transport_set_ptr(client->ssl, (gnutls_transport_ptr_t)(intptr_t)client->tcp.ip.socket); /* Perform the TLS handshake, ignore non-fatal errors. */ do { ret = gnutls_handshake(client->ssl); } while (ret != 0 && !gnutls_error_is_fatal(ret)); if (gnutls_error_is_fatal(ret)) { logit(LOG_ERR, "SSL handshake with %s failed: %s", sn, gnutls_strerror(ret)); return RC_HTTPS_FAILED_CONNECT; } ssl_get_info(client); /* Get server's certificate (note: beware of dynamic allocation) - opt */ cert_list = gnutls_certificate_get_peers(client->ssl, &cert_list_size); if (cert_list_size > 0) { if (gnutls_x509_crt_init(&cert)) return RC_HTTPS_FAILED_GETTING_CERT; gnutls_x509_crt_import(cert, &cert_list[0], GNUTLS_X509_FMT_DER); len = sizeof(buf); gnutls_x509_crt_get_dn(cert, buf, &len); logit(LOG_INFO, "SSL server cert subject: %s", buf); len = sizeof(buf); gnutls_x509_crt_get_issuer_dn(cert, buf, &len); logit(LOG_INFO, "SSL server cert issuer: %s", buf); gnutls_x509_crt_deinit(cert); } return 0; }
static void test_ciphersuite_kx(const char *cipher_prio, unsigned pk) { /* Server stuff. */ gnutls_anon_server_credentials_t s_anoncred; gnutls_session_t server; int sret, cret; const char *str; char *suite = NULL; /* Client stuff. */ gnutls_anon_client_credentials_t c_anoncred; gnutls_certificate_credentials_t c_certcred, s_certcred; gnutls_session_t client; /* Need to enable anonymous KX specifically. */ int ret; struct benchmark_st st; struct timespec tr_start, tr_stop; double avg, sstddev; gnutls_priority_t priority_cache; total_diffs_size = 0; /* Init server */ gnutls_certificate_allocate_credentials(&s_certcred); gnutls_anon_allocate_server_credentials(&s_anoncred); ret = 0; if (pk == GNUTLS_PK_RSA_PSS) ret = gnutls_certificate_set_x509_key_mem(s_certcred, &server_rsa_pss_cert, &server_key, GNUTLS_X509_FMT_PEM); else if (pk == GNUTLS_PK_RSA) ret = gnutls_certificate_set_x509_key_mem(s_certcred, &server_cert, &server_key, GNUTLS_X509_FMT_PEM); if (ret < 0) { fprintf(stderr, "Error in %d: %s\n", __LINE__, gnutls_strerror(ret)); exit(1); } ret = 0; if (pk == GNUTLS_PK_ECDSA) ret = gnutls_certificate_set_x509_key_mem(s_certcred, &server_ecc_cert, &server_ecc_key, GNUTLS_X509_FMT_PEM); else if (pk == GNUTLS_PK_EDDSA_ED25519) ret = gnutls_certificate_set_x509_key_mem(s_certcred, &server_ed25519_cert, &server_ed25519_key, GNUTLS_X509_FMT_PEM); if (ret < 0) { fprintf(stderr, "Error in %d: %s\n", __LINE__, gnutls_strerror(ret)); exit(1); } /* Init client */ gnutls_anon_allocate_client_credentials(&c_anoncred); gnutls_certificate_allocate_credentials(&c_certcred); start_benchmark(&st); ret = gnutls_priority_init(&priority_cache, cipher_prio, &str); if (ret < 0) { fprintf(stderr, "Error in %s\n", str); exit(1); } do { gnutls_init(&server, GNUTLS_SERVER); ret = gnutls_priority_set(server, priority_cache); if (ret < 0) { fprintf(stderr, "Error in setting priority: %s\n", gnutls_strerror(ret)); exit(1); } gnutls_credentials_set(server, GNUTLS_CRD_ANON, s_anoncred); gnutls_credentials_set(server, GNUTLS_CRD_CERTIFICATE, s_certcred); 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); reset_buffers(); gnutls_init(&client, GNUTLS_CLIENT); ret = gnutls_priority_set(client, priority_cache); if (ret < 0) { fprintf(stderr, "Error in setting priority: %s\n", gnutls_strerror(ret)); exit(1); } gnutls_credentials_set(client, GNUTLS_CRD_ANON, c_anoncred); gnutls_credentials_set(client, GNUTLS_CRD_CERTIFICATE, c_certcred); 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); gettime(&tr_start); HANDSHAKE(client, server); gettime(&tr_stop); if (suite == NULL) suite = gnutls_session_get_desc(server); gnutls_deinit(client); gnutls_deinit(server); total_diffs[total_diffs_size++] = timespec_sub_ms(&tr_stop, &tr_start); if (total_diffs_size > sizeof(total_diffs)/sizeof(total_diffs[0])) abort(); st.size += 1; } while (benchmark_must_finish == 0); fprintf(stdout, "%38s ", suite); gnutls_free(suite); stop_benchmark(&st, "transactions", 1); gnutls_priority_deinit(priority_cache); avg = calc_avg(total_diffs, total_diffs_size); sstddev = calc_sstdev(total_diffs, total_diffs_size, avg); printf("%32s %.2f ms, sample variance: %.2f)\n", "(avg. handshake time:", avg, sstddev); gnutls_anon_free_client_credentials(c_anoncred); gnutls_anon_free_server_credentials(s_anoncred); }
void VerifyCertificate() { unsigned int certstatus; const gnutls_datum_t* cert_list; int ret; unsigned int cert_list_size; gnutls_x509_crt_t cert; char str[512]; unsigned char digest[512]; size_t digest_size = sizeof(digest); size_t name_size = sizeof(str); ssl_cert* certinfo = new ssl_cert; this->certificate = certinfo; /* This verification function uses the trusted CAs in the credentials * structure. So you must have installed one or more CA certificates. */ ret = gnutls_certificate_verify_peers2(this->sess, &certstatus); if (ret < 0) { certinfo->error = std::string(gnutls_strerror(ret)); return; } certinfo->invalid = (certstatus & GNUTLS_CERT_INVALID); certinfo->unknownsigner = (certstatus & GNUTLS_CERT_SIGNER_NOT_FOUND); certinfo->revoked = (certstatus & GNUTLS_CERT_REVOKED); certinfo->trusted = !(certstatus & GNUTLS_CERT_SIGNER_NOT_CA); /* Up to here the process is the same for X.509 certificates and * OpenPGP keys. From now on X.509 certificates are assumed. This can * be easily extended to work with openpgp keys as well. */ if (gnutls_certificate_type_get(this->sess) != GNUTLS_CRT_X509) { certinfo->error = "No X509 keys sent"; return; } ret = gnutls_x509_crt_init(&cert); if (ret < 0) { certinfo->error = gnutls_strerror(ret); return; } cert_list_size = 0; cert_list = gnutls_certificate_get_peers(this->sess, &cert_list_size); if (cert_list == NULL) { certinfo->error = "No certificate was found"; goto info_done_dealloc; } /* This is not a real world example, since we only check the first * certificate in the given chain. */ ret = gnutls_x509_crt_import(cert, &cert_list[0], GNUTLS_X509_FMT_DER); if (ret < 0) { certinfo->error = gnutls_strerror(ret); goto info_done_dealloc; } if (gnutls_x509_crt_get_dn(cert, str, &name_size) == 0) { std::string& dn = certinfo->dn; dn = str; // Make sure there are no chars in the string that we consider invalid if (dn.find_first_of("\r\n") != std::string::npos) dn.clear(); } name_size = sizeof(str); if (gnutls_x509_crt_get_issuer_dn(cert, str, &name_size) == 0) { std::string& issuer = certinfo->issuer; issuer = str; if (issuer.find_first_of("\r\n") != std::string::npos) issuer.clear(); } if ((ret = gnutls_x509_crt_get_fingerprint(cert, profile->GetHash(), digest, &digest_size)) < 0) { certinfo->error = gnutls_strerror(ret); } else { certinfo->fingerprint = BinToHex(digest, digest_size); } /* Beware here we do not check for errors. */ if ((gnutls_x509_crt_get_expiration_time(cert) < ServerInstance->Time()) || (gnutls_x509_crt_get_activation_time(cert) > ServerInstance->Time())) { certinfo->error = "Not activated, or expired certificate"; } info_done_dealloc: gnutls_x509_crt_deinit(cert); }
static void client(int fd, const char *prio, unsigned etm) { int ret; char buffer[MAX_BUF + 1]; gnutls_anon_client_credentials_t anoncred; gnutls_certificate_credentials_t x509_cred; gnutls_session_t session; /* Need to enable anonymous KX specifically. */ global_init(); if (debug) { gnutls_global_set_log_function(client_log_func); gnutls_global_set_log_level(7); } gnutls_anon_allocate_client_credentials(&anoncred); gnutls_certificate_allocate_credentials(&x509_cred); /* Initialize TLS session */ gnutls_init(&session, GNUTLS_CLIENT); /* Use default priorities */ gnutls_priority_set_direct(session, prio, NULL); /* put the anonymous credentials to the current session */ gnutls_credentials_set(session, GNUTLS_CRD_ANON, anoncred); gnutls_credentials_set(session, GNUTLS_CRD_CERTIFICATE, x509_cred); gnutls_transport_set_int(session, fd); /* Perform the TLS handshake */ do { ret = gnutls_handshake(session); } while (ret < 0 && gnutls_error_is_fatal(ret) == 0); if (ret < 0) { fail("client: Handshake failed\n"); gnutls_perror(ret); exit(1); } else { if (debug) success("client: Handshake was completed\n"); } if (debug) success("client: TLS version is: %s\n", gnutls_protocol_get_name (gnutls_protocol_get_version(session))); if (etm != 0 && gnutls_session_etm_status(session) == 0) { fail("server: EtM was not negotiated with %s!\n", prio); exit(1); } else if (etm == 0 && gnutls_session_etm_status(session) != 0) { fail("server: EtM was negotiated with %s!\n", prio); exit(1); } do { do { ret = gnutls_record_recv(session, buffer, MAX_BUF); } while (ret == GNUTLS_E_AGAIN || ret == GNUTLS_E_INTERRUPTED); } while (ret > 0); if (ret == 0) { if (debug) success ("client: Peer has closed the TLS connection\n"); goto end; } else if (ret < 0) { if (ret != 0) { fail("client: Error: %s\n", gnutls_strerror(ret)); exit(1); } } gnutls_bye(session, GNUTLS_SHUT_WR); end: close(fd); gnutls_deinit(session); gnutls_anon_free_client_credentials(anoncred); gnutls_certificate_free_credentials(x509_cred); gnutls_global_deinit(); }
int main (int argc, char **argv) { gaainfo info; int ret; struct passwd *pwd; unsigned char key[MAX_KEY_SIZE]; char hex_key[MAX_KEY_SIZE * 2 + 1]; gnutls_datum_t dkey; size_t hex_key_size = sizeof (hex_key); set_program_name (argv[0]); if ((ret = gnutls_global_init ()) < 0) { fprintf (stderr, "global_init: %s\n", gnutls_strerror (ret)); exit (1); } umask (066); if (gaa (argc, argv, &info) != -1) { fprintf (stderr, "Error in the arguments.\n"); return -1; } if (info.passwd == NULL) info.passwd = (char *) KPASSWD; if (info.username == NULL) { #ifndef _WIN32 pwd = getpwuid (getuid ()); if (pwd == NULL) { fprintf (stderr, "No such user\n"); return -1; } info.username = pwd->pw_name; #else fprintf (stderr, "Please specify a user\n"); return -1; #endif } if (info.key_size > MAX_KEY_SIZE) { fprintf (stderr, "Key size is too long\n"); exit (1); } if (info.key_size < 1) info.key_size = 16; printf ("Generating a random key for user '%s'\n", info.username); ret = gnutls_rnd (GNUTLS_RND_RANDOM, (char *) key, info.key_size); if (ret < 0) { fprintf (stderr, "Not enough randomness\n"); exit (1); } dkey.data = key; dkey.size = info.key_size; ret = gnutls_hex_encode (&dkey, hex_key, &hex_key_size); if (ret < 0) { fprintf (stderr, "HEX encoding error\n"); exit (1); } ret = write_key (info.username, hex_key, hex_key_size, info.passwd); if (ret == 0) printf ("Key stored to %s\n", info.passwd); return ret; }
static void server(int fd) { int ret, csend = 0; gnutls_anon_server_credentials_t anoncred; char buffer[MAX_BUF + 1]; gnutls_datum_t cookie_key; gnutls_dtls_prestate_st prestate; gnutls_session_t session; /* this must be called once in the program */ global_init(); if (debug) { gnutls_global_set_log_function(server_log_func); gnutls_global_set_log_level(4711); } ret = gnutls_key_generate(&cookie_key, GNUTLS_COOKIE_KEY_SIZE); if (ret < 0) { fail("Cannot generate key: %s\n", gnutls_strerror(ret)); terminate(); } gnutls_anon_allocate_server_credentials(&anoncred); gnutls_init(&session, GNUTLS_SERVER | GNUTLS_DATAGRAM); gnutls_handshake_set_timeout(session, 20 * 1000); gnutls_dtls_set_mtu(session, 1500); /* avoid calling all the priority functions, since the defaults * are adequate. */ gnutls_priority_set_direct(session, "NONE:+VERS-DTLS1.0:+CIPHER-ALL:+MAC-ALL:+SIGN-ALL:+COMP-ALL:+ANON-ECDH:+CURVE-ALL", NULL); gnutls_credentials_set(session, GNUTLS_CRD_ANON, anoncred); gnutls_transport_set_int(session, fd); gnutls_transport_set_push_function(session, push); for (;;) { ret = recv(fd, buffer, sizeof(buffer), MSG_PEEK); if (ret < 0) { fail("Cannot receive data\n"); terminate(); } memset(&prestate, 0, sizeof(prestate)); ret = gnutls_dtls_cookie_verify(&cookie_key, CLI_ADDR, CLI_ADDR_LEN, buffer, ret, &prestate); if (ret < 0) { /* cookie not valid */ if (debug) success("Sending hello verify request\n"); ret = gnutls_dtls_cookie_send(&cookie_key, CLI_ADDR, CLI_ADDR_LEN, &prestate, (gnutls_transport_ptr_t) (long) fd, push); if (ret < 0) { fail("Cannot send data\n"); terminate(); } /* discard peeked data */ recv(fd, buffer, sizeof(buffer), 0); csend++; if (csend > 2) { fail("too many cookies sent\n"); terminate(); } continue; } /* success */ break; } gnutls_dtls_prestate_set(session, &prestate); do { ret = gnutls_handshake(session); } while (ret < 0 && gnutls_error_is_fatal(ret) == 0); if (ret < 0) { close(fd); gnutls_deinit(session); fail("server: Handshake has failed (%s)\n\n", gnutls_strerror(ret)); terminate(); } if (debug) success("server: Handshake was completed\n"); if (debug) success("server: TLS version is: %s\n", gnutls_protocol_get_name (gnutls_protocol_get_version(session))); /* see the Getting peer's information example */ /* print_info(session); */ do { ret = gnutls_record_send(session, buffer, sizeof(buffer)); } while (ret == GNUTLS_E_AGAIN || ret == GNUTLS_E_INTERRUPTED); if (ret < 0) { close(fd); gnutls_deinit(session); fail("server: data sending has failed (%s)\n\n", gnutls_strerror(ret)); terminate(); } /* do not wait for the peer to close the connection. */ gnutls_bye(session, GNUTLS_SHUT_WR); close(fd); gnutls_deinit(session); gnutls_anon_free_server_credentials(anoncred); gnutls_free(cookie_key.data); gnutls_global_deinit(); if (debug) success("server: finished\n"); }
void TLSClient::connect (const std::string& host, const std::string& port) { // Store the host name, so the verification callback can access it during the // handshake below. gnutls_session_set_ptr (_session, (void*) host.c_str ()); // use IPv4 or IPv6, does not matter. struct addrinfo hints = {0}; hints.ai_family = AF_UNSPEC; hints.ai_socktype = SOCK_STREAM; hints.ai_flags = AI_PASSIVE; // use my IP struct addrinfo* res; if (::getaddrinfo (host.c_str (), port.c_str (), &hints, &res) != 0) throw std::string (::gai_strerror (errno)); // Try them all, stop on success. struct addrinfo* p; for (p = res; p != NULL; p = p->ai_next) { if ((_socket = ::socket (p->ai_family, p->ai_socktype, p->ai_protocol)) == -1) continue; // When a socket is closed, it remains unavailable for a while (netstat -an). // Setting SO_REUSEADDR allows this program to assume control of a closed, // but unavailable socket. int on = 1; if (::setsockopt (_socket, SOL_SOCKET, SO_REUSEADDR, (const void*) &on, sizeof (on)) == -1) throw std::string (::strerror (errno)); if (::connect (_socket, p->ai_addr, p->ai_addrlen) == -1) continue; break; } free (res); if (p == NULL) throw std::string ("Could not connect to ") + host + " " + port; #if GNUTLS_VERSION_NUMBER >= 0x030109 gnutls_transport_set_int (_session, _socket); #else gnutls_transport_set_ptr (_session, (gnutls_transport_ptr_t) (long) _socket); #endif // Perform the TLS handshake int ret; do { ret = gnutls_handshake (_session); } while (ret < 0 && gnutls_error_is_fatal (ret) == 0); if (ret < 0) throw std::string ("Handshake failed. ") + gnutls_strerror (ret); if (_debug) { #if GNUTLS_VERSION_NUMBER >= 0x03010a char* desc = gnutls_session_get_desc (_session); std::cout << "c: INFO Handshake was completed: " << desc << "\n"; gnutls_free (desc); #else std::cout << "c: INFO Handshake was completed.\n"; #endif } }
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_x509_crt_t *crts; unsigned int crts_size; unsigned i; gnutls_x509_privkey_t pkey; /* General init. */ global_init(); gnutls_global_set_log_function(tls_log_func); if (debug) gnutls_global_set_log_level(2); ret = gnutls_x509_crt_list_import2(&crts, &crts_size, &server_cert, GNUTLS_X509_FMT_PEM, GNUTLS_X509_CRT_LIST_FAIL_IF_UNSORTED); if (ret < 0) { fprintf(stderr, "error: %s\n", gnutls_strerror(ret)); exit(1); } ret = gnutls_x509_privkey_init(&pkey); if (ret < 0) { fprintf(stderr, "error: %s\n", gnutls_strerror(ret)); exit(1); } ret = gnutls_x509_privkey_import(pkey, &server_key, GNUTLS_X509_FMT_PEM); if (ret < 0) { fprintf(stderr, "error: %s\n", gnutls_strerror(ret)); exit(1); } /* Init server */ gnutls_certificate_allocate_credentials(&serverx509cred); gnutls_certificate_set_x509_key(serverx509cred, crts, crts_size, pkey); gnutls_x509_privkey_deinit(pkey); for (i=0;i<crts_size;i++) gnutls_x509_crt_deinit(crts[i]); gnutls_free(crts); gnutls_init(&server, GNUTLS_SERVER); gnutls_credentials_set(server, GNUTLS_CRD_CERTIFICATE, serverx509cred); gnutls_priority_set_direct(server, "NORMAL:-CIPHER-ALL:+AES-128-GCM", NULL); gnutls_transport_set_push_function(server, server_push); gnutls_transport_set_pull_function(server, server_pull); gnutls_transport_set_ptr(server, server); gnutls_certificate_server_set_request(server, GNUTLS_CERT_REQUEST); /* Init client */ /* Init client */ ret = gnutls_certificate_allocate_credentials(&clientx509cred); if (ret < 0) exit(1); ret = gnutls_certificate_set_x509_trust_mem(clientx509cred, &ca_cert, GNUTLS_X509_FMT_PEM); if (ret < 0) exit(1); ret = gnutls_certificate_set_x509_key_mem(clientx509cred, &cli_cert, &cli_key, GNUTLS_X509_FMT_PEM); ret = gnutls_init(&client, GNUTLS_CLIENT); if (ret < 0) exit(1); ret = gnutls_credentials_set(client, GNUTLS_CRD_CERTIFICATE, clientx509cred); if (ret < 0) exit(1); 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, client); HANDSHAKE(client, server); /* check gnutls_certificate_get_ours() - server side */ { const gnutls_datum_t *mcert; gnutls_datum_t scert; gnutls_x509_crt_t crt; mcert = gnutls_certificate_get_ours(server); if (mcert == NULL) { fail("gnutls_certificate_get_ours(): failed\n"); exit(1); } gnutls_x509_crt_init(&crt); ret = gnutls_x509_crt_import(crt, &server_cert, GNUTLS_X509_FMT_PEM); if (ret < 0) { fail("gnutls_x509_crt_import: %s\n", gnutls_strerror(ret)); exit(1); } ret = gnutls_x509_crt_export2(crt, GNUTLS_X509_FMT_DER, &scert); if (ret < 0) { fail("gnutls_x509_crt_export2: %s\n", gnutls_strerror(ret)); exit(1); } gnutls_x509_crt_deinit(crt); if (scert.size != mcert->size || memcmp(scert.data, mcert->data, mcert->size) != 0) { fail("gnutls_certificate_get_ours output doesn't match cert\n"); exit(1); } gnutls_free(scert.data); } /* check gnutls_certificate_get_ours() - client side */ { const gnutls_datum_t *mcert; gnutls_datum_t ccert; gnutls_x509_crt_t crt; mcert = gnutls_certificate_get_ours(client); if (mcert == NULL) { fail("gnutls_certificate_get_ours(): failed\n"); exit(1); } gnutls_x509_crt_init(&crt); ret = gnutls_x509_crt_import(crt, &cli_cert, GNUTLS_X509_FMT_PEM); if (ret < 0) { fail("gnutls_x509_crt_import: %s\n", gnutls_strerror(ret)); exit(1); } ret = gnutls_x509_crt_export2(crt, GNUTLS_X509_FMT_DER, &ccert); if (ret < 0) { fail("gnutls_x509_crt_export2: %s\n", gnutls_strerror(ret)); exit(1); } gnutls_x509_crt_deinit(crt); if (ccert.size != mcert->size || memcmp(ccert.data, mcert->data, mcert->size) != 0) { fail("gnutls_certificate_get_ours output doesn't match cert\n"); exit(1); } gnutls_free(ccert.data); } /* check the number of certificates received */ { unsigned cert_list_size = 0; gnutls_typed_vdata_st data[2]; unsigned status; memset(data, 0, sizeof(data)); /* check with wrong hostname */ data[0].type = GNUTLS_DT_DNS_HOSTNAME; data[0].data = (void*)"localhost1"; data[1].type = GNUTLS_DT_KEY_PURPOSE_OID; data[1].data = (void*)GNUTLS_KP_TLS_WWW_SERVER; gnutls_certificate_get_peers(client, &cert_list_size); if (cert_list_size < 2) { fprintf(stderr, "received a certificate list of %d!\n", cert_list_size); exit(1); } ret = gnutls_certificate_verify_peers(client, data, 2, &status); if (ret < 0) { fprintf(stderr, "could not verify certificate: %s\n", gnutls_strerror(ret)); exit(1); } if (status == 0) { fprintf(stderr, "should not have accepted!\n"); exit(1); } /* check with wrong purpose */ data[0].type = GNUTLS_DT_DNS_HOSTNAME; data[0].data = (void*)"localhost"; data[1].type = GNUTLS_DT_KEY_PURPOSE_OID; data[1].data = (void*)GNUTLS_KP_TLS_WWW_CLIENT; gnutls_certificate_get_peers(client, &cert_list_size); if (cert_list_size < 2) { fprintf(stderr, "received a certificate list of %d!\n", cert_list_size); exit(1); } ret = gnutls_certificate_verify_peers(client, data, 2, &status); if (ret < 0) { fprintf(stderr, "could not verify certificate: %s\n", gnutls_strerror(ret)); exit(1); } if (status == 0) { fprintf(stderr, "should not have accepted!\n"); exit(1); } /* check with correct purpose */ data[0].type = GNUTLS_DT_DNS_HOSTNAME; data[0].data = (void*)"localhost"; data[1].type = GNUTLS_DT_KEY_PURPOSE_OID; data[1].data = (void*)GNUTLS_KP_TLS_WWW_SERVER; ret = gnutls_certificate_verify_peers(client, data, 2, &status); if (ret < 0) { fprintf(stderr, "could not verify certificate: %s\n", gnutls_strerror(ret)); exit(1); } if (status != 0) { fprintf(stderr, "could not verify certificate: %.4x\n", status); 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_global_deinit(); if (debug > 0) { if (exit_code == 0) puts("Self-test successful"); else puts("Self-test failed"); } }
void TLSClient::recv (std::string& data) { data = ""; // No appending of data. int received = 0; // Get the encoded length. unsigned char header[4] = {0}; do { received = gnutls_record_recv (_session, header, 4); } while (received > 0 && (errno == GNUTLS_E_INTERRUPTED || errno == GNUTLS_E_AGAIN)); int total = received; // Decode the length. unsigned long expected = (header[0]<<24) | (header[1]<<16) | (header[2]<<8) | header[3]; if (_debug) std::cout << "c: INFO expecting " << expected << " bytes.\n"; // TODO This would be a good place to assert 'expected < _limit'. // Arbitrary buffer size. char buffer[MAX_BUF]; // Keep reading until no more data. Concatenate chunks of data if a) the // read was interrupted by a signal, and b) if there is more data than // fits in the buffer. do { do { received = gnutls_record_recv (_session, buffer, MAX_BUF - 1); } while (received > 0 && (errno == GNUTLS_E_INTERRUPTED || errno == GNUTLS_E_AGAIN)); // Other end closed the connection. if (received == 0) { if (_debug) std::cout << "c: INFO Peer has closed the TLS connection\n"; break; } // Something happened. if (received < 0 && gnutls_error_is_fatal (received) == 0) { if (_debug) std::cout << "c: WARNING " << gnutls_strerror (received) << "\n"; } else if (received < 0) throw std::string (gnutls_strerror (received)); buffer [received] = '\0'; data += buffer; total += received; // Stop at defined limit. if (_limit && total > _limit) break; } while (received > 0 && total < (int) expected); if (_debug) std::cout << "c: INFO Receiving 'XXXX" << data.c_str () << "' (" << total << " bytes)" << std::endl; }
int qcrypto_tls_creds_get_dh_params_file(QCryptoTLSCreds *creds, const char *filename, gnutls_dh_params_t *dh_params, Error **errp) { int ret; trace_qcrypto_tls_creds_load_dh(creds, filename ? filename : "<generated>"); if (filename == NULL) { ret = gnutls_dh_params_init(dh_params); if (ret < 0) { error_setg(errp, "Unable to initialize DH parameters: %s", gnutls_strerror(ret)); return -1; } ret = gnutls_dh_params_generate2(*dh_params, DH_BITS); if (ret < 0) { gnutls_dh_params_deinit(*dh_params); *dh_params = NULL; error_setg(errp, "Unable to generate DH parameters: %s", gnutls_strerror(ret)); return -1; } } else { GError *gerr = NULL; gchar *contents; gsize len; gnutls_datum_t data; if (!g_file_get_contents(filename, &contents, &len, &gerr)) { error_setg(errp, "%s", gerr->message); g_error_free(gerr); return -1; } data.data = (unsigned char *)contents; data.size = len; ret = gnutls_dh_params_init(dh_params); if (ret < 0) { g_free(contents); error_setg(errp, "Unable to initialize DH parameters: %s", gnutls_strerror(ret)); return -1; } ret = gnutls_dh_params_import_pkcs3(*dh_params, &data, GNUTLS_X509_FMT_PEM); g_free(contents); if (ret < 0) { gnutls_dh_params_deinit(*dh_params); *dh_params = NULL; error_setg(errp, "Unable to load DH parameters from %s: %s", filename, gnutls_strerror(ret)); return -1; } } return 0; }
int tls_global_set_params(void *tls_ctx, const struct tls_connection_params *params) { struct tls_global *global = tls_ctx; int ret; /* Currently, global parameters are only set when running in server * mode. */ global->server = 1; if (global->params_set) { gnutls_certificate_free_credentials(global->xcred); global->params_set = 0; } ret = gnutls_certificate_allocate_credentials(&global->xcred); if (ret) { wpa_printf(MSG_DEBUG, "Failed to allocate global credentials " "%s", gnutls_strerror(ret)); return -1; } if (params->ca_cert) { ret = gnutls_certificate_set_x509_trust_file( global->xcred, params->ca_cert, GNUTLS_X509_FMT_PEM); if (ret < 0) { wpa_printf(MSG_DEBUG, "Failed to read CA cert '%s' " "in PEM format: %s", params->ca_cert, gnutls_strerror(ret)); ret = gnutls_certificate_set_x509_trust_file( global->xcred, params->ca_cert, GNUTLS_X509_FMT_DER); if (ret < 0) { wpa_printf(MSG_DEBUG, "Failed to read CA cert " "'%s' in DER format: %s", params->ca_cert, gnutls_strerror(ret)); goto fail; } } if (params->flags & TLS_CONN_ALLOW_SIGN_RSA_MD5) { gnutls_certificate_set_verify_flags( global->xcred, GNUTLS_VERIFY_ALLOW_SIGN_RSA_MD5); } #if LIBGNUTLS_VERSION_NUMBER >= 0x020800 if (params->flags & TLS_CONN_DISABLE_TIME_CHECKS) { gnutls_certificate_set_verify_flags( global->xcred, GNUTLS_VERIFY_DISABLE_TIME_CHECKS); } #endif /* LIBGNUTLS_VERSION_NUMBER >= 0x020800 */ } if (params->client_cert && params->private_key) { /* TODO: private_key_passwd? */ ret = gnutls_certificate_set_x509_key_file( global->xcred, params->client_cert, params->private_key, GNUTLS_X509_FMT_PEM); if (ret < 0) { wpa_printf(MSG_DEBUG, "Failed to read client cert/key " "in PEM format: %s", gnutls_strerror(ret)); ret = gnutls_certificate_set_x509_key_file( global->xcred, params->client_cert, params->private_key, GNUTLS_X509_FMT_DER); if (ret < 0) { wpa_printf(MSG_DEBUG, "Failed to read client " "cert/key in DER format: %s", gnutls_strerror(ret)); goto fail; } } } else if (params->private_key) { int pkcs12_ok = 0; #ifdef PKCS12_FUNCS /* Try to load in PKCS#12 format */ #if LIBGNUTLS_VERSION_NUMBER >= 0x010302 ret = gnutls_certificate_set_x509_simple_pkcs12_file( global->xcred, params->private_key, GNUTLS_X509_FMT_DER, params->private_key_passwd); if (ret != 0) { wpa_printf(MSG_DEBUG, "Failed to load private_key in " "PKCS#12 format: %s", gnutls_strerror(ret)); goto fail; } else pkcs12_ok = 1; #endif /* LIBGNUTLS_VERSION_NUMBER >= 0x010302 */ #endif /* PKCS12_FUNCS */ if (!pkcs12_ok) { wpa_printf(MSG_DEBUG, "GnuTLS: PKCS#12 support not " "included"); goto fail; } } global->params_set = 1; return 0; fail: gnutls_certificate_free_credentials(global->xcred); return -1; }
LIBIMOBILEDEVICE_API idevice_error_t idevice_connection_enable_ssl(idevice_connection_t connection) { if (!connection || connection->ssl_data) return IDEVICE_E_INVALID_ARG; idevice_error_t ret = IDEVICE_E_SSL_ERROR; #ifdef HAVE_OPENSSL uint32_t return_me = 0; #else int return_me = 0; #endif plist_t pair_record = NULL; userpref_read_pair_record(connection->udid, &pair_record); if (!pair_record) { debug_info("ERROR: Failed enabling SSL. Unable to read pair record for udid %s.", connection->udid); return ret; } #ifdef HAVE_OPENSSL key_data_t root_cert = { NULL, 0 }; key_data_t root_privkey = { NULL, 0 }; pair_record_import_crt_with_name(pair_record, USERPREF_ROOT_CERTIFICATE_KEY, &root_cert); pair_record_import_key_with_name(pair_record, USERPREF_ROOT_PRIVATE_KEY_KEY, &root_privkey); if (pair_record) plist_free(pair_record); BIO *ssl_bio = BIO_new(BIO_s_socket()); if (!ssl_bio) { debug_info("ERROR: Could not create SSL bio."); return ret; } BIO_set_fd(ssl_bio, (int)(long)connection->data, BIO_NOCLOSE); SSL_CTX *ssl_ctx = SSL_CTX_new(TLSv1_method()); if (ssl_ctx == NULL) { debug_info("ERROR: Could not create SSL context."); BIO_free(ssl_bio); return ret; } BIO* membp; X509* rootCert = NULL; membp = BIO_new_mem_buf(root_cert.data, root_cert.size); PEM_read_bio_X509(membp, &rootCert, NULL, NULL); BIO_free(membp); if (SSL_CTX_use_certificate(ssl_ctx, rootCert) != 1) { debug_info("WARNING: Could not load RootCertificate"); } X509_free(rootCert); free(root_cert.data); RSA* rootPrivKey = NULL; membp = BIO_new_mem_buf(root_privkey.data, root_privkey.size); PEM_read_bio_RSAPrivateKey(membp, &rootPrivKey, NULL, NULL); BIO_free(membp); if (SSL_CTX_use_RSAPrivateKey(ssl_ctx, rootPrivKey) != 1) { debug_info("WARNING: Could not load RootPrivateKey"); } RSA_free(rootPrivKey); free(root_privkey.data); SSL *ssl = SSL_new(ssl_ctx); if (!ssl) { debug_info("ERROR: Could not create SSL object"); BIO_free(ssl_bio); SSL_CTX_free(ssl_ctx); return ret; } SSL_set_connect_state(ssl); SSL_set_verify(ssl, 0, ssl_verify_callback); SSL_set_bio(ssl, ssl_bio, ssl_bio); return_me = SSL_do_handshake(ssl); if (return_me != 1) { debug_info("ERROR in SSL_do_handshake: %s", ssl_error_to_string(SSL_get_error(ssl, return_me))); SSL_free(ssl); SSL_CTX_free(ssl_ctx); } else { ssl_data_t ssl_data_loc = (ssl_data_t)malloc(sizeof(struct ssl_data_private)); ssl_data_loc->session = ssl; ssl_data_loc->ctx = ssl_ctx; connection->ssl_data = ssl_data_loc; ret = IDEVICE_E_SUCCESS; debug_info("SSL mode enabled, cipher: %s", SSL_get_cipher(ssl)); } /* required for proper multi-thread clean up to prevent leaks */ openssl_remove_thread_state(); #else ssl_data_t ssl_data_loc = (ssl_data_t)malloc(sizeof(struct ssl_data_private)); /* Set up GnuTLS... */ debug_info("enabling SSL mode"); errno = 0; gnutls_certificate_allocate_credentials(&ssl_data_loc->certificate); #if GNUTLS_VERSION_NUMBER >= 0x020b07 gnutls_certificate_set_retrieve_function(ssl_data_loc->certificate, internal_cert_callback); #else gnutls_certificate_client_set_retrieve_function(ssl_data_loc->certificate, internal_cert_callback); #endif gnutls_init(&ssl_data_loc->session, GNUTLS_CLIENT); gnutls_priority_set_direct(ssl_data_loc->session, "NONE:+VERS-TLS1.0:+ANON-DH:+RSA:+AES-128-CBC:+AES-256-CBC:+SHA1:+MD5:+COMP-NULL", NULL); gnutls_credentials_set(ssl_data_loc->session, GNUTLS_CRD_CERTIFICATE, ssl_data_loc->certificate); gnutls_session_set_ptr(ssl_data_loc->session, ssl_data_loc); gnutls_x509_crt_init(&ssl_data_loc->root_cert); gnutls_x509_crt_init(&ssl_data_loc->host_cert); gnutls_x509_privkey_init(&ssl_data_loc->root_privkey); gnutls_x509_privkey_init(&ssl_data_loc->host_privkey); pair_record_import_crt_with_name(pair_record, USERPREF_ROOT_CERTIFICATE_KEY, ssl_data_loc->root_cert); pair_record_import_crt_with_name(pair_record, USERPREF_HOST_CERTIFICATE_KEY, ssl_data_loc->host_cert); pair_record_import_key_with_name(pair_record, USERPREF_ROOT_PRIVATE_KEY_KEY, ssl_data_loc->root_privkey); pair_record_import_key_with_name(pair_record, USERPREF_HOST_PRIVATE_KEY_KEY, ssl_data_loc->host_privkey); if (pair_record) plist_free(pair_record); debug_info("GnuTLS step 1..."); gnutls_transport_set_ptr(ssl_data_loc->session, (gnutls_transport_ptr_t)connection); debug_info("GnuTLS step 2..."); gnutls_transport_set_push_function(ssl_data_loc->session, (gnutls_push_func) & internal_ssl_write); debug_info("GnuTLS step 3..."); gnutls_transport_set_pull_function(ssl_data_loc->session, (gnutls_pull_func) & internal_ssl_read); debug_info("GnuTLS step 4 -- now handshaking..."); if (errno) { debug_info("WARNING: errno says %s before handshake!", strerror(errno)); } do { return_me = gnutls_handshake(ssl_data_loc->session); } while(return_me == GNUTLS_E_AGAIN || return_me == GNUTLS_E_INTERRUPTED); debug_info("GnuTLS handshake done..."); if (return_me != GNUTLS_E_SUCCESS) { internal_ssl_cleanup(ssl_data_loc); free(ssl_data_loc); debug_info("GnuTLS reported something wrong: %s", gnutls_strerror(return_me)); debug_info("oh.. errno says %s", strerror(errno)); } else { connection->ssl_data = ssl_data_loc; ret = IDEVICE_E_SUCCESS; debug_info("SSL mode enabled"); } #endif return ret; }
struct wpabuf * tls_connection_handshake(void *tls_ctx, struct tls_connection *conn, const struct wpabuf *in_data, struct wpabuf **appl_data) { struct tls_global *global = tls_ctx; struct wpabuf *out_data; int ret; if (appl_data) *appl_data = NULL; if (in_data && wpabuf_len(in_data) > 0) { if (conn->pull_buf) { wpa_printf(MSG_DEBUG, "%s - %lu bytes remaining in " "pull_buf", __func__, (unsigned long) wpabuf_len(conn->pull_buf)); wpabuf_free(conn->pull_buf); } conn->pull_buf = wpabuf_dup(in_data); if (conn->pull_buf == NULL) return NULL; conn->pull_buf_offset = wpabuf_head(conn->pull_buf); } ret = gnutls_handshake(conn->session); if (ret < 0) { switch (ret) { case GNUTLS_E_AGAIN: if (global->server && conn->established && conn->push_buf == NULL) { /* Need to return something to trigger * completion of EAP-TLS. */ conn->push_buf = wpabuf_alloc(0); } break; case GNUTLS_E_FATAL_ALERT_RECEIVED: wpa_printf(MSG_DEBUG, "%s - received fatal '%s' alert", __func__, gnutls_alert_get_name( gnutls_alert_get(conn->session))); conn->read_alerts++; /* continue */ default: wpa_printf(MSG_DEBUG, "%s - gnutls_handshake failed " "-> %s", __func__, gnutls_strerror(ret)); conn->failed++; } } else { size_t size; gnutls_alert_description_t err; if (conn->verify_peer && tls_connection_verify_peer(conn, &err)) { wpa_printf(MSG_INFO, "TLS: Peer certificate chain " "failed validation"); conn->failed++; gnutls_alert_send(conn->session, GNUTLS_AL_FATAL, err); goto out; } wpa_printf(MSG_DEBUG, "TLS: Handshake completed successfully"); conn->established = 1; if (conn->push_buf == NULL) { /* Need to return something to get final TLS ACK. */ conn->push_buf = wpabuf_alloc(0); } gnutls_session_get_data(conn->session, NULL, &size); if (global->session_data == NULL || global->session_data_size < size) { os_free(global->session_data); global->session_data = os_malloc(size); } if (global->session_data) { global->session_data_size = size; gnutls_session_get_data(conn->session, global->session_data, &global->session_data_size); } if (conn->pull_buf && appl_data) *appl_data = gnutls_get_appl_data(conn); } out: out_data = conn->push_buf; conn->push_buf = NULL; return out_data; }
static void fusion_tls_connection_handle_error (FusionTLSConnection* self, int ecode, gint where, GError** error) { gboolean _tmp0_ = FALSE; int _tmp1_ = 0; gboolean _tmp3_ = FALSE; gboolean _tmp8_ = FALSE; int _tmp9_ = 0; gboolean _tmp12_ = FALSE; GError * _inner_error_ = NULL; g_return_if_fail (self != NULL); _tmp1_ = ecode; if (_tmp1_ == GNUTLS_E_WARNING_ALERT_RECEIVED) { _tmp0_ = TRUE; } else { int _tmp2_ = 0; _tmp2_ = ecode; _tmp0_ = _tmp2_ == GNUTLS_E_FATAL_ALERT_RECEIVED; } _tmp3_ = _tmp0_; if (_tmp3_) { gnutls_alert_description_t alert = 0; struct gnutls_session_int* _tmp4_ = NULL; gnutls_alert_description_t _tmp5_ = 0; gnutls_alert_description_t _tmp6_ = 0; const gchar* _tmp7_ = NULL; _tmp4_ = self->tls_session; _tmp5_ = gnutls_alert_get (_tmp4_); alert = _tmp5_; _tmp6_ = alert; _tmp7_ = gnutls_alert_get_name (_tmp6_); g_warning ("TLSConnection.vala:74: TLS handshake alert: %s", _tmp7_); } _tmp9_ = ecode; if (_tmp9_ < 0) { int _tmp10_ = 0; gboolean _tmp11_ = FALSE; _tmp10_ = ecode; _tmp11_ = gnutls_error_is_fatal (_tmp10_); _tmp8_ = _tmp11_; } else { _tmp8_ = FALSE; } _tmp12_ = _tmp8_; if (_tmp12_) { gint _tmp13_ = 0; _tmp13_ = where; switch (_tmp13_) { case 0: { int _tmp14_ = 0; const gchar* _tmp15_ = NULL; GError* _tmp16_ = NULL; _tmp14_ = ecode; _tmp15_ = gnutls_strerror (_tmp14_); _tmp16_ = g_error_new (G_IO_ERROR, G_IO_ERROR_FAILED, "Handshake failed: %s", _tmp15_); _inner_error_ = _tmp16_; if (_inner_error_->domain == G_IO_ERROR) { g_propagate_error (error, _inner_error_); return; } else { g_critical ("file %s: line %d: uncaught error: %s (%s, %d)", __FILE__, __LINE__, _inner_error_->message, g_quark_to_string (_inner_error_->domain), _inner_error_->code); g_clear_error (&_inner_error_); return; } } case 1: { int _tmp17_ = 0; const gchar* _tmp18_ = NULL; GError* _tmp19_ = NULL; _tmp17_ = ecode; _tmp18_ = gnutls_strerror (_tmp17_); _tmp19_ = g_error_new (G_IO_ERROR, G_IO_ERROR_FAILED, "Receive failed: %s", _tmp18_); _inner_error_ = _tmp19_; if (_inner_error_->domain == G_IO_ERROR) { g_propagate_error (error, _inner_error_); return; } else { g_critical ("file %s: line %d: uncaught error: %s (%s, %d)", __FILE__, __LINE__, _inner_error_->message, g_quark_to_string (_inner_error_->domain), _inner_error_->code); g_clear_error (&_inner_error_); return; } } case 2: { int _tmp20_ = 0; const gchar* _tmp21_ = NULL; GError* _tmp22_ = NULL; _tmp20_ = ecode; _tmp21_ = gnutls_strerror (_tmp20_); _tmp22_ = g_error_new (G_IO_ERROR, G_IO_ERROR_FAILED, "Send failed: %s", _tmp21_); _inner_error_ = _tmp22_; if (_inner_error_->domain == G_IO_ERROR) { g_propagate_error (error, _inner_error_); return; } else { g_critical ("file %s: line %d: uncaught error: %s (%s, %d)", __FILE__, __LINE__, _inner_error_->message, g_quark_to_string (_inner_error_->domain), _inner_error_->code); g_clear_error (&_inner_error_); return; } } default: { g_assert_not_reached (); } } } }
static void test_ciphersuite(const char *cipher_prio, int size) { /* Server stuff. */ gnutls_anon_server_credentials_t s_anoncred; gnutls_certificate_credentials_t c_certcred, s_certcred; gnutls_session_t server; int sret, cret; const char *str; /* Client stuff. */ gnutls_anon_client_credentials_t c_anoncred; gnutls_session_t client; /* Need to enable anonymous KX specifically. */ int ret; struct benchmark_st st; gnutls_packet_t packet; const char *name; /* Init server */ gnutls_anon_allocate_server_credentials(&s_anoncred); gnutls_certificate_allocate_credentials(&s_certcred); gnutls_certificate_set_x509_key_mem(s_certcred, &server_cert, &server_key, GNUTLS_X509_FMT_PEM); gnutls_certificate_set_x509_key_mem(s_certcred, &server_ecc_cert, &server_ecc_key, GNUTLS_X509_FMT_PEM); gnutls_init(&server, GNUTLS_SERVER); ret = gnutls_priority_set_direct(server, cipher_prio, &str); if (ret < 0) { fprintf(stderr, "Error in %s\n", str); exit(1); } gnutls_credentials_set(server, GNUTLS_CRD_ANON, s_anoncred); gnutls_credentials_set(server, GNUTLS_CRD_CERTIFICATE, s_certcred); 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); reset_buffers(); /* Init client */ gnutls_anon_allocate_client_credentials(&c_anoncred); gnutls_certificate_allocate_credentials(&c_certcred); gnutls_init(&client, GNUTLS_CLIENT); ret = gnutls_priority_set_direct(client, cipher_prio, &str); if (ret < 0) { fprintf(stderr, "Error in %s\n", str); exit(1); } gnutls_credentials_set(client, GNUTLS_CRD_ANON, c_anoncred); gnutls_credentials_set(client, GNUTLS_CRD_CERTIFICATE, c_certcred); 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); name = gnutls_cipher_get_name(gnutls_cipher_get(server)); fprintf(stdout, "%30s - %s ", name, gnutls_protocol_get_name( gnutls_protocol_get_version(server))); fflush(stdout); ret = gnutls_rnd(GNUTLS_RND_NONCE, buffer, sizeof(buffer)); if (ret < 0) { fprintf(stderr, "Error in %s\n", str); exit(1); } start_benchmark(&st); do { do { ret = gnutls_record_send(client, buffer, size); } while (ret == GNUTLS_E_AGAIN); if (ret < 0) { fprintf(stderr, "Failed sending to server\n"); exit(1); } do { ret = gnutls_record_recv_packet(server, &packet); } while (ret == GNUTLS_E_AGAIN); if (ret < 0) { fprintf(stderr, "Failed receiving from client: %s\n", gnutls_strerror(ret)); exit(1); } st.size += size; gnutls_packet_deinit(packet); } while (benchmark_must_finish == 0); stop_benchmark(&st, NULL, 1); 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); }
int tls_connection_set_params(void *tls_ctx, struct tls_connection *conn, const struct tls_connection_params *params) { int ret; if (conn == NULL || params == NULL) return -1; os_free(conn->subject_match); conn->subject_match = NULL; if (params->subject_match) { conn->subject_match = os_strdup(params->subject_match); if (conn->subject_match == NULL) return -1; } os_free(conn->altsubject_match); conn->altsubject_match = NULL; if (params->altsubject_match) { conn->altsubject_match = os_strdup(params->altsubject_match); if (conn->altsubject_match == NULL) return -1; } /* TODO: gnutls_certificate_set_verify_flags(xcred, flags); * to force peer validation(?) */ if (params->ca_cert) { conn->verify_peer = 1; ret = gnutls_certificate_set_x509_trust_file( conn->xcred, params->ca_cert, GNUTLS_X509_FMT_PEM); if (ret < 0) { wpa_printf(MSG_DEBUG, "Failed to read CA cert '%s' " "in PEM format: %s", params->ca_cert, gnutls_strerror(ret)); ret = gnutls_certificate_set_x509_trust_file( conn->xcred, params->ca_cert, GNUTLS_X509_FMT_DER); if (ret < 0) { wpa_printf(MSG_DEBUG, "Failed to read CA cert " "'%s' in DER format: %s", params->ca_cert, gnutls_strerror(ret)); return -1; } } if (params->flags & TLS_CONN_ALLOW_SIGN_RSA_MD5) { gnutls_certificate_set_verify_flags( conn->xcred, GNUTLS_VERIFY_ALLOW_SIGN_RSA_MD5); } if (params->flags & TLS_CONN_DISABLE_TIME_CHECKS) { gnutls_certificate_set_verify_flags( conn->xcred, GNUTLS_VERIFY_DISABLE_TIME_CHECKS); } } if (params->client_cert && params->private_key) { /* TODO: private_key_passwd? */ ret = gnutls_certificate_set_x509_key_file( conn->xcred, params->client_cert, params->private_key, GNUTLS_X509_FMT_PEM); if (ret < 0) { wpa_printf(MSG_DEBUG, "Failed to read client cert/key " "in PEM format: %s", gnutls_strerror(ret)); ret = gnutls_certificate_set_x509_key_file( conn->xcred, params->client_cert, params->private_key, GNUTLS_X509_FMT_DER); if (ret < 0) { wpa_printf(MSG_DEBUG, "Failed to read client " "cert/key in DER format: %s", gnutls_strerror(ret)); return ret; } } } else if (params->private_key) { int pkcs12_ok = 0; #ifdef PKCS12_FUNCS /* Try to load in PKCS#12 format */ #if LIBGNUTLS_VERSION_NUMBER >= 0x010302 ret = gnutls_certificate_set_x509_simple_pkcs12_file( conn->xcred, params->private_key, GNUTLS_X509_FMT_DER, params->private_key_passwd); if (ret != 0) { wpa_printf(MSG_DEBUG, "Failed to load private_key in " "PKCS#12 format: %s", gnutls_strerror(ret)); return -1; } else pkcs12_ok = 1; #endif /* LIBGNUTLS_VERSION_NUMBER >= 0x010302 */ #endif /* PKCS12_FUNCS */ if (!pkcs12_ok) { wpa_printf(MSG_DEBUG, "GnuTLS: PKCS#12 support not " "included"); return -1; } } conn->tls_ia = params->tls_ia; conn->params_set = 1; ret = gnutls_credentials_set(conn->session, GNUTLS_CRD_CERTIFICATE, conn->xcred); if (ret < 0) { wpa_printf(MSG_INFO, "Failed to configure credentials: %s", gnutls_strerror(ret)); } #ifdef GNUTLS_IA if (conn->iacred_cli) gnutls_ia_free_client_credentials(conn->iacred_cli); ret = gnutls_ia_allocate_client_credentials(&conn->iacred_cli); if (ret) { wpa_printf(MSG_DEBUG, "Failed to allocate IA credentials: %s", gnutls_strerror(ret)); return -1; } ret = gnutls_credentials_set(conn->session, GNUTLS_CRD_IA, conn->iacred_cli); if (ret) { wpa_printf(MSG_DEBUG, "Failed to configure IA credentials: %s", gnutls_strerror(ret)); gnutls_ia_free_client_credentials(conn->iacred_cli); conn->iacred_cli = NULL; return -1; } #endif /* GNUTLS_IE */ return ret; }
/***************************************************************************** * tls_ServerCreate: ***************************************************************************** * Allocates a whole server's TLS credentials. * Returns NULL on error. *****************************************************************************/ static tls_server_t * gnutls_ServerCreate( tls_t *p_this, const char *psz_cert_path, const char *psz_key_path ) { tls_server_t *p_server; tls_server_sys_t *p_server_sys; int val; msg_Dbg( p_this, "Creating TLS server" ); p_server_sys = (tls_server_sys_t *)malloc( sizeof(struct tls_server_sys_t) ); if( p_server_sys == NULL ) return NULL; /* Sets server's credentials */ val = gnutls_certificate_allocate_credentials( &p_server_sys->x509_cred ); if( val != 0 ) { msg_Err( p_this, "Cannot allocate X509 credentials : %s", gnutls_strerror( val ) ); free( p_server_sys ); return NULL; } val = gnutls_certificate_set_x509_key_file( p_server_sys->x509_cred, psz_cert_path, psz_key_path, GNUTLS_X509_FMT_PEM ); if( val < 0 ) { msg_Err( p_this, "Cannot set certificate chain or private key : %s", gnutls_strerror( val ) ); gnutls_certificate_free_credentials( p_server_sys->x509_cred ); free( p_server_sys ); return NULL; } /* FIXME: regenerate these regularly */ val = gnutls_dh_params_init( &p_server_sys->dh_params ); if( val >= 0 ) { vlc_value_t bits; if( var_Get( p_this, "dh-bits", &bits ) != VLC_SUCCESS ) { var_Create( p_this, "dh-bits", VLC_VAR_INTEGER | VLC_VAR_DOINHERIT ); var_Get( p_this, "dh-bits", &bits ); } msg_Dbg( p_this, "Computing Diffie Hellman ciphers parameters" ); val = gnutls_dh_params_generate2( p_server_sys->dh_params, bits.i_int ); } if( val < 0 ) { msg_Err( p_this, "Cannot initialize DH cipher suites : %s", gnutls_strerror( val ) ); gnutls_certificate_free_credentials( p_server_sys->x509_cred ); free( p_server_sys ); return NULL; } msg_Dbg( p_this, "Ciphers parameters computed" ); gnutls_certificate_set_dh_params( p_server_sys->x509_cred, p_server_sys->dh_params); p_server = (tls_server_t *)malloc( sizeof(struct tls_server_t) ); if( p_server == NULL ) { free( p_server_sys ); return NULL; } p_server->p_tls = p_this; p_server->p_sys = p_server_sys; p_server->pf_delete = gnutls_ServerDelete; p_server->pf_add_CA = gnutls_ServerAddCA; p_server->pf_add_CRL = gnutls_ServerAddCRL; p_server->pf_session_prepare = gnutls_ServerSessionPrepare; return p_server; }