summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorCarl Hetherington <cth@carlh.net>2014-07-18 00:15:34 +0100
committerCarl Hetherington <cth@carlh.net>2014-07-18 00:15:34 +0100
commit56e7a6f1768036df852a45d939b9adc038b17057 (patch)
tree93cf6bb1fb7c9ebe43de09d7690e69cd75b634ea /src
parent0b85b9216da9d6519a553de67103a9417504aba1 (diff)
Quite large reworking of signer/cert handling.
Diffstat (limited to 'src')
-rw-r--r--src/certificate_chain.cc (renamed from src/signer_chain.cc)17
-rw-r--r--src/certificate_chain.h (renamed from src/signer_chain.h)8
-rw-r--r--src/certificates.cc15
-rw-r--r--src/certificates.h12
-rw-r--r--src/decrypted_kdm.cc14
-rw-r--r--src/decrypted_kdm.h4
-rw-r--r--src/signer.cc40
-rw-r--r--src/signer.h18
-rw-r--r--src/wscript4
9 files changed, 95 insertions, 37 deletions
diff --git a/src/signer_chain.cc b/src/certificate_chain.cc
index 3b75b06c..dbed590b 100644
--- a/src/signer_chain.cc
+++ b/src/certificate_chain.cc
@@ -21,7 +21,7 @@
* @brief Functions to make signer chains.
*/
-#include "signer_chain.h"
+#include "certificate_chain.h"
#include "exceptions.h"
#include "util.h"
#include "KM_util.h"
@@ -156,18 +156,17 @@ public_key_digest (boost::filesystem::path private_key, boost::filesystem::path
return dig;
}
-/** Generate a chain of root, intermediate and leaf keys by running an OpenSSL binary.
- * @param directory Directory to write the files to.
- * @param openssl openssl binary path.
- */
-void
-dcp::make_signer_chain (boost::filesystem::path directory, boost::filesystem::path openssl)
+boost::filesystem::path
+dcp::make_certificate_chain (boost::filesystem::path openssl)
{
+ boost::filesystem::path directory = boost::filesystem::unique_path ();
+ boost::filesystem::create_directories (directory);
+
boost::filesystem::path const cwd = boost::filesystem::current_path ();
+ boost::filesystem::current_path (directory);
string quoted_openssl = "\"" + openssl.string() + "\"";
- boost::filesystem::current_path (directory);
command (quoted_openssl + " genrsa -out ca.key 2048");
{
@@ -265,4 +264,6 @@ dcp::make_signer_chain (boost::filesystem::path directory, boost::filesystem::pa
);
boost::filesystem::current_path (cwd);
+
+ return directory;
}
diff --git a/src/signer_chain.h b/src/certificate_chain.h
index f039caf3..6a6fc483 100644
--- a/src/signer_chain.h
+++ b/src/certificate_chain.h
@@ -26,9 +26,13 @@
namespace dcp {
/** Create a chain of certificates for signing things.
- * @param directory Directory to write files to.
* @param openssl Name of openssl binary (if it is on the path) or full path.
+ * @return Directory (which should be deleted by the caller) containing:
+ * - ca.self-signed.pem self-signed root certificate
+ * - intermediate.signed.pem intermediate certificate
+ * - leaf.key leaf certificate private key
+ * - leaf.signed.pem leaf certificate
*/
-void make_signer_chain (boost::filesystem::path directory, boost::filesystem::path openssl);
+boost::filesystem::path make_certificate_chain (boost::filesystem::path openssl);
}
diff --git a/src/certificates.cc b/src/certificates.cc
index b331c6b6..46c60d6b 100644
--- a/src/certificates.cc
+++ b/src/certificates.cc
@@ -294,7 +294,7 @@ Certificate::public_key () const
}
/** @return Root certificate */
-shared_ptr<Certificate>
+shared_ptr<const Certificate>
CertificateChain::root () const
{
assert (!_certificates.empty());
@@ -302,7 +302,7 @@ CertificateChain::root () const
}
/** @return Leaf certificate */
-shared_ptr<Certificate>
+shared_ptr<const Certificate>
CertificateChain::leaf () const
{
assert (_certificates.size() >= 2);
@@ -329,13 +329,13 @@ CertificateChain::leaf_to_root () const
* @param c Certificate to add.
*/
void
-CertificateChain::add (shared_ptr<Certificate> c)
+CertificateChain::add (shared_ptr<const Certificate> c)
{
_certificates.push_back (c);
}
void
-CertificateChain::remove (shared_ptr<Certificate> c)
+CertificateChain::remove (shared_ptr<const Certificate> c)
{
_certificates.remove (c);
}
@@ -357,11 +357,12 @@ CertificateChain::remove (int i)
}
}
-/** Verify the chain.
+/** Check to see if the chain is valid (i.e. root signs the intermediate, intermediate
+ * signs the leaf and so on).
* @return true if it's ok, false if not.
*/
bool
-CertificateChain::verify () const
+CertificateChain::valid () const
{
X509_STORE* store = X509_STORE_new ();
if (!store) {
@@ -416,7 +417,7 @@ CertificateChain::attempt_reorder ()
List original = _certificates;
_certificates.sort ();
do {
- if (verify ()) {
+ if (valid ()) {
return true;
}
} while (std::next_permutation (_certificates.begin(), _certificates.end ()));
diff --git a/src/certificates.h b/src/certificates.h
index 8ae562c9..06ce92a9 100644
--- a/src/certificates.h
+++ b/src/certificates.h
@@ -92,19 +92,19 @@ class CertificateChain
public:
CertificateChain () {}
- void add (boost::shared_ptr<Certificate> c);
- void remove (boost::shared_ptr<Certificate> c);
+ void add (boost::shared_ptr<const Certificate> c);
+ void remove (boost::shared_ptr<const Certificate> c);
void remove (int);
- boost::shared_ptr<Certificate> root () const;
- boost::shared_ptr<Certificate> leaf () const;
+ boost::shared_ptr<const Certificate> root () const;
+ boost::shared_ptr<const Certificate> leaf () const;
- typedef std::list<boost::shared_ptr<Certificate> > List;
+ typedef std::list<boost::shared_ptr<const Certificate> > List;
List leaf_to_root () const;
List root_to_leaf () const;
- bool verify () const;
+ bool valid () const;
bool attempt_reorder ();
private:
diff --git a/src/decrypted_kdm.cc b/src/decrypted_kdm.cc
index 8a714b1e..556cd9d5 100644
--- a/src/decrypted_kdm.cc
+++ b/src/decrypted_kdm.cc
@@ -98,17 +98,16 @@ get (uint8_t ** p, int N)
return g;
}
-DecryptedKDM::DecryptedKDM (EncryptedKDM const & kdm, boost::filesystem::path private_key)
+DecryptedKDM::DecryptedKDM (EncryptedKDM const & kdm, string private_key)
{
/* Read the private key */
-
- FILE* private_key_file = fopen_boost (private_key, "r");
- if (!private_key_file) {
- throw FileError ("could not find RSA private key file", private_key, errno);
+
+ BIO* bio = BIO_new_mem_buf (const_cast<char *> (private_key.c_str ()), -1);
+ if (!bio) {
+ throw MiscError ("could not create memory BIO");
}
- RSA* rsa = PEM_read_RSAPrivateKey (private_key_file, 0, 0, 0);
- fclose (private_key_file);
+ RSA* rsa = PEM_read_bio_RSAPrivateKey (bio, 0, 0, 0);
if (!rsa) {
throw FileError ("could not read RSA private key file", private_key, errno);
}
@@ -180,6 +179,7 @@ DecryptedKDM::DecryptedKDM (EncryptedKDM const & kdm, boost::filesystem::path pr
}
RSA_free (rsa);
+ BIO_free (bio);
}
DecryptedKDM::DecryptedKDM (
diff --git a/src/decrypted_kdm.h b/src/decrypted_kdm.h
index 3c3d07db..dfba7563 100644
--- a/src/decrypted_kdm.h
+++ b/src/decrypted_kdm.h
@@ -48,9 +48,9 @@ class DecryptedKDM
{
public:
/** @param kdm Encrypted KDM.
- * @param private_key Private key file name.
+ * @param private_key Private key as a PEM-format string.
*/
- DecryptedKDM (EncryptedKDM const & kdm, boost::filesystem::path private_key);
+ DecryptedKDM (EncryptedKDM const & kdm, std::string private_key);
/** Construct a DecryptedKDM.
* @param cpl CPL that the keys are for.
diff --git a/src/signer.cc b/src/signer.cc
index a0d9912a..55684759 100644
--- a/src/signer.cc
+++ b/src/signer.cc
@@ -23,6 +23,8 @@
#include "signer.h"
#include "exceptions.h"
+#include "certificate_chain.h"
+#include "util.h"
#include <libcxml/cxml.h>
#include <libxml++/libxml++.h>
#include <xmlsec/xmldsig.h>
@@ -37,6 +39,20 @@ using std::cout;
using boost::shared_ptr;
using namespace dcp;
+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")));
+
+ _key = dcp::file_to_string (directory / "leaf.key");
+
+ boost::filesystem::remove_all (directory);
+}
+
+
/** Add a &lt;Signer&gt; and &lt;ds:Signature&gt; nodes to an XML node.
* @param parent XML node to add to.
* @param standard INTEROP or SMPTE.
@@ -96,8 +112,8 @@ Signer::add_signature_value (xmlpp::Node* parent, string ns) const
xmlpp::Node* key_info = cp.node_child("KeyInfo")->node ();
/* Add the certificate chain to the KeyInfo child node of parent */
- list<shared_ptr<Certificate> > c = _certificates.leaf_to_root ();
- for (list<shared_ptr<Certificate> >::iterator i = c.begin(); i != c.end(); ++i) {
+ CertificateChain::List c = _certificates.leaf_to_root ();
+ for (CertificateChain::List::iterator i = c.begin(); i != c.end(); ++i) {
xmlpp::Element* data = key_info->add_child("X509Data", ns);
{
@@ -134,3 +150,23 @@ Signer::add_signature_value (xmlpp::Node* parent, string ns) const
xmlSecDSigCtxDestroy (signature_context);
}
+
+bool
+Signer::valid () const
+{
+ if (!_certificates.valid ()) {
+ return false;
+ }
+
+ BIO* bio = BIO_new_mem_buf (const_cast<char *> (_key.c_str ()), -1);
+ if (!bio) {
+ throw MiscError ("could not create memory BIO");
+ }
+
+ RSA* private_key = PEM_read_bio_RSAPrivateKey (bio, 0, 0, 0);
+ RSA* public_key = _certificates.leaf()->public_key ();
+ bool const valid = !BN_cmp (private_key->n, public_key->n);
+ BIO_free (bio);
+
+ return valid;
+}
diff --git a/src/signer.h b/src/signer.h
index 92745ff2..6fd17033 100644
--- a/src/signer.h
+++ b/src/signer.h
@@ -38,9 +38,11 @@ namespace dcp {
/** @class Signer
* @brief A class which can sign XML files.
*/
-class Signer : public boost::noncopyable
+class Signer
{
public:
+ Signer (boost::filesystem::path openssl);
+
/** @param c Certificate chain to sign with.
* @param k Key to sign with as a PEM-format string.
*/
@@ -55,6 +57,20 @@ public:
CertificateChain const & certificates () const {
return _certificates;
}
+
+ CertificateChain& certificates () {
+ return _certificates;
+ }
+
+ std::string key () const {
+ return _key;
+ }
+
+ void set_key (std::string k) {
+ _key = k;
+ }
+
+ bool valid () const;
private:
diff --git a/src/wscript b/src/wscript
index e9b3c955..87059b36 100644
--- a/src/wscript
+++ b/src/wscript
@@ -14,6 +14,7 @@ def build(bld):
obj.source = """
argb_frame.cc
asset.cc
+ certificate_chain.cc
certificates.cc
colour_matrix.cc
content.cc
@@ -49,7 +50,6 @@ def build(bld):
reel_subtitle_asset.cc
rgb_xyz.cc
signer.cc
- signer_chain.cc
sound_mxf.cc
sound_mxf_writer.cc
sound_frame.cc
@@ -68,6 +68,7 @@ def build(bld):
headers = """
asset.h
+ certificate_chain.h
certificates.h
colour_matrix.h
cpl.h
@@ -103,7 +104,6 @@ def build(bld):
ref.h
argb_frame.h
signer.h
- signer_chain.h
sound_frame.h
sound_mxf.h
sound_mxf_writer.h