Skip to content

Commit

Permalink
Add verifyWithX509StoreCtx in fizz::DefaultCertificateVerifier to ret…
Browse files Browse the repository at this point in the history
…urn a pointer to X509_STORE_CTX

Summary: Add verifyWithX509StoreCtx in fizz::DefaultCertificateVerifier to return an pointer to X509StoreCtx after cert chain verification. This context can be used in the next diff to extract root CA cert's public key.

Reviewed By: knekritz

Differential Revision: D44733007

fbshipit-source-id: f7ccd49e315eb2b34cc548d571c3201f085a6144
  • Loading branch information
Fred Qiu authored and facebook-github-bot committed Apr 11, 2023
1 parent 8980263 commit 91482d4
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 2 deletions.
11 changes: 9 additions & 2 deletions fizz/protocol/DefaultCertificateVerifier.cpp
Expand Up @@ -49,6 +49,14 @@ DefaultCertificateVerifier::createFromCAFiles(
std::shared_ptr<const folly::AsyncTransportCertificate>
DefaultCertificateVerifier::verify(
const std::vector<std::shared_ptr<const fizz::PeerCert>>& certs) const {
std::ignore = verifyWithX509StoreCtx(certs);
// Just return the original cert in the default case
return certs.front();
}

folly::ssl::X509StoreCtxUniquePtr
DefaultCertificateVerifier::verifyWithX509StoreCtx(
const std::vector<std::shared_ptr<const fizz::PeerCert>>& certs) const {
if (certs.empty()) {
throw std::runtime_error("no certificates to verify");
}
Expand Down Expand Up @@ -118,8 +126,7 @@ DefaultCertificateVerifier::verify(
throw std::runtime_error("certificate verification failed: " + errorText);
}

// Just return the original cert in the default case
return certs.front();
return ctx;
}

void DefaultCertificateVerifier::createAuthorities() {
Expand Down
9 changes: 9 additions & 0 deletions fizz/protocol/DefaultCertificateVerifier.h
Expand Up @@ -9,6 +9,7 @@
#pragma once

#include <fizz/protocol/CertificateVerifier.h>
#include <folly/ssl/OpenSSLPtrTypes.h>

namespace fizz {

Expand Down Expand Up @@ -45,6 +46,14 @@ class DefaultCertificateVerifier : public CertificateVerifier {
const std::vector<std::shared_ptr<const fizz::PeerCert>>& certs)
const override;

/**
* Return a std::unique_ptr to X509_STORE_CTX which is used for verifying
* the certificate chain. Additional verification result can be extracted
* from the returned store context.
*/
folly::ssl::X509StoreCtxUniquePtr verifyWithX509StoreCtx(
const std::vector<std::shared_ptr<const fizz::PeerCert>>& certs) const;

void setCustomVerifyCallback(X509VerifyCallback cb) {
customVerifyCallback_ = cb;
}
Expand Down
18 changes: 18 additions & 0 deletions fizz/protocol/test/DefaultCertificateVerifierTest.cpp
Expand Up @@ -45,12 +45,25 @@ class DefaultCertificateVerifierTest : public testing::Test {

TEST_F(DefaultCertificateVerifierTest, TestVerifySuccess) {
verifier_->verify({getPeerCert(leafCertAndKey_)});

auto ctx = verifier_->verifyWithX509StoreCtx({getPeerCert(leafCertAndKey_)});
STACK_OF(X509)* certChain = X509_STORE_CTX_get0_chain(ctx.get());
X509* rootX509 = sk_X509_value(certChain, sk_X509_num(certChain) - 1);
auto rootCertName = folly::ssl::OpenSSLCertUtils::getCommonName(*rootX509);
EXPECT_EQ(rootCertName, "root");
}

TEST_F(DefaultCertificateVerifierTest, TestVerifyWithIntermediates) {
auto subauth = createCert("subauth", true, &rootCertAndKey_);
auto subleaf = createCert("subleaf", false, &subauth);
verifier_->verify({getPeerCert(subleaf), getPeerCert(subauth)});

auto ctx = verifier_->verifyWithX509StoreCtx(
{getPeerCert(subleaf), getPeerCert(subauth)});
STACK_OF(X509)* certChain = X509_STORE_CTX_get0_chain(ctx.get());
X509* rootX509 = sk_X509_value(certChain, sk_X509_num(certChain) - 1);
auto rootCertName = folly::ssl::OpenSSLCertUtils::getCommonName(*rootX509);
EXPECT_EQ(rootCertName, "root");
}

TEST_F(DefaultCertificateVerifierTest, TestVerifySelfSignedCert) {
Expand All @@ -66,6 +79,11 @@ TEST_F(DefaultCertificateVerifierTest, TestVerifySelfSignedCertWithOverride) {
&DefaultCertificateVerifierTest::allowSelfSignedLeafCertCallback);
// Will not throw because the override allows for this type of error.
verifier_->verify({getPeerCert(selfsigned)});
auto ctx = verifier_->verifyWithX509StoreCtx({getPeerCert(selfsigned)});
STACK_OF(X509)* certChain = X509_STORE_CTX_get0_chain(ctx.get());
X509* rootX509 = sk_X509_value(certChain, sk_X509_num(certChain) - 1);
auto rootCertName = folly::ssl::OpenSSLCertUtils::getCommonName(*rootX509);
EXPECT_EQ(rootCertName, "self");
}

TEST_F(DefaultCertificateVerifierTest, TestVerifyWithIntermediateMissing) {
Expand Down

0 comments on commit 91482d4

Please sign in to comment.