More error information from CertificateChain::valid.
authorCarl Hetherington <cth@carlh.net>
Tue, 4 Apr 2017 22:15:23 +0000 (23:15 +0100)
committerCarl Hetherington <cth@carlh.net>
Tue, 4 Apr 2017 22:15:23 +0000 (23:15 +0100)
src/certificate_chain.cc
src/certificate_chain.h

index f06b2c3e7a40aa89885b0d77381fe0832965f56d..d6b8a7a04d0103366bd88c37ee979b2c14ae29af 100644 (file)
@@ -402,18 +402,21 @@ CertificateChain::remove (int i)
 /** Check to see if the chain is valid (i.e. root signs the intermediate, intermediate
  *  signs the leaf and so on) and that the private key (if there is one) matches the
  *  leaf certificate.
+ *  @param valid if non-0 and the CertificateChain is not valid, this is filled in with
+ *  an explanation.
  *  @return true if it's ok, false if not.
  */
 bool
-CertificateChain::valid () const
+CertificateChain::valid (string* reason) const
 {
        /* Check the certificate chain */
 
        X509_STORE* store = X509_STORE_new ();
        if (!store) {
-               return false;
+               throw MiscError ("could not create X509 store");
        }
 
+       int n = 1;
        for (List::const_iterator i = _certificates.begin(); i != _certificates.end(); ++i) {
 
                List::const_iterator j = i;
@@ -424,19 +427,25 @@ CertificateChain::valid () const
 
                if (!X509_STORE_add_cert (store, i->x509 ())) {
                        X509_STORE_free (store);
+                       if (reason) {
+                               *reason = "X509_STORE_add_cert failed";
+                       }
                        return false;
                }
 
                X509_STORE_CTX* ctx = X509_STORE_CTX_new ();
                if (!ctx) {
                        X509_STORE_free (store);
-                       return false;
+                       throw MiscError ("could not create X509 store context");
                }
 
                X509_STORE_set_flags (store, 0);
-               if (!X509_STORE_CTX_init (ctx, store, j->x509 (), 0)) {
+               if (!X509_STORE_CTX_init (ctx, store, j->x509(), 0)) {
                        X509_STORE_CTX_free (ctx);
                        X509_STORE_free (store);
+                       if (reason) {
+                               *reason = "X509_STORE_CTX_init failed";
+                       }
                        return false;
                }
 
@@ -445,8 +454,13 @@ CertificateChain::valid () const
 
                if (v == 0) {
                        X509_STORE_free (store);
+                       if (reason) {
+                               *reason = String::compose ("X509_verify_cert failed for certificate number %1", n);
+                       }
                        return false;
                }
+
+               ++n;
        }
 
        X509_STORE_free (store);
@@ -477,6 +491,10 @@ CertificateChain::valid () const
 #endif
        BIO_free (bio);
 
+       if (!valid && reason) {
+               *reason = "leaf certificate does not match private key";
+       }
+
        return valid;
 }
 
index 9d7ab47c1cf6e676f374a2a78b626ceaaec5dc08..b5954d5b6288ff59ef1abc2552d16ffeabb1f271 100644 (file)
@@ -88,7 +88,7 @@ public:
        List leaf_to_root () const;
        List root_to_leaf () const;
 
-       bool valid () const;
+       bool valid (std::string* reason = 0) const;
        bool attempt_reorder ();
 
        void sign (xmlpp::Element* parent, Standard standard) const;