3 #include <boost/algorithm/string.hpp>
4 #include <openssl/x509.h>
5 #include <openssl/ssl.h>
6 #include <openssl/asn1.h>
7 #include <libxml++/nodes/element.h>
8 #include "certificates.h"
9 #include "exceptions.h"
13 using std::stringstream;
15 using boost::shared_ptr;
16 using namespace libdcp;
18 /** @param c X509 certificate, which this object will take ownership of */
19 Certificate::Certificate (X509* c)
25 Certificate::~Certificate ()
27 X509_free (_certificate);
31 Certificate::certificate () const
33 BIO* bio = BIO_new (BIO_s_mem ());
35 throw MiscError ("could not create memory BIO");
38 PEM_write_bio_X509 (bio, _certificate);
42 long int const data_length = BIO_get_mem_data (bio, &data);
43 for (long int i = 0; i < data_length; ++i) {
49 boost::replace_all (s, "-----BEGIN CERTIFICATE-----\n", "");
50 boost::replace_all (s, "\n-----END CERTIFICATE-----\n", "");
55 Certificate::issuer () const
57 X509_NAME* n = X509_get_issuer_name (_certificate);
61 X509_NAME_oneline (n, b, 256);
66 Certificate::name_for_xml (string const & n)
71 boost::split (p, n, boost::is_any_of ("/"));
72 for (vector<string>::const_reverse_iterator i = p.rbegin(); i != p.rend(); ++i) {
77 boost::replace_all (s, "+", "\\+");
79 return s.substr(0, s.length() - 2);
83 Certificate::subject () const
85 X509_NAME* n = X509_get_subject_name (_certificate);
89 X509_NAME_oneline (n, b, 256);
94 Certificate::serial () const
96 ASN1_INTEGER* s = X509_get_serialNumber (_certificate);
99 BIGNUM* b = ASN1_INTEGER_to_BN (s, 0);
100 char* c = BN_bn2dec (b);
109 /** @param filename Text file of PEM-format certificates,
112 * 1. self-signed root certificate
113 * 2. intermediate certificate signed by root certificate
115 * n. leaf certificate signed by previous intermediate.
118 CertificateChain::CertificateChain (string const & filename)
120 FILE* f = fopen (filename.c_str(), "r");
122 throw FileError ("could not open file", filename);
127 if (!PEM_read_X509 (f, &c, 0, 0)) {
131 _certificates.push_back (shared_ptr<Certificate> (new Certificate (c)));
135 shared_ptr<Certificate>
136 CertificateChain::root () const
138 assert (!_certificates.empty());
139 return _certificates.front ();
142 shared_ptr<Certificate>
143 CertificateChain::leaf () const
145 assert (_certificates.size() >= 2);
146 return _certificates.back ();
149 list<shared_ptr<Certificate> >
150 CertificateChain::leaf_to_root () const
152 list<shared_ptr<Certificate> > c = _certificates;