Various small tweaks and fixes.
authorCarl Hetherington <cth@carlh.net>
Fri, 18 Jul 2014 10:45:19 +0000 (11:45 +0100)
committerCarl Hetherington <cth@carlh.net>
Fri, 18 Jul 2014 10:45:19 +0000 (11:45 +0100)
src/certificates.cc
src/certificates.h
src/signer.cc
src/util.cc
src/util.h
test/certificates_test.cc
test/encryption_test.cc
test/util_test.cc

index 46c60d6beb2e27477a774fec265142b16d288b0f..c03c371b5b2afd1dfbe78f08d1e82be938c5a472 100644 (file)
@@ -49,23 +49,6 @@ Certificate::Certificate (X509* c)
        
 }
 
-/** Load an X509 certificate from a file.
- *  @param filename File to load.
- */
-Certificate::Certificate (boost::filesystem::path filename)
-       : _certificate (0)
-       , _public_key (0)
-{
-       FILE* f = fopen_boost (filename, "r");
-       if (!f) {
-               throw FileError ("could not open file", filename, errno);
-       }
-       
-       if (!PEM_read_X509 (f, &_certificate, 0, 0)) {
-               throw MiscError ("could not read X509 certificate");
-       }
-}
-
 /** Load an X509 certificate from a string.
  *  @param cert String to read from.
  */
@@ -255,8 +238,8 @@ Certificate::thumbprint () const
        uint8_t buffer[8192];
        uint8_t* p = buffer;
        i2d_X509_CINF (_certificate->cert_info, &p);
-       int const length = p - buffer;
-       if (length > 8192) {
+       unsigned int const length = p - buffer;
+       if (length > sizeof (buffer)) {
                throw MiscError ("buffer too small to generate thumbprint");
        }
 
index 06ce92a9dd76d8a7deb276a503492be25b6bbf99..1593ddbc6788a8c0a13cd9c98e74df18ca7902b1 100644 (file)
@@ -51,7 +51,6 @@ public:
                : _certificate (0)
        {}
 
-       Certificate (boost::filesystem::path);
        Certificate (std::string);
        Certificate (X509 *);
        Certificate (Certificate const &);
index 55684759895a828eea1664ec441c281829671d53..d9c46145e272675b4236a3623e64b065be335fad 100644 (file)
@@ -43,9 +43,9 @@ Signer::Signer (boost::filesystem::path openssl)
 {
        boost::filesystem::path directory = make_certificate_chain (openssl);
 
-       _certificates.add (shared_ptr<dcp::Certificate> (new dcp::Certificate (directory / "ca.self-signed.pem")));
-       _certificates.add (shared_ptr<dcp::Certificate> (new dcp::Certificate (directory / "intermediate.signed.pem")));
-       _certificates.add (shared_ptr<dcp::Certificate> (new dcp::Certificate (directory / "leaf.signed.pem")));
+       _certificates.add (shared_ptr<dcp::Certificate> (new dcp::Certificate (dcp::file_to_string (directory / "ca.self-signed.pem"))));
+       _certificates.add (shared_ptr<dcp::Certificate> (new dcp::Certificate (dcp::file_to_string (directory / "intermediate.signed.pem"))));
+       _certificates.add (shared_ptr<dcp::Certificate> (new dcp::Certificate (dcp::file_to_string (directory / "leaf.signed.pem"))));
 
        _key = dcp::file_to_string (directory / "leaf.key");
 
index 9758db9cf030fae331ffbb4d1b9072cb6131774f..1334b21db6c298e5c5c03cf0d2bd756104ff62e4 100644 (file)
@@ -370,10 +370,14 @@ dcp::ids_equal (string a, string b)
 }
 
 string
-dcp::file_to_string (boost::filesystem::path p)
+dcp::file_to_string (boost::filesystem::path p, uintmax_t max_length)
 {
        uintmax_t len = boost::filesystem::file_size (p);
-       char* c = new char[len];
+       if (len > max_length) {
+               throw MiscError ("Unexpectedly long file");
+       }
+       
+       char* c = new char[len + 1];
                           
        FILE* f = fopen_boost (p, "r");
        if (!f) {
@@ -382,9 +386,32 @@ dcp::file_to_string (boost::filesystem::path p)
 
        fread (c, 1, len, f);
        fclose (f);
+       c[len] = '\0';
 
        string s (c);
        delete[] c;
 
        return s;
 }
+
+/** @param key RSA private key in PEM format (optionally with -----BEGIN... / -----END...)
+ *  @return SHA1 fingerprint of key
+ */
+string
+dcp::private_key_fingerprint (string key)
+{
+       boost::replace_all (key, "-----BEGIN RSA PRIVATE KEY-----\n", "");
+       boost::replace_all (key, "\n-----END RSA PRIVATE KEY-----\n", "");
+
+       unsigned char buffer[4096];
+       int const N = base64_decode (key, buffer, sizeof (buffer));
+
+       SHA_CTX sha;
+       SHA1_Init (&sha);
+       SHA1_Update (&sha, buffer, N);
+       uint8_t digest[20];
+       SHA1_Final (digest, &sha);
+
+       char digest_base64[64];
+       return Kumu::base64encode (digest, 20, digest_base64, 64);
+}
index 33fd79a327ca230d4b80e5500a546dac12889199..d3843e3db06720fd85173f2ed061be28720710c6 100644 (file)
@@ -88,7 +88,8 @@ extern void add_signer (xmlpp::Element* parent, CertificateChain const & certifi
 extern int base64_decode (std::string const & in, unsigned char* out, int out_length);
 extern boost::optional<boost::filesystem::path> relative_to_root (boost::filesystem::path root, boost::filesystem::path file);
 extern FILE * fopen_boost (boost::filesystem::path, std::string);
-extern std::string file_to_string (boost::filesystem::path);
+extern std::string file_to_string (boost::filesystem::path, uintmax_t max_length = 4096);
+extern std::string private_key_fingerprint (std::string key);
 
 template <class F, class T>
 std::list<boost::shared_ptr<T> >
index 8cbe9527e39d0a73af3967330647a4e103bdb814..4f0a41f987b3636e07ef88f996ef5e42242aa6a6 100644 (file)
@@ -31,9 +31,9 @@ BOOST_AUTO_TEST_CASE (certificates)
 {
        dcp::CertificateChain c;
 
-       c.add (shared_ptr<dcp::Certificate> (new dcp::Certificate (boost::filesystem::path ("test/ref/crypt/ca.self-signed.pem"))));
-       c.add (shared_ptr<dcp::Certificate> (new dcp::Certificate (boost::filesystem::path ("test/ref/crypt/intermediate.signed.pem"))));
-       c.add (shared_ptr<dcp::Certificate> (new dcp::Certificate (boost::filesystem::path ("test/ref/crypt/leaf.signed.pem"))));
+       c.add (shared_ptr<dcp::Certificate> (new dcp::Certificate (dcp::file_to_string ("test/ref/crypt/ca.self-signed.pem"))));
+       c.add (shared_ptr<dcp::Certificate> (new dcp::Certificate (dcp::file_to_string ("test/ref/crypt/intermediate.signed.pem"))));
+       c.add (shared_ptr<dcp::Certificate> (new dcp::Certificate (dcp::file_to_string ("test/ref/crypt/leaf.signed.pem"))));
 
        dcp::CertificateChain::List leaf_to_root = c.leaf_to_root ();
 
@@ -90,45 +90,45 @@ BOOST_AUTO_TEST_CASE (certificates)
 BOOST_AUTO_TEST_CASE (certificates_validation)
 {
        dcp::CertificateChain good1;
-       good1.add (shared_ptr<dcp::Certificate> (new dcp::Certificate (boost::filesystem::path ("test/ref/crypt/ca.self-signed.pem"))));
-       good1.add (shared_ptr<dcp::Certificate> (new dcp::Certificate (boost::filesystem::path ("test/ref/crypt/intermediate.signed.pem"))));
-       good1.add (shared_ptr<dcp::Certificate> (new dcp::Certificate (boost::filesystem::path ("test/ref/crypt/leaf.signed.pem"))));
+       good1.add (shared_ptr<dcp::Certificate> (new dcp::Certificate (dcp::file_to_string ("test/ref/crypt/ca.self-signed.pem"))));
+       good1.add (shared_ptr<dcp::Certificate> (new dcp::Certificate (dcp::file_to_string ("test/ref/crypt/intermediate.signed.pem"))));
+       good1.add (shared_ptr<dcp::Certificate> (new dcp::Certificate (dcp::file_to_string ("test/ref/crypt/leaf.signed.pem"))));
        BOOST_CHECK (good1.valid ());
 
        dcp::CertificateChain good2;
-       good2.add (shared_ptr<dcp::Certificate> (new dcp::Certificate (boost::filesystem::path ("test/ref/crypt/ca.self-signed.pem"))));
+       good2.add (shared_ptr<dcp::Certificate> (new dcp::Certificate (dcp::file_to_string ("test/ref/crypt/ca.self-signed.pem"))));
        BOOST_CHECK (good2.valid ());
        
        dcp::CertificateChain bad1;
-       bad1.add (shared_ptr<dcp::Certificate> (new dcp::Certificate (boost::filesystem::path ("test/ref/crypt/intermediate.signed.pem"))));
-       bad1.add (shared_ptr<dcp::Certificate> (new dcp::Certificate (boost::filesystem::path ("test/ref/crypt/leaf.signed.pem"))));
+       bad1.add (shared_ptr<dcp::Certificate> (new dcp::Certificate (dcp::file_to_string ("test/ref/crypt/intermediate.signed.pem"))));
+       bad1.add (shared_ptr<dcp::Certificate> (new dcp::Certificate (dcp::file_to_string ("test/ref/crypt/leaf.signed.pem"))));
        BOOST_CHECK (!bad1.valid ());
        BOOST_CHECK (!bad1.attempt_reorder ());
 
        dcp::CertificateChain bad2;
-       bad2.add (shared_ptr<dcp::Certificate> (new dcp::Certificate (boost::filesystem::path ("test/ref/crypt/leaf.signed.pem"))));
-       bad2.add (shared_ptr<dcp::Certificate> (new dcp::Certificate (boost::filesystem::path ("test/ref/crypt/ca.self-signed.pem"))));
-       bad2.add (shared_ptr<dcp::Certificate> (new dcp::Certificate (boost::filesystem::path ("test/ref/crypt/intermediate.signed.pem"))));
+       bad2.add (shared_ptr<dcp::Certificate> (new dcp::Certificate (dcp::file_to_string ("test/ref/crypt/leaf.signed.pem"))));
+       bad2.add (shared_ptr<dcp::Certificate> (new dcp::Certificate (dcp::file_to_string ("test/ref/crypt/ca.self-signed.pem"))));
+       bad2.add (shared_ptr<dcp::Certificate> (new dcp::Certificate (dcp::file_to_string ("test/ref/crypt/intermediate.signed.pem"))));
        BOOST_CHECK (!bad2.valid ());
        BOOST_CHECK (bad2.attempt_reorder ());
 
        dcp::CertificateChain bad3;
-       bad3.add (shared_ptr<dcp::Certificate> (new dcp::Certificate (boost::filesystem::path ("test/ref/crypt/intermediate.signed.pem"))));
-       bad3.add (shared_ptr<dcp::Certificate> (new dcp::Certificate (boost::filesystem::path ("test/ref/crypt/leaf.signed.pem"))));
-       bad3.add (shared_ptr<dcp::Certificate> (new dcp::Certificate (boost::filesystem::path ("test/ref/crypt/ca.self-signed.pem"))));
+       bad3.add (shared_ptr<dcp::Certificate> (new dcp::Certificate (dcp::file_to_string ("test/ref/crypt/intermediate.signed.pem"))));
+       bad3.add (shared_ptr<dcp::Certificate> (new dcp::Certificate (dcp::file_to_string ("test/ref/crypt/leaf.signed.pem"))));
+       bad3.add (shared_ptr<dcp::Certificate> (new dcp::Certificate (dcp::file_to_string ("test/ref/crypt/ca.self-signed.pem"))));
        BOOST_CHECK (!bad3.valid ());
        BOOST_CHECK (bad3.attempt_reorder ());
 
        dcp::CertificateChain bad4;
-       bad4.add (shared_ptr<dcp::Certificate> (new dcp::Certificate (boost::filesystem::path ("test/ref/crypt/leaf.signed.pem"))));
-       bad4.add (shared_ptr<dcp::Certificate> (new dcp::Certificate (boost::filesystem::path ("test/ref/crypt/intermediate.signed.pem"))));
-       bad4.add (shared_ptr<dcp::Certificate> (new dcp::Certificate (boost::filesystem::path ("test/ref/crypt/ca.self-signed.pem"))));
+       bad4.add (shared_ptr<dcp::Certificate> (new dcp::Certificate (dcp::file_to_string ("test/ref/crypt/leaf.signed.pem"))));
+       bad4.add (shared_ptr<dcp::Certificate> (new dcp::Certificate (dcp::file_to_string ("test/ref/crypt/intermediate.signed.pem"))));
+       bad4.add (shared_ptr<dcp::Certificate> (new dcp::Certificate (dcp::file_to_string ("test/ref/crypt/ca.self-signed.pem"))));
        BOOST_CHECK (!bad4.valid ());
        BOOST_CHECK (bad4.attempt_reorder ());
 
        dcp::CertificateChain bad5;
-       bad5.add (shared_ptr<dcp::Certificate> (new dcp::Certificate (boost::filesystem::path ("test/ref/crypt/ca.self-signed.pem"))));
-       bad5.add (shared_ptr<dcp::Certificate> (new dcp::Certificate (boost::filesystem::path ("test/ref/crypt/leaf.signed.pem"))));
+       bad5.add (shared_ptr<dcp::Certificate> (new dcp::Certificate (dcp::file_to_string ("test/ref/crypt/ca.self-signed.pem"))));
+       bad5.add (shared_ptr<dcp::Certificate> (new dcp::Certificate (dcp::file_to_string ("test/ref/crypt/leaf.signed.pem"))));
        BOOST_CHECK (!bad5.valid ());
        BOOST_CHECK (!bad5.attempt_reorder ());
 }
@@ -138,9 +138,9 @@ BOOST_AUTO_TEST_CASE (signer_validation)
 {
        /* Check a valid signer */
        dcp::CertificateChain chain;
-       chain.add (shared_ptr<dcp::Certificate> (new dcp::Certificate (boost::filesystem::path ("test/ref/crypt/ca.self-signed.pem"))));
-       chain.add (shared_ptr<dcp::Certificate> (new dcp::Certificate (boost::filesystem::path ("test/ref/crypt/intermediate.signed.pem"))));
-       chain.add (shared_ptr<dcp::Certificate> (new dcp::Certificate (boost::filesystem::path ("test/ref/crypt/leaf.signed.pem"))));
+       chain.add (shared_ptr<dcp::Certificate> (new dcp::Certificate (dcp::file_to_string ("test/ref/crypt/ca.self-signed.pem"))));
+       chain.add (shared_ptr<dcp::Certificate> (new dcp::Certificate (dcp::file_to_string ("test/ref/crypt/intermediate.signed.pem"))));
+       chain.add (shared_ptr<dcp::Certificate> (new dcp::Certificate (dcp::file_to_string ("test/ref/crypt/leaf.signed.pem"))));
        dcp::Signer signer (chain, dcp::file_to_string ("test/ref/crypt/leaf.key"));
        BOOST_CHECK (signer.valid ());
 
index 6d2e052e99d9be22ed58c812081377791a941afa..e096c5fd9428898ed70b94c57769286b94852761 100644 (file)
@@ -67,9 +67,9 @@ BOOST_AUTO_TEST_CASE (encryption_test)
 
        /* Use test/ref/crypt so this test is repeatable */
        dcp::CertificateChain chain;
-       chain.add (shared_ptr<dcp::Certificate> (new dcp::Certificate (boost::filesystem::path ("test/ref/crypt/ca.self-signed.pem"))));
-       chain.add (shared_ptr<dcp::Certificate> (new dcp::Certificate (boost::filesystem::path ("test/ref/crypt/intermediate.signed.pem"))));
-       chain.add (shared_ptr<dcp::Certificate> (new dcp::Certificate (boost::filesystem::path ("test/ref/crypt/leaf.signed.pem"))));
+       chain.add (shared_ptr<dcp::Certificate> (new dcp::Certificate (dcp::file_to_string ("test/ref/crypt/ca.self-signed.pem"))));
+       chain.add (shared_ptr<dcp::Certificate> (new dcp::Certificate (dcp::file_to_string ("test/ref/crypt/intermediate.signed.pem"))));
+       chain.add (shared_ptr<dcp::Certificate> (new dcp::Certificate (dcp::file_to_string ("test/ref/crypt/leaf.signed.pem"))));
 
        shared_ptr<dcp::Signer> signer (
                new dcp::Signer (
index 15f22f57db5806099825661115d4b19c8af2ea92..34dc0c1862e2fd6c816131db3caeb4cfe023bcc6 100644 (file)
@@ -113,3 +113,9 @@ BOOST_AUTO_TEST_CASE (relative_to_root_test)
                BOOST_CHECK_EQUAL (rel.get(), check);
        }
 }
+
+/** Test private_key_fingerprint() */
+BOOST_AUTO_TEST_CASE (private_key_fingerprint_test)
+{
+       BOOST_CHECK_EQUAL (dcp::private_key_fingerprint (dcp::file_to_string ("test/data/private.key")), "Jdz1bFpCcKI7R16Ccx9JHYytag0=");
+}