Add a somewhat dubious constructor.
[libdcp.git] / src / certificates.cc
index fe03f10e3b8a4dffd46ca636d3f473bce434ed57..6ed32dcadf1d74e71d7e282c5fa0c8a1370627c0 100644 (file)
@@ -1,9 +1,30 @@
+/*
+    Copyright (C) 2012 Carl Hetherington <cth@carlh.net>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
 #include <sstream>
 #include <vector>
 #include <boost/algorithm/string.hpp>
 #include <openssl/x509.h>
 #include <openssl/ssl.h>
 #include <openssl/asn1.h>
+#include <libxml++/nodes/element.h>
+#include "KM_util.h"
 #include "certificates.h"
 #include "exceptions.h"
 
@@ -26,6 +47,30 @@ Certificate::~Certificate ()
        X509_free (_certificate);
 }
 
+string
+Certificate::certificate () const
+{
+       BIO* bio = BIO_new (BIO_s_mem ());
+       if (!bio) {
+               throw MiscError ("could not create memory BIO");
+       }
+       
+       PEM_write_bio_X509 (bio, _certificate);
+
+       string s;
+       char* data;
+       long int const data_length = BIO_get_mem_data (bio, &data);
+       for (long int i = 0; i < data_length; ++i) {
+               s += data[i];
+       }
+
+       BIO_free (bio);
+
+       boost::replace_all (s, "-----BEGIN CERTIFICATE-----\n", "");
+       boost::replace_all (s, "\n-----END CERTIFICATE-----\n", "");
+       return s;
+}
+
 string
 Certificate::issuer () const
 {
@@ -48,7 +93,10 @@ Certificate::name_for_xml (string const & n)
                x << *i << ",";
        }
 
-       return x.str().substr(0, x.str().length() - 2);
+       string s = x.str();
+       boost::replace_all (s, "+", "\\+");
+
+       return s.substr(0, s.length() - 2);
 }
 
 string
@@ -77,7 +125,27 @@ Certificate::serial () const
 
        return st;
 }
-               
+
+string
+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) {
+               throw MiscError ("buffer too small to generate thumbprint");
+       }
+
+       SHA_CTX sha;
+       SHA1_Init (&sha);
+       SHA1_Update (&sha, buffer, length);
+       uint8_t digest[20];
+       SHA1_Final (digest, &sha);
+
+       char digest_base64[64];
+       return Kumu::base64encode (digest, 20, digest_base64, 64);
+}
 
 /** @param filename Text file of PEM-format certificates,
  *  in the order:
@@ -126,3 +194,4 @@ CertificateChain::leaf_to_root () const
        c.reverse ();
        return c;
 }
+