27 std::string getOpenSSLErrorString(
unsigned long err) {
28 std::array<char, 256> errBuff;
29 ERR_error_string_n(err, errBuff.data(), errBuff.size());
35 auto subject = X509_get_subject_name(&x509);
40 auto cnLoc = X509_NAME_get_index_by_NID(subject, NID_commonName, -1);
45 auto cnEntry = X509_NAME_get_entry(subject, cnLoc);
50 auto cnAsn = X509_NAME_ENTRY_get_data(cnEntry);
56 auto cnLen = ASN1_STRING_length(cnAsn);
57 if (!cnData || cnLen <= 0) {
65 auto names =
reinterpret_cast<STACK_OF(GENERAL_NAME)*
>(
66 X509_get_ext_d2i(&x509, NID_subject_alt_name,
nullptr,
nullptr));
71 sk_GENERAL_NAME_pop_free(names, GENERAL_NAME_free);
74 std::vector<std::string> ret;
75 auto count = sk_GENERAL_NAME_num(names);
77 auto genName = sk_GENERAL_NAME_value(names,
i);
78 if (!genName || genName->type != GEN_DNS) {
81 auto nameData =
reinterpret_cast<const char*
>(
83 auto nameLen = ASN1_STRING_length(genName->d.dNSName);
84 if (!nameData || nameLen <= 0) {
87 ret.emplace_back(nameData, nameLen);
93 auto subject = X509_get_subject_name(&x509);
100 throw std::runtime_error(
"Cannot allocate bio");
102 if (X509_NAME_print_ex(bio.get(), subject, 0, XN_FLAG_ONELINE) <= 0) {
106 char* bioData =
nullptr;
107 size_t bioLen = BIO_get_mem_data(bio.get(), &bioData);
112 auto issuer = X509_get_issuer_name(&x509);
118 if (bio ==
nullptr) {
119 throw std::runtime_error(
"Cannot allocate bio");
122 if (X509_NAME_print_ex(bio.get(), issuer, 0, XN_FLAG_ONELINE) <= 0) {
126 char* bioData =
nullptr;
127 size_t bioLen = BIO_get_mem_data(bio.get(), &bioData);
134 throw std::runtime_error(
"Cannot allocate bio");
139 flags |= X509_FLAG_NO_HEADER |
140 X509_FLAG_NO_PUBKEY |
142 X509_FLAG_NO_SIGDUMP |
143 X509_FLAG_NO_SIGNAME;
145 #ifdef X509_FLAG_NO_IDS 146 flags |= X509_FLAG_NO_IDS;
149 if (X509_print_ex(in.get(), &x509, XN_FLAG_ONELINE,
flags) > 0) {
150 char* bioData =
nullptr;
151 size_t bioLen = BIO_get_mem_data(in.get(), &bioData);
172 if (bio ==
nullptr) {
173 throw std::runtime_error(
"Cannot allocate bio");
176 if (ASN1_TIME_print(bio.get(),
time) <= 0) {
177 throw std::runtime_error(
"Cannot print ASN1_TIME");
180 char* bioData =
nullptr;
181 size_t bioLen = BIO_get_mem_data(bio.get(), &bioData);
189 throw std::runtime_error(
"could not read cert");
195 auto len = i2d_X509(&x509,
nullptr);
197 throw std::runtime_error(
"Error computing length");
200 auto dataPtr = buf->writableData();
201 len = i2d_X509(&x509, &
dataPtr);
203 throw std::runtime_error(
"Error converting cert to DER");
212 BIO_new_mem_buf(const_cast<unsigned char*>(range.
data()), range.
size()));
214 throw std::runtime_error(
"failed to create BIO");
216 std::vector<X509UniquePtr> certs;
219 X509UniquePtr x509(PEM_read_bio_X509(b.get(),
nullptr,
nullptr,
nullptr));
224 auto err = ERR_get_error();
226 if (BIO_eof(b.get()) && ERR_GET_LIB(err) == ERR_LIB_PEM &&
227 ERR_GET_REASON(err) == PEM_R_NO_START_LINE) {
231 throw std::runtime_error(folly::to<std::string>(
232 "Unable to parse cert ",
235 getOpenSSLErrorString(err)));
243 std::array<uint8_t, SHA_DIGEST_LENGTH> md;
244 int rc = X509_digest(&x509, EVP_sha1(), md.data(), &len);
247 throw std::runtime_error(
"Could not calculate SHA1 digest for cert");
255 std::array<uint8_t, SHA256_DIGEST_LENGTH> md;
256 int rc = X509_digest(&x509, EVP_sha256(), md.data(), &len);
259 throw std::runtime_error(
"Could not calculate SHA256 digest for cert");
267 throw std::runtime_error(
268 folly::to<std::string>(
"Could not read store file: ", caFile));
277 for (
auto& caCert : certs) {
278 if (X509_STORE_add_cert(store.get(), caCert.get()) != 1) {
279 auto err = ERR_get_error();
280 if (ERR_GET_LIB(err) != ERR_LIB_X509 ||
281 ERR_GET_REASON(err) != X509_R_CERT_ALREADY_IN_HASH_TABLE) {
282 throw std::runtime_error(folly::to<std::string>(
283 "Could not insert CA certificate into store: ",
284 getOpenSSLErrorString(err)));
bool readFile(int fd, Container &out, size_t num_bytes=std::numeric_limits< size_t >::max())
static folly::Optional< std::string > toString(X509 &x509)
std::unique_ptr< X509, X509Deleter > X509UniquePtr
static std::unique_ptr< IOBuf > create(std::size_t capacity)
std::unique_ptr< BIO, BioDeleter > BioUniquePtr
static std::array< uint8_t, SHA_DIGEST_LENGTH > getDigestSha1(X509 &x509)
static std::array< uint8_t, SHA256_DIGEST_LENGTH > getDigestSha256(X509 &x509)
static Optional< std::string > getSubject(X509 &x509)
STACK_OF(X509_OBJECT)*X509_STORE_get0_objects(X509_STORE *store)
static X509StoreUniquePtr readStoreFromBuffer(ByteRange range)
constexpr detail::Map< Move > move
static X509UniquePtr derDecode(ByteRange)
constexpr size_type size() const
auto begin(TestAdlIterable &instance)
unsigned char * ASN1_STRING_get0_data(const ASN1_STRING *x)
—— Concurrent Priority Queue Implementation ——
static std::vector< std::string > getSubjectAltNames(X509 &x509)
static X509StoreUniquePtr readStoreFromFile(std::string caFile)
static Optional< std::string > getIssuer(X509 &x509)
static std::string getNotAfterTime(X509 &x509)
constexpr Iter data() const
std::unique_ptr< X509_STORE, X509StoreDeleter > X509StoreUniquePtr
constexpr Range< Iter > range(Iter first, Iter last)
static Optional< std::string > getCommonName(X509 &x509)
static std::string getDateTimeStr(const ASN1_TIME *time)
Container::value_type * dataPtr(Container &cont)
static std::vector< X509UniquePtr > readCertsFromBuffer(ByteRange range)
static std::unique_ptr< IOBuf > derEncode(X509 &)
std::chrono::nanoseconds time()
static std::string getNotBeforeTime(X509 &x509)