Skip to content

Commit

Permalink
try to allow certificate-chains
Browse files Browse the repository at this point in the history
Currently the verification of certificates uses only the first pem in
the ca-file and the first pem in the certificate-file. This breaks if an
intermediate certificate is needed.

A simple workaround is to put the full chain into the ca-file and give
the ca-file instead of the X509-structure to the VerifyCertificate()
methode. There we can just do the usual business but add the full
ca-file again to OpenSSLs SSL_CTX_load_verify_locations().

While this seems a little bit hackish it should at least allow the
proper verification of a certificate chain without introducing any
security implications for setups with just a single root-ca.
The only downside currently: while the CLI "pki verify" will correctly
check the supplied parameters, it still only shows the topmost
certificate from the ca-file (which I guess is fine for the moment).
  • Loading branch information
sircubbi committed May 12, 2022
1 parent f46d474 commit 9ac156a
Show file tree
Hide file tree
Showing 5 changed files with 9 additions and 5 deletions.
6 changes: 5 additions & 1 deletion lib/base/tlsutility.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -948,8 +948,10 @@ String BinaryToHex(const unsigned char* data, size_t length) {
return output;
}

bool VerifyCertificate(const std::shared_ptr<X509> &caCertificate, const std::shared_ptr<X509> &certificate, const String& crlFile)
bool VerifyCertificate(const String& caFile, const std::shared_ptr<X509> &certificate, const String& crlFile)
{
std::shared_ptr<X509> caCertificate = GetX509Certificate(caFile);

X509_STORE *store = X509_STORE_new();

if (!store)
Expand All @@ -961,6 +963,8 @@ bool VerifyCertificate(const std::shared_ptr<X509> &caCertificate, const std::sh
AddCRLToSSLContext(store, crlFile);
}

X509_STORE_load_locations(store, caFile.CStr(), NULL); /* ignore any errors for the moment, since this is just the convenient way to add full chain */

X509_STORE_CTX *csc = X509_STORE_CTX_new();
X509_STORE_CTX_init(csc, store, certificate.get(), nullptr);

Expand Down
2 changes: 1 addition & 1 deletion lib/base/tlsutility.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ String SHA256(const String& s);
String RandomString(int length);
String BinaryToHex(const unsigned char* data, size_t length);

bool VerifyCertificate(const std::shared_ptr<X509>& caCertificate, const std::shared_ptr<X509>& certificate, const String& crlFile);
bool VerifyCertificate(const String& caFile, const std::shared_ptr<X509>& certificate, const String& crlFile);
bool IsCa(const std::shared_ptr<X509>& cacert);
int GetCertificateVersion(const std::shared_ptr<X509>& cert);
String GetSignatureAlgorithm(const std::shared_ptr<X509>& cert);
Expand Down
2 changes: 1 addition & 1 deletion lib/cli/pkiverifycommand.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ int PKIVerifyCommand::Run(const boost::program_options::variables_map& vm, const
bool signedByCA;

try {
signedByCA = VerifyCertificate(cacert, cert, crlFile);
signedByCA = VerifyCertificate(caCertFile, cert, crlFile);
} catch (const std::exception& ex) {
Log logmsg (LogCritical, "cli");
logmsg << "CRITICAL: Certificate with CN '" << certCN << "' is NOT signed by CA: ";
Expand Down
2 changes: 1 addition & 1 deletion lib/remote/apilistener.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,7 @@ std::shared_ptr<X509> ApiListener::RenewCert(const std::shared_ptr<X509>& cert)
{
std::shared_ptr<EVP_PKEY> pubkey (X509_get_pubkey(cert.get()), EVP_PKEY_free);
auto subject (X509_get_subject_name(cert.get()));
auto cacert (GetX509Certificate(GetDefaultCaPath()));
auto cacert (GetDefaultCaPath());
auto newcert (CreateCertIcingaCA(pubkey.get(), subject));

/* verify that the new cert matches the CA we're using for the ApiListener;
Expand Down
2 changes: 1 addition & 1 deletion lib/remote/jsonrpcconnection-pki.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ Value RequestCertificateHandler(const MessageOrigin::Ptr& origin, const Dictiona
logmsg << "Received certificate request for CN '" << cn << "'";

try {
signedByCA = VerifyCertificate(cacert, cert, listener->GetCrlPath());
signedByCA = VerifyCertificate(listener->GetDefaultCaPath(), cert, listener->GetCrlPath());
if (!signedByCA) {
logmsg << " not";
}
Expand Down

0 comments on commit 9ac156a

Please sign in to comment.