Various fixes for non-Latin filenames.
[libdcp.git] / src / certificates.cc
index d02754f1f098ccaa07c9d117dba821477c93da76..aa7972a55411d1ec972040347d76196783fb1a82 100644 (file)
 #include <openssl/x509.h>
 #include <openssl/ssl.h>
 #include <openssl/asn1.h>
+#include <openssl/err.h>
 #include <libxml++/nodes/element.h>
 #include "KM_util.h"
 #include "certificates.h"
 #include "compose.hpp"
 #include "exceptions.h"
+#include "util.h"
 
 using std::list;
 using std::string;
@@ -39,14 +41,16 @@ using namespace libdcp;
 /** @param c X509 certificate, which this object will take ownership of */
 Certificate::Certificate (X509* c)
        : _certificate (c)
+       , _public_key (0)
 {
        
 }
 
 Certificate::Certificate (boost::filesystem::path filename)
        : _certificate (0)
+       , _public_key (0)
 {
-       FILE* f = fopen (filename.c_str(), "r");
+       FILE* f = fopen_boost (filename, "r");
        if (!f) {
                throw FileError ("could not open file", filename);
        }
@@ -58,12 +62,14 @@ Certificate::Certificate (boost::filesystem::path filename)
 
 Certificate::Certificate (string cert)
        : _certificate (0)
+       , _public_key (0)
 {
        read_string (cert);
 }
 
 Certificate::Certificate (Certificate const & other)
        : _certificate (0)
+       , _public_key (0)
 {
        read_string (other.certificate (true));
 }
@@ -87,6 +93,7 @@ Certificate::read_string (string cert)
 Certificate::~Certificate ()
 {
        X509_free (_certificate);
+       RSA_free (_public_key);
 }
 
 Certificate &
@@ -97,6 +104,10 @@ Certificate::operator= (Certificate const & other)
        }
 
        X509_free (_certificate);
+       _certificate = 0;
+       RSA_free (_public_key);
+       _public_key = 0;
+       
        read_string (other.certificate ());
 
        return *this;
@@ -183,6 +194,14 @@ Certificate::subject () const
        return name_for_xml (X509_get_subject_name (_certificate));
 }
 
+string
+Certificate::common_name () const
+{
+       assert (_certificate);
+
+       return get_name_part (X509_get_subject_name (_certificate), NID_commonName);
+}
+
 string
 Certificate::serial () const
 {
@@ -224,6 +243,28 @@ Certificate::thumbprint () const
        return Kumu::base64encode (digest, 20, digest_base64, 64);
 }
 
+RSA *
+Certificate::public_key () const
+{
+       assert (_certificate);
+
+       if (_public_key) {
+               return _public_key;
+       }
+
+       EVP_PKEY* key = X509_get_pubkey (_certificate);
+       if (!key) {
+               throw MiscError ("could not get public key from certificate");
+       }
+
+       _public_key = EVP_PKEY_get1_RSA (key);
+       if (!_public_key) {
+               throw MiscError (String::compose ("could not get RSA public key (%1)", ERR_error_string (ERR_get_error(), 0)));
+       }
+
+       return _public_key;
+}
+
 shared_ptr<Certificate>
 CertificateChain::root () const
 {