Commit 14a19db2 authored by Ranjeeth Dasineni's avatar Ranjeeth Dasineni Committed by facebook-github-bot-9

add callback to specify a client next protocol filter

Summary: From the client perspective, we set the list in order of
preference once and call into openssl to do the selection. This adds
a little more flexibility in that client optionally can customize the
selection for each negotiation. added tests for the no-op case and the
customized case. Feel free to suggest improvements.

Reviewed By: @afrind

Differential Revision: D2489142
parent 1f46d8c5
main 2016.07.26 v2022.02.14.00 v2022.02.07.00 v2022.01.31.00 v2022.01.24.00 v2022.01.17.00 v2022.01.10.00 v2022.01.03.00 v2021.12.27.00 v2021.12.20.00 v2021.12.13.00 v2021.12.06.00 v2021.11.29.00 v2021.11.15.00 v2021.11.08.00 v2021.11.01.00 v2021.10.25.00 v2021.10.18.00 v2021.10.11.00 v2021.10.04.00 v2021.09.27.00 v2021.09.20.00 v2021.09.13.00 v2021.09.06.00 v2021.08.30.00 v2021.08.23.00 v2021.08.02.00 v2021.07.22.00 v2021.07.20.01 v2021.07.20.00 v2021.06.28.00 v2021.06.14.00 v2021.06.07.00 v2021.05.31.00 v2021.05.24.00 v2021.05.17.00 v2021.05.10.00 v2021.05.03.00 v2021.04.26.00 v2021.04.19.00 v2021.04.12.00 v2021.04.05.00 v2021.03.29.00 v2021.03.22.00 v2021.03.15.00 v2021.03.08.00 v2021.03.01.00 v2021.02.22.00 v2021.02.15.00 v2021.02.08.00 v2021.02.01.00 v2021.01.25.00 v2021.01.18.01 v2021.01.18.00 v2021.01.11.00 v2021.01.04.00 v2020.12.28.00 v2020.12.21.00 v2020.12.14.00 v2020.12.07.00 v2020.11.30.00 v2020.11.23.00 v2020.11.16.00 v2020.11.09.00 v2020.11.02.00 v2020.10.26.00 v2020.10.19.00 v2020.10.12.00 v2020.10.05.00 v2020.09.28.00 v2020.09.21.00 v2020.09.14.00 v2020.09.07.00 v2020.08.31.00 v2020.08.24.00 v2020.08.17.00 v2020.08.10.00 v2020.08.03.00 v2020.07.27.00 v2020.07.20.00 v2020.07.13.00 v2020.07.06.00 v2020.06.29.00 v2020.06.15.00 v2020.06.08.00 v2020.06.01.00 v2020.05.25.00 v2020.05.18.00 v2020.05.11.00 v2020.05.04.00 v2020.04.27.00 v2020.04.20.00 v2020.04.13.00 v2020.04.06.00 v2020.03.30.00 v2020.03.23.00 v2020.03.16.00 v2020.03.09.00 v2020.03.02.00 v2020.02.24.00 v2020.02.17.00 v2020.02.10.00 v2020.02.03.00 v2020.01.27.00 v2020.01.20.00 v2020.01.13.00 v2020.01.06.00 v2019.12.30.00 v2019.12.23.00 v2019.12.16.00 v2019.12.09.00 v2019.12.06.00 v2019.12.02.00 v2019.11.11.00 v2019.11.04.00 v2019.10.28.00 v2019.10.21.00 v2019.10.14.00 v2019.10.07.00 v2019.09.30.00 v2019.09.23.00 v2019.09.16.00 v2019.09.09.00 v2019.09.02.00 v2019.08.26.00 v2019.08.19.00 v2019.08.12.00 v2019.08.05.00 v2019.07.29.00 v2019.07.22.00 v2019.06.17.00 v2019.06.10.00 v2019.06.03.00 v2019.05.27.00 v2019.05.20.00 v2019.05.13.00 v2019.05.06.00 v2019.04.29.00 v2019.04.22.00 v2019.04.15.00 v2019.04.08.00 v2019.04.01.00 v2019.03.25.00 v2019.03.18.00 v2019.03.04.00 v2019.02.25.00 v2019.02.18.00 v2019.02.11.00 v2019.02.04.00 v2019.01.28.00 v2019.01.21.00 v2019.01.14.00 v2019.01.07.00 v2018.12.31.00 v2018.12.24.00 v2018.12.17.00 v2018.12.10.00 v2018.12.03.00 v2018.11.26.00 v2018.11.19.00 v2018.11.12.00 v2018.11.05.00 v2018.10.29.00 v2018.10.22.00 v2018.10.15.00 v2018.10.08.00 v2018.10.01.00 v2018.09.24.00 v2018.09.17.00 v2018.09.10.01 v2018.09.10.00 v2018.09.03.01 v2018.09.03.00 v2018.08.27.00 v2018.08.20.00 v2018.08.13.00 v2018.08.09.00 v2018.08.06.00 v2018.07.30.00 v2018.07.23.00 v2018.07.16.00 v2018.07.09.00 v2018.07.02.00 v2018.06.25.00 v2018.06.18.00 v2018.06.11.00 v2018.06.04.00 v2018.05.28.00 v2018.05.21.00 v2018.05.14.00 v2018.05.07.00 v2018.04.30.00 v2018.04.23.00 v2018.04.16.00 v2018.04.09.00 v2018.04.02.00 v2018.03.26.00 v2018.03.19.00 v2018.03.12.00 v2018.03.05.00 v2018.02.26.00 v2018.02.19.00 v2018.02.12.00 v2018.02.05.00 v2018.01.29.00 v2018.01.22.00 v2018.01.15.00 v2018.01.08.00 v2018.01.01.00 v2017.12.25.00 v2017.12.18.00 v2017.12.11.00 v2017.12.04.00 v2017.11.27.00 v2017.11.20.00 v2017.11.13.00 v2017.11.06.00 v2017.10.30.00 v2017.10.23.00 v2017.10.16.00 v2017.10.09.00 v2017.10.02.00 v2017.09.25.00 v2017.09.18.00 v2017.09.11.00 v2017.09.04.00 v2017.08.28.00 v2017.08.21.00 v2017.08.14.00 v2017.08.07.00 v2017.07.31.00 v2017.07.24.00 v2017.07.17.01 v2017.07.17.00 v2017.07.10.00 v2017.07.03.00 v2017.06.26.01 v2017.06.26.00 v2017.06.19.00 v2017.06.12.00 v2017.06.05.00 v2017.05.29.00 v2017.05.22.00 v2017.05.15.00 v2017.05.08.00 v2017.05.01.00 v2017.04.24.00 v2017.04.17.00 v2017.04.10.00 v2017.04.03.00 v2017.03.27.00 v2017.03.20.00 v2017.03.13.00 v2017.03.06.00 v2016.12.19.00 v2016.12.12.00 v2016.12.05.00 v2016.11.28.00 v2016.11.21.00 v2016.11.14.00 v2016.11.07.00 v2016.10.31.00 v2016.10.24.00 v2016.10.17.00 v2016.10.10.00 v2016.10.03.00 v2016.09.26.00 v2016.09.19.00 v2016.09.12.01 v2016.09.12.00 v2016.09.05.00 v2016.08.29.00 v2016.08.22.00 v2016.08.15.00 v2016.08.08.00 v2016.08.01.00 v2016.07.29.00 deprecate-dynamic-initializer
No related merge requests found
...@@ -513,13 +513,21 @@ int SSLContext::selectNextProtocolCallback( ...@@ -513,13 +513,21 @@ int SSLContext::selectNextProtocolCallback(
} }
unsigned char *client; unsigned char *client;
int client_len; unsigned int client_len;
if (ctx->advertisedNextProtocols_.empty()) { bool filtered = false;
client = (unsigned char *) ""; auto cpf = ctx->getClientProtocolFilterCallback();
client_len = 0; if (cpf) {
} else { filtered = (*cpf)(&client, &client_len, server, server_len);
client = ctx->advertisedNextProtocols_[0].protocols; }
client_len = ctx->advertisedNextProtocols_[0].length;
if (!filtered) {
if (ctx->advertisedNextProtocols_.empty()) {
client = (unsigned char *) "";
client_len = 0;
} else {
client = ctx->advertisedNextProtocols_[0].protocols;
client_len = ctx->advertisedNextProtocols_[0].length;
}
} }
int retval = SSL_select_next_proto(out, outlen, server, server_len, int retval = SSL_select_next_proto(out, outlen, server, server_len,
......
...@@ -93,6 +93,10 @@ class SSLContext { ...@@ -93,6 +93,10 @@ class SSLContext {
double probability; double probability;
}; };
// Function that selects a client protocol given the server's list
using ClientProtocolFilterCallback = bool (*)(unsigned char**, unsigned int*,
const unsigned char*, unsigned int);
/** /**
* Convenience function to call getErrors() with the current errno value. * Convenience function to call getErrors() with the current errno value.
* *
...@@ -327,6 +331,13 @@ class SSLContext { ...@@ -327,6 +331,13 @@ class SSLContext {
bool setRandomizedAdvertisedNextProtocols( bool setRandomizedAdvertisedNextProtocols(
const std::list<NextProtocolsItem>& items); const std::list<NextProtocolsItem>& items);
void setClientProtocolFilterCallback(ClientProtocolFilterCallback cb) {
clientProtoFilter_ = cb;
}
ClientProtocolFilterCallback getClientProtocolFilterCallback() {
return clientProtoFilter_;
}
/** /**
* Disables NPN on this SSL context. * Disables NPN on this SSL context.
*/ */
...@@ -431,6 +442,8 @@ class SSLContext { ...@@ -431,6 +442,8 @@ class SSLContext {
std::vector<ClientHelloCallback> clientHelloCbs_; std::vector<ClientHelloCallback> clientHelloCbs_;
#endif #endif
ClientProtocolFilterCallback clientProtoFilter_{nullptr};
static bool initialized_; static bool initialized_;
#ifdef OPENSSL_NPN_NEGOTIATED #ifdef OPENSSL_NPN_NEGOTIATED
......
...@@ -127,6 +127,21 @@ void sslsocketpair( ...@@ -127,6 +127,21 @@ void sslsocketpair(
// (*serverSock)->setSendTimeout(100); // (*serverSock)->setSendTimeout(100);
} }
// client protocol filters
bool clientProtoFilterPickPony(unsigned char** client,
unsigned int* client_len, const unsigned char*, unsigned int ) {
//the protocol string in length prefixed byte string. the
//length byte is not included in the length
static unsigned char p[7] = {6,'p','o','n','i','e','s'};
*client = p;
*client_len = 7;
return true;
}
bool clientProtoFilterPickNone(unsigned char**, unsigned int*,
const unsigned char*, unsigned int) {
return false;
}
/** /**
* Test connecting to, writing to, reading from, and closing the * Test connecting to, writing to, reading from, and closing the
...@@ -387,6 +402,64 @@ TEST(AsyncSSLSocketTest, NpnTestNoOverlap) { ...@@ -387,6 +402,64 @@ TEST(AsyncSSLSocketTest, NpnTestNoOverlap) {
EXPECT_EQ(selected.compare("blub"), 0); EXPECT_EQ(selected.compare("blub"), 0);
} }
TEST(AsyncSSLSocketTest, NpnTestClientProtoFilterHit) {
EventBase eventBase;
auto clientCtx = std::make_shared<SSLContext>();
auto serverCtx = std::make_shared<SSLContext>();
int fds[2];
getfds(fds);
getctx(clientCtx, serverCtx);
clientCtx->setAdvertisedNextProtocols({"blub"});
clientCtx->setClientProtocolFilterCallback(clientProtoFilterPickPony);
serverCtx->setAdvertisedNextProtocols({"foo","bar","baz"});
AsyncSSLSocket::UniquePtr clientSock(
new AsyncSSLSocket(clientCtx, &eventBase, fds[0], false));
AsyncSSLSocket::UniquePtr serverSock(
new AsyncSSLSocket(serverCtx, &eventBase, fds[1], true));
NpnClient client(std::move(clientSock));
NpnServer server(std::move(serverSock));
eventBase.loop();
EXPECT_TRUE(client.nextProtoLength != 0);
EXPECT_EQ(client.nextProtoLength, server.nextProtoLength);
EXPECT_EQ(memcmp(client.nextProto, server.nextProto,
server.nextProtoLength), 0);
string selected((const char*)client.nextProto, client.nextProtoLength);
EXPECT_EQ(selected.compare("ponies"), 0);
}
TEST(AsyncSSLSocketTest, NpnTestClientProtoFilterMiss) {
EventBase eventBase;
auto clientCtx = std::make_shared<SSLContext>();
auto serverCtx = std::make_shared<SSLContext>();
int fds[2];
getfds(fds);
getctx(clientCtx, serverCtx);
clientCtx->setAdvertisedNextProtocols({"blub"});
clientCtx->setClientProtocolFilterCallback(clientProtoFilterPickNone);
serverCtx->setAdvertisedNextProtocols({"foo","bar","baz"});
AsyncSSLSocket::UniquePtr clientSock(
new AsyncSSLSocket(clientCtx, &eventBase, fds[0], false));
AsyncSSLSocket::UniquePtr serverSock(
new AsyncSSLSocket(serverCtx, &eventBase, fds[1], true));
NpnClient client(std::move(clientSock));
NpnServer server(std::move(serverSock));
eventBase.loop();
EXPECT_TRUE(client.nextProtoLength != 0);
EXPECT_EQ(client.nextProtoLength, server.nextProtoLength);
EXPECT_EQ(memcmp(client.nextProto, server.nextProto,
server.nextProtoLength), 0);
string selected((const char*)client.nextProto, client.nextProtoLength);
EXPECT_EQ(selected.compare("blub"), 0);
}
TEST(AsyncSSLSocketTest, RandomizedNpnTest) { TEST(AsyncSSLSocketTest, RandomizedNpnTest) {
// Probability that this test will fail is 2^-64, which could be considered // Probability that this test will fail is 2^-64, which could be considered
// as negligible. // as negligible.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment