Skip to content

Commit 39445a1

Browse files
Huilin Chenmeta-codesync[bot]
authored andcommitted
Include IP Sans in Hostname Validation Error Message
Summary: Previous only hostname sans are printed in error message for hostname validation. This diff adds IP sans as well, since they are also used in hostname validation. Reviewed By: mingtaoy Differential Revision: D116704462 fbshipit-source-id: 6393613b68ba99dbf77a1523104846f3c5bd0d3f
1 parent d3c9281 commit 39445a1

3 files changed

Lines changed: 35 additions & 1 deletion

File tree

third-party/fizz/src/fizz/protocol/test/CertUtil.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ void throwIfNull(const A& a, const std::string& msg) {
3636
struct CreateCertOptions {
3737
std::string cn;
3838
std::vector<std::string> sans;
39+
std::vector<std::string> ipSans = {};
3940
bool ca{false};
4041
CertAndKey* issuer{nullptr};
4142
std::optional<std::chrono::system_clock::time_point> notBefore;
@@ -97,6 +98,7 @@ inline void generateRSAKey(folly::ssl::EvpPkeyUniquePtr& pk) {
9798
inline CertAndKey createCert(CreateCertOptions options) {
9899
const auto& cn = options.cn;
99100
const auto& sans = options.sans;
101+
const auto& ipSans = options.ipSans;
100102
bool ca = options.ca;
101103
const auto& issuer = options.issuer;
102104
const auto& keyType = options.keyType;
@@ -182,6 +184,9 @@ authorityKeyIdentifier = keyid:always, issuer
182184
std::string dnsSan = "DNS:" + san;
183185
subjectAltNames.push_back(std::move(dnsSan));
184186
}
187+
for (const auto& ipSan : ipSans) {
188+
subjectAltNames.push_back("IP:" + ipSan);
189+
}
185190
if (!subjectAltNames.empty()) {
186191
std::string sansConfigRow = fmt::format(
187192
"subjectAltName = {}\n", folly::join(", ", subjectAltNames));

third-party/proxygen/src/proxygen/lib/http/coro/client/ProxygenCertVerifier.cpp

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,16 @@
1717
namespace proxygen::coro {
1818
namespace {
1919
static std::string getErrorMsg(X509* leaf, const std::string& expected) {
20-
auto sans = folly::ssl::OpenSSLCertUtils::getSubjectAltNames(*leaf);
20+
auto entries = folly::ssl::OpenSSLCertUtils::getSubjectAltNameEntries(*leaf);
21+
std::vector<std::string> sans;
22+
sans.reserve(entries.size());
23+
for (const auto& entry : entries) {
24+
if (const auto* dnsName = std::get_if<folly::ssl::DnsName>(&entry)) {
25+
sans.emplace_back(dnsName->value);
26+
} else if (const auto* ipAddress = std::get_if<folly::IPAddress>(&entry)) {
27+
sans.emplace_back(ipAddress->str());
28+
}
29+
}
2130
return fmt::format(
2231
"certificate identity verification failed: expected={}, "
2332
"cert_sans=[{}]",

third-party/proxygen/src/proxygen/lib/http/coro/client/test/ProxygenCertVerifierTest.cpp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,26 @@ TEST_F(ProxygenCertVerifierTest, MismatchedIpFails) {
9595
EXPECT_THAT(err.msg(), HasSubstr("expected=127.0.0.1"));
9696
}
9797

98+
TEST_F(ProxygenCertVerifierTest, ErrorIncludesDnsAndIpSans) {
99+
auto leafWithIp = createCert({
100+
.cn = "example.com",
101+
.sans = {"example.com"},
102+
.ipSans = {"127.0.0.1"},
103+
.ca = false,
104+
.issuer = &rootCertAndKey_,
105+
.keyType = KeyType::P256,
106+
});
107+
108+
auto verifier =
109+
makeVerifier(ExpectedIdentity::expectIP(folly::IPAddress("127.0.0.2")),
110+
ValidationPolicy::Enforcing);
111+
Error err;
112+
std::shared_ptr<const Cert> verifiedCert;
113+
EXPECT_NE(verifier->verify(verifiedCert, err, {getPeerCert(leafWithIp)}),
114+
Status::Success);
115+
EXPECT_THAT(err.msg(), HasSubstr("cert_sans=[example.com, 127.0.0.1]"));
116+
}
117+
98118
TEST_F(ProxygenCertVerifierTest, UnderlyingVerifierFailure) {
99119
auto untrustedRoot = createCert(
100120
"untrusted-root", /*ca=*/true, /*issuer=*/nullptr, KeyType::P256);

0 commit comments

Comments
 (0)