Give a better error from chain_valid() when a certificate has some problem (e.g....
authorCarl Hetherington <cth@carlh.net>
Thu, 22 Dec 2022 15:36:41 +0000 (16:36 +0100)
committerCarl Hetherington <cth@carlh.net>
Thu, 22 Dec 2022 15:36:41 +0000 (16:36 +0100)
src/certificate_chain.cc
src/certificate_chain.h

index 84478dc1d2fb37c5a820d4b0890029ce7db06761..51f2ca6814d950214625015444cf331dfc69ed64 100644 (file)
@@ -420,8 +420,13 @@ CertificateChain::chain_valid () const
 }
 
 
+/** @param error if non-null, filled with an error if a certificate in the list has a
+ *  a problem.
+ *  @return true if all the given certificates verify OK, and are in the correct order in the list
+ *  (root to leaf).  false if any certificate has a problem, or the order is wrong.
+ */
 bool
-CertificateChain::chain_valid (List const & chain) const
+CertificateChain::chain_valid(List const & chain, string* error) const
 {
         /* Here I am taking a chain of certificates A/B/C/D and checking validity of B wrt A,
           C wrt B and D wrt C.  It also appears necessary to check the issuer of B/C/D matches
@@ -470,6 +475,9 @@ CertificateChain::chain_valid (List const & chain) const
 
                if (v != 1) {
                        X509_STORE_free (store);
+                       if (error) {
+                               *error = X509_verify_cert_error_string(X509_STORE_CTX_get_error(ctx));
+                       }
                        return false;
                }
 
@@ -559,13 +567,14 @@ CertificateChain::root_to_leaf () const
 {
        auto rtl = _certificates;
        std::sort (rtl.begin(), rtl.end());
+       string error;
        do {
-               if (chain_valid (rtl)) {
+               if (chain_valid(rtl, &error)) {
                        return rtl;
                }
        } while (std::next_permutation (rtl.begin(), rtl.end()));
 
-       throw CertificateChainError ("certificate chain is not consistent");
+       throw CertificateChainError(error.empty() ? string{"certificate chain is not consistent"} : error);
 }
 
 
index df9f4ccfbf723fab1f1abf679abf0652e0d83c3a..8d07ebc26db6124343c3df55bc5739e5fbe5abbc 100644 (file)
@@ -175,7 +175,7 @@ private:
        friend struct ::certificates_validation7;
        friend struct ::certificates_validation8;
 
-       bool chain_valid (List const & chain) const;
+       bool chain_valid(List const & chain, std::string* error = nullptr) const;
 
        /** Our certificates, not in any particular order */
        List _certificates;