Test server-side getPeerCert().
authorXiangyu Bu <xbu@fb.com>
Fri, 4 Aug 2017 21:32:14 +0000 (14:32 -0700)
committerFacebook Github Bot <facebook-github-bot@users.noreply.github.com>
Fri, 4 Aug 2017 21:37:37 +0000 (14:37 -0700)
Summary: Make sure server can get client cert using AsyncSSLSocket::getPeerCert() call.

Reviewed By: anirudhvr

Differential Revision: D5557303

fbshipit-source-id: d95696f592e3b3f67acba9f92add32b91c29a000

folly/io/async/test/AsyncSSLSocketTest.cpp
folly/io/async/test/TestSSLServer.cpp
folly/io/async/test/TestSSLServer.h
folly/io/async/test/certs/client_ca_cert.pem [new file with mode: 0644]
folly/io/async/test/certs/client_cert.pem [new file with mode: 0644]
folly/io/async/test/certs/client_key.pem [new file with mode: 0644]

index b006349295f0d7fafd39825015f3b6cc2faba11e..3dd62e5debd52b06769340aa84029ef8ef025183 100644 (file)
@@ -1053,6 +1053,59 @@ TEST(AsyncSSLSocketTest, SSLParseClientHelloSuccess) {
   EXPECT_TRUE(!server.handshakeError_);
 }
 
+/**
+ * Verify that server is able to get client cert by getPeerCert() API.
+ */
+TEST(AsyncSSLSocketTest, GetClientCertificate) {
+  EventBase eventBase;
+  auto clientCtx = std::make_shared<SSLContext>();
+  auto serverCtx = std::make_shared<SSLContext>();
+  serverCtx->setVerificationOption(SSLContext::SSLVerifyPeerEnum::VERIFY);
+  serverCtx->ciphers("ECDHE-RSA-AES128-SHA:AES128-SHA:AES256-SHA");
+  serverCtx->loadPrivateKey(kTestKey);
+  serverCtx->loadCertificate(kTestCert);
+  serverCtx->loadTrustedCertificates(kClientTestCA);
+  serverCtx->loadClientCAList(kClientTestCA);
+
+  clientCtx->setVerificationOption(SSLContext::SSLVerifyPeerEnum::VERIFY);
+  clientCtx->ciphers("AES256-SHA:AES128-SHA");
+  clientCtx->loadPrivateKey(kClientTestKey);
+  clientCtx->loadCertificate(kClientTestCert);
+  clientCtx->loadTrustedCertificates(kTestCA);
+
+  std::array<int, 2> fds;
+  getfds(fds.data());
+
+  AsyncSSLSocket::UniquePtr clientSock(
+      new AsyncSSLSocket(clientCtx, &eventBase, fds[0], false));
+  AsyncSSLSocket::UniquePtr serverSock(
+      new AsyncSSLSocket(serverCtx, &eventBase, fds[1], true));
+
+  SSLHandshakeClient client(std::move(clientSock), true, true);
+  SSLHandshakeServerParseClientHello server(std::move(serverSock), true, true);
+
+  eventBase.loop();
+
+  // Handshake should succeed.
+  EXPECT_TRUE(client.handshakeSuccess_);
+  EXPECT_TRUE(server.handshakeSuccess_);
+
+  // Reclaim the sockets from SSLHandshakeBase.
+  auto cliSocket = std::move(client).moveSocket();
+  auto srvSocket = std::move(server).moveSocket();
+
+  // Client cert retrieved from server side.
+  folly::ssl::X509UniquePtr serverPeerCert = srvSocket->getPeerCert();
+  CHECK(serverPeerCert);
+
+  // Client cert retrieved from client side.
+  const X509* clientSelfCert = cliSocket->getSelfCert();
+  CHECK(clientSelfCert);
+
+  // The two certs should be the same.
+  EXPECT_EQ(0, X509_cmp(clientSelfCert, serverPeerCert.get()));
+}
+
 TEST(AsyncSSLSocketTest, SSLParseClientHelloOnePacket) {
   EventBase eventBase;
   auto ctx = std::make_shared<SSLContext>();
index 46d6743d14c937d1d26b100d548056dd0bea8f75..c75afec655bb99e2d71a17dd54bd9ad3f8d19325 100644 (file)
@@ -21,6 +21,10 @@ const char* kTestCert = "folly/io/async/test/certs/tests-cert.pem";
 const char* kTestKey = "folly/io/async/test/certs/tests-key.pem";
 const char* kTestCA = "folly/io/async/test/certs/ca-cert.pem";
 
+const char* kClientTestCert = "folly/io/async/test/certs/client_cert.pem";
+const char* kClientTestKey = "folly/io/async/test/certs/client_key.pem";
+const char* kClientTestCA = "folly/io/async/test/certs/client_ca_cert.pem";
+
 TestSSLServer::~TestSSLServer() {
   if (thread_.joinable()) {
     evb_.runInEventBaseThread([&]() { socket_->stopAccepting(); });
index 506b3d1351f312ab7df18923bf2c8a9dfa7afc81..e03e45506561aa7b0c9d4fd49527a9ecd4688a20 100644 (file)
@@ -38,6 +38,10 @@ extern const char* kTestCert;
 extern const char* kTestKey;
 extern const char* kTestCA;
 
+extern const char* kClientTestCert;
+extern const char* kClientTestKey;
+extern const char* kClientTestCA;
+
 enum StateEnum { STATE_WAITING, STATE_SUCCEEDED, STATE_FAILED };
 
 class HandshakeCallback;
diff --git a/folly/io/async/test/certs/client_ca_cert.pem b/folly/io/async/test/certs/client_ca_cert.pem
new file mode 100644 (file)
index 0000000..065b08d
--- /dev/null
@@ -0,0 +1,22 @@
+-----BEGIN CERTIFICATE-----
+MIIDmjCCAoKgAwIBAgIBATANBgkqhkiG9w0BAQsFADBQMQswCQYDVQQGEwJVUzEL
+MAkGA1UECAwCQ0ExDTALBgNVBAoMBEFzb3gxJTAjBgNVBAMMHEFzb3ggQ2VydGlm
+aWNhdGlvbiBBdXRob3JpdHkwHhcNMTcwODAzMjMyMTA1WhcNNDQxMjE5MjMyMTA1
+WjBQMQswCQYDVQQGEwJVUzELMAkGA1UECAwCQ0ExDTALBgNVBAoMBEFzb3gxJTAj
+BgNVBAMMHEFzb3ggQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwggEiMA0GCSqGSIb3
+DQEBAQUAA4IBDwAwggEKAoIBAQDfv3KonszKqaZLZ5Vwnl/v6BhwQNqyx3nEDXTY
+pCn17En3DJzsa0zlqkmw8XJeQrx6+iZjLyGqEjIcqHAFcabux7PJ5z+T41kabNzU
++WEYBhNbEB1xRm7Rqz9OzroajWIK8Wugzmqu2Sz+QYaFPjsW85+zVB6E3YPbBpz/
+uPmAecwpInzFH7C9o5TZGoYS+0K1fH935EhM617HSVvHQflQL8IcGZuLExVxiOZ+
+SkJIXO+JaM2cXBFnqf4halHQ5O+866Xk09WbhUpOqi/tGE74VQBKC2u2F1DUga0W
+37Gwcp4o9WWdeCL10323QOSnAJoaMccBpILZSL3g7YJD1ZlFAgMBAAGjfzB9MB0G
+A1UdDgQWBBR8WSTHikglMmAbowGKfg4kFNNFbzAfBgNVHSMEGDAWgBR8WSTHikgl
+MmAbowGKfg4kFNNFbzAMBgNVHRMEBTADAQH/MC0GCCsGAQUFBwEBBCEwHzAdBggr
+BgEFBQcwAoYRaHR0cHM6Ly90ZXN0X2NlcnQwDQYJKoZIhvcNAQELBQADggEBAACe
+5R64MK058S3g6mQuviburcnKeBojMt1liqKGcCDwFKFHiYCN3hKoZmEQ4XvQu0U5
+U2a3/sFG5mZD8UjAQzlQQkdjy4CwM3iGA5EeTT+VYnc9/UQU1yeyiGIRkNDJKp2y
+p4vw5sm40uBwc+QfUAl7AExO4Q8FOdVqoS/zixYtFNQ2CjlLEzY5FRgyzfHQQDtn
+rmtdVKOeWd0itvgSCeMs5KfetZlFAHavclcAN/721ukGiaWXyxQPfRLX2dS4RB8j
+TwC15NBTsRTbYhJLYuBoUwTdhCojBUr8NN1kgwjHsT6wjtLJpRl6qeKHMw+Y9IlT
+VgbFH84VIfIB1tnMNNA=
+-----END CERTIFICATE-----
diff --git a/folly/io/async/test/certs/client_cert.pem b/folly/io/async/test/certs/client_cert.pem
new file mode 100644 (file)
index 0000000..afe8415
--- /dev/null
@@ -0,0 +1,21 @@
+-----BEGIN CERTIFICATE-----
+MIIDZjCCAk6gAwIBAgIBCjANBgkqhkiG9w0BAQsFADBQMQswCQYDVQQGEwJVUzEL
+MAkGA1UECAwCQ0ExDTALBgNVBAoMBEFzb3gxJTAjBgNVBAMMHEFzb3ggQ2VydGlm
+aWNhdGlvbiBBdXRob3JpdHkwHhcNMTcwODAzMjMyMTA2WhcNNDQxMjE5MjMyMTA2
+WjAwMQswCQYDVQQGEwJVUzENMAsGA1UECgwEQXNveDESMBAGA1UEAwwJdGVzdHVz
+ZXIxMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxNjbq/fOD9BZN1N+
+UPwTLK0jSE3zW3o4YIIZKnOc8ln3kY6xI0Xtm96uGD/y+nWFHGiEX5eqcTZEEaX7
+4kHBU3mcWaZvC/JfBwyG1gf3/5sl5yxgJB9LsSZRcBKcET+JJ8Ps7WADBU0IVUsj
+yejt25wnpsmglXbt7rObay8H0AYstRmNhpq7N92R6CKeVpHzuvUujSFnMGmxh5ux
+l9anytFfr84E4G/AEUFkEKimFsqtG5Je3ZAfREhoNdCSERENYNtNXgLVCeWLGAT8
+Mp0gNDHgBGheiWDIFRK5PKbJENMfOZt0mjQAM3ypmsLCNhSV81CDc9Q/GEOLMMxX
+VP773wIDAQABo2swaTAJBgNVHRMEAjAAMA4GA1UdDwEB/wQEAwIFoDAdBgNVHSUE
+FjAUBggrBgEFBQgCAgYIKwYBBQUHAwIwLQYIKwYBBQUHAQEEITAfMB0GCCsGAQUF
+BzAChhFodHRwczovL3Rlc3RfY2VydDANBgkqhkiG9w0BAQsFAAOCAQEAO/kPyxvj
+ZXxb4uCjqLFiPWKcGHhX1U+rE6tHf/iBh6WJ7D751Z56AT8YjtSWXxDgD3zOvhml
+TGjkWIofG5yhYBeYEvrlHzXIqsPmUhOYgO42V4AXFB8u5gPw7tB5aozhxA4jB6Ik
+JXkmDiBsyP4DvYknl7gGl4eubOPM/MDy0YasZH3C3shmjAJEW2CEbIrLXyT+N6yK
++zVtxEVlTZ4TPmXzOLqMIrgjLBWq5I9ATf5BCcqjs2bnHvVkErmY6WcpPTKDyCg6
+Nmtla39ffF6V1S9BItLB7nZsGwMuExwPvotFseTppiAQyZGH0rPECxyPDpNNij/G
+5ro+AZN3usfsqw==
+-----END CERTIFICATE-----
diff --git a/folly/io/async/test/certs/client_key.pem b/folly/io/async/test/certs/client_key.pem
new file mode 100644 (file)
index 0000000..6200a65
--- /dev/null
@@ -0,0 +1,27 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIEogIBAAKCAQEAxNjbq/fOD9BZN1N+UPwTLK0jSE3zW3o4YIIZKnOc8ln3kY6x
+I0Xtm96uGD/y+nWFHGiEX5eqcTZEEaX74kHBU3mcWaZvC/JfBwyG1gf3/5sl5yxg
+JB9LsSZRcBKcET+JJ8Ps7WADBU0IVUsjyejt25wnpsmglXbt7rObay8H0AYstRmN
+hpq7N92R6CKeVpHzuvUujSFnMGmxh5uxl9anytFfr84E4G/AEUFkEKimFsqtG5Je
+3ZAfREhoNdCSERENYNtNXgLVCeWLGAT8Mp0gNDHgBGheiWDIFRK5PKbJENMfOZt0
+mjQAM3ypmsLCNhSV81CDc9Q/GEOLMMxXVP773wIDAQABAoIBAGDrlV1aqa7HmuXO
+ykb9lkNNDC4xkzzbNJ7v74wjWIdLHMYiR71iVNeGEJoIAo6nBl8yZtraRiVv3pwB
+6b9BOPrsybqqY8qyD2/dDxaa3dSQg10LUFr4vb//aeGQiB9F9TYLFcDaoSIfB5dX
+Y8uqUFLs0+kfJV3yLLx22nMvuN0HD4ra8pzWOzO6r/cyGV5Q0hY+GjfbXUvO1Kk7
+ez/Hc2MSR/rQTReEldExB839lcYjlxpQ5FyfXBVsBev6DLl3YRZe0Zq3cE94BBTs
+EksD4O1maWpW9RMsLyxGiPKt08zIXdupuOQXWG+d3K/ZhVheGtQz2bqBobDANB2I
+l6o7xcECgYEA8pgXaktdxOxErDeiy0TRYg2/GVkqmzH7JK3cy9vWL67ihbCKSDzF
+H3B27PbBx/DDCRdV1zXHwY2fuqVdrNbJXCzeXg8xw6VrIwtWNKJksi5+echCOgf8
+dfpr5d/ujcVPDd/oqBFBXqTwA93H6rablLRxlIM6j74u+fvfKKYsnLkCgYEAz7mY
+1PHcpf39+SCp1gyP6tNSk5W5gkgmQYNVD1gEgYvAThJ+SYpsq/FvyutF8gQwugZk
++ESlrMn79CxDmxmwLDkI1dhH87rK63QadcKAf6gGzmmW5iF7JpfEI2sCgHRzo+YY
+DvjXPYHORXmG8FzSwXEFeaGmkUfZkQCnlGaBAVcCgYBkeETKSuhM1CUkxe3wDVJC
+L7tDPkB9AdgnOrJE44jzOpSqFZFPlYt2F9fJD/D1Y2sC6t0sQiO2r3bFkBMZr+K5
+AAQgJF7RzkJuwxUyu0bE3KiYuy1iZ0hRfCMPkwxzPpIdBuyOHodaMSkOEN3pATOy
+BIE9ppOsUHGYKo4jgZ7cUQKBgCnUONdgoMr4O4VIM4r72psx1KYNd16pwrJcjOtb
+EQU5LA9MoAuVCU8Sfi2BdQNIHrvG/9wSjr4dqlO/+hkochZlocbWF58X1TbWmWFv
+Okr6fexgzNcolNDvrLppGQbe7E5rzhptt4IWOoA4+Zg7SOFVLgIRMCZ/LmuJkzVJ
+8t5fAoGAT5aji/j7w+isIU4R13w2x5UXyVSapmAPZt0N3KQeD5/WHMEvUgu7Lk3a
+FrBHbs1bvF6Q6uJhe+OvN0/vqhesa334XzBPoyMVa3UfTkVrW6TvEoJa/Gc8oIno
+Pjrn8wSA0SCFf/wuCcXIDhk9Mq2q5dOD5FeTPFciR7zYWFlOQnI=
+-----END RSA PRIVATE KEY-----