int get_bits(gnutls_pk_algorithm_t key_type, int info_bits, const char *info_sec_param, int warn) { int bits; if (info_bits != 0) { static int warned = 0; if (warned == 0 && warn != 0) { warned = 1; fprintf(stderr, "** Note: Please use the --sec-param instead of --bits\n"); } bits = info_bits; } else { if (info_sec_param) { bits = gnutls_sec_param_to_pk_bits(key_type, str_to_sec_param (info_sec_param)); } else bits = gnutls_sec_param_to_pk_bits(key_type, GNUTLS_SEC_PARAM_NORMAL); } return bits; }
void TLSServer::init ( const std::string& ca, const std::string& crl, const std::string& cert, const std::string& key) { _ca = ca; _crl = crl; _cert = cert; _key = key; int ret = gnutls_global_init (); if (ret < 0) throw format ("TLS init error. {1}", gnutls_strerror (ret)); ret = gnutls_certificate_allocate_credentials (&_credentials); if (ret < 0) throw format ("TLS allocation error. {1}", gnutls_strerror (ret)); if (_ca != "" && (ret = gnutls_certificate_set_x509_trust_file (_credentials, _ca.c_str (), GNUTLS_X509_FMT_PEM)) < 0) throw format ("Bad CA file. {1}", gnutls_strerror (ret)); if ( _crl != "" && (ret = gnutls_certificate_set_x509_crl_file (_credentials, _crl.c_str (), GNUTLS_X509_FMT_PEM)) < 0) throw format ("Bad CRL file. {1}", gnutls_strerror (ret)); if (_cert != "" && _key != "" && (ret = gnutls_certificate_set_x509_key_file (_credentials, _cert.c_str (), _key.c_str (), GNUTLS_X509_FMT_PEM)) < 0) throw format ("Bad CERT file. {1}", gnutls_strerror (ret)); #if GNUTLS_VERSION_NUMBER >= 0x020b00 #if GNUTLS_VERSION_NUMBER >= 0x03000d unsigned int bits = gnutls_sec_param_to_pk_bits (GNUTLS_PK_DH, GNUTLS_SEC_PARAM_LEGACY); #else unsigned int bits = gnutls_sec_param_to_pk_bits (GNUTLS_PK_DH, GNUTLS_SEC_PARAM_NORMAL); #endif #else unsigned int bits = DH_BITS; #endif gnutls_dh_params_init (&_params); gnutls_dh_params_generate2 (_params, bits); if (_ciphers == "") _ciphers = "NORMAL"; gnutls_priority_init (&_priorities, _ciphers.c_str (), NULL); gnutls_certificate_set_dh_params (_credentials, _params); #if GNUTLS_VERSION_NUMBER >= 0x02090a // The automatic verification for the client certificate with // gnutls_certificate_set_verify_function only works with gnutls // >=2.9.10. So with older versions we should call the verify function // manually after the gnutls handshake. gnutls_certificate_set_verify_function (_credentials, verify_certificate_callback); #endif }
int get_bits(gnutls_pk_algorithm_t key_type, int info_bits, const char *info_sec_param, int warn) { int bits; if (info_bits != 0) { static int warned = 0; if (warned == 0 && warn != 0 && GNUTLS_BITS_ARE_CURVE(info_bits)==0) { warned = 1; fprintf(stderr, "** Note: You may use '--sec-param %s' instead of '--bits %d'\n", bits_to_sp(key_type, info_bits), info_bits); } bits = info_bits; } else { if (info_sec_param == 0) { /* For ECDSA keys use 256 bits or better, as they are widely supported */ info_sec_param = "HIGH"; } bits = gnutls_sec_param_to_pk_bits(key_type, str_to_sec_param (info_sec_param)); } return bits; }
void TLSServer::init ( const std::string& ca, const std::string& crl, const std::string& cert, const std::string& key) { _ca = ca; _crl = crl; _cert = cert; _key = key; gnutls_global_init (); gnutls_certificate_allocate_credentials (&_credentials); if (_ca != "" && gnutls_certificate_set_x509_trust_file (_credentials, _ca.c_str (), GNUTLS_X509_FMT_PEM) < 0) throw std::string ("Missing CA file."); if ( _crl != "" && gnutls_certificate_set_x509_crl_file (_credentials, _crl.c_str (), GNUTLS_X509_FMT_PEM) < 0) throw std::string ("Missing CRL file."); if (_cert != "" && _key != "" && gnutls_certificate_set_x509_key_file (_credentials, _cert.c_str (), _key.c_str (), GNUTLS_X509_FMT_PEM) < 0) throw std::string ("Missing CERT file."); #if GNUTLS_VERSION_NUMBER >= 0x020b00 #if GNUTLS_VERSION_NUMBER >= 0x03000d unsigned int bits = gnutls_sec_param_to_pk_bits (GNUTLS_PK_DH, GNUTLS_SEC_PARAM_LEGACY); #else unsigned int bits = gnutls_sec_param_to_pk_bits (GNUTLS_PK_DH, GNUTLS_SEC_PARAM_NORMAL); #endif #else unsigned int bits = DH_BITS; #endif gnutls_dh_params_init (&_params); gnutls_dh_params_generate2 (_params, bits); if (_ciphers == "") _ciphers = "NORMAL"; gnutls_priority_init (&_priorities, _ciphers.c_str (), NULL); gnutls_certificate_set_dh_params (_credentials, _params); #if GNUTLS_VERSION_NUMBER >= 0x02090a gnutls_certificate_set_verify_function (_credentials, verify_certificate_callback); #endif }
/** * gnutls_dh_set_prime_bits: * @session: is a #gnutls_session_t structure. * @bits: is the number of bits * * This function sets the number of bits, for use in a Diffie-Hellman * key exchange. This is used both in DH ephemeral and DH anonymous * cipher suites. This will set the minimum size of the prime that * will be used for the handshake. * * In the client side it sets the minimum accepted number of bits. If * a server sends a prime with less bits than that * %GNUTLS_E_DH_PRIME_UNACCEPTABLE will be returned by the handshake. * * Note that values lower than 512 bits may allow decryption of the * exchanged data. * * The function has no effect in server side. * * Note that since 3.1.7 this function is deprecated. The minimum * number of bits is set by the priority string level. * Also this function must be called after gnutls_priority_set_direct() * or the set value may be overridden by the selected priority options. * * **/ void gnutls_dh_set_prime_bits(gnutls_session_t session, unsigned int bits) { if (bits <= gnutls_sec_param_to_pk_bits(GNUTLS_PK_DH, GNUTLS_SEC_PARAM_VERY_WEAK) && bits != 0) _gnutls_audit_log(session, "Note that the security level of the Diffie-Hellman key exchange has been lowered to %u bits and this may allow decryption of the session data\n", bits); session->internals.priorities.dh_prime_bits = bits; }
static int generate_dh_params (void) { int bits = gnutls_sec_param_to_pk_bits (GNUTLS_PK_DH, GNUTLS_SEC_PARAM_LOW); /* Generate Diffie-Hellman parameters - for use with DHE * kx algorithms. When short bit length is used, it might * be wise to regenerate parameters often. */ gnutls_dh_params_init (&dh_params); gnutls_dh_params_generate2 (dh_params, bits); return 0; }
void Plugin::_loadPrivateKey() { QFile file(this->keyFile); int bits; size_t size; QByteArray data; gnutls_datum_t datum; int error; if (!file.open(QIODevice::ReadWrite)) throw Properties("error", "Unable to open the private key file").add("file", this->keyFile); ASSERT_INIT(gnutls_x509_privkey_init(&this->key), "privkey"); // Checks that the private key is valid if (file.size() > 0) { data = file.readAll(); datum.size = data.size(); datum.data = (unsigned char *)data.data(); if ((error = gnutls_x509_privkey_import_pkcs8(this->key, &datum, GNUTLS_X509_FMT_PEM, this->keyPassword.data(), 0)) != GNUTLS_E_SUCCESS) { LOG_ERROR("Invalid private key", Properties("error", gnutls_strerror(error)).toMap(), "Plugin", "_generatePrivateKey"); file.resize(0); } else if (gnutls_x509_privkey_sec_param(this->key) != this->secParam) file.resize(0); } // Generates the private key if (file.size() == 0) { bits = gnutls_sec_param_to_pk_bits(GNUTLS_PK_RSA, this->secParam); LOG_INFO("Generating a new private key", Properties("secParam", gnutls_sec_param_get_name(this->secParam)).add("bits", bits).toMap(), "Plugin", "_generatePrivateKey"); ASSERT(gnutls_x509_privkey_generate(this->key, GNUTLS_PK_RSA, bits, 0)); ASSERT(gnutls_x509_privkey_verify_params(this->key)); size = bits; data.resize((int)size); ASSERT(gnutls_x509_privkey_export_pkcs8(this->key, GNUTLS_X509_FMT_PEM, this->keyPassword.data(), GNUTLS_PKCS_USE_PBES2_AES_256, data.data(), &size)); data.resize((int)size); file.write(data); } }
void SSLi_init() { unsigned const bitCount = gnutls_sec_param_to_pk_bits(GNUTLS_PK_DH, GNUTLS_SEC_PARAM_MEDIUM); gnutls_priority_init(&cipherCache, ciphers, NULL); initializeCertificate(); gnutls_dh_params_init(&dhParameters); Log_info("Generating Diffie-Hellman parameters (%i bits)", bitCount); int error = gnutls_dh_params_generate2(dhParameters, bitCount); if(!error) { Log_info("Successfully generated Diffie-Hellman parameters"); } else { Log_warn("Failed to generate Diffie-Hellman parameters: %s", gnutls_strerror(error)); } gnutls_certificate_set_dh_params(certificate, dhParameters); Log_info("Sucessfully initialized GNUTLS version %s", gnutls_check_version(NULL)); }
void Plugin::_loadDHParams() { QByteArray data; QFile file(this->dhParamsFile); int bits; gnutls_datum_t datum; int error; if (!file.open(QIODevice::ReadWrite)) throw Properties("error", "Unable to open the Diffie-Hellman parameters file").add("file", this->dhParamsFile); bits = gnutls_sec_param_to_pk_bits(GNUTLS_PK_DH, this->secParam); ASSERT_INIT(gnutls_dh_params_init(&this->dhParams), "dh_params"); // The Diffie-Hellman parameters expired if (QFileInfo(file).lastModified() < this->dhParamsExpiration) file.resize(0); // Import the DH parameters from the PEM file if (file.size() > 0) { data = file.readAll(); datum.data = (unsigned char *)data.data(); datum.size = data.size(); if (gnutls_dh_params_import_pkcs3(this->dhParams, &datum, GNUTLS_X509_FMT_PEM) != GNUTLS_E_SUCCESS) file.resize(0); } // Generates the DH parameters and store them in a PEM file if (file.size() == 0) { LOG_INFO("Generating new Diffie-Hellman parameters. This might take some time.", Properties("secParam", gnutls_sec_param_get_name(this->secParam)).add("bits", bits).toMap(), "Plugin", "_generateDHParams"); data.resize(bits); datum.data = (unsigned char *)data.data(); datum.size = bits; ASSERT(gnutls_dh_params_generate2(this->dhParams, bits)); size_t size = datum.size; ASSERT(gnutls_dh_params_export_pkcs3(this->dhParams, GNUTLS_X509_FMT_PEM, datum.data, &size)); file.write(data.data(), size); } }
struct dtls_gnutls_data *dtls_gnutls_data_create(struct conn *conn,int config) { const char *errpos; int rc; gnutls_datum_t key; int bits; struct dtls_gnutls_data *d = malloc(sizeof(struct dtls_gnutls_data)); if (!d) return 0; gnutls_global_set_log_level(10); gnutls_global_set_log_function(dtls_log_cb); rc = gnutls_init(&d->session, config); if (rc < 0) { cw_log(LOG_ERR, "DTLS - Can't init session: %s", gnutls_strerror(rc)); dtls_gnutls_data_destroy(d); return 0; } gnutls_certificate_allocate_credentials(&d->x509_cred); /* Set credentials */ if (conn->dtls_cert_file && conn->dtls_key_file){ rc = gnutls_certificate_set_x509_key_file(d->x509_cred, conn->dtls_cert_file, conn->dtls_key_file, GNUTLS_X509_FMT_PEM); if (rc < 0) { cw_log(LOG_ERR, "DTLS - Can't set cert/key: %s", gnutls_strerror(rc)); dtls_gnutls_data_destroy(d); return 0; } } /* #if GNUTLS_VERSION_NUMBER >= 0x030100 bits = gnutls_sec_param_to_pk_bits(GNUTLS_PK_DH, GNUTLS_SEC_PARAM_INSECURE); #else */ bits = gnutls_sec_param_to_pk_bits(GNUTLS_PK_DH, GNUTLS_SEC_PARAM_LEGACY); /*#endif*/ /* Set ciphers */ /* rc = gnutls_priority_init(&d->priority_cache, conn->dtls_cipher, &errpos); if (rc < 0) { cw_log(LOG_ERR, "DTLS - Can't init ciphers '%s' at '%s' : %s", conn->dtls_cipher, errpos, gnutls_strerror(rc)); dtls_gnutls_data_destroy(d); return 0; } rc = gnutls_priority_set(d->session, d->priority_cache); if (rc < 0) { cw_log(LOG_ERR, "DTLS - Can't set priority: %s", gnutls_strerror(rc)); dtls_gnutls_data_destroy(d); return 0; } */ rc = gnutls_priority_set_direct(d->session,conn->dtls_cipher,&errpos); if (rc < 0) { cw_log(LOG_ERR, "DTLS - Can't init ciphers '%s' at '%s' : %s", conn->dtls_cipher, errpos, gnutls_strerror(rc)); dtls_gnutls_data_destroy(d); return 0; } rc = gnutls_credentials_set(d->session, GNUTLS_CRD_CERTIFICATE, d->x509_cred); if (rc < 0) { cw_log(LOG_ERR, "DTLS - Can't set x.509 credentials: %s", gnutls_strerror(rc)); dtls_gnutls_data_destroy(d); return 0; } gnutls_certificate_set_verify_function(d->x509_cred,verify_cert); gnutls_session_set_ptr(d->session, conn); gnutls_transport_set_ptr(d->session, conn); gnutls_transport_set_pull_function(d->session, dtls_gnutls_bio_read); gnutls_transport_set_push_function(d->session, dtls_gnutls_bio_write); gnutls_transport_set_pull_timeout_function(d->session, dtls_gnutls_bio_wait); #if GNUTLS_VERSION_NUMBER >= 0x030100 gnutls_handshake_set_timeout(d->session, GNUTLS_DEFAULT_HANDSHAKE_TIMEOUT); gnutls_dtls_set_data_mtu(d->session, conn->dtls_mtu); #endif gnutls_dtls_set_mtu(d->session, conn->dtls_mtu); return d; }
/* Use all available information to decide the DH parameters to use, * that being the negotiated RFC7919 group, the callback, and the * provided parameters structure. */ int _gnutls_figure_dh_params(gnutls_session_t session, gnutls_dh_params_t dh_params, gnutls_params_function * func, gnutls_sec_param_t sec_param) { gnutls_params_st params; bigint_t p, g; unsigned free_pg = 0; int ret; unsigned q_bits = 0, i; const gnutls_group_entry_st *group; group = get_group(session); params.deinit = 0; /* if we negotiated RFC7919 FFDHE */ if (group && group->pk == GNUTLS_PK_DH) { for (i=0;i<session->internals.priorities->groups.size;i++) { if (session->internals.priorities->groups.entry[i] == group) { ret = _gnutls_mpi_init_scan_nz(&p, session->internals.priorities->groups.entry[i]->prime->data, session->internals.priorities->groups.entry[i]->prime->size); if (ret < 0) return gnutls_assert_val(ret); free_pg = 1; ret = _gnutls_mpi_init_scan_nz(&g, session->internals.priorities->groups.entry[i]->generator->data, session->internals.priorities->groups.entry[i]->generator->size); if (ret < 0) { gnutls_assert(); goto cleanup; } session->internals.hsk_flags |= HSK_USED_FFDHE; q_bits = *session->internals.priorities->groups.entry[i]->q_bits; goto finished; } } /* didn't find anything, that shouldn't have occurred * as we received that extension */ return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR); } else if (sec_param) { unsigned bits = gnutls_sec_param_to_pk_bits(GNUTLS_PK_DH, sec_param)/8; for (i=0;i<session->internals.priorities->groups.size;i++) { if (!session->internals.priorities->groups.entry[i]->prime) continue; if (bits <= session->internals.priorities->groups.entry[i]->prime->size) { ret = _gnutls_mpi_init_scan_nz(&p, session->internals.priorities->groups.entry[i]->prime->data, session->internals.priorities->groups.entry[i]->prime->size); if (ret < 0) return gnutls_assert_val(ret); free_pg = 1; ret = _gnutls_mpi_init_scan_nz(&g, session->internals.priorities->groups.entry[i]->generator->data, session->internals.priorities->groups.entry[i]->generator->size); if (ret < 0) { gnutls_assert(); goto cleanup; } q_bits = *session->internals.priorities->groups.entry[i]->q_bits; goto finished; } } } if (dh_params) { p = dh_params->params[0]; g = dh_params->params[1]; q_bits = dh_params->q_bits; } else if (func) { ret = func(session, GNUTLS_PARAMS_DH, ¶ms); if (ret == 0 && params.type == GNUTLS_PARAMS_DH) { p = params.params.dh->params[0]; g = params.params.dh->params[1]; q_bits = params.params.dh->q_bits; } else return gnutls_assert_val(GNUTLS_E_NO_TEMPORARY_DH_PARAMS); } else return gnutls_assert_val(GNUTLS_E_NO_TEMPORARY_DH_PARAMS); finished: _gnutls_dh_save_group(session, g, p); ret = set_dh_pk_params(session, g, p, q_bits); if (ret < 0) { gnutls_assert(); } cleanup: if (free_pg) { _gnutls_mpi_release(&p); _gnutls_mpi_release(&g); } if (params.deinit && params.type == GNUTLS_PARAMS_DH) gnutls_dh_params_deinit(params.params.dh); return ret; }
/** * @short Creates a new listen point with HTTPS powers. * @memberof onion_https_t * * Creates the HTTPS listen point. * * Might be called with (O_SSL_NONE,NULL), and set up the certificate later with onion_https_set_certificate. * * @param type Type of certificate to setup * @param filename File from where to get the data * @param ... More types and filenames until O_SSL_NONE. * @returns An onion_listen_point with the desired data, ready to start listening. */ onion_listen_point *onion_https_new(){ onion_listen_point *op=onion_listen_point_new(); op->request_init=onion_https_request_init; op->free_user_data=onion_https_free_user_data; op->listen_stop=onion_https_listen_stop; op->read=onion_https_read; op->write=onion_https_write; op->close=onion_https_close; op->read_ready=onion_http_read_ready; op->secure = true; op->user_data=onion_low_calloc(1,sizeof(onion_https)); onion_https *https=(onion_https*)op->user_data; #ifdef HAVE_PTHREADS gcry_control (GCRYCTL_SET_THREAD_CBS, &gcry_threads_pthread); #endif //if (!(o->flags&O_USE_DEV_RANDOM)){ gcry_control(GCRYCTL_ENABLE_QUICK_RANDOM, 0); //} gnutls_global_init (); gnutls_certificate_allocate_credentials (&https->x509_cred); // set cert here?? //onion_https_set_certificate(op,O_SSL_CERTIFICATE_KEY, "mycert.pem","mycert.pem"); int e; int bits = gnutls_sec_param_to_pk_bits (GNUTLS_PK_DH, GNUTLS_SEC_PARAM_LOW); e=gnutls_dh_params_init (&https->dh_params); if (e<0){ ONION_ERROR("Error initializing HTTPS: %s", gnutls_strerror(e)); gnutls_certificate_free_credentials (https->x509_cred); op->free_user_data=NULL; onion_listen_point_free(op); onion_low_free(https); return NULL; } e=gnutls_dh_params_generate2 (https->dh_params, bits); if (e<0){ ONION_ERROR("Error initializing HTTPS: %s", gnutls_strerror(e)); gnutls_certificate_free_credentials (https->x509_cred); op->free_user_data=NULL; onion_listen_point_free(op); onion_low_free(https); return NULL; } e=gnutls_priority_init (&https->priority_cache, "PERFORMANCE:%SAFE_RENEGOTIATION:-VERS-TLS1.0", NULL); if (e<0){ ONION_ERROR("Error initializing HTTPS: %s", gnutls_strerror(e)); gnutls_certificate_free_credentials (https->x509_cred); gnutls_dh_params_deinit(https->dh_params); op->free_user_data=NULL; onion_listen_point_free(op); onion_low_free(https); return NULL; } gnutls_certificate_set_dh_params (https->x509_cred, https->dh_params); gnutls_priority_init (&https->priority_cache, "NORMAL:-VERS-TLS-ALL:+VERS-TLS1.0:+VERS-SSL3.0:%COMPAT", NULL); // PERFORMANCE:%SAFE_RENEGOTIATION:-VERS-TLS1.0:%COMPAT" ONION_DEBUG("HTTPS connection ready"); return op; }
int initdh() { unsigned int bits = gnutls_sec_param_to_pk_bits(GNUTLS_PK_DH, GNUTLS_SEC_PARAM_LEGACY); gnutls_dh_params_init(&dh_params); gnutls_dh_params_generate2(dh_params, bits); return 0; }
int main (void) { gnutls_x509_crq_t crq; gnutls_x509_privkey_t key; unsigned char buffer[10 * 1024]; size_t buffer_size = sizeof (buffer); unsigned int bits; gnutls_global_init (); /* Initialize an empty certificate request, and * an empty private key. */ gnutls_x509_crq_init (&crq); gnutls_x509_privkey_init (&key); /* Generate an RSA key of moderate security. */ bits = gnutls_sec_param_to_pk_bits (GNUTLS_PK_RSA, GNUTLS_SEC_PARAM_NORMAL); gnutls_x509_privkey_generate (key, GNUTLS_PK_RSA, bits, 0); /* Add stuff to the distinguished name */ gnutls_x509_crq_set_dn_by_oid (crq, GNUTLS_OID_X520_COUNTRY_NAME, 0, "GR", 2); gnutls_x509_crq_set_dn_by_oid (crq, GNUTLS_OID_X520_COMMON_NAME, 0, "Nikos", strlen ("Nikos")); /* Set the request version. */ gnutls_x509_crq_set_version (crq, 1); /* Set a challenge password. */ gnutls_x509_crq_set_challenge_password (crq, "something to remember here"); /* Associate the request with the private key */ gnutls_x509_crq_set_key (crq, key); /* Self sign the certificate request. */ gnutls_x509_crq_sign2 (crq, key, GNUTLS_DIG_SHA1, 0); /* Export the PEM encoded certificate request, and * display it. */ gnutls_x509_crq_export (crq, GNUTLS_X509_FMT_PEM, buffer, &buffer_size); printf ("Certificate Request: \n%s", buffer); /* Export the PEM encoded private key, and * display it. */ buffer_size = sizeof (buffer); gnutls_x509_privkey_export (key, GNUTLS_X509_FMT_PEM, buffer, &buffer_size); printf ("\n\nPrivate key: \n%s", buffer); gnutls_x509_crq_deinit (crq); gnutls_x509_privkey_deinit (key); return 0; }
int main(int argc, char *argv[]) { int result; pid_t pid; unsigned int pk_bits; gnutls_dh_params_t dh_params; is_server_test = 0; is_client_test = 0; test_msg = 0; if (argc == 4) { if (strncmp(argv[1], "-s", 2) == 0) is_server_test = 1; else if (strncmp(argv[1], "-c", 2) == 0) is_client_test = 1; test_msg = atoi(argv[2]); input_file = fopen(argv[3], "r"); } msg_num = 0; gnutls_session_t client_session; gnutls_session_t server_session; gnutls_certificate_credentials_t x509_cred; // Initialize GNUTLS and add test certificates result = gnutls_global_init(); gnutls_global_set_time_function(stuck_time); gnutls_certificate_allocate_credentials(&x509_cred); gnutls_certificate_set_x509_trust_file(x509_cred, CAFILE, GNUTLS_X509_FMT_PEM); gnutls_certificate_set_x509_key_file(x509_cred, CERTFILE, KEYFILE, GNUTLS_X509_FMT_PEM); pk_bits = gnutls_sec_param_to_pk_bits(GNUTLS_PK_DH, GNUTLS_SEC_PARAM_MEDIUM); gnutls_dh_params_init(&dh_params); gnutls_dh_params_generate2(dh_params, pk_bits); gnutls_certificate_set_dh_params(x509_cred, dh_params); // Initialize the server session gnutls_init(&server_session, GNUTLS_SERVER); gnutls_credentials_set(server_session, GNUTLS_CRD_CERTIFICATE, x509_cred); gnutls_certificate_server_set_request(server_session, GNUTLS_CERT_IGNORE); gnutls_set_default_priority(server_session); gnutls_transport_set_push_function(server_session, server_push); gnutls_transport_set_pull_function(server_session, server_pull); gnutls_handshake_set_timeout(server_session, 0); //Initialize the client session gnutls_init(&client_session, GNUTLS_CLIENT); gnutls_credentials_set(client_session, GNUTLS_CRD_CERTIFICATE, x509_cred); gnutls_set_default_priority(client_session); gnutls_transport_set_push_function(client_session, client_push); gnutls_transport_set_pull_function(client_session, client_pull); // No timeout for handshake gnutls_handshake_set_timeout(client_session, 0); #ifdef __AFL_HAVE_MANUAL_CONTROL __AFL_INIT(); #endif pipe(client_to_server); pipe(server_to_client); pid = fork(); if (pid == 0) { // Running server session close(client_to_server[1]); close(server_to_client[0]); do { result = gnutls_handshake(server_session); } while ( result != 0 && !gnutls_error_is_fatal(result) ); } else { close(server_to_client[1]); close(client_to_server[0]); do { result = gnutls_handshake(client_session); } while ( result != 0 && !gnutls_error_is_fatal(result) ); } return 0; }