/* Create SSL_CTX. */ static SSL_CTX* create_ssl_ctx(const char *key_file, const char *cert_file) { SSL_CTX *ssl_ctx; ssl_ctx = SSL_CTX_new(SSLv23_server_method()); if(!ssl_ctx) { errx(1, "Could not create SSL/TLS context: %s", ERR_error_string(ERR_get_error(), NULL)); } SSL_CTX_set_options(ssl_ctx, SSL_OP_ALL | SSL_OP_NO_SSLv2 | SSL_OP_NO_COMPRESSION | SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION); if(SSL_CTX_use_PrivateKey_file(ssl_ctx, key_file, SSL_FILETYPE_PEM) != 1) { errx(1, "Could not read private key file %s", key_file); } if(SSL_CTX_use_certificate_chain_file(ssl_ctx, cert_file) != 1) { errx(1, "Could not read certificate file %s", cert_file); } next_proto_list[0] = NGHTTP2_PROTO_VERSION_ID_LEN; memcpy(&next_proto_list[1], NGHTTP2_PROTO_VERSION_ID, NGHTTP2_PROTO_VERSION_ID_LEN); next_proto_list_len = 1 + NGHTTP2_PROTO_VERSION_ID_LEN; SSL_CTX_set_next_protos_advertised_cb(ssl_ctx, next_proto_cb, NULL); return ssl_ctx; }
bool SSLContext::setRandomizedAdvertisedNextProtocols( const std::list<NextProtocolsItem>& items, NextProtocolType protocolType) { unsetNextProtocols(); if (items.size() == 0) { return false; } int total_weight = 0; for (const auto &item : items) { if (item.protocols.size() == 0) { continue; } AdvertisedNextProtocolsItem advertised_item; advertised_item.length = 0; for (const auto& proto : item.protocols) { ++advertised_item.length; unsigned protoLength = proto.length(); if (protoLength >= 256) { deleteNextProtocolsStrings(); return false; } advertised_item.length += protoLength; } advertised_item.protocols = new unsigned char[advertised_item.length]; if (!advertised_item.protocols) { throw std::runtime_error("alloc failure"); } unsigned char* dst = advertised_item.protocols; for (auto& proto : item.protocols) { unsigned protoLength = proto.length(); *dst++ = (unsigned char)protoLength; memcpy(dst, proto.data(), protoLength); dst += protoLength; } total_weight += item.weight; advertisedNextProtocols_.push_back(advertised_item); advertisedNextProtocolWeights_.push_back(item.weight); } if (total_weight == 0) { deleteNextProtocolsStrings(); return false; } nextProtocolDistribution_ = std::discrete_distribution<>(advertisedNextProtocolWeights_.begin(), advertisedNextProtocolWeights_.end()); if ((uint8_t)protocolType & (uint8_t)NextProtocolType::NPN) { SSL_CTX_set_next_protos_advertised_cb( ctx_, advertisedNextProtocolCallback, this); SSL_CTX_set_next_proto_select_cb(ctx_, selectNextProtocolCallback, this); } #if OPENSSL_VERSION_NUMBER >= 0x1000200fL && !defined(OPENSSL_NO_TLSEXT) if ((uint8_t)protocolType & (uint8_t)NextProtocolType::ALPN) { SSL_CTX_set_alpn_select_cb(ctx_, alpnSelectCallback, this); // Client cannot really use randomized alpn SSL_CTX_set_alpn_protos(ctx_, advertisedNextProtocols_[0].protocols, advertisedNextProtocols_[0].length); } #endif return true; }
void SSLContext::unsetNextProtocols() { deleteNextProtocolsStrings(); SSL_CTX_set_next_protos_advertised_cb(ctx_, nullptr, nullptr); SSL_CTX_set_next_proto_select_cb(ctx_, nullptr, nullptr); #if OPENSSL_VERSION_NUMBER >= 0x1000200fL && !defined(OPENSSL_NO_TLSEXT) SSL_CTX_set_alpn_select_cb(ctx_, nullptr, nullptr); SSL_CTX_set_alpn_protos(ctx_, nullptr, 0); #endif }
h2o_ssl_context_t *h2o_ssl_new_server_context(const char *cert_file, const char *key_file, const h2o_buf_t *protocols) { h2o_ssl_context_t *ctx = h2o_malloc(sizeof(*ctx)); memset(ctx, 0, sizeof(*ctx)); SSL_load_error_strings(); SSL_library_init(); OpenSSL_add_all_algorithms(); ctx->ctx = SSL_CTX_new(SSLv23_server_method()); SSL_CTX_set_options(ctx->ctx, SSL_OP_NO_SSLv2); /* load certificate and private key */ if (SSL_CTX_use_certificate_file(ctx->ctx, cert_file, SSL_FILETYPE_PEM) != 1) { fprintf(stderr, "an error occured while trying to load server certificate file:%s\n", cert_file); goto Error; } if (SSL_CTX_use_PrivateKey_file(ctx->ctx, key_file, SSL_FILETYPE_PEM) != 1) { fprintf(stderr, "an error occured while trying to load private key file:%s\n", key_file); goto Error; } /* copy list of protocols, init npm */ ctx->protocols = protocols; if (protocols != NULL) { size_t i, off; #if USE_ALPN SSL_CTX_set_alpn_select_cb(ctx->ctx, on_alpn_select, ctx); #endif #if USE_NPN SSL_CTX_set_next_protos_advertised_cb(ctx->ctx, on_npn_advertise, ctx); #endif for (i = 0; protocols[i].len != 0; ++i) { assert(protocols[i].len <= 255); ctx->_npn_list_of_protocols.len += 1 + protocols[i].len; } ctx->_npn_list_of_protocols.base = h2o_malloc(ctx->_npn_list_of_protocols.len); for (i = 0, off = 0; protocols[i].len != 0; ++i) { ((unsigned char*)ctx->_npn_list_of_protocols.base)[off++] = protocols[i].len; memcpy(ctx->_npn_list_of_protocols.base + off, protocols[i].base, protocols[i].len); off += protocols[i].len; } assert(off == ctx->_npn_list_of_protocols.len); } return ctx; Error: SSL_CTX_free(ctx->ctx); free(ctx); return NULL; }
int caucho_ssl_alpn_register_server(SSL_CTX *ctx, char *protocols) { if (! ctx || ! protocols) { return -1; } SSL_CTX_set_next_protos_advertised_cb(ctx, ssl_npn_server_cb, protocols); return 0; }
bool SSLContext::setRandomizedAdvertisedNextProtocols( const std::list<NextProtocolsItem>& items) { unsetNextProtocols(); if (items.size() == 0) { return false; } int total_weight = 0; for (const auto &item : items) { if (item.protocols.size() == 0) { continue; } AdvertisedNextProtocolsItem advertised_item; advertised_item.length = 0; for (const auto& proto : item.protocols) { ++advertised_item.length; unsigned protoLength = proto.length(); if (protoLength >= 256) { deleteNextProtocolsStrings(); return false; } advertised_item.length += protoLength; } advertised_item.protocols = new unsigned char[advertised_item.length]; if (!advertised_item.protocols) { throw std::runtime_error("alloc failure"); } unsigned char* dst = advertised_item.protocols; for (auto& proto : item.protocols) { unsigned protoLength = proto.length(); *dst++ = (unsigned char)protoLength; memcpy(dst, proto.data(), protoLength); dst += protoLength; } total_weight += item.weight; advertised_item.probability = item.weight; advertisedNextProtocols_.push_back(advertised_item); } if (total_weight == 0) { deleteNextProtocolsStrings(); return false; } for (auto &advertised_item : advertisedNextProtocols_) { advertised_item.probability /= total_weight; } SSL_CTX_set_next_protos_advertised_cb( ctx_, advertisedNextProtocolCallback, this); SSL_CTX_set_next_proto_select_cb( ctx_, selectNextProtocolCallback, this); return true; }
int SPDYF_openssl_init(struct SPDY_Daemon *daemon) { int options; //create ssl context. TLSv1 used if(NULL == (daemon->io_context = SSL_CTX_new(TLSv1_server_method()))) { SPDYF_DEBUG("Couldn't create ssl context"); return SPDY_NO; } //set options for tls //TODO DH is not enabled for easier debugging //SSL_CTX_set_options(daemon->io_context, SSL_OP_SINGLE_DH_USE); //TODO here session tickets are disabled for easier debuging with //wireshark when using Chrome // SSL_OP_NO_COMPRESSION disables TLS compression to avoid CRIME attack options = SSL_OP_NO_TICKET; #ifdef SSL_OP_NO_COMPRESSION options |= SSL_OP_NO_COMPRESSION; #elif OPENSSL_VERSION_NUMBER >= 0x00908000L /* workaround for OpenSSL 0.9.8 */ sk_SSL_COMP_zero(SSL_COMP_get_compression_methods()); #endif SSL_CTX_set_options(daemon->io_context, options); if(1 != SSL_CTX_use_certificate_file(daemon->io_context, daemon->certfile , SSL_FILETYPE_PEM)) { SPDYF_DEBUG("Couldn't load the cert file"); SSL_CTX_free(daemon->io_context); return SPDY_NO; } if(1 != SSL_CTX_use_PrivateKey_file(daemon->io_context, daemon->keyfile, SSL_FILETYPE_PEM)) { SPDYF_DEBUG("Couldn't load the name file"); SSL_CTX_free(daemon->io_context); return SPDY_NO; } SSL_CTX_set_next_protos_advertised_cb(daemon->io_context, &spdyf_next_protos_advertised_cb, NULL); //TODO only RC4-SHA is used to make it easy to debug with wireshark if (1 != SSL_CTX_set_cipher_list(daemon->io_context, "RC4-SHA")) { SPDYF_DEBUG("Couldn't set the desired cipher list"); SSL_CTX_free(daemon->io_context); return SPDY_NO; } return SPDY_YES; }
void swSSL_server_http_advise(SSL_CTX* ssl_context, swSSL_config *cfg) { #ifdef TLSEXT_TYPE_application_layer_protocol_negotiation SSL_CTX_set_alpn_select_cb(ssl_context, swSSL_alpn_advertised, cfg); #endif #ifdef TLSEXT_TYPE_next_proto_neg SSL_CTX_set_next_protos_advertised_cb(ssl_context, swSSL_npn_advertised, cfg); #endif if (cfg->http) { SSL_CTX_set_session_id_context(ssl_context, (const unsigned char *) "HTTP", strlen("HTTP")); SSL_CTX_set_session_cache_mode(ssl_context, SSL_SESS_CACHE_SERVER); SSL_CTX_sess_set_cache_size(ssl_context, 1); } }
void bb_socket_ssl(struct bb_acceptor *acceptor) { if (!blastbeat.ssl_initialized) { OPENSSL_config(NULL); SSL_library_init(); SSL_load_error_strings(); OpenSSL_add_all_algorithms(); blastbeat.ssl_initialized = 1; blastbeat.ssl_index = SSL_CTX_get_ex_new_index(0, NULL, NULL, NULL, NULL); } acceptor->ctx = SSL_CTX_new(SSLv23_server_method()); if (!acceptor->ctx) { fprintf(stderr, "unable to initialize SSL context: SSL_CTX_new()"); exit(1); } long ssloptions = SSL_OP_NO_SSLv2 | SSL_OP_ALL | SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION; // disable compression (if possibile) #ifdef SSL_OP_NO_COMPRESSION ssloptions |= SSL_OP_NO_COMPRESSION; #endif SSL_CTX_set_options(acceptor->ctx, ssloptions); // release/reuse buffers as soon as possibile #ifdef SSL_MODE_RELEASE_BUFFERS SSL_CTX_set_mode(acceptor->ctx, SSL_MODE_RELEASE_BUFFERS); #endif if (SSL_CTX_set_cipher_list(acceptor->ctx, "HIGH") == 0) { fprintf(stderr,"unable to set SSL ciphers: SSL_CTX_set_cipher_list()"); exit(1); } SSL_CTX_set_options(acceptor->ctx, SSL_OP_CIPHER_SERVER_PREFERENCE); SSL_CTX_set_info_callback(acceptor->ctx, bb_ssl_info_cb); #ifdef OPENSSL_NPN_UNSUPPORTED SSL_CTX_set_next_protos_advertised_cb(acceptor->ctx, bb_ssl_npn, NULL); #endif SSL_CTX_set_session_cache_mode(acceptor->ctx, SSL_SESS_CACHE_SERVER); acceptor->read = bb_ssl_read; acceptor->write = bb_ssl_write; }
LWS_VISIBLE void lws_context_init_http2_ssl(struct lws_context *context) { #if OPENSSL_VERSION_NUMBER >= 0x10002000L static struct alpn_ctx protos = { (unsigned char *)"\x05h2-14" "\x08http/1.1", 6 + 9 }; SSL_CTX_set_next_protos_advertised_cb(context->ssl_ctx, npn_cb, &protos); // ALPN selection callback SSL_CTX_set_alpn_select_cb(context->ssl_ctx, alpn_cb, &protos); lwsl_notice(" HTTP2 / ALPN enabled\n"); #else lwsl_notice( " HTTP2 / ALPN configured but not supported by OpenSSL 0x%x\n", OPENSSL_VERSION_NUMBER); #endif // OPENSSL_VERSION_NUMBER >= 0x10002000L }
SSL_CTX *bb_new_ssl_ctx() { SSL_CTX *ctx = SSL_CTX_new(SSLv23_server_method()); if (!ctx) { fprintf(stderr, "unable to initialize SSL context: SSL_CTX_new()"); return NULL; } long ssloptions = SSL_OP_NO_SSLv2 | SSL_OP_ALL | SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION; // disable compression (if possibile) #ifdef SSL_OP_NO_COMPRESSION ssloptions |= SSL_OP_NO_COMPRESSION; #endif SSL_CTX_set_options(ctx, ssloptions); // release/reuse buffers as soon as possibile #ifdef SSL_MODE_RELEASE_BUFFERS SSL_CTX_set_mode(ctx, SSL_MODE_RELEASE_BUFFERS); #endif if (SSL_CTX_set_cipher_list(ctx, "HIGH") == 0) { fprintf(stderr,"unable to set SSL ciphers: SSL_CTX_set_cipher_list()"); SSL_CTX_free(ctx); return NULL; } SSL_CTX_set_options(ctx, SSL_OP_CIPHER_SERVER_PREFERENCE); SSL_CTX_set_info_callback(ctx, bb_ssl_info_cb); #ifdef OPENSSL_NPN_UNSUPPORTED SSL_CTX_set_next_protos_advertised_cb(ctx, bb_ssl_npn, NULL); #endif #ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME SSL_CTX_set_tlsext_servername_callback(ctx, bb_ssl_servername); #else #warning TLS SNI support not available !!! #endif SSL_CTX_set_session_cache_mode(ctx, SSL_SESS_CACHE_SERVER); return ctx; }
/* Create SSL_CTX. */ static SSL_CTX *create_ssl_ctx(const char *key_file, const char *cert_file) { SSL_CTX *ssl_ctx; EC_KEY *ecdh; ssl_ctx = SSL_CTX_new(SSLv23_server_method()); if (!ssl_ctx) { errx(1, "Could not create SSL/TLS context: %s", ERR_error_string(ERR_get_error(), NULL)); } SSL_CTX_set_options(ssl_ctx, SSL_OP_ALL | SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 | SSL_OP_NO_COMPRESSION | SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION); ecdh = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1); if (!ecdh) { errx(1, "EC_KEY_new_by_curv_name failed: %s", ERR_error_string(ERR_get_error(), NULL)); } SSL_CTX_set_tmp_ecdh(ssl_ctx, ecdh); EC_KEY_free(ecdh); if (SSL_CTX_use_PrivateKey_file(ssl_ctx, key_file, SSL_FILETYPE_PEM) != 1) { errx(1, "Could not read private key file %s", key_file); } if (SSL_CTX_use_certificate_chain_file(ssl_ctx, cert_file) != 1) { errx(1, "Could not read certificate file %s", cert_file); } next_proto_list[0] = NGHTTP2_PROTO_VERSION_ID_LEN; memcpy(&next_proto_list[1], NGHTTP2_PROTO_VERSION_ID, NGHTTP2_PROTO_VERSION_ID_LEN); next_proto_list_len = 1 + NGHTTP2_PROTO_VERSION_ID_LEN; SSL_CTX_set_next_protos_advertised_cb(ssl_ctx, next_proto_cb, NULL); #if OPENSSL_VERSION_NUMBER >= 0x10002000L SSL_CTX_set_alpn_select_cb(ssl_ctx, alpn_select_proto_cb, NULL); #endif // OPENSSL_VERSION_NUMBER >= 0x10002000L return ssl_ctx; }
int swSSL_server_config(SSL_CTX* ssl_context, swSSL_config *cfg) { #ifndef TLS1_2_VERSION return SW_OK; #endif SSL_CTX_set_read_ahead(ssl_context, 1); #ifdef TLSEXT_TYPE_application_layer_protocol_negotiation SSL_CTX_set_alpn_select_cb(ssl_context, swSSL_alpn_advertised, cfg); #endif #ifdef TLSEXT_TYPE_next_proto_neg SSL_CTX_set_next_protos_advertised_cb(ssl_context, swSSL_npn_advertised, cfg); #endif if (SSL_CTX_set_cipher_list(ssl_context, cfg->ciphers) == 0) { swWarn("SSL_CTX_set_cipher_list(\"%s\") failed", SW_SSL_CIPHER_LIST); return SW_ERR; } if (cfg->prefer_server_ciphers) { SSL_CTX_set_options(ssl_context, SSL_OP_CIPHER_SERVER_PREFERENCE); } #ifndef LIBRESSL_VERSION_NUMBER SSL_CTX_set_tmp_rsa_callback(ssl_context, swSSL_rsa512_key_callback); #endif swSSL_set_dhparam(ssl_context); swSSL_set_ecdh_curve(ssl_context); if (cfg->http) { SSL_CTX_set_session_id_context(ssl_context, (const unsigned char *) "HTTP", strlen("HTTP")); SSL_CTX_set_session_cache_mode(ssl_context, SSL_SESS_CACHE_SERVER); SSL_CTX_sess_set_cache_size(ssl_context, 1); } return SW_OK; }
/* * Configure callbacks and other properties that can't be set directly * in the server/client CONF. */ static void configure_handshake_ctx(SSL_CTX *server_ctx, SSL_CTX *server2_ctx, SSL_CTX *client_ctx, const SSL_TEST_CTX *test_ctx, CTX_DATA *server_ctx_data, CTX_DATA *server2_ctx_data, CTX_DATA *client_ctx_data) { unsigned char *ticket_keys; size_t ticket_key_len; switch (test_ctx->client_verify_callback) { case SSL_TEST_VERIFY_ACCEPT_ALL: SSL_CTX_set_cert_verify_callback(client_ctx, &verify_accept_cb, NULL); break; case SSL_TEST_VERIFY_REJECT_ALL: SSL_CTX_set_cert_verify_callback(client_ctx, &verify_reject_cb, NULL); break; default: break; } /* link the two contexts for SNI purposes */ switch (test_ctx->servername_callback) { case SSL_TEST_SERVERNAME_IGNORE_MISMATCH: SSL_CTX_set_tlsext_servername_callback(server_ctx, servername_ignore_cb); SSL_CTX_set_tlsext_servername_arg(server_ctx, server2_ctx); break; case SSL_TEST_SERVERNAME_REJECT_MISMATCH: SSL_CTX_set_tlsext_servername_callback(server_ctx, servername_reject_cb); SSL_CTX_set_tlsext_servername_arg(server_ctx, server2_ctx); break; default: break; } /* * The initial_ctx/session_ctx always handles the encrypt/decrypt of the * session ticket. This ticket_key callback is assigned to the second * session (assigned via SNI), and should never be invoked */ if (server2_ctx != NULL) SSL_CTX_set_tlsext_ticket_key_cb(server2_ctx, do_not_call_session_ticket_cb); if (test_ctx->session_ticket_expected == SSL_TEST_SESSION_TICKET_BROKEN) { SSL_CTX_set_tlsext_ticket_key_cb(server_ctx, broken_session_ticket_cb); } if (test_ctx->server_npn_protocols != NULL) { parse_protos(test_ctx->server_npn_protocols, &server_ctx_data->npn_protocols, &server_ctx_data->npn_protocols_len); SSL_CTX_set_next_protos_advertised_cb(server_ctx, server_npn_cb, server_ctx_data); } if (test_ctx->server2_npn_protocols != NULL) { parse_protos(test_ctx->server2_npn_protocols, &server2_ctx_data->npn_protocols, &server2_ctx_data->npn_protocols_len); OPENSSL_assert(server2_ctx != NULL); SSL_CTX_set_next_protos_advertised_cb(server2_ctx, server_npn_cb, server2_ctx_data); } if (test_ctx->client_npn_protocols != NULL) { parse_protos(test_ctx->client_npn_protocols, &client_ctx_data->npn_protocols, &client_ctx_data->npn_protocols_len); SSL_CTX_set_next_proto_select_cb(client_ctx, client_npn_cb, client_ctx_data); } if (test_ctx->server_alpn_protocols != NULL) { parse_protos(test_ctx->server_alpn_protocols, &server_ctx_data->alpn_protocols, &server_ctx_data->alpn_protocols_len); SSL_CTX_set_alpn_select_cb(server_ctx, server_alpn_cb, server_ctx_data); } if (test_ctx->server2_alpn_protocols != NULL) { OPENSSL_assert(server2_ctx != NULL); parse_protos(test_ctx->server2_alpn_protocols, &server2_ctx_data->alpn_protocols, &server2_ctx_data->alpn_protocols_len); SSL_CTX_set_alpn_select_cb(server2_ctx, server_alpn_cb, server2_ctx_data); } if (test_ctx->client_alpn_protocols != NULL) { unsigned char *alpn_protos = NULL; size_t alpn_protos_len; parse_protos(test_ctx->client_alpn_protocols, &alpn_protos, &alpn_protos_len); /* Reversed return value convention... */ OPENSSL_assert(SSL_CTX_set_alpn_protos(client_ctx, alpn_protos, alpn_protos_len) == 0); OPENSSL_free(alpn_protos); } /* * Use fixed session ticket keys so that we can decrypt a ticket created with * one CTX in another CTX. Don't address server2 for the moment. */ ticket_key_len = SSL_CTX_set_tlsext_ticket_keys(server_ctx, NULL, 0); ticket_keys = OPENSSL_zalloc(ticket_key_len); OPENSSL_assert(ticket_keys != NULL); OPENSSL_assert(SSL_CTX_set_tlsext_ticket_keys(server_ctx, ticket_keys, ticket_key_len) == 1); OPENSSL_free(ticket_keys); }
void SSLHandler::init(const SecurityProperties& securityProperties) { if(isSSLEnabled) { this->securityProperties = securityProperties; if(securityProperties.alpnEnabled && securityProperties.alpnProtoList.size()>0) { for(int pn=0;pn<(int)securityProperties.alpnProtoList.size();pn++) { string protoname = securityProperties.alpnProtoList.at(pn); vector<unsigned char> res = vector<unsigned char>(1 + protoname.length()); unsigned char* p = res.data(); *p++ = protoname.length(); memcpy(p, protoname.c_str(), protoname.length()); advertisedProtos.push_back(res); } } string sslConfsettings = "Server setup with SSL enabled, CERTFILE = "; sslConfsettings.append(securityProperties.cert_file); sslConfsettings.append(", KEYFILE = "); sslConfsettings.append(securityProperties.key_file); sslConfsettings.append(", PASSWORD = "******", DHFILE = "); sslConfsettings.append(securityProperties.dh_file); sslConfsettings.append(", CA_LIST = "); sslConfsettings.append(securityProperties.ca_list); sslConfsettings.append(", ISDH_PARAMS = "); //sslConfsettings.append(CastUtil::lexical_cast<string>(securityProperties.isDHParams)); //sslConfsettings.append(", CLIENT_SEC_LEVEL = "); //sslConfsettings.append(CastUtil::lexical_cast<string>(securityProperties.client_auth)); logger << sslConfsettings << endl; /* Build our SSL context*/ ctx = SSLCommon::initialize_ctx(true); pass = (char*)securityProperties.sec_password.c_str(); SSL_CTX_set_default_passwd_cb(ctx, SSLHandler::password_cb); SSL_CTX_set_options(ctx, SSL_OP_ALL | SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3 | SSL_OP_NO_COMPRESSION | SSL_OP_SINGLE_DH_USE | SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION | SSL_OP_SINGLE_ECDH_USE | SSL_OP_NO_TICKET | SSL_OP_CIPHER_SERVER_PREFERENCE); SSL_CTX_set_mode(ctx, SSL_MODE_AUTO_RETRY); SSL_CTX_set_mode(ctx, SSL_MODE_RELEASE_BUFFERS); if(securityProperties.isDHParams) { SSLCommon::load_dh_params(ctx,(char*)securityProperties.dh_file.c_str()); } else { SSLCommon::load_ecdh_params(ctx); } const unsigned char sid_ctx[] = "Ffead"; SSL_CTX_set_session_id_context(ctx, sid_ctx, sizeof(sid_ctx) - 1); SSL_CTX_set_session_cache_mode(ctx, SSL_SESS_CACHE_SERVER); /*SSL_CTX_set_session_id_context(ctx, (const unsigned char*)&s_server_session_id_context, sizeof s_server_session_id_context); */ /* Set our cipher list */ if(SSLCommon::ciphers!=""){ SSL_CTX_set_cipher_list(ctx, SSLCommon::ciphers.c_str()); } SSLCommon::loadCerts(ctx, (char*)securityProperties.cert_file.c_str(), (char*)securityProperties.key_file.c_str(), securityProperties.ca_list, true); if(securityProperties.client_auth==2) { /* Set to require peer (client) certificate verification */ SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER|SSL_VERIFY_CLIENT_ONCE|SSL_VERIFY_FAIL_IF_NO_PEER_CERT, NULL); /* Set the verification depth to 1 */ #if (OPENSSL_VERSION_NUMBER < 0x00905100L) SSL_CTX_set_verify_depth(ctx,1); #endif } else if(securityProperties.client_auth==1) { /* Set to require peer (client) certificate verification */ SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER, NULL); /* Set the verification depth to 1 */ #if (OPENSSL_VERSION_NUMBER < 0x00905100L) SSL_CTX_set_verify_depth(ctx,1); #endif } else { SSL_CTX_set_verify(ctx, SSL_VERIFY_NONE, NULL); } #if OPENSSL_VERSION_NUMBER >= 0x10002000L if(securityProperties.alpnEnabled) { for (int var = 0; var < (int)advertisedProtos.size(); ++var) { SSL_CTX_set_next_protos_advertised_cb(ctx, SSLHandler::next_proto_cb, &(advertisedProtos.at(var))); } // ALPN selection callback SSL_CTX_set_alpn_select_cb(ctx, SSLHandler::alpn_select_proto_cb, NULL); } #endif // OPENSSL_VERSION_NUMBER >= 0x10002000L } }
static char * ngx_http_ssl_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child) { ngx_http_ssl_srv_conf_t *prev = parent; ngx_http_ssl_srv_conf_t *conf = child; ngx_pool_cleanup_t *cln; if (conf->enable == NGX_CONF_UNSET) { if (prev->enable == NGX_CONF_UNSET) { conf->enable = 0; } else { conf->enable = prev->enable; conf->file = prev->file; conf->line = prev->line; } } ngx_conf_merge_value(conf->session_timeout, prev->session_timeout, 300); ngx_conf_merge_value(conf->prefer_server_ciphers, prev->prefer_server_ciphers, 0); ngx_conf_merge_bitmask_value(conf->protocols, prev->protocols, (NGX_CONF_BITMASK_SET|NGX_SSL_SSLv3|NGX_SSL_TLSv1 |NGX_SSL_TLSv1_1|NGX_SSL_TLSv1_2)); ngx_conf_merge_uint_value(conf->verify, prev->verify, 0); ngx_conf_merge_uint_value(conf->verify_depth, prev->verify_depth, 1); ngx_conf_merge_str_value(conf->certificate, prev->certificate, ""); ngx_conf_merge_str_value(conf->certificate_key, prev->certificate_key, ""); ngx_conf_merge_str_value(conf->dhparam, prev->dhparam, ""); ngx_conf_merge_str_value(conf->client_certificate, prev->client_certificate, ""); ngx_conf_merge_str_value(conf->trusted_certificate, prev->trusted_certificate, ""); ngx_conf_merge_str_value(conf->crl, prev->crl, ""); ngx_conf_merge_str_value(conf->ecdh_curve, prev->ecdh_curve, NGX_DEFAULT_ECDH_CURVE); ngx_conf_merge_str_value(conf->ciphers, prev->ciphers, NGX_DEFAULT_CIPHERS); ngx_conf_merge_value(conf->stapling, prev->stapling, 0); ngx_conf_merge_value(conf->stapling_verify, prev->stapling_verify, 0); ngx_conf_merge_str_value(conf->stapling_file, prev->stapling_file, ""); ngx_conf_merge_str_value(conf->stapling_responder, prev->stapling_responder, ""); conf->ssl.log = cf->log; if (conf->enable) { if (conf->certificate.len == 0) { ngx_log_error(NGX_LOG_EMERG, cf->log, 0, "no \"ssl_certificate\" is defined for " "the \"ssl\" directive in %s:%ui", conf->file, conf->line); return NGX_CONF_ERROR; } if (conf->certificate_key.len == 0) { ngx_log_error(NGX_LOG_EMERG, cf->log, 0, "no \"ssl_certificate_key\" is defined for " "the \"ssl\" directive in %s:%ui", conf->file, conf->line); return NGX_CONF_ERROR; } } else { if (conf->certificate.len == 0) { return NGX_CONF_OK; } if (conf->certificate_key.len == 0) { ngx_log_error(NGX_LOG_EMERG, cf->log, 0, "no \"ssl_certificate_key\" is defined " "for certificate \"%V\"", &conf->certificate); return NGX_CONF_ERROR; } } if (ngx_ssl_create(&conf->ssl, conf->protocols, conf) != NGX_OK) { return NGX_CONF_ERROR; } #ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME if (SSL_CTX_set_tlsext_servername_callback(conf->ssl.ctx, ngx_http_ssl_servername) == 0) { ngx_log_error(NGX_LOG_WARN, cf->log, 0, "nginx was built with SNI support, however, now it is linked " "dynamically to an OpenSSL library which has no tlsext support, " "therefore SNI is not available"); } #endif #ifdef TLSEXT_TYPE_next_proto_neg SSL_CTX_set_next_protos_advertised_cb(conf->ssl.ctx, ngx_http_ssl_npn_advertised, NULL); #endif cln = ngx_pool_cleanup_add(cf->pool, 0); if (cln == NULL) { return NGX_CONF_ERROR; } cln->handler = ngx_ssl_cleanup_ctx; cln->data = &conf->ssl; if (ngx_ssl_certificate(cf, &conf->ssl, &conf->certificate, &conf->certificate_key) != NGX_OK) { return NGX_CONF_ERROR; } if (SSL_CTX_set_cipher_list(conf->ssl.ctx, (const char *) conf->ciphers.data) == 0) { ngx_ssl_error(NGX_LOG_EMERG, cf->log, 0, "SSL_CTX_set_cipher_list(\"%V\") failed", &conf->ciphers); return NGX_CONF_ERROR; } if (conf->verify) { if (conf->client_certificate.len == 0 && conf->verify != 3) { ngx_log_error(NGX_LOG_EMERG, cf->log, 0, "no ssl_client_certificate for ssl_client_verify"); return NGX_CONF_ERROR; } if (ngx_ssl_client_certificate(cf, &conf->ssl, &conf->client_certificate, conf->verify_depth) != NGX_OK) { return NGX_CONF_ERROR; } } if (ngx_ssl_trusted_certificate(cf, &conf->ssl, &conf->trusted_certificate, conf->verify_depth) != NGX_OK) { return NGX_CONF_ERROR; } if (ngx_ssl_crl(cf, &conf->ssl, &conf->crl) != NGX_OK) { return NGX_CONF_ERROR; } if (conf->prefer_server_ciphers) { SSL_CTX_set_options(conf->ssl.ctx, SSL_OP_CIPHER_SERVER_PREFERENCE); } /* a temporary 512-bit RSA key is required for export versions of MSIE */ SSL_CTX_set_tmp_rsa_callback(conf->ssl.ctx, ngx_ssl_rsa512_key_callback); if (ngx_ssl_dhparam(cf, &conf->ssl, &conf->dhparam) != NGX_OK) { return NGX_CONF_ERROR; } if (ngx_ssl_ecdh_curve(cf, &conf->ssl, &conf->ecdh_curve) != NGX_OK) { return NGX_CONF_ERROR; } ngx_conf_merge_value(conf->builtin_session_cache, prev->builtin_session_cache, NGX_SSL_NONE_SCACHE); if (conf->shm_zone == NULL) { conf->shm_zone = prev->shm_zone; } if (ngx_ssl_session_cache(&conf->ssl, &ngx_http_ssl_sess_id_ctx, conf->builtin_session_cache, conf->shm_zone, conf->session_timeout) != NGX_OK) { return NGX_CONF_ERROR; } if (conf->stapling) { if (ngx_ssl_stapling(cf, &conf->ssl, &conf->stapling_file, &conf->stapling_responder, conf->stapling_verify) != NGX_OK) { return NGX_CONF_ERROR; } } return NGX_CONF_OK; }
bud_error_t bud_config_new_ssl_ctx(bud_config_t* config, bud_context_t* context) { SSL_CTX* ctx; bud_error_t err; int options; /* Choose method, tlsv1_2 by default */ if (config->frontend.method == NULL) { if (strcmp(config->frontend.security, "tls1.1") == 0) config->frontend.method = TLSv1_1_server_method(); else if (strcmp(config->frontend.security, "tls1.0") == 0) config->frontend.method = TLSv1_server_method(); else if (strcmp(config->frontend.security, "tls1.2") == 0) config->frontend.method = TLSv1_2_server_method(); else if (strcmp(config->frontend.security, "ssl3") == 0) config->frontend.method = SSLv3_server_method(); else config->frontend.method = SSLv23_server_method(); } ctx = SSL_CTX_new(config->frontend.method); if (ctx == NULL) return bud_error_str(kBudErrNoMem, "SSL_CTX"); SSL_CTX_set_session_cache_mode(ctx, SSL_SESS_CACHE_SERVER | SSL_SESS_CACHE_NO_INTERNAL | SSL_SESS_CACHE_NO_AUTO_CLEAR); if (context->ciphers != NULL) SSL_CTX_set_cipher_list(ctx, context->ciphers); else if (config->frontend.ciphers != NULL) SSL_CTX_set_cipher_list(ctx, config->frontend.ciphers); /* Disable SSL2 */ options = SSL_OP_NO_SSLv2 | SSL_OP_ALL; if (!config->frontend.ssl3) options |= SSL_OP_NO_SSLv3; if (config->frontend.server_preference) options |= SSL_OP_CIPHER_SERVER_PREFERENCE; SSL_CTX_set_options(ctx, options); #ifdef SSL_CTRL_SET_TLSEXT_SERVERNAME_CB if (config->context_count != 0) { SSL_CTX_set_tlsext_servername_callback(ctx, bud_config_select_sni_context); SSL_CTX_set_tlsext_servername_arg(ctx, config); } #endif /* SSL_CTRL_SET_TLSEXT_SERVERNAME_CB */ #ifdef OPENSSL_NPN_NEGOTIATED context->npn_line = bud_config_encode_npn(config, context->npn, &context->npn_line_len, &err); if (!bud_is_ok(err)) goto fatal; if (context->npn_line != NULL) { SSL_CTX_set_next_protos_advertised_cb(ctx, bud_config_advertise_next_proto, context); } #else /* !OPENSSL_NPN_NEGOTIATED */ err = bud_error(kBudErrNPNNotSupported); goto fatal; #endif /* OPENSSL_NPN_NEGOTIATED */ SSL_CTX_set_tlsext_status_cb(ctx, bud_client_stapling_cb); context->ctx = ctx; return bud_ok(); fatal: SSL_CTX_free(ctx); return err; }
void SSLContext::unsetNextProtocols() { deleteNextProtocolsStrings(); SSL_CTX_set_next_protos_advertised_cb(ctx_, nullptr, nullptr); SSL_CTX_set_next_proto_select_cb(ctx_, nullptr, nullptr); }
bud_error_t bud_config_new_ssl_ctx(bud_config_t* config, bud_context_t* context) { SSL_CTX* ctx; int ecdh_nid; EC_KEY* ecdh; bud_error_t err; int options; int r; const char* ticket_key; size_t max_len; if (context->backend != NULL) { if (context->backend->keepalive == -1) context->backend->keepalive = kBudDefaultKeepalive; r = bud_config_str_to_addr(context->backend->host, context->backend->port, &context->backend->addr); if (r != 0) return bud_error_num(kBudErrPton, r); } /* Decode ticket_key */ ticket_key = context->ticket_key == NULL ? config->frontend.ticket_key : context->ticket_key; if (ticket_key != NULL) { max_len = sizeof(context->ticket_key_storage); if (bud_base64_decode(context->ticket_key_storage, max_len, ticket_key, strlen(ticket_key)) < max_len) { return bud_error(kBudErrSmallTicketKey); } } /* Choose method, tlsv1_2 by default */ if (config->frontend.method == NULL) { if (strcmp(config->frontend.security, "tls1.1") == 0) config->frontend.method = TLSv1_1_server_method(); else if (strcmp(config->frontend.security, "tls1.0") == 0) config->frontend.method = TLSv1_server_method(); else if (strcmp(config->frontend.security, "tls1.2") == 0) config->frontend.method = TLSv1_2_server_method(); else if (strcmp(config->frontend.security, "ssl3") == 0) config->frontend.method = SSLv3_server_method(); else config->frontend.method = SSLv23_server_method(); } ctx = SSL_CTX_new(config->frontend.method); if (ctx == NULL) return bud_error_str(kBudErrNoMem, "SSL_CTX"); /* Disable sessions, they won't work with cluster anyway */ SSL_CTX_set_session_cache_mode(ctx, SSL_SESS_CACHE_OFF); if (config->frontend.max_send_fragment) SSL_CTX_set_max_send_fragment(ctx, config->frontend.max_send_fragment); if (ticket_key != NULL) { SSL_CTX_set_tlsext_ticket_keys(ctx, context->ticket_key_storage, sizeof(context->ticket_key_storage)); } /* ECDH curve selection */ if (context->ecdh != NULL || config->frontend.ecdh != NULL) { if (context->ecdh != NULL) ecdh_nid = OBJ_sn2nid(context->ecdh); else ecdh_nid = OBJ_sn2nid(config->frontend.ecdh); if (ecdh_nid == NID_undef) { ecdh = NULL; err = bud_error_str(kBudErrECDHNotFound, context->ecdh == NULL ? config->frontend.ecdh : context->ecdh); goto fatal; } ecdh = EC_KEY_new_by_curve_name(ecdh_nid); if (ecdh == NULL) { err = bud_error_str(kBudErrNoMem, "EC_KEY"); goto fatal; } SSL_CTX_set_options(ctx, SSL_OP_SINGLE_ECDH_USE); SSL_CTX_set_tmp_ecdh(ctx, ecdh); EC_KEY_free(ecdh); } ecdh = NULL; /* Cipher suites */ if (context->ciphers != NULL) SSL_CTX_set_cipher_list(ctx, context->ciphers); else if (config->frontend.ciphers != NULL) SSL_CTX_set_cipher_list(ctx, config->frontend.ciphers); /* Disable SSL2 */ options = SSL_OP_NO_SSLv2 | SSL_OP_ALL; if (!config->frontend.ssl3) options |= SSL_OP_NO_SSLv3; if (config->frontend.server_preference) options |= SSL_OP_CIPHER_SERVER_PREFERENCE; SSL_CTX_set_options(ctx, options); #ifdef SSL_CTRL_SET_TLSEXT_SERVERNAME_CB if (config->context_count != 0) { SSL_CTX_set_tlsext_servername_callback(ctx, bud_config_select_sni_context); SSL_CTX_set_tlsext_servername_arg(ctx, config); } #endif /* SSL_CTRL_SET_TLSEXT_SERVERNAME_CB */ #ifdef OPENSSL_NPN_NEGOTIATED context->npn_line = bud_config_encode_npn(config, context->npn, &context->npn_line_len, &err); if (!bud_is_ok(err)) goto fatal; if (context->npn_line != NULL) { SSL_CTX_set_next_protos_advertised_cb(ctx, bud_config_advertise_next_proto, context); } #else /* !OPENSSL_NPN_NEGOTIATED */ err = bud_error(kBudErrNPNNotSupported); goto fatal; #endif /* OPENSSL_NPN_NEGOTIATED */ SSL_CTX_set_tlsext_status_cb(ctx, bud_client_stapling_cb); context->ctx = ctx; return bud_ok(); fatal: if (ecdh != NULL) EC_KEY_free(ecdh); SSL_CTX_free(ctx); return err; }
int LLVMFuzzerInitialize(int* argc, char*** argv) { rand_predictable = 1; SSL_library_init(); OpenSSL_add_ssl_algorithms(); ERR_load_crypto_strings(); if (RAND_reset_for_fuzzing) RAND_reset_for_fuzzing(); ctx = SSL_CTX_new(SSLv23_method()); const uint8_t* bufp = kRSAPrivateKeyDER; RSA* privkey = d2i_RSAPrivateKey(NULL, &bufp, sizeof(kRSAPrivateKeyDER)); assert(privkey != NULL); EVP_PKEY* pkey = EVP_PKEY_new(); EVP_PKEY_assign_RSA(pkey, privkey); int ret = SSL_CTX_use_PrivateKey(ctx, pkey); assert(ret == 1); EVP_PKEY_free(pkey); bufp = kCertificateDER; X509* cert = d2i_X509(NULL, &bufp, sizeof(kCertificateDER)); assert(cert != NULL); ret = SSL_CTX_use_certificate(ctx, cert); assert(ret == 1); X509_free(cert); ret = SSL_CTX_set_cipher_list(ctx, "ALL:eNULL:aNULL:DSS"); assert(ret == 1); X509_STORE* store = X509_STORE_new(); assert(store != NULL); bufp = kRSACACertDER; cert = d2i_X509(NULL, &bufp, sizeof(kRSACACertDER)); assert(cert != NULL); ret = SSL_CTX_add_client_CA(ctx, cert); assert(ret == 1); ret = X509_STORE_add_cert(store, cert); assert(ret == 1); X509_free(cert); bufp = kECCACertDER; cert = d2i_X509(NULL, &bufp, sizeof(kECCACertDER)); assert(cert != NULL); ret = SSL_CTX_add_client_CA(ctx, cert); assert(ret == 1); ret = X509_STORE_add_cert(store, cert); assert(ret == 1); X509_free(cert); bufp = kDSACertDER; cert = d2i_X509(NULL, &bufp, sizeof(kDSACertDER)); ret = SSL_CTX_add_client_CA(ctx, cert); assert(ret == 1); ret = X509_STORE_add_cert(store, cert); assert(ret == 1); X509_free(cert); SSL_CTX_set_cert_store(ctx, store); SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER | SSL_VERIFY_CLIENT_ONCE, NULL); SSL_CTX_set_verify_depth(ctx, 10); #if !defined(LIBRESSL_VERSION_NUMBER) SSL_CTX_set_psk_server_callback(ctx, psk_callback); ret = SSL_CTX_use_psk_identity_hint(ctx, "ABCDEFUZZ"); assert(ret == 1); #endif /* !defined(LIBRESSL_VERSION_NUMBER) */ #if !defined(LIBRESSL_VERSION_NUMBER) && !defined(BORINGSSL_API_VERSION) ret = SSL_CTX_set_srp_username_callback(ctx, srp_callback); assert(ret == 1); ret = SSL_CTX_set_srp_cb_arg(ctx, NULL); assert(ret == 1); #endif /* !defined(LIBRESSL_VERSION_NUMBER) && !defined(BORINGSSL_API_VERSION) */ SSL_CTX_set_alpn_select_cb(ctx, alpn_callback, NULL); SSL_CTX_set_next_protos_advertised_cb(ctx, npn_callback, NULL); SSL_CTX_set_ecdh_auto(ctx, 1); return 1; }
void uwsgi_opt_https2(char *opt, char *value, void *cr) { struct uwsgi_corerouter *ucr = (struct uwsgi_corerouter *) cr; char *s2_addr = NULL; char *s2_cert = NULL; char *s2_key = NULL; char *s2_ciphers = NULL; char *s2_clientca = NULL; char *s2_spdy = NULL; if (uwsgi_kvlist_parse(value, strlen(value), ',', '=', "addr", &s2_addr, "cert", &s2_cert, "crt", &s2_cert, "key", &s2_key, "ciphers", &s2_ciphers, "clientca", &s2_clientca, "client_ca", &s2_clientca, "spdy", &s2_spdy, NULL)) { uwsgi_log("error parsing --https2 option\n"); exit(1); } if (!s2_addr || !s2_cert || !s2_key) { uwsgi_log("--https2 option needs addr, cert and key items\n"); exit(1); } struct uwsgi_gateway_socket *ugs = uwsgi_new_gateway_socket(s2_addr, ucr->name); // ok we have the socket, initialize ssl if required if (!uwsgi.ssl_initialized) { uwsgi_ssl_init(); } // initialize ssl context char *name = uhttp.https_session_context; if (!name) { name = uwsgi_concat3(ucr->short_name, "-", ugs->name); } #ifdef UWSGI_SPDY if (s2_spdy) { uhttp.spdy_index = SSL_CTX_get_ex_new_index(0, NULL, NULL, NULL, NULL); uhttp.spdy3_settings = uwsgi_buffer_new(uwsgi.page_size); if (uwsgi_buffer_append(uhttp.spdy3_settings, "\x80\x03\x00\x04\x01", 5)) goto spdyerror; if (uwsgi_buffer_u24be(uhttp.spdy3_settings, (8 * 2) + 4)) goto spdyerror; if (uwsgi_buffer_u32be(uhttp.spdy3_settings, 2)) goto spdyerror; // SETTINGS_ROUND_TRIP_TIME if (uwsgi_buffer_append(uhttp.spdy3_settings, "\x01\x00\x00\x03", 4)) goto spdyerror; if (uwsgi_buffer_u32be(uhttp.spdy3_settings, 30 * 1000)) goto spdyerror; // SETTINGS_INITIAL_WINDOW_SIZE if (uwsgi_buffer_append(uhttp.spdy3_settings, "\x01\x00\x00\x07", 4)) goto spdyerror; if (uwsgi_buffer_u32be(uhttp.spdy3_settings, 8192)) goto spdyerror; uhttp.spdy3_settings_size = uhttp.spdy3_settings->pos; } #endif ugs->ctx = uwsgi_ssl_new_server_context(name, s2_cert, s2_key, s2_ciphers, s2_clientca); if (!ugs->ctx) { exit(1); } #ifdef UWSGI_SPDY if (s2_spdy) { SSL_CTX_set_info_callback(ugs->ctx, uwsgi_spdy_info_cb); SSL_CTX_set_next_protos_advertised_cb(ugs->ctx, uwsgi_spdy_npn, NULL); } #endif // set the ssl mode ugs->mode = UWSGI_HTTP_SSL; ucr->has_sockets++; return; #ifdef UWSGI_SPDY spdyerror: uwsgi_log("unable to initialize SPDY settings buffers\n"); exit(1); #endif }
static char * ngx_http_ssl_merge_srv_conf(ngx_conf_t *cf, void *parent, void *child) { ngx_http_ssl_srv_conf_t *prev = parent; ngx_http_ssl_srv_conf_t *conf = child; ngx_pool_cleanup_t *cln; if (conf->enable == NGX_CONF_UNSET) { if (prev->enable == NGX_CONF_UNSET) { conf->enable = 0; } else { conf->enable = prev->enable; conf->file = prev->file; conf->line = prev->line; } } ngx_conf_merge_value(conf->session_timeout, prev->session_timeout, 300); ngx_conf_merge_value(conf->prefer_server_ciphers, prev->prefer_server_ciphers, 0); ngx_conf_merge_value(conf->early_data, prev->early_data, 0); ngx_conf_merge_bitmask_value(conf->protocols, prev->protocols, (NGX_CONF_BITMASK_SET|NGX_SSL_TLSv1 |NGX_SSL_TLSv1_1|NGX_SSL_TLSv1_2)); ngx_conf_merge_size_value(conf->buffer_size, prev->buffer_size, NGX_SSL_BUFSIZE); ngx_conf_merge_uint_value(conf->verify, prev->verify, 0); ngx_conf_merge_uint_value(conf->verify_depth, prev->verify_depth, 1); ngx_conf_merge_ptr_value(conf->certificates, prev->certificates, NULL); ngx_conf_merge_ptr_value(conf->certificate_keys, prev->certificate_keys, NULL); ngx_conf_merge_ptr_value(conf->passwords, prev->passwords, NULL); ngx_conf_merge_str_value(conf->dhparam, prev->dhparam, ""); ngx_conf_merge_str_value(conf->client_certificate, prev->client_certificate, ""); ngx_conf_merge_str_value(conf->trusted_certificate, prev->trusted_certificate, ""); ngx_conf_merge_str_value(conf->crl, prev->crl, ""); ngx_conf_merge_str_value(conf->ecdh_curve, prev->ecdh_curve, NGX_DEFAULT_ECDH_CURVE); ngx_conf_merge_str_value(conf->ciphers, prev->ciphers, NGX_DEFAULT_CIPHERS); ngx_conf_merge_value(conf->stapling, prev->stapling, 0); ngx_conf_merge_value(conf->stapling_verify, prev->stapling_verify, 0); ngx_conf_merge_str_value(conf->stapling_file, prev->stapling_file, ""); ngx_conf_merge_str_value(conf->stapling_responder, prev->stapling_responder, ""); conf->ssl.log = cf->log; if (conf->enable) { if (conf->certificates == NULL) { ngx_log_error(NGX_LOG_EMERG, cf->log, 0, "no \"ssl_certificate\" is defined for " "the \"ssl\" directive in %s:%ui", conf->file, conf->line); return NGX_CONF_ERROR; } if (conf->certificate_keys == NULL) { ngx_log_error(NGX_LOG_EMERG, cf->log, 0, "no \"ssl_certificate_key\" is defined for " "the \"ssl\" directive in %s:%ui", conf->file, conf->line); return NGX_CONF_ERROR; } if (conf->certificate_keys->nelts < conf->certificates->nelts) { ngx_log_error(NGX_LOG_EMERG, cf->log, 0, "no \"ssl_certificate_key\" is defined " "for certificate \"%V\" and " "the \"ssl\" directive in %s:%ui", ((ngx_str_t *) conf->certificates->elts) + conf->certificates->nelts - 1, conf->file, conf->line); return NGX_CONF_ERROR; } } else { if (conf->certificates == NULL) { return NGX_CONF_OK; } if (conf->certificate_keys == NULL || conf->certificate_keys->nelts < conf->certificates->nelts) { ngx_log_error(NGX_LOG_EMERG, cf->log, 0, "no \"ssl_certificate_key\" is defined " "for certificate \"%V\"", ((ngx_str_t *) conf->certificates->elts) + conf->certificates->nelts - 1); return NGX_CONF_ERROR; } } if (ngx_ssl_create(&conf->ssl, conf->protocols, conf) != NGX_OK) { return NGX_CONF_ERROR; } cln = ngx_pool_cleanup_add(cf->pool, 0); if (cln == NULL) { ngx_ssl_cleanup_ctx(&conf->ssl); return NGX_CONF_ERROR; } cln->handler = ngx_ssl_cleanup_ctx; cln->data = &conf->ssl; #ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME if (SSL_CTX_set_tlsext_servername_callback(conf->ssl.ctx, ngx_http_ssl_servername) == 0) { ngx_log_error(NGX_LOG_WARN, cf->log, 0, "nginx was built with SNI support, however, now it is linked " "dynamically to an OpenSSL library which has no tlsext support, " "therefore SNI is not available"); } #endif #ifdef TLSEXT_TYPE_application_layer_protocol_negotiation SSL_CTX_set_alpn_select_cb(conf->ssl.ctx, ngx_http_ssl_alpn_select, NULL); #endif #ifdef TLSEXT_TYPE_next_proto_neg SSL_CTX_set_next_protos_advertised_cb(conf->ssl.ctx, ngx_http_ssl_npn_advertised, NULL); #endif if (ngx_http_ssl_compile_certificates(cf, conf) != NGX_OK) { return NGX_CONF_ERROR; } if (conf->certificate_values) { #ifdef SSL_R_CERT_CB_ERROR /* install callback to lookup certificates */ SSL_CTX_set_cert_cb(conf->ssl.ctx, ngx_http_ssl_certificate, conf); #else ngx_log_error(NGX_LOG_EMERG, cf->log, 0, "variables in " "\"ssl_certificate\" and \"ssl_certificate_key\" " "directives are not supported on this platform"); return NGX_CONF_ERROR; #endif } else { /* configure certificates */ if (ngx_ssl_certificates(cf, &conf->ssl, conf->certificates, conf->certificate_keys, conf->passwords) != NGX_OK) { return NGX_CONF_ERROR; } } if (ngx_ssl_ciphers(cf, &conf->ssl, &conf->ciphers, conf->prefer_server_ciphers) != NGX_OK) { return NGX_CONF_ERROR; } conf->ssl.buffer_size = conf->buffer_size; if (conf->verify) { if (conf->client_certificate.len == 0 && conf->verify != 3) { ngx_log_error(NGX_LOG_EMERG, cf->log, 0, "no ssl_client_certificate for ssl_client_verify"); return NGX_CONF_ERROR; } if (ngx_ssl_client_certificate(cf, &conf->ssl, &conf->client_certificate, conf->verify_depth) != NGX_OK) { return NGX_CONF_ERROR; } } if (ngx_ssl_trusted_certificate(cf, &conf->ssl, &conf->trusted_certificate, conf->verify_depth) != NGX_OK) { return NGX_CONF_ERROR; } if (ngx_ssl_crl(cf, &conf->ssl, &conf->crl) != NGX_OK) { return NGX_CONF_ERROR; } if (ngx_ssl_dhparam(cf, &conf->ssl, &conf->dhparam) != NGX_OK) { return NGX_CONF_ERROR; } if (ngx_ssl_ecdh_curve(cf, &conf->ssl, &conf->ecdh_curve) != NGX_OK) { return NGX_CONF_ERROR; } ngx_conf_merge_value(conf->builtin_session_cache, prev->builtin_session_cache, NGX_SSL_NONE_SCACHE); if (conf->shm_zone == NULL) { conf->shm_zone = prev->shm_zone; } if (ngx_ssl_session_cache(&conf->ssl, &ngx_http_ssl_sess_id_ctx, conf->certificates, conf->builtin_session_cache, conf->shm_zone, conf->session_timeout) != NGX_OK) { return NGX_CONF_ERROR; } ngx_conf_merge_value(conf->session_tickets, prev->session_tickets, 1); #ifdef SSL_OP_NO_TICKET if (!conf->session_tickets) { SSL_CTX_set_options(conf->ssl.ctx, SSL_OP_NO_TICKET); } #endif ngx_conf_merge_ptr_value(conf->session_ticket_keys, prev->session_ticket_keys, NULL); if (ngx_ssl_session_ticket_keys(cf, &conf->ssl, conf->session_ticket_keys) != NGX_OK) { return NGX_CONF_ERROR; } if (conf->stapling) { if (ngx_ssl_stapling(cf, &conf->ssl, &conf->stapling_file, &conf->stapling_responder, conf->stapling_verify) != NGX_OK) { return NGX_CONF_ERROR; } } if (ngx_ssl_early_data(cf, &conf->ssl, conf->early_data) != NGX_OK) { return NGX_CONF_ERROR; } return NGX_CONF_OK; }
void h2o_ssl_register_npn_protocols(SSL_CTX *ctx, const char *protocols) { SSL_CTX_set_next_protos_advertised_cb(ctx, on_npn_advertise, (void *)protocols); }
/* * Configure callbacks and other properties that can't be set directly * in the server/client CONF. */ static void configure_handshake_ctx(SSL_CTX *server_ctx, SSL_CTX *server2_ctx, SSL_CTX *client_ctx, const SSL_TEST_CTX *test, const SSL_TEST_EXTRA_CONF *extra, CTX_DATA *server_ctx_data, CTX_DATA *server2_ctx_data, CTX_DATA *client_ctx_data) { unsigned char *ticket_keys; size_t ticket_key_len; TEST_check(SSL_CTX_set_max_send_fragment(server_ctx, test->max_fragment_size) == 1); if (server2_ctx != NULL) { TEST_check(SSL_CTX_set_max_send_fragment(server2_ctx, test->max_fragment_size) == 1); } TEST_check(SSL_CTX_set_max_send_fragment(client_ctx, test->max_fragment_size) == 1); switch (extra->client.verify_callback) { case SSL_TEST_VERIFY_ACCEPT_ALL: SSL_CTX_set_cert_verify_callback(client_ctx, &verify_accept_cb, NULL); break; case SSL_TEST_VERIFY_REJECT_ALL: SSL_CTX_set_cert_verify_callback(client_ctx, &verify_reject_cb, NULL); break; default: break; } /* link the two contexts for SNI purposes */ switch (extra->server.servername_callback) { case SSL_TEST_SERVERNAME_IGNORE_MISMATCH: SSL_CTX_set_tlsext_servername_callback(server_ctx, servername_ignore_cb); SSL_CTX_set_tlsext_servername_arg(server_ctx, server2_ctx); break; case SSL_TEST_SERVERNAME_REJECT_MISMATCH: SSL_CTX_set_tlsext_servername_callback(server_ctx, servername_reject_cb); SSL_CTX_set_tlsext_servername_arg(server_ctx, server2_ctx); break; default: break; } /* * The initial_ctx/session_ctx always handles the encrypt/decrypt of the * session ticket. This ticket_key callback is assigned to the second * session (assigned via SNI), and should never be invoked */ if (server2_ctx != NULL) SSL_CTX_set_tlsext_ticket_key_cb(server2_ctx, do_not_call_session_ticket_cb); if (extra->server.broken_session_ticket) { SSL_CTX_set_tlsext_ticket_key_cb(server_ctx, broken_session_ticket_cb); } #ifndef OPENSSL_NO_NEXTPROTONEG if (extra->server.npn_protocols != NULL) { parse_protos(extra->server.npn_protocols, &server_ctx_data->npn_protocols, &server_ctx_data->npn_protocols_len); SSL_CTX_set_next_protos_advertised_cb(server_ctx, server_npn_cb, server_ctx_data); } if (extra->server2.npn_protocols != NULL) { parse_protos(extra->server2.npn_protocols, &server2_ctx_data->npn_protocols, &server2_ctx_data->npn_protocols_len); TEST_check(server2_ctx != NULL); SSL_CTX_set_next_protos_advertised_cb(server2_ctx, server_npn_cb, server2_ctx_data); } if (extra->client.npn_protocols != NULL) { parse_protos(extra->client.npn_protocols, &client_ctx_data->npn_protocols, &client_ctx_data->npn_protocols_len); SSL_CTX_set_next_proto_select_cb(client_ctx, client_npn_cb, client_ctx_data); } #endif if (extra->server.alpn_protocols != NULL) { parse_protos(extra->server.alpn_protocols, &server_ctx_data->alpn_protocols, &server_ctx_data->alpn_protocols_len); SSL_CTX_set_alpn_select_cb(server_ctx, server_alpn_cb, server_ctx_data); } if (extra->server2.alpn_protocols != NULL) { TEST_check(server2_ctx != NULL); parse_protos(extra->server2.alpn_protocols, &server2_ctx_data->alpn_protocols, &server2_ctx_data->alpn_protocols_len); SSL_CTX_set_alpn_select_cb(server2_ctx, server_alpn_cb, server2_ctx_data); } if (extra->client.alpn_protocols != NULL) { unsigned char *alpn_protos = NULL; size_t alpn_protos_len; parse_protos(extra->client.alpn_protocols, &alpn_protos, &alpn_protos_len); /* Reversed return value convention... */ TEST_check(SSL_CTX_set_alpn_protos(client_ctx, alpn_protos, alpn_protos_len) == 0); OPENSSL_free(alpn_protos); } /* * Use fixed session ticket keys so that we can decrypt a ticket created with * one CTX in another CTX. Don't address server2 for the moment. */ ticket_key_len = SSL_CTX_set_tlsext_ticket_keys(server_ctx, NULL, 0); ticket_keys = OPENSSL_zalloc(ticket_key_len); TEST_check(ticket_keys != NULL); TEST_check(SSL_CTX_set_tlsext_ticket_keys(server_ctx, ticket_keys, ticket_key_len) == 1); OPENSSL_free(ticket_keys); /* The default log list includes EC keys, so CT can't work without EC. */ #if !defined(OPENSSL_NO_CT) && !defined(OPENSSL_NO_EC) TEST_check(SSL_CTX_set_default_ctlog_list_file(client_ctx)); switch (extra->client.ct_validation) { case SSL_TEST_CT_VALIDATION_PERMISSIVE: TEST_check(SSL_CTX_enable_ct(client_ctx, SSL_CT_VALIDATION_PERMISSIVE)); break; case SSL_TEST_CT_VALIDATION_STRICT: TEST_check(SSL_CTX_enable_ct(client_ctx, SSL_CT_VALIDATION_STRICT)); break; case SSL_TEST_CT_VALIDATION_NONE: break; } #endif }