Commit 79c30edd authored by Neel Goyal's avatar Neel Goyal Committed by Facebook Github Bot

Add utility to create stores

Summary: Add methods to create a X509StoreUniquePtr from a ca file or buffer.

Reviewed By: yfeldblum

Differential Revision: D6662538

fbshipit-source-id: 646f61596f2787756b2fa5998a43f36d75a91d90
parent c60784b8
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
*/ */
#include <folly/ssl/OpenSSLCertUtils.h> #include <folly/ssl/OpenSSLCertUtils.h>
#include <folly/FileUtil.h>
#include <folly/ScopeGuard.h> #include <folly/ScopeGuard.h>
#include <folly/String.h> #include <folly/String.h>
#include <folly/ssl/OpenSSLPtrTypes.h> #include <folly/ssl/OpenSSLPtrTypes.h>
...@@ -240,6 +241,32 @@ std::array<uint8_t, SHA256_DIGEST_LENGTH> OpenSSLCertUtils::getDigestSha256( ...@@ -240,6 +241,32 @@ std::array<uint8_t, SHA256_DIGEST_LENGTH> OpenSSLCertUtils::getDigestSha256(
return md; return md;
} }
X509StoreUniquePtr OpenSSLCertUtils::readStoreFromFile(std::string caFile) {
std::string certData;
if (!folly::readFile(caFile.c_str(), certData)) {
throw std::runtime_error(
folly::to<std::string>("Could not read store file: ", caFile));
}
auto certRange = folly::ByteRange(folly::StringPiece(certData));
return readStoreFromBuffer(std::move(certRange));
}
X509StoreUniquePtr OpenSSLCertUtils::readStoreFromBuffer(ByteRange certRange) {
auto certs = readCertsFromBuffer(certRange);
ERR_clear_error();
folly::ssl::X509StoreUniquePtr store(X509_STORE_new());
for (auto& caCert : certs) {
if (X509_STORE_add_cert(store.get(), caCert.get()) != 1) {
auto err = ERR_get_error();
if (ERR_GET_LIB(err) != ERR_LIB_X509 ||
ERR_GET_REASON(err) != X509_R_CERT_ALREADY_IN_HASH_TABLE) {
throw std::runtime_error(folly::to<std::string>(
"Could not insert CA certificate into store: ",
std::string(ERR_error_string(err, nullptr))));
}
}
}
return store;
}
} // namespace ssl } // namespace ssl
} // namespace folly } // namespace folly
/* /*
* Copyright 2017 Facebook, Inc. * Copyright 2017-present Facebook, Inc.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
...@@ -90,6 +90,12 @@ class OpenSSLCertUtils { ...@@ -90,6 +90,12 @@ class OpenSSLCertUtils {
static std::array<uint8_t, SHA_DIGEST_LENGTH> getDigestSha1(X509& x509); static std::array<uint8_t, SHA_DIGEST_LENGTH> getDigestSha1(X509& x509);
static std::array<uint8_t, SHA256_DIGEST_LENGTH> getDigestSha256(X509& x509); static std::array<uint8_t, SHA256_DIGEST_LENGTH> getDigestSha256(X509& x509);
/**
* Reads a store from a file (or buffer). Throws on error.
*/
static X509StoreUniquePtr readStoreFromFile(std::string caFile);
static X509StoreUniquePtr readStoreFromBuffer(ByteRange);
private: private:
static std::string getDateTimeStr(const ASN1_TIME* time); static std::string getDateTimeStr(const ASN1_TIME* time);
}; };
......
/* /*
* Copyright 2017 Facebook, Inc. * Copyright 2017-present Facebook, Inc.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
...@@ -13,7 +13,6 @@ ...@@ -13,7 +13,6 @@
* See the License for the specific language governing permissions and * See the License for the specific language governing permissions and
* limitations under the License. * limitations under the License.
*/ */
#include <folly/ssl/OpenSSLCertUtils.h> #include <folly/ssl/OpenSSLCertUtils.h>
#include <folly/Format.h> #include <folly/Format.h>
...@@ -29,6 +28,7 @@ using namespace testing; ...@@ -29,6 +28,7 @@ using namespace testing;
using namespace folly; using namespace folly;
const char* kTestCertWithoutSan = "folly/io/async/test/certs/tests-cert.pem"; const char* kTestCertWithoutSan = "folly/io/async/test/certs/tests-cert.pem";
const char* kTestCa = "folly/io/async/test/certs/ca-cert.pem";
// Test key // Test key
// -----BEGIN EC PRIVATE KEY----- // -----BEGIN EC PRIVATE KEY-----
...@@ -273,3 +273,15 @@ TEST_F(OpenSSLCertUtilsTest, TestX509Digest) { ...@@ -273,3 +273,15 @@ TEST_F(OpenSSLCertUtilsTest, TestX509Digest) {
folly::hexlify(folly::range(sha2Digest)), folly::hexlify(folly::range(sha2Digest)),
"364d3a6a0b10d0635ce59b40c0b7f505ab2cd9fd0a06661cdc61d9cb8c9c9821"); "364d3a6a0b10d0635ce59b40c0b7f505ab2cd9fd0a06661cdc61d9cb8c9c9821");
} }
TEST_F(OpenSSLCertUtilsTest, TestX509Store) {
auto store = folly::ssl::OpenSSLCertUtils::readStoreFromFile(kTestCa);
EXPECT_NE(store, nullptr);
auto x509 = readCertFromFile(kTestCertWithoutSan);
folly::ssl::X509StoreCtxUniquePtr ctx(X509_STORE_CTX_new());
auto rc = X509_STORE_CTX_init(ctx.get(), store.get(), x509.get(), nullptr);
EXPECT_EQ(rc, 1);
rc = X509_verify_cert(ctx.get());
EXPECT_EQ(rc, 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