static int test_fatalerr(void) { SSL_CTX *sctx = NULL, *cctx = NULL; SSL *sssl = NULL, *cssl = NULL; const char *msg = "Dummy"; BIO *wbio = NULL; int ret = 0, len; char buf[80]; unsigned char dummyrec[] = { 0x17, 0x03, 0x03, 0x00, 0x05, 'D', 'u', 'm', 'm', 'y' }; if (!TEST_true(create_ssl_ctx_pair(TLS_method(), TLS_method(), &sctx, &cctx, cert, privkey))) goto err; /* * Deliberately set the cipher lists for client and server to be different * to force a handshake failure. */ if (!TEST_true(SSL_CTX_set_cipher_list(sctx, "AES128-SHA")) || !TEST_true(SSL_CTX_set_cipher_list(cctx, "AES256-SHA")) || !TEST_true(create_ssl_objects(sctx, cctx, &sssl, &cssl, NULL, NULL))) goto err; wbio = SSL_get_wbio(cssl); if (!TEST_ptr(wbio)) { printf("Unexpected NULL bio received\n"); goto err; } /* Connection should fail */ if (!TEST_false(create_ssl_connection(sssl, cssl, SSL_ERROR_NONE))) goto err; ERR_clear_error(); /* Inject a plaintext record from client to server */ if (!TEST_int_gt(BIO_write(wbio, dummyrec, sizeof(dummyrec)), 0)) goto err; /* SSL_read()/SSL_write should fail because of a previous fatal error */ if (!TEST_int_le(len = SSL_read(sssl, buf, sizeof(buf - 1)), 0)) { buf[len] = '\0'; TEST_error("Unexpected success reading data: %s\n", buf); goto err; } if (!TEST_int_le(SSL_write(sssl, msg, strlen(msg)), 0)) goto err; ret = 1; err: SSL_free(sssl); SSL_free(cssl); SSL_CTX_free(sctx); SSL_CTX_free(cctx); return ret; }
int setup_tests(void) { if (!TEST_ptr(ctx = SSL_CTX_new(TLS_method()))) return 0; ADD_TEST(test_func); return 1; }
/* * ssl_check_version_downgrade - In response to RFC7507 SCSV version * fallback indication from a client check whether we're using the highest * supported protocol version. * * @s server SSL handle. * * Returns 1 when using the highest enabled version, 0 otherwise. */ int ssl_check_version_downgrade(SSL *s) { const version_info *vent; const version_info *table; /* * Check that the current protocol is the highest enabled version * (according to s->ctx->method, as version negotiation may have changed * s->method). */ if (s->version == s->ctx->method->version) return 1; /* * Apparently we're using a version-flexible SSL_METHOD (not at its * highest protocol version). */ if (s->ctx->method->version == TLS_method()->version) table = tls_version_table; else if (s->ctx->method->version == DTLS_method()->version) table = dtls_version_table; else { /* Unexpected state; fail closed. */ return 0; } for (vent = table; vent->version != 0; ++vent) { if (vent->smeth != NULL && ssl_method_error(s, vent->smeth()) == 0) return s->version == vent->version; } return 0; }
MONO_API MonoBtlsSslCtx * mono_btls_ssl_ctx_new (void) { MonoBtlsSslCtx *ctx; ctx = OPENSSL_malloc (sizeof (MonoBtlsSslCtx)); if (!ctx) return NULL; memset (ctx, 0, sizeof (MonoBtlsSslCtx)); ctx->references = 1; ctx->ctx = SSL_CTX_new (TLS_method ()); return ctx; }
static int client_setup_sni_after_state(void) { SSL_CTX *ctx; SSL *con = NULL; BIO *rbio; BIO *wbio; char *hostname = NULL; int ret = 0; /* use TLS_method to blur 'side' */ ctx = SSL_CTX_new(TLS_method()); if (!TEST_ptr(ctx)) goto end; con = SSL_new(ctx); if (!TEST_ptr(con)) goto end; rbio = BIO_new(BIO_s_mem()); wbio = BIO_new(BIO_s_mem()); if (!TEST_ptr(rbio)|| !TEST_ptr(wbio)) { BIO_free(rbio); BIO_free(wbio); goto end; } SSL_set_bio(con, rbio, wbio); SSL_set_connect_state(con); /* set SNI after 'client side' is set */ SSL_set_tlsext_host_name(con, host); if (!TEST_int_le(SSL_connect(con), 0)) /* This shouldn't succeed because we don't have a server! */ goto end; if (!TEST_true(get_sni_from_client_hello(wbio, &hostname))) /* no SNI in client hello */ goto end; if (!TEST_str_eq(hostname, host)) /* incorrect SNI value */ goto end; ret = 1; end: OPENSSL_free(hostname); SSL_free(con); SSL_CTX_free(ctx); return ret; }
static const SSL_METHOD *tls1_get_method(int ver) { if (ver == TLS_ANY_VERSION) return TLS_method(); if (ver == TLS1_2_VERSION) return TLSv1_2_method(); if (ver == TLS1_1_VERSION) return TLSv1_1_method(); if (ver == TLS1_VERSION) return TLSv1_method(); #ifndef OPENSSL_NO_SSL3 if (ver == SSL3_VERSION) return (SSLv3_method()); else #endif return NULL; }
std::string CreateFamilySignature (const std::string& family, const IdentHash& ident) { auto filename = i2p::fs::DataDirPath("family", (family + ".key")); std::string sig; SSL_CTX * ctx = SSL_CTX_new (TLS_method ()); int ret = SSL_CTX_use_PrivateKey_file (ctx, filename.c_str (), SSL_FILETYPE_PEM); if (ret) { SSL * ssl = SSL_new (ctx); EVP_PKEY * pkey = SSL_get_privatekey (ssl); EC_KEY * ecKey = EVP_PKEY_get1_EC_KEY (pkey); if (ecKey) { auto group = EC_KEY_get0_group (ecKey); if (group) { int curve = EC_GROUP_get_curve_name (group); if (curve == NID_X9_62_prime256v1) { uint8_t signingPrivateKey[32], buf[50], signature[64]; i2p::crypto::bn2buf (EC_KEY_get0_private_key (ecKey), signingPrivateKey, 32); i2p::crypto::ECDSAP256Signer signer (signingPrivateKey); size_t len = family.length (); memcpy (buf, family.c_str (), len); memcpy (buf + len, (const uint8_t *)ident, 32); len += 32; signer.Sign (buf, len, signature); len = Base64EncodingBufferSize (64); char * b64 = new char[len+1]; len = ByteStreamToBase64 (signature, 64, b64, len); b64[len] = 0; sig = b64; delete[] b64; } else LogPrint (eLogWarning, "Family: elliptic curve ", curve, " is not supported"); } } SSL_free (ssl); } else LogPrint (eLogError, "Family: Can't open keys file: ", filename); SSL_CTX_free (ctx); return sig; }
const SSL_METHOD * hb_ssl_method_id_to_ptr( int n ) { const SSL_METHOD * p; switch( n ) { #if OPENSSL_VERSION_NUMBER >= 0x10100000L case HB_SSL_CTX_NEW_METHOD_TLS: p = TLS_method(); break; case HB_SSL_CTX_NEW_METHOD_TLS_SERVER: p = TLS_server_method(); break; case HB_SSL_CTX_NEW_METHOD_TLS_CLIENT: p = TLS_client_method(); break; #else case HB_SSL_CTX_NEW_METHOD_TLSV1: p = TLSv1_method(); break; case HB_SSL_CTX_NEW_METHOD_TLSV1_SERVER: p = TLSv1_server_method(); break; case HB_SSL_CTX_NEW_METHOD_TLSV1_CLIENT: p = TLSv1_client_method(); break; case HB_SSL_CTX_NEW_METHOD_TLS: p = SSLv23_method(); break; case HB_SSL_CTX_NEW_METHOD_TLS_SERVER: p = SSLv23_server_method(); break; case HB_SSL_CTX_NEW_METHOD_TLS_CLIENT: p = SSLv23_client_method(); break; #endif default: p = SSLv23_method(); } return p; }
MonoBtlsSslCtx * mono_btls_ssl_ctx_new (void) { MonoBtlsSslCtx *ctx; ctx = OPENSSL_malloc (sizeof (MonoBtlsSslCtx)); if (!ctx) return NULL; memset (ctx, 0, sizeof (MonoBtlsSslCtx)); ctx->references = 1; ctx->ctx = SSL_CTX_new (TLS_method ()); // enable the default ciphers but disable any RC4 based ciphers // since they're insecure: RFC 7465 "Prohibiting RC4 Cipher Suites" SSL_CTX_set_cipher_list (ctx->ctx, "DEFAULT:!RC4"); // disable SSLv2 and SSLv3 by default, they are deprecated // and should generally not be used according to the openssl docs SSL_CTX_set_options (ctx->ctx, SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3); return ctx; }
const SSL_METHOD *TLS_server_method(void) { return TLS_method(); }
static int test_tls13_encryption(void) { SSL_CTX *ctx = NULL; SSL *s = NULL; SSL3_RECORD rec; unsigned char *key = NULL, *iv = NULL, *seq = NULL; const EVP_CIPHER *ciph = EVP_aes_128_gcm(); int ret = 0; size_t ivlen, ctr; /* * Encrypted TLSv1.3 records always have an outer content type of * application data, and a record version of TLSv1.2. */ rec.data = NULL; rec.type = SSL3_RT_APPLICATION_DATA; rec.rec_version = TLS1_2_VERSION; ctx = SSL_CTX_new(TLS_method()); if (!TEST_ptr(ctx)) { TEST_info("Failed creating SSL_CTX"); goto err; } s = SSL_new(ctx); if (!TEST_ptr(s)) { TEST_info("Failed creating SSL"); goto err; } s->enc_read_ctx = EVP_CIPHER_CTX_new(); if (!TEST_ptr(s->enc_read_ctx)) goto err; s->enc_write_ctx = EVP_CIPHER_CTX_new(); if (!TEST_ptr(s->enc_write_ctx)) goto err; s->s3->tmp.new_cipher = SSL_CIPHER_find(s, TLS13_AES_128_GCM_SHA256_BYTES); if (!TEST_ptr(s->s3->tmp.new_cipher)) { TEST_info("Failed to find cipher"); goto err; } for (ctr = 0; ctr < OSSL_NELEM(refdata); ctr++) { /* Load the record */ ivlen = EVP_CIPHER_iv_length(ciph); if (!load_record(&rec, &refdata[ctr], &key, s->read_iv, ivlen, RECORD_LAYER_get_read_sequence(&s->rlayer))) { TEST_error("Failed loading key into EVP_CIPHER_CTX"); goto err; } /* Set up the read/write sequences */ memcpy(RECORD_LAYER_get_write_sequence(&s->rlayer), RECORD_LAYER_get_read_sequence(&s->rlayer), SEQ_NUM_SIZE); memcpy(s->write_iv, s->read_iv, ivlen); /* Load the key into the EVP_CIPHER_CTXs */ if (EVP_CipherInit_ex(s->enc_write_ctx, ciph, NULL, key, NULL, 1) <= 0 || EVP_CipherInit_ex(s->enc_read_ctx, ciph, NULL, key, NULL, 0) <= 0) { TEST_error("Failed loading key into EVP_CIPHER_CTX\n"); goto err; } /* Encrypt it */ if (!TEST_size_t_eq(tls13_enc(s, &rec, 1, 1), 1)) { TEST_info("Failed to encrypt record %zu", ctr); goto err; } if (!TEST_true(test_record(&rec, &refdata[ctr], 1))) { TEST_info("Record %zu encryption test failed", ctr); goto err; } /* Decrypt it */ if (!TEST_int_eq(tls13_enc(s, &rec, 1, 0), 1)) { TEST_info("Failed to decrypt record %zu", ctr); goto err; } if (!TEST_true(test_record(&rec, &refdata[ctr], 0))) { TEST_info("Record %zu decryption test failed", ctr); goto err; } OPENSSL_free(rec.data); OPENSSL_free(key); OPENSSL_free(iv); OPENSSL_free(seq); rec.data = NULL; key = NULL; iv = NULL; seq = NULL; } TEST_note("PASS: %zu records tested", ctr); ret = 1; err: OPENSSL_free(rec.data); OPENSSL_free(key); OPENSSL_free(iv); OPENSSL_free(seq); SSL_free(s); SSL_CTX_free(ctx); return ret; }
void Families::LoadCertificate (const std::string& filename) { SSL_CTX * ctx = SSL_CTX_new (TLS_method ()); int ret = SSL_CTX_use_certificate_file (ctx, filename.c_str (), SSL_FILETYPE_PEM); if (ret) { SSL * ssl = SSL_new (ctx); X509 * cert = SSL_get_certificate (ssl); if (cert) { std::shared_ptr<i2p::crypto::Verifier> verifier; // extract issuer name char name[100]; X509_NAME_oneline (X509_get_issuer_name(cert), name, 100); char * cn = strstr (name, "CN="); if (cn) { cn += 3; char * family = strstr (cn, ".family"); if (family) family[0] = 0; } auto pkey = X509_get_pubkey (cert); int keyType = EVP_PKEY_base_id (pkey); switch (keyType) { case EVP_PKEY_DSA: // TODO: break; case EVP_PKEY_EC: { EC_KEY * ecKey = EVP_PKEY_get1_EC_KEY (pkey); if (ecKey) { auto group = EC_KEY_get0_group (ecKey); if (group) { int curve = EC_GROUP_get_curve_name (group); if (curve == NID_X9_62_prime256v1) { uint8_t signingKey[64]; BIGNUM * x = BN_new(), * y = BN_new(); EC_POINT_get_affine_coordinates_GFp (group, EC_KEY_get0_public_key (ecKey), x, y, NULL); i2p::crypto::bn2buf (x, signingKey, 32); i2p::crypto::bn2buf (y, signingKey + 32, 32); BN_free (x); BN_free (y); verifier = std::make_shared<i2p::crypto::ECDSAP256Verifier>(); verifier->SetPublicKey (signingKey); } else LogPrint (eLogWarning, "Family: elliptic curve ", curve, " is not supported"); } EC_KEY_free (ecKey); } break; } default: LogPrint (eLogWarning, "Family: Certificate key type ", keyType, " is not supported"); } EVP_PKEY_free (pkey); if (verifier && cn) m_SigningKeys[cn] = verifier; } SSL_free (ssl); } else LogPrint (eLogError, "Family: Can't open certificate file ", filename); SSL_CTX_free (ctx); }
static int test_handshake_secrets(void) { SSL_CTX *ctx = NULL; SSL *s = NULL; int ret = 0; size_t hashsize; unsigned char out_master_secret[EVP_MAX_MD_SIZE]; size_t master_secret_length; ctx = SSL_CTX_new(TLS_method()); if (ctx == NULL) goto err; s = SSL_new(ctx); if (s == NULL) goto err; s->session = SSL_SESSION_new(); if (s->session == NULL) goto err; if (!tls13_generate_secret(s, ssl_handshake_md(s), NULL, NULL, 0, (unsigned char *)&s->early_secret)) { fprintf(stderr, "Early secret generation failed\n"); goto err; } if (memcmp(s->early_secret, early_secret, sizeof(early_secret)) != 0) { fprintf(stderr, "Early secret does not match\n"); goto err; } if (!tls13_generate_handshake_secret(s, ecdhe_secret, sizeof(ecdhe_secret))) { fprintf(stderr, "Hanshake secret generation failed\n"); goto err; } if (memcmp(s->handshake_secret, handshake_secret, sizeof(handshake_secret)) != 0) { fprintf(stderr, "Handshake secret does not match\n"); goto err; } hashsize = EVP_MD_size(ssl_handshake_md(s)); if (sizeof(client_hts) != hashsize || sizeof(client_hts_key) != KEYLEN || sizeof(client_hts_iv) != IVLEN) { fprintf(stderr, "Internal test error\n"); goto err; } if (!test_secret(s, s->handshake_secret, (unsigned char *)client_hts_label, strlen(client_hts_label), client_hts, client_hts_key, client_hts_iv)) { fprintf(stderr, "Client handshake secret test failed\n"); goto err; } if (sizeof(server_hts) != hashsize || sizeof(server_hts_key) != KEYLEN || sizeof(server_hts_iv) != IVLEN) { fprintf(stderr, "Internal test error\n"); goto err; } if (!test_secret(s, s->handshake_secret, (unsigned char *)server_hts_label, strlen(server_hts_label), server_hts, server_hts_key, server_hts_iv)) { fprintf(stderr, "Server handshake secret test failed\n"); goto err; } /* * Ensure the mocked out ssl_handshake_hash() returns the full handshake * hash. */ full_hash = 1; if (!tls13_generate_master_secret(s, out_master_secret, s->handshake_secret, hashsize, &master_secret_length)) { fprintf(stderr, "Master secret generation failed\n"); goto err; } if (master_secret_length != sizeof(master_secret) || memcmp(out_master_secret, master_secret, sizeof(master_secret)) != 0) { fprintf(stderr, "Master secret does not match\n"); goto err; } if (sizeof(client_ats) != hashsize || sizeof(client_ats_key) != KEYLEN || sizeof(client_ats_iv) != IVLEN) { fprintf(stderr, "Internal test error\n"); goto err; } if (!test_secret(s, out_master_secret, (unsigned char *)client_ats_label, strlen(client_ats_label), client_ats, client_ats_key, client_ats_iv)) { fprintf(stderr, "Client application data secret test failed\n"); goto err; } if (sizeof(server_ats) != hashsize || sizeof(server_ats_key) != KEYLEN || sizeof(server_ats_iv) != IVLEN) { fprintf(stderr, "Internal test error\n"); goto err; } if (!test_secret(s, out_master_secret, (unsigned char *)server_ats_label, strlen(server_ats_label), server_ats, server_ats_key, server_ats_iv)) { fprintf(stderr, "Server application data secret test failed\n"); goto err; } ret = 1; err: SSL_free(s); SSL_CTX_free(ctx); return ret; }
int main(int argc, char *argv[]) { unsigned int bundleLength=0, urlLength=0; if (argc == 3) { printf("UNSUPPORTED\n"); //for now at least return EXIT_SUCCESS; } else if (argc != 4) { printf("usage: %s <host> <port> <ca-bundle>\n", argv[0]); return EXIT_FAILURE; } else if ((urlLength = strlen(argv[1]) + strlen(argv[2]) + 2) > MAX_LENGTH) { printf("Too long URL: %d characters, max: %d\n", urlLength, MAX_LENGTH); return EXIT_FAILURE; } else if ((bundleLength = strlen(argv[3]) + 1) > MAX_LENGTH) { printf("Too long ca-bundle filepath: %d characters, max: %d\n", bundleLength, MAX_LENGTH); return EXIT_FAILURE; } char url[1024]; snprintf(url, sizeof(url), "%s:%s", argv[1], argv[2]); char ca_bundle[1024]; memcpy(ca_bundle, argv[3], bundleLength); int exitvalue = 0; BIO *sbio; SSL_CTX *ssl_ctx; SSL *ssl; X509 *cert; const char *servername = NULL; X509_VERIFY_PARAM *param = NULL; SSL_load_error_strings(); SSL_library_init(); ssl_ctx = SSL_CTX_new(TLS_method()); //if you are using an older version of openssl, you may need to change this into for example: TLSv1_2_client_method param = SSL_CTX_get0_param(ssl_ctx); //set certificate verify //https://wiki.openssl.org/index.php/Hostname_validation X509_VERIFY_PARAM_set_hostflags(param, X509_CHECK_FLAG_NO_PARTIAL_WILDCARDS); X509_VERIFY_PARAM_set1_host(param, argv[1], 0); SSL_CTX_set_verify(ssl_ctx, SSL_VERIFY_PEER, NULL); if (SSL_CTX_load_verify_locations(ssl_ctx, ca_bundle, NULL) != 1) { printf("Couldn't load certificate trust store\n"); printf("%s\n", ERR_reason_error_string(ERR_get_error())); exitvalue=EXIT_FAILURE; goto end; } sbio = BIO_new_ssl_connect(ssl_ctx); BIO_get_ssl(sbio, &ssl); if (!ssl) { printf("Connection failed\n"); printf("%s\n", ERR_reason_error_string(ERR_get_error())); exitvalue=EXIT_FAILURE; goto connect_end; } //handshake SSL_set_tlsext_host_name(ssl, url); BIO_set_conn_hostname(sbio, url); if(SSL_do_handshake(ssl) <= 0) { unsigned long int error = ERR_get_error(); printf("%s\n", ERR_reason_error_string(error)); printf("REJECT\n"); } else { printf ("ACCEPT\n"); } connect_end: BIO_free_all(sbio); end: SSL_CTX_free(ssl_ctx); EVP_cleanup(); ERR_free_strings(); return exitvalue; }
int ssl_run(int sd) { SSL_CTX *ctx = SSL_CTX_new(TLS_method()); int ssl_opts = (SSL_OP_ALL & ~SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS) | SSL_OP_SINGLE_ECDH_USE | SSL_OP_CIPHER_SERVER_PREFERENCE; SSL_CTX_set_options(ctx, ssl_opts); struct timespec tp[3]; clock_gettime(CLOCK_REALTIME, &tp[0]); SSL_CTX_use_certificate_file(ctx, "gw.cert.pem", SSL_FILETYPE_PEM); SSL_CTX_set_default_passwd_cb(ctx, password_cb); SSL_CTX_use_PrivateKey_file(ctx, "gw.key.pem", SSL_FILETYPE_PEM); SSL_CTX_set_verify(ctx, SSL_VERIFY_NONE, 0); SSL *ssl = SSL_new(ctx); BIO *accept_bio = BIO_new_socket(sd, BIO_CLOSE); SSL_set_bio(ssl, accept_bio, accept_bio); SSL_accept(ssl); ERR_print_errors_fp(stderr); BIO *bio = BIO_pop(accept_bio); clock_gettime(CLOCK_REALTIME, &tp[1]); char buf[8192]; while (1) { // first read data int r = SSL_read(ssl, buf, sizeof buf); switch (SSL_get_error(ssl, r)) { case SSL_ERROR_NONE: break; case SSL_ERROR_ZERO_RETURN: goto end; default: printf("SSL read problem"); goto end; } clock_gettime(CLOCK_REALTIME, &tp[2]); long sh_time = (tp[1].tv_sec - tp[0].tv_sec) * 1000 + (tp[1].tv_nsec - tp[0].tv_nsec) / 1000000; long serv_time = (tp[2].tv_sec - tp[1].tv_sec) * 1000000 + (tp[2].tv_nsec - tp[1].tv_nsec) / 1000; char content[200]; int cnt_len = snprintf(content, sizeof (content), "ssl hank shake: %ldms, service: %ldus\r\n", sh_time, serv_time); int len = snprintf(buf, sizeof buf, "HTTP/1.1 200 OK\r\n" "Content-Type: text/plain\r\n" "Content-Length: %d\r\n" "Access-Control-Allow-Origin: *\r\n\r\n%s", cnt_len, content); // now keep writing until we've written everything int offset = 0; while (len) { r = SSL_write(ssl, buf + offset, len); switch (SSL_get_error(ssl, r)) { case SSL_ERROR_NONE: len -= r; offset += r; break; default: printf("SSL write problem"); goto end; } } break; } end: SSL_shutdown(ssl); BIO_free_all(bio); BIO_free_all(accept_bio); }
const SSL_METHOD * SSLv23_method(void) { return (TLS_method()); }
static int test_ssl_set_bio(int idx) { SSL_CTX *ctx = SSL_CTX_new(TLS_method()); BIO *bio1 = NULL; BIO *bio2 = NULL; BIO *irbio = NULL, *iwbio = NULL, *nrbio = NULL, *nwbio = NULL; SSL *ssl = NULL; int initrbio, initwbio, newrbio, newwbio; int testresult = 0; if (ctx == NULL) { printf("Failed to allocate SSL_CTX\n"); goto end; } ssl = SSL_new(ctx); if (ssl == NULL) { printf("Failed to allocate SSL object\n"); goto end; } initrbio = idx % 3; idx /= 3; initwbio = idx % 3; idx /= 3; newrbio = idx % 3; idx /= 3; newwbio = idx; OPENSSL_assert(newwbio <= 2); if (initrbio == USE_BIO_1 || initwbio == USE_BIO_1 || newrbio == USE_BIO_1 || newwbio == USE_BIO_1) { bio1 = BIO_new(BIO_s_mem()); if (bio1 == NULL) { printf("Failed to allocate bio1\n"); goto end; } } if (initrbio == USE_BIO_2 || initwbio == USE_BIO_2 || newrbio == USE_BIO_2 || newwbio == USE_BIO_2) { bio2 = BIO_new(BIO_s_mem()); if (bio2 == NULL) { printf("Failed to allocate bio2\n"); goto end; } } setupbio(&irbio, bio1, bio2, initrbio); setupbio(&iwbio, bio1, bio2, initwbio); /* * We want to maintain our own refs to these BIO, so do an up ref for each * BIO that will have ownership transferred in the SSL_set_bio() call */ if (irbio != NULL) BIO_up_ref(irbio); if (iwbio != NULL && iwbio != irbio) BIO_up_ref(iwbio); SSL_set_bio(ssl, irbio, iwbio); setupbio(&nrbio, bio1, bio2, newrbio); setupbio(&nwbio, bio1, bio2, newwbio); /* * We will (maybe) transfer ownership again so do more up refs. * SSL_set_bio() has some really complicated ownership rules where BIOs have * already been set! */ if (nrbio != NULL && nrbio != irbio && (nwbio != iwbio || nrbio != nwbio)) BIO_up_ref(nrbio); if (nwbio != NULL && nwbio != nrbio && (nwbio != iwbio || (nwbio == iwbio && irbio == iwbio))) BIO_up_ref(nwbio); SSL_set_bio(ssl, nrbio, nwbio); testresult = 1; end: SSL_free(ssl); BIO_free(bio1); BIO_free(bio2); /* * This test is checking that the ref counting for SSL_set_bio is correct. * If we get here and we did too many frees then we will fail in the above * functions. If we haven't done enough then this will only be detected in * a crypto-mdebug build */ SSL_CTX_free(ctx); return testresult; }
static int test_client_hello(int currtest) { SSL_CTX *ctx; SSL *con = NULL; BIO *rbio; BIO *wbio; long len; unsigned char *data; PACKET pkt = {0}, pkt2 = {0}, pkt3 = {0}; char *dummytick = "Hello World!"; unsigned int type = 0; int testresult = 0; size_t msglen; BIO *sessbio = NULL; SSL_SESSION *sess = NULL; #ifdef OPENSSL_NO_TLS1_3 if (currtest == TEST_ADD_PADDING_AND_PSK) return 1; #endif /* * For each test set up an SSL_CTX and SSL and see what ClientHello gets * produced when we try to connect */ ctx = SSL_CTX_new(TLS_method()); if (!TEST_ptr(ctx)) goto end; switch(currtest) { case TEST_SET_SESSION_TICK_DATA_VER_NEG: /* Testing for session tickets <= TLS1.2; not relevant for 1.3 */ if (!TEST_true(SSL_CTX_set_max_proto_version(ctx, TLS1_2_VERSION))) goto end; break; case TEST_ADD_PADDING_AND_PSK: case TEST_ADD_PADDING: case TEST_PADDING_NOT_NEEDED: SSL_CTX_set_options(ctx, SSL_OP_TLSEXT_PADDING); /* * Add lots of ciphersuites so that the ClientHello is at least * F5_WORKAROUND_MIN_MSG_LEN bytes long - meaning padding will be * needed. Also add some dummy ALPN protocols in case we still don't * have enough. */ if (currtest == TEST_ADD_PADDING && (!TEST_true(SSL_CTX_set_cipher_list(ctx, "ALL")) || !TEST_false(SSL_CTX_set_alpn_protos(ctx, (unsigned char *)alpn_prots, sizeof(alpn_prots) - 1)))) goto end; break; default: goto end; } con = SSL_new(ctx); if (!TEST_ptr(con)) goto end; if (currtest == TEST_ADD_PADDING_AND_PSK) { sessbio = BIO_new_file(sessionfile, "r"); if (!TEST_ptr(sessbio)) { TEST_info("Unable to open session.pem"); goto end; } sess = PEM_read_bio_SSL_SESSION(sessbio, NULL, NULL, NULL); if (!TEST_ptr(sess)) { TEST_info("Unable to load SSL_SESSION"); goto end; } /* * We reset the creation time so that we don't discard the session as * too old. */ if (!TEST_true(SSL_SESSION_set_time(sess, time(NULL))) || !TEST_true(SSL_set_session(con, sess))) goto end; } rbio = BIO_new(BIO_s_mem()); wbio = BIO_new(BIO_s_mem()); if (!TEST_ptr(rbio)|| !TEST_ptr(wbio)) { BIO_free(rbio); BIO_free(wbio); goto end; } SSL_set_bio(con, rbio, wbio); SSL_set_connect_state(con); if (currtest == TEST_SET_SESSION_TICK_DATA_VER_NEG) { if (!TEST_true(SSL_set_session_ticket_ext(con, dummytick, strlen(dummytick)))) goto end; } if (!TEST_int_le(SSL_connect(con), 0)) { /* This shouldn't succeed because we don't have a server! */ goto end; } len = BIO_get_mem_data(wbio, (char **)&data); if (!TEST_true(PACKET_buf_init(&pkt, data, len)) /* Skip the record header */ || !PACKET_forward(&pkt, SSL3_RT_HEADER_LENGTH)) goto end; msglen = PACKET_remaining(&pkt); /* Skip the handshake message header */ if (!TEST_true(PACKET_forward(&pkt, SSL3_HM_HEADER_LENGTH)) /* Skip client version and random */ || !TEST_true(PACKET_forward(&pkt, CLIENT_VERSION_LEN + SSL3_RANDOM_SIZE)) /* Skip session id */ || !TEST_true(PACKET_get_length_prefixed_1(&pkt, &pkt2)) /* Skip ciphers */ || !TEST_true(PACKET_get_length_prefixed_2(&pkt, &pkt2)) /* Skip compression */ || !TEST_true(PACKET_get_length_prefixed_1(&pkt, &pkt2)) /* Extensions len */ || !TEST_true(PACKET_as_length_prefixed_2(&pkt, &pkt2))) goto end; /* Loop through all extensions */ while (PACKET_remaining(&pkt2)) { if (!TEST_true(PACKET_get_net_2(&pkt2, &type)) || !TEST_true(PACKET_get_length_prefixed_2(&pkt2, &pkt3))) goto end; if (type == TLSEXT_TYPE_session_ticket) { if (currtest == TEST_SET_SESSION_TICK_DATA_VER_NEG) { if (TEST_true(PACKET_equal(&pkt3, dummytick, strlen(dummytick)))) { /* Ticket data is as we expected */ testresult = 1; } goto end; } } if (type == TLSEXT_TYPE_padding) { if (!TEST_false(currtest == TEST_PADDING_NOT_NEEDED)) goto end; else if (TEST_true(currtest == TEST_ADD_PADDING || currtest == TEST_ADD_PADDING_AND_PSK)) testresult = TEST_true(msglen == F5_WORKAROUND_MAX_MSG_LEN); } } if (currtest == TEST_PADDING_NOT_NEEDED) testresult = 1; end: SSL_free(con); SSL_CTX_free(ctx); SSL_SESSION_free(sess); BIO_free(sessbio); return testresult; }
int main(int argc, char **argv) { int i; int socklen; int use_ssl = 0; struct evconnlistener *listener; if (argc < 3) syntax(); for (i=1; i < argc; ++i) { if (!strcmp(argv[i], "-s")) { use_ssl = 1; } else if (!strcmp(argv[i], "-W")) { use_wrapper = 0; } else if (argv[i][0] == '-') { syntax(); } else break; } if (i+2 != argc) syntax(); memset(&listen_on_addr, 0, sizeof(listen_on_addr)); socklen = sizeof(listen_on_addr); if (evutil_parse_sockaddr_port(argv[i], (struct sockaddr*)&listen_on_addr, &socklen)<0) { int p = atoi(argv[i]); struct sockaddr_in *sin = (struct sockaddr_in*)&listen_on_addr; if (p < 1 || p > 65535) syntax(); sin->sin_port = htons(p); sin->sin_addr.s_addr = htonl(0x7f000001); sin->sin_family = AF_INET; socklen = sizeof(struct sockaddr_in); } memset(&connect_to_addr, 0, sizeof(connect_to_addr)); connect_to_addrlen = sizeof(connect_to_addr); if (evutil_parse_sockaddr_port(argv[i+1], (struct sockaddr*)&connect_to_addr, &connect_to_addrlen)<0) syntax(); base = event_base_new(); if (!base) { perror("event_base_new()"); return 1; } if (use_ssl) { int r; #if (OPENSSL_VERSION_NUMBER < 0x10100000L) || defined(LIBRESSL_VERSION_NUMBER) SSL_library_init(); ERR_load_crypto_strings(); SSL_load_error_strings(); OpenSSL_add_all_algorithms(); #endif r = RAND_poll(); if (r == 0) { fprintf(stderr, "RAND_poll() failed.\n"); return 1; } ssl_ctx = SSL_CTX_new(TLS_method()); } listener = evconnlistener_new_bind(base, accept_cb, NULL, LEV_OPT_CLOSE_ON_FREE|LEV_OPT_CLOSE_ON_EXEC|LEV_OPT_REUSEABLE, -1, (struct sockaddr*)&listen_on_addr, socklen); if (! listener) { fprintf(stderr, "Couldn't open listener.\n"); event_base_free(base); return 1; } event_base_dispatch(base); evconnlistener_free(listener); event_base_free(base); return 0; }
static int execute_test_ssl_bio(SSL_BIO_TEST_FIXTURE fix) { BIO *sslbio = NULL, *membio1 = NULL, *membio2 = NULL; SSL_CTX *ctx = SSL_CTX_new(TLS_method()); SSL *ssl = NULL; int testresult = 0; if (ctx == NULL) { printf("Failed to allocate SSL_CTX\n"); return 0; } ssl = SSL_new(ctx); if (ssl == NULL) { printf("Failed to allocate SSL object\n"); goto end; } sslbio = BIO_new(BIO_f_ssl()); membio1 = BIO_new(BIO_s_mem()); if (sslbio == NULL || membio1 == NULL) { printf("Malloc failure creating BIOs\n"); goto end; } BIO_set_ssl(sslbio, ssl, BIO_CLOSE); /* * If anything goes wrong here then we could leak memory, so this will * be caught in a crypto-mdebug build */ BIO_push(sslbio, membio1); /* Verify changing the rbio/wbio directly does not cause leaks */ if (fix.change_bio != NO_BIO_CHANGE) { membio2 = BIO_new(BIO_s_mem()); if (membio2 == NULL) { printf("Malloc failure creating membio2\n"); goto end; } if (fix.change_bio == CHANGE_RBIO) SSL_set0_rbio(ssl, membio2); else SSL_set0_wbio(ssl, membio2); } ssl = NULL; if (fix.pop_ssl) BIO_pop(sslbio); else BIO_pop(membio1); testresult = 1; end: BIO_free(membio1); BIO_free(sslbio); SSL_free(ssl); SSL_CTX_free(ctx); return testresult; }
const SSL_METHOD *TLS_client_method(void) { return TLS_method(); }
static int test_handshake_secrets(void) { SSL_CTX *ctx = NULL; SSL *s = NULL; int ret = 0; size_t hashsize; unsigned char out_master_secret[EVP_MAX_MD_SIZE]; size_t master_secret_length; ctx = SSL_CTX_new(TLS_method()); if (!TEST_ptr(ctx)) goto err; s = SSL_new(ctx); if (!TEST_ptr(s )) goto err; s->session = SSL_SESSION_new(); if (!TEST_ptr(s->session)) goto err; if (!TEST_true(tls13_generate_secret(s, ssl_handshake_md(s), NULL, NULL, 0, (unsigned char *)&s->early_secret))) { TEST_info("Early secret generation failed"); goto err; } if (!TEST_mem_eq(s->early_secret, sizeof(early_secret), early_secret, sizeof(early_secret))) { TEST_info("Early secret does not match"); goto err; } if (!TEST_true(tls13_generate_handshake_secret(s, ecdhe_secret, sizeof(ecdhe_secret)))) { TEST_info("Hanshake secret generation failed"); goto err; } if (!TEST_mem_eq(s->handshake_secret, sizeof(handshake_secret), handshake_secret, sizeof(handshake_secret))) goto err; hashsize = EVP_MD_size(ssl_handshake_md(s)); if (!TEST_size_t_eq(sizeof(client_hts), hashsize)) goto err; if (!TEST_size_t_eq(sizeof(client_hts_key), KEYLEN)) goto err; if (!TEST_size_t_eq(sizeof(client_hts_iv), IVLEN)) goto err; if (!TEST_true(test_secret(s, s->handshake_secret, (unsigned char *)client_hts_label, strlen(client_hts_label), client_hts, client_hts_key, client_hts_iv))) { TEST_info("Client handshake secret test failed"); goto err; } if (!TEST_size_t_eq(sizeof(server_hts), hashsize)) goto err; if (!TEST_size_t_eq(sizeof(server_hts_key), KEYLEN)) goto err; if (!TEST_size_t_eq(sizeof(server_hts_iv), IVLEN)) goto err; if (!TEST_true(test_secret(s, s->handshake_secret, (unsigned char *)server_hts_label, strlen(server_hts_label), server_hts, server_hts_key, server_hts_iv))) { TEST_info("Server handshake secret test failed"); goto err; } /* * Ensure the mocked out ssl_handshake_hash() returns the full handshake * hash. */ full_hash = 1; if (!TEST_true(tls13_generate_master_secret(s, out_master_secret, s->handshake_secret, hashsize, &master_secret_length))) { TEST_info("Master secret generation failed"); goto err; } if (!TEST_mem_eq(out_master_secret, master_secret_length, master_secret, sizeof(master_secret))) { TEST_info("Master secret does not match"); goto err; } if (!TEST_size_t_eq(sizeof(client_ats), hashsize)) goto err; if (!TEST_size_t_eq(sizeof(client_ats_key), KEYLEN)) goto err; if (!TEST_size_t_eq(sizeof(client_ats_iv), IVLEN)) goto err; if (!TEST_true(test_secret(s, out_master_secret, (unsigned char *)client_ats_label, strlen(client_ats_label), client_ats, client_ats_key, client_ats_iv))) { TEST_info("Client application data secret test failed"); goto err; } if (!TEST_size_t_eq(sizeof(server_ats), hashsize)) goto err; if (!TEST_size_t_eq(sizeof(server_ats_key), KEYLEN)) goto err; if (!TEST_size_t_eq(sizeof(server_ats_iv), IVLEN)) goto err; if (!TEST_true(test_secret(s, out_master_secret, (unsigned char *)server_ats_label, strlen(server_ats_label), server_ats, server_ats_key, server_ats_iv))) { TEST_info("Server application data secret test failed"); goto err; } ret = 1; err: SSL_free(s); SSL_CTX_free(ctx); return ret; }
SSL_CTX* SslHelper::genSslCtx(const std::string& keyPath, const std::string& certPath, const std::string& caPath, const std::string& caFile, bool verifyPeer, int depth) { /* This method supprots from SSLv3 to newest TLS. SSLv3 will be disabled * below. */ const SSL_METHOD* m = TLS_method(); SSL_CTX* sslCtx = SSL_CTX_new(m); if (!sslCtx) { /* If here, did you forget to call SslHelper::init()? */ PARROT_ASSERT(0); } const char* caFilePtr = nullptr; const char* caPathPtr = nullptr; if (caFile.length() > 0) { caFilePtr = caFile.c_str(); } if (caPath.length() > 0) { caPathPtr = caPath.c_str(); } /* Add ca-cert to SSL_CTX. */ if (caFilePtr || caPathPtr) { /* Add ca-cert file. */ if (SSL_CTX_load_verify_locations(sslCtx, caFilePtr, caPathPtr) != 1) { PARROT_ASSERT(0); } } /* Add cert to SSL_CTX. */ if (caPath.length() > 0 && SSL_CTX_use_certificate_file(sslCtx, certPath.c_str(), SSL_FILETYPE_PEM) <= 0) { PARROT_ASSERT(0); } // Add private key to SSL_CTX. if (keyPath.length() > 0 && SSL_CTX_use_PrivateKey_file(sslCtx, keyPath.c_str(), SSL_FILETYPE_PEM) != 1) { PARROT_ASSERT(0); } // Enable nonblock. SSL_CTX_set_mode(sslCtx, SSL_MODE_ENABLE_PARTIAL_WRITE | SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER); if (verifyPeer) { /* We need to verify peer, but the client doesn't tell us where * to find the ca-certs, we use default. */ if (caPath.empty()) { if (SSL_CTX_set_default_verify_paths(sslCtx) != 1) { PARROT_ASSERT(0); } } SSL_CTX_set_verify( sslCtx, SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, nullptr); SSL_CTX_set_verify_depth(sslCtx, depth); } else { SSL_CTX_set_verify(sslCtx, SSL_VERIFY_NONE, nullptr); } /* TLSv1.0 is the minimal requirement. SSLv3.0 will not be supported. */ PARROT_ASSERT(SSL_CTX_set_min_proto_version(sslCtx, TLS1_VERSION) == 1); return sslCtx; }