2 * Copyright (c) 2015, Facebook, Inc.
5 * This source code is licensed under the BSD-style license found in the
6 * LICENSE file in the root directory of this source tree. An additional grant
7 * of patent rights can be found in the PATENTS file in the same directory.
10 #include <folly/wangle/ssl/SSLUtil.h>
12 #include <folly/Memory.h>
14 #if OPENSSL_VERSION_NUMBER >= 0x1000105fL
15 #define OPENSSL_GE_101 1
16 #include <openssl/asn1.h>
17 #include <openssl/x509v3.h>
24 std::mutex SSLUtil::sIndexLock_;
26 std::unique_ptr<std::string> SSLUtil::getCommonName(const X509* cert) {
27 X509_NAME* subject = X509_get_subject_name((X509*)cert);
31 char cn[ub_common_name + 1];
32 int res = X509_NAME_get_text_by_NID(subject, NID_commonName,
37 cn[ub_common_name] = '\0';
38 return folly::make_unique<std::string>(cn);
42 std::unique_ptr<std::list<std::string>> SSLUtil::getSubjectAltName(
45 auto nameList = folly::make_unique<std::list<std::string>>();
46 GENERAL_NAMES* names = (GENERAL_NAMES*)X509_get_ext_d2i(
47 (X509*)cert, NID_subject_alt_name, nullptr, nullptr);
49 auto guard = folly::makeGuard([names] { GENERAL_NAMES_free(names); });
50 size_t count = sk_GENERAL_NAME_num(names);
51 CHECK(count < std::numeric_limits<int>::max());
52 for (int i = 0; i < (int)count; ++i) {
53 GENERAL_NAME* generalName = sk_GENERAL_NAME_value(names, i);
54 if (generalName->type == GEN_DNS) {
55 ASN1_STRING* s = generalName->d.dNSName;
56 const char* name = (const char*)ASN1_STRING_data(s);
57 // I can't find any docs on what a negative return value here
58 // would mean, so I'm going to ignore it.
59 auto len = ASN1_STRING_length(s);
61 if (size_t(len) != strlen(name)) {
62 // Null byte(s) in the name; return an error rather than depending on
63 // the caller to safely handle this case.
66 nameList->emplace_back(name);