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; }
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; }
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 }
SSLContext::~SSLContext() { if (ctx_ != nullptr) { SSL_CTX_free(ctx_); ctx_ = nullptr; } #ifdef OPENSSL_NPN_NEGOTIATED deleteNextProtocolsStrings(); #endif }
SSLContext::~SSLContext() { if (ctx_ != nullptr) { SSL_CTX_free(ctx_); ctx_ = nullptr; } #ifdef OPENSSL_NPN_NEGOTIATED deleteNextProtocolsStrings(); #endif #ifndef SSLCONTEXT_NO_REFCOUNT { std::lock_guard<std::mutex> g(mutex_); if (!--count_) { cleanupOpenSSLLocked(); } } #endif }
void SSLContext::unsetNextProtocols() { deleteNextProtocolsStrings(); SSL_CTX_set_next_protos_advertised_cb(ctx_, nullptr, nullptr); SSL_CTX_set_next_proto_select_cb(ctx_, nullptr, nullptr); }