Commit ecd0fb38 authored by Alex Guzman's avatar Alex Guzman Committed by Facebook Github Bot

Add utility function for loading certificates from a buffer

Summary: Adds a function that reads certificates in from a buffer and returns them as a vector of X509 pointers.

Reviewed By: yfeldblum

Differential Revision: D6133332

fbshipit-source-id: eaaaffcbd4d03f37d9d5b4c99a52b0d968b163ba
parent e3d0887c
...@@ -196,5 +196,24 @@ std::unique_ptr<IOBuf> OpenSSLCertUtils::derEncode(X509& x509) { ...@@ -196,5 +196,24 @@ std::unique_ptr<IOBuf> OpenSSLCertUtils::derEncode(X509& x509) {
buf->append(len); buf->append(len);
return buf; return buf;
} }
std::vector<X509UniquePtr> OpenSSLCertUtils::readCertsFromBuffer(
ByteRange range) {
BioUniquePtr b(BIO_new_mem_buf(range.data(), range.size()));
if (!b) {
throw std::runtime_error("failed to create BIO");
}
std::vector<X509UniquePtr> certs;
while (true) {
X509UniquePtr x509(PEM_read_bio_X509(b.get(), nullptr, nullptr, nullptr));
if (!x509) {
break;
}
certs.push_back(std::move(x509));
}
return certs;
}
} // namespace ssl } // namespace ssl
} // namespace folly } // namespace folly
...@@ -76,6 +76,12 @@ class OpenSSLCertUtils { ...@@ -76,6 +76,12 @@ class OpenSSLCertUtils {
*/ */
static std::unique_ptr<IOBuf> derEncode(X509&); static std::unique_ptr<IOBuf> derEncode(X509&);
/**
* Reads certificates from memory and returns them as a vector of X509
* pointers.
*/
static std::vector<X509UniquePtr> readCertsFromBuffer(ByteRange);
private: private:
static std::string getDateTimeStr(const ASN1_TIME* time); static std::string getDateTimeStr(const ASN1_TIME* time);
}; };
......
...@@ -16,8 +16,10 @@ ...@@ -16,8 +16,10 @@
#include <folly/ssl/OpenSSLCertUtils.h> #include <folly/ssl/OpenSSLCertUtils.h>
#include <folly/Format.h>
#include <folly/Range.h> #include <folly/Range.h>
#include <folly/String.h> #include <folly/String.h>
#include <folly/container/Enumerate.h>
#include <folly/portability/GTest.h> #include <folly/portability/GTest.h>
#include <folly/portability/OpenSSL.h> #include <folly/portability/OpenSSL.h>
#include <folly/ssl/Init.h> #include <folly/ssl/Init.h>
...@@ -57,6 +59,72 @@ const std::string kTestCertWithSan = folly::stripLeftMargin(R"( ...@@ -57,6 +59,72 @@ const std::string kTestCertWithSan = folly::stripLeftMargin(R"(
-----END CERTIFICATE----- -----END CERTIFICATE-----
)"); )");
const std::string kTestCertBundle = folly::stripLeftMargin(R"(
-----BEGIN CERTIFICATE-----
MIIDgzCCAmugAwIBAgIJAIkcS3PQcCm+MA0GCSqGSIb3DQEBCwUAMFgxCzAJBgNV
BAYTAlhYMRUwEwYDVQQHDAxEZWZhdWx0IENpdHkxHDAaBgNVBAoME0RlZmF1bHQg
Q29tcGFueSBMdGQxFDASBgNVBAMMC3Rlc3QgY2VydCAxMB4XDTE3MTAyMzIwNTcw
M1oXDTE4MTAyMzIwNTcwM1owWDELMAkGA1UEBhMCWFgxFTATBgNVBAcMDERlZmF1
bHQgQ2l0eTEcMBoGA1UECgwTRGVmYXVsdCBDb21wYW55IEx0ZDEUMBIGA1UEAwwL
dGVzdCBjZXJ0IDEwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCplTzR
6shdhVNbx5HFViiYDBjRYXCWiUeR0/0+XPkyI+DPIGAQ6Mre8WD03GPebYn7j3Lr
JwgV06BJNvVCLDy0SJbf6ToxGfKWSLEWOoip32nIpb9qxURtx44NUvhChP54hhKI
zAf8nNlS+qKUYbmixJHeUWO//8wNpsMKDkvtfVUZ6oVV3JPOOihJ+sQ0sIc5x+xk
3eWfa0cNoZnxu4plQg2O4RlHOv8ruMW6BttpcqQ8I+Rxq+/YOhNQhX+6GZ1+Rs+f
ddWXYNH6tFxsLIEbgCqHhLGw7g+JRms9R+CxLCpjmhYhR2xgl6KQu/Racr2T/17z
897VfY7X94PmamidAgMBAAGjUDBOMB0GA1UdDgQWBBRHQvRr2p3/83y1yXiiVnnS
zObpzTAfBgNVHSMEGDAWgBRHQvRr2p3/83y1yXiiVnnSzObpzTAMBgNVHRMEBTAD
AQH/MA0GCSqGSIb3DQEBCwUAA4IBAQAk61K1sjrS7rrLnGND1o1Q6D2ebgb1wcfU
WX+ZnhlkUxjSS1nHmaulMftpvzbgrOt7HWZKMXIpetnDSfksrGpw6QJ3VWFIJlH5
P4x8//pVeI5jQd4W7gIl65tZOc5cEH8aqnzkaGP8YBx6BI6N8px1gZVgePVu3ebR
eLdrWH2l4VishWOf6rO/ltQdTwRIqj08QNsWmSrRK2d7J/DGA6R9JkdyxeLdxqmB
2BMwJ7IVR+bWuTzD9Zk5lZseIVFcIksxmQ8jJuZXUdN8WOT/65p9UnN+Cc6+Q7F4
rlVz+ytcdvaf5mDeqFILDK6btWcUP2Vr1EfRDt/QBrU6OjAVQD+U
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIDgzCCAmugAwIBAgIJAPzrfjTkvHezMA0GCSqGSIb3DQEBCwUAMFgxCzAJBgNV
BAYTAlhYMRUwEwYDVQQHDAxEZWZhdWx0IENpdHkxHDAaBgNVBAoME0RlZmF1bHQg
Q29tcGFueSBMdGQxFDASBgNVBAMMC3Rlc3QgY2VydCAyMB4XDTE3MTAyMzIwNTcx
NloXDTE4MTAyMzIwNTcxNlowWDELMAkGA1UEBhMCWFgxFTATBgNVBAcMDERlZmF1
bHQgQ2l0eTEcMBoGA1UECgwTRGVmYXVsdCBDb21wYW55IEx0ZDEUMBIGA1UEAwwL
dGVzdCBjZXJ0IDIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCzy9G/
NM7Llp+foYxug2Dqc3r9zWtb4PvbRqoz8W0ZRy0GkL3JtOfLWtlz+RCGa//mlGMA
HLa+Qg77nnjuhO/KCCgQS9fxHY+zcv1VBwzsKmKcju4BCscsTLPsy0SJCXBXSgnH
S4NMR/K+YozwdikEZRbU4VLJiw44CeJ1h74r2ElHYuOL0SpL8PSlv7kJu3/xWUiV
L2iWk+y8yKIpCRQ9I7+L0kuhylZAmVBTKtgbdcLfERqQNNWAT7D+p/6CwNmpT9ei
G2xJ0N4bt3w8kwcZ+IkGwei8Nadix+POe3WVU9K1VXVfoLZ9nNWKRnwIFP4Bsmld
rP4Uy2IZuhrKE4BPAgMBAAGjUDBOMB0GA1UdDgQWBBQkmeMfPQaax9wCZL16jSSG
XigBWjAfBgNVHSMEGDAWgBQkmeMfPQaax9wCZL16jSSGXigBWjAMBgNVHRMEBTAD
AQH/MA0GCSqGSIb3DQEBCwUAA4IBAQCXzqxYp1FqMS2M+opCSPezgPDBdE2S9g6d
HJHV5CLptGnu1vQIlyCXy/7X9b6Qq8UzuYyFacN/37tbNw6sGyTRfL8sEeFYfFoT
GvgSrRqSM47ZBYx5jW/Uslkc5qbq+v4zeGCq5611stQKsJYIudu0+PjJmgtNF6en
zTx8B6eS79GRN3/M7/kFLlxeZNCQpmKwvPp8P7JE4ZHUtuzQoKtjdt/etWpS76fV
Akx7VhCFg/lw80tmgSclq885hYRYc6DOKfUubWOacKVfmHwL4oDiSffBonI7MoH8
SJbzsCBpVd/tkDADZpxBQplGV7AaDBoNS0qvZHfH5x9R9R5lx9M+
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
MIIDgzCCAmugAwIBAgIJAOzqPJDDfSKDMA0GCSqGSIb3DQEBCwUAMFgxCzAJBgNV
BAYTAlhYMRUwEwYDVQQHDAxEZWZhdWx0IENpdHkxHDAaBgNVBAoME0RlZmF1bHQg
Q29tcGFueSBMdGQxFDASBgNVBAMMC3Rlc3QgY2VydCAzMB4XDTE3MTAyMzIwNTcy
NVoXDTE4MTAyMzIwNTcyNVowWDELMAkGA1UEBhMCWFgxFTATBgNVBAcMDERlZmF1
bHQgQ2l0eTEcMBoGA1UECgwTRGVmYXVsdCBDb21wYW55IEx0ZDEUMBIGA1UEAwwL
dGVzdCBjZXJ0IDMwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDWqU2b
eBzaOAja6od84hFfgvitOGrCYqLXMUXe0X7AlldzXV4zHaVyTKdEwDwvKDi5p9OF
uTxSZkZ0JSPHZeH2/rHXidNMWdtiy5x/5ra1u9ctN7jHeboIxmdpfxoGq7s6cRA5
oRh0bCNmw+Y7K+1RITmPloB7155RbrJYZR5MOFIaCnZV3j/icKjASTOg3ivXX4lx
BoHGMYF8rl+51FIJsuXvnBgF+GhadMVSWl4Qy6gLliml1MgujlmFg9/1y/xzdWZg
yyLI3tvw7fo/NN62u41VQBdCGdpvnVxU4ADu2/T0vhAS+Bh2CMK1OAAw61x1507S
f68mab9s8at49qefAgMBAAGjUDBOMB0GA1UdDgQWBBQnn76Swsnld6Q1weLgpo/S
tt0KeTAfBgNVHSMEGDAWgBQnn76Swsnld6Q1weLgpo/Stt0KeTAMBgNVHRMEBTAD
AQH/MA0GCSqGSIb3DQEBCwUAA4IBAQCB0XANIWyP7DYROh6MFQLqeylngd9iUGNe
BMT4pWu60p5ZX13kK/gbV/P2cayUkkWEMWpzKcIX70IkaB5y/OxVMXUXo94UupsM
b1T736wHA0TLeL7yDj9OnMYj/qa2r8pAyEObI84KoWRGMHH9UPSRbVMVrhg/agBA
LA6eZhwiGctkCy09kp+SFbUpv+SMyVp60UrPub6j68Hzd0FioGY01Os7nScuPNo0
rl2S+G36bcem8Z5MOkJ0LEFi6ctK9JdLcHkr1SVavo3fsYZaIZraJxFGcYUVyLT+
Rw7ydBokxHWsmVJczuRmEovXcTmgIphti234e7usKjw8M5mGwYfa
-----END CERTIFICATE-----
)");
class OpenSSLCertUtilsTest : public Test { class OpenSSLCertUtilsTest : public Test {
public: public:
void SetUp() override { void SetUp() override {
...@@ -179,3 +247,14 @@ TEST_F(OpenSSLCertUtilsTest, TestDerDecodeTooShort) { ...@@ -179,3 +247,14 @@ TEST_F(OpenSSLCertUtilsTest, TestDerDecodeTooShort) {
folly::ssl::OpenSSLCertUtils::derDecode(der->coalesce()), folly::ssl::OpenSSLCertUtils::derDecode(der->coalesce()),
std::runtime_error); std::runtime_error);
} }
TEST_F(OpenSSLCertUtilsTest, TestReadCertsFromBuffer) {
auto certs = folly::ssl::OpenSSLCertUtils::readCertsFromBuffer(
StringPiece(kTestCertBundle));
EXPECT_EQ(certs.size(), 3);
for (auto i : folly::enumerate(certs)) {
auto identity = folly::ssl::OpenSSLCertUtils::getCommonName(**i);
EXPECT_TRUE(identity);
EXPECT_EQ(*identity, folly::sformat("test cert {}", i.index + 1));
}
}
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