1616
1717#include < folly/ssl/OpenSSLCertUtils.h>
1818
19+ #include < optional>
20+
1921#include < folly/FileUtil.h>
2022#include < folly/ScopeGuard.h>
2123#include < folly/String.h>
@@ -49,6 +51,45 @@ std::string asn1ToString(ASN1_STRING* a) {
4951 }
5052}
5153
54+ std::optional<std::string> getStringSubjectAltName (const ASN1_STRING * value) {
55+ const auto * data =
56+ reinterpret_cast <const char *>(ASN1_STRING_get0_data (value));
57+ const int len = ASN1_STRING_length (value);
58+ if (!data || len <= 0 ) {
59+ return std::nullopt ;
60+ }
61+ return std::string (data, len);
62+ }
63+
64+ std::optional<IPAddress> getIpSubjectAltName (const ASN1_STRING * value) {
65+ const auto * data = ASN1_STRING_get0_data (value);
66+ const int len = ASN1_STRING_length (value);
67+ if (!data || (len != 4 && len != 16 )) {
68+ return std::nullopt ;
69+ }
70+ return IPAddress::fromBinary (ByteRange (data, static_cast <size_t >(len)));
71+ }
72+
73+ std::optional<GeneralName> getSubjectAltName (const GENERAL_NAME & name) {
74+ if (name.type == GEN_DNS ) {
75+ if (auto value = getStringSubjectAltName (name.d .dNSName )) {
76+ return GeneralName{DnsName{std::move (*value)}};
77+ }
78+ }
79+ if (name.type == GEN_URI ) {
80+ if (auto value =
81+ getStringSubjectAltName (name.d .uniformResourceIdentifier )) {
82+ return GeneralName{UriName{std::move (*value)}};
83+ }
84+ }
85+ if (name.type == GEN_IPADD ) {
86+ if (auto value = getIpSubjectAltName (name.d .iPAddress )) {
87+ return GeneralName{std::move (*value)};
88+ }
89+ }
90+ return std::nullopt ;
91+ }
92+
5293std::string getExtOid (X509_EXTENSION * extension) {
5394 CHECK_NOTNULL (extension);
5495 ASN1_OBJECT * object = X509_EXTENSION_get_object (extension);
@@ -113,34 +154,27 @@ Optional<std::string> OpenSSLCertUtils::getIssuerCommonName(const X509& x509) {
113154
114155std::vector<std::string> OpenSSLCertUtils::getSubjectAltNames (
115156 const X509 & x509) {
116- auto names = reinterpret_cast <STACK_OF (GENERAL_NAME )*>(
117- X509_get_ext_d2i (&x509, NID_subject_alt_name, nullptr , nullptr ));
118- if (!names) {
119- return {};
157+ std::vector<std::string> result;
158+ for (auto & name : getSubjectAltNameEntries (x509)) {
159+ if (auto * dnsName = std::get_if<DnsName>(&name)) {
160+ result.emplace_back (std::move (dnsName->value ));
161+ }
120162 }
121- SCOPE_EXIT {
122- sk_GENERAL_NAME_pop_free (names, GENERAL_NAME_free);
123- };
163+ return result;
164+ }
124165
125- std::vector<std::string> ret;
126- auto count = sk_GENERAL_NAME_num (names);
127- for (int i = 0 ; i < count; i++) {
128- auto genName = sk_GENERAL_NAME_value (names, i);
129- if (!genName || genName->type != GEN_DNS ) {
130- continue ;
131- }
132- auto nameData = reinterpret_cast <const char *>(
133- ASN1_STRING_get0_data (genName->d .dNSName ));
134- auto nameLen = ASN1_STRING_length (genName->d .dNSName );
135- if (!nameData || nameLen <= 0 ) {
136- continue ;
166+ std::vector<std::string> OpenSSLCertUtils::getSubjectAltNameURIs (
167+ const X509 & x509) {
168+ std::vector<std::string> result;
169+ for (auto & name : getSubjectAltNameEntries (x509)) {
170+ if (auto * uriName = std::get_if<UriName>(&name)) {
171+ result.emplace_back (std::move (uriName->value ));
137172 }
138- ret.emplace_back (nameData, nameLen);
139173 }
140- return ret ;
174+ return result ;
141175}
142176
143- std::vector<std::string > OpenSSLCertUtils::getSubjectAltNameURIs (
177+ std::vector<GeneralName > OpenSSLCertUtils::getSubjectAltNameEntries (
144178 const X509 & x509) {
145179 auto names = reinterpret_cast <STACK_OF (GENERAL_NAME )*>(
146180 X509_get_ext_d2i (&x509, NID_subject_alt_name, nullptr , nullptr ));
@@ -152,22 +186,18 @@ std::vector<std::string> OpenSSLCertUtils::getSubjectAltNameURIs(
152186 };
153187
154188 auto count = sk_GENERAL_NAME_num (names);
155- std::vector<std::string> ret ;
156- ret .reserve (count);
189+ std::vector<GeneralName> result ;
190+ result .reserve (count);
157191 for (int i = 0 ; i < count; i++) {
158- auto genName = sk_GENERAL_NAME_value (names, i);
159- if (!genName || genName-> type != GEN_URI ) {
192+ auto name = sk_GENERAL_NAME_value (names, i);
193+ if (!name ) {
160194 continue ;
161195 }
162- auto nameData = reinterpret_cast <const char *>(
163- ASN1_STRING_get0_data (genName->d .uniformResourceIdentifier ));
164- auto nameLen = ASN1_STRING_length (genName->d .uniformResourceIdentifier );
165- if (!nameData || nameLen <= 0 ) {
166- continue ;
196+ if (auto value = getSubjectAltName (*name)) {
197+ result.emplace_back (std::move (*value));
167198 }
168- ret.emplace_back (nameData, nameLen);
169199 }
170- return ret ;
200+ return result ;
171201}
172202
173203std::vector<std::string> OpenSSLCertUtils::getExtendedKeyUsage (
0 commit comments