aboutsummaryrefslogtreecommitdiffstats
path: root/src/security/cert
diff options
context:
space:
mode:
authorVincent Richard <[email protected]>2013-12-29 10:02:12 +0100
committerVincent Richard <[email protected]>2013-12-29 10:02:12 +0100
commit152c6bed75598a6ca5efb7914701157270155833 (patch)
tree8faced1d75a45c819630323da256248415992ed0 /src/security/cert
parentMerge branch 'master' of https://github.com/kisli/vmime (diff)
downloadvmime-152c6bed75598a6ca5efb7914701157270155833.tar.gz
vmime-152c6bed75598a6ca5efb7914701157270155833.zip
Merged source and header files in directory structure. Got rid of SConstruct build.
Diffstat (limited to 'src/security/cert')
-rw-r--r--src/security/cert/X509Certificate.cpp48
-rw-r--r--src/security/cert/certificateChain.cpp53
-rw-r--r--src/security/cert/defaultCertificateVerifier.cpp178
-rw-r--r--src/security/cert/gnutls/X509Certificate_GnuTLS.cpp290
-rw-r--r--src/security/cert/openssl/X509Certificate_OpenSSL.cpp574
5 files changed, 0 insertions, 1143 deletions
diff --git a/src/security/cert/X509Certificate.cpp b/src/security/cert/X509Certificate.cpp
deleted file mode 100644
index 2eebabfd..00000000
--- a/src/security/cert/X509Certificate.cpp
+++ /dev/null
@@ -1,48 +0,0 @@
-//
-// VMime library (http://www.vmime.org)
-// Copyright (C) 2002-2013 Vincent Richard <[email protected]>
-//
-// 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 3 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.,
-// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-//
-// Linking this library statically or dynamically with other modules is making
-// a combined work based on this library. Thus, the terms and conditions of
-// the GNU General Public License cover the whole combination.
-//
-
-#include "vmime/config.hpp"
-
-
-#if VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_TLS_SUPPORT
-
-
-#include "vmime/security/cert/X509Certificate.hpp"
-
-
-namespace vmime {
-namespace security {
-namespace cert {
-
-
-X509Certificate::~X509Certificate()
-{
-}
-
-
-} // cert
-} // security
-} // vmime
-
-
-#endif // VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_TLS_SUPPORT
diff --git a/src/security/cert/certificateChain.cpp b/src/security/cert/certificateChain.cpp
deleted file mode 100644
index 3cb4e360..00000000
--- a/src/security/cert/certificateChain.cpp
+++ /dev/null
@@ -1,53 +0,0 @@
-//
-// VMime library (http://www.vmime.org)
-// Copyright (C) 2002-2013 Vincent Richard <[email protected]>
-//
-// 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 3 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.,
-// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-//
-// Linking this library statically or dynamically with other modules is making
-// a combined work based on this library. Thus, the terms and conditions of
-// the GNU General Public License cover the whole combination.
-//
-
-#include "vmime/security/cert/certificateChain.hpp"
-
-
-namespace vmime {
-namespace security {
-namespace cert {
-
-
-certificateChain::certificateChain(const std::vector <shared_ptr <certificate> >& certs)
- : m_certs(certs)
-{
-}
-
-
-unsigned int certificateChain::getCount() const
-{
- return static_cast <unsigned int>(m_certs.size());
-}
-
-
-shared_ptr <certificate> certificateChain::getAt(const unsigned int index)
-{
- return m_certs[index];
-}
-
-
-} // cert
-} // security
-} // vmime
-
diff --git a/src/security/cert/defaultCertificateVerifier.cpp b/src/security/cert/defaultCertificateVerifier.cpp
deleted file mode 100644
index 1a95b353..00000000
--- a/src/security/cert/defaultCertificateVerifier.cpp
+++ /dev/null
@@ -1,178 +0,0 @@
-//
-// VMime library (http://www.vmime.org)
-// Copyright (C) 2002-2013 Vincent Richard <[email protected]>
-//
-// 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 3 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.,
-// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-//
-// Linking this library statically or dynamically with other modules is making
-// a combined work based on this library. Thus, the terms and conditions of
-// the GNU General Public License cover the whole combination.
-//
-
-#include "vmime/config.hpp"
-
-#if VMIME_HAVE_TLS_SUPPORT
-
-#include "vmime/security/cert/defaultCertificateVerifier.hpp"
-
-#include "vmime/security/cert/X509Certificate.hpp"
-
-#include "vmime/exception.hpp"
-
-
-namespace vmime {
-namespace security {
-namespace cert {
-
-
-defaultCertificateVerifier::defaultCertificateVerifier()
-{
-}
-
-
-defaultCertificateVerifier::~defaultCertificateVerifier()
-{
-}
-
-
-defaultCertificateVerifier::defaultCertificateVerifier(const defaultCertificateVerifier&)
- : certificateVerifier()
-{
- // Not used
-}
-
-
-void defaultCertificateVerifier::verify
- (shared_ptr <certificateChain> chain, const string& hostname)
-{
- if (chain->getCount() == 0)
- return;
-
- const string type = chain->getAt(0)->getType();
-
- if (type == "X.509")
- verifyX509(chain, hostname);
- else
- throw exceptions::unsupported_certificate_type(type);
-}
-
-
-void defaultCertificateVerifier::verifyX509
- (shared_ptr <certificateChain> chain, const string& hostname)
-{
- // For every certificate in the chain, verify that the certificate
- // has been issued by the next certificate in the chain
- if (chain->getCount() >= 2)
- {
- for (unsigned int i = 0 ; i < chain->getCount() - 1 ; ++i)
- {
- shared_ptr <X509Certificate> cert =
- dynamicCast <X509Certificate>(chain->getAt(i));
-
- shared_ptr <X509Certificate> next =
- dynamicCast <X509Certificate>(chain->getAt(i + 1));
-
- if (!cert->checkIssuer(next))
- {
- throw exceptions::certificate_verification_exception
- ("Subject/issuer verification failed.");
- }
- }
- }
-
- // For every certificate in the chain, verify that the certificate
- // is valid at the current time
- const datetime now = datetime::now();
-
- for (unsigned int i = 0 ; i < chain->getCount() ; ++i)
- {
- shared_ptr <X509Certificate> cert =
- dynamicCast <X509Certificate>(chain->getAt(i));
-
- const datetime begin = cert->getActivationDate();
- const datetime end = cert->getExpirationDate();
-
- if (now < begin || now > end)
- {
- throw exceptions::certificate_verification_exception
- ("Validity date check failed.");
- }
- }
-
- // Check whether the certificate can be trusted
-
- // -- First, verify that the the last certificate in the chain was
- // -- issued by a third-party that we trust
- shared_ptr <X509Certificate> lastCert =
- dynamicCast <X509Certificate>(chain->getAt(chain->getCount() - 1));
-
- bool trusted = false;
-
- for (unsigned int i = 0 ; !trusted && i < m_x509RootCAs.size() ; ++i)
- {
- shared_ptr <X509Certificate> rootCa = m_x509RootCAs[i];
-
- if (lastCert->verify(rootCa))
- trusted = true;
- }
-
- // -- Next, if the issuer certificate cannot be verified against
- // -- root CAs, compare the subject's certificate against the
- // -- trusted certificates
- shared_ptr <X509Certificate> firstCert =
- dynamicCast <X509Certificate>(chain->getAt(0));
-
- for (unsigned int i = 0 ; !trusted && i < m_x509TrustedCerts.size() ; ++i)
- {
- shared_ptr <X509Certificate> cert = m_x509TrustedCerts[i];
-
- if (firstCert->equals(cert))
- trusted = true;
- }
-
- if (!trusted)
- {
- throw exceptions::certificate_verification_exception
- ("Cannot verify certificate against trusted certificates.");
- }
-
- // Ensure the first certificate's subject name matches server hostname
- if (!firstCert->verifyHostName(hostname))
- {
- throw exceptions::certificate_verification_exception
- ("Server identity cannot be verified.");
- }
-}
-
-
-void defaultCertificateVerifier::setX509RootCAs
- (const std::vector <shared_ptr <X509Certificate> >& caCerts)
-{
- m_x509RootCAs = caCerts;
-}
-
-
-void defaultCertificateVerifier::setX509TrustedCerts
- (const std::vector <shared_ptr <X509Certificate> >& trustedCerts)
-{
- m_x509TrustedCerts = trustedCerts;
-}
-
-
-} // cert
-} // security
-} // vmime
-
-#endif
diff --git a/src/security/cert/gnutls/X509Certificate_GnuTLS.cpp b/src/security/cert/gnutls/X509Certificate_GnuTLS.cpp
deleted file mode 100644
index f96ddddb..00000000
--- a/src/security/cert/gnutls/X509Certificate_GnuTLS.cpp
+++ /dev/null
@@ -1,290 +0,0 @@
-//
-// VMime library (http://www.vmime.org)
-// Copyright (C) 2002-2013 Vincent Richard <[email protected]>
-//
-// 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 3 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.,
-// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-//
-// Linking this library statically or dynamically with other modules is making
-// a combined work based on this library. Thus, the terms and conditions of
-// the GNU General Public License cover the whole combination.
-//
-
-#include "vmime/config.hpp"
-
-
-#if VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_TLS_SUPPORT && VMIME_TLS_SUPPORT_LIB_IS_GNUTLS
-
-
-#include <gnutls/gnutls.h>
-#include <gnutls/x509.h>
-
-#include <ctime>
-
-#include "vmime/security/cert/gnutls/X509Certificate_GnuTLS.hpp"
-
-#include "vmime/utility/outputStreamByteArrayAdapter.hpp"
-
-
-namespace vmime {
-namespace security {
-namespace cert {
-
-
-#ifndef VMIME_BUILDING_DOC
-
-struct GnuTLSX509CertificateInternalData
-{
- GnuTLSX509CertificateInternalData()
- {
- gnutls_x509_crt_init(&cert);
- }
-
- ~GnuTLSX509CertificateInternalData()
- {
- gnutls_x509_crt_deinit(cert);
- }
-
-
- gnutls_x509_crt cert;
-};
-
-#endif // VMIME_BUILDING_DOC
-
-
-X509Certificate_GnuTLS::X509Certificate_GnuTLS()
- : m_data(new GnuTLSX509CertificateInternalData)
-{
-}
-
-
-X509Certificate_GnuTLS::X509Certificate_GnuTLS(const X509Certificate&)
- : X509Certificate(), m_data(NULL)
-{
- // Not used
-}
-
-
-X509Certificate_GnuTLS::~X509Certificate_GnuTLS()
-{
- delete m_data;
-}
-
-
-void* X509Certificate_GnuTLS::getInternalData()
-{
- return &m_data->cert;
-}
-
-
-// static
-shared_ptr <X509Certificate> X509Certificate::import(utility::inputStream& is)
-{
- byteArray bytes;
- byte_t chunk[4096];
-
- while (!is.eof())
- {
- const size_t len = is.read(chunk, sizeof(chunk));
- bytes.insert(bytes.end(), chunk, chunk + len);
- }
-
- return import(&bytes[0], bytes.size());
-}
-
-
-// static
-shared_ptr <X509Certificate> X509Certificate::import
- (const byte_t* data, const size_t length)
-{
- gnutls_datum buffer;
- buffer.data = const_cast <byte_t*>(data);
- buffer.size = static_cast <unsigned int>(length);
-
- // Try DER format
- shared_ptr <X509Certificate_GnuTLS> derCert = make_shared <X509Certificate_GnuTLS>();
-
- if (gnutls_x509_crt_import(derCert->m_data->cert, &buffer, GNUTLS_X509_FMT_DER) >= 0)
- return derCert;
-
- // Try PEM format
- shared_ptr <X509Certificate_GnuTLS> pemCert = make_shared <X509Certificate_GnuTLS>();
-
- if (gnutls_x509_crt_import(pemCert->m_data->cert, &buffer, GNUTLS_X509_FMT_PEM) >= 0)
- return pemCert;
-
- return null;
-}
-
-
-void X509Certificate_GnuTLS::write
- (utility::outputStream& os, const Format format) const
-{
- size_t dataSize = 0;
- gnutls_x509_crt_fmt fmt = GNUTLS_X509_FMT_DER;
-
- switch (format)
- {
- case FORMAT_DER: fmt = GNUTLS_X509_FMT_DER; break;
- case FORMAT_PEM: fmt = GNUTLS_X509_FMT_PEM; break;
- }
-
- gnutls_x509_crt_export(m_data->cert, fmt, NULL, &dataSize);
-
- std::vector <byte_t> data(dataSize);
-
- gnutls_x509_crt_export(m_data->cert, fmt, &data[0], &dataSize);
-
- os.write(reinterpret_cast <byte_t*>(&data[0]), dataSize);
-}
-
-
-const byteArray X509Certificate_GnuTLS::getSerialNumber() const
-{
- char serial[64];
- size_t serialSize = sizeof(serial);
-
- gnutls_x509_crt_get_serial(m_data->cert, serial, &serialSize);
-
- return byteArray(serial, serial + serialSize);
-}
-
-
-bool X509Certificate_GnuTLS::checkIssuer(shared_ptr <const X509Certificate> issuer_) const
-{
- shared_ptr <const X509Certificate_GnuTLS> issuer =
- dynamicCast <const X509Certificate_GnuTLS>(issuer_);
-
- return (gnutls_x509_crt_check_issuer
- (m_data->cert, issuer->m_data->cert) >= 1);
-}
-
-
-bool X509Certificate_GnuTLS::verify(shared_ptr <const X509Certificate> caCert_) const
-{
- shared_ptr <const X509Certificate_GnuTLS> caCert =
- dynamicCast <const X509Certificate_GnuTLS>(caCert_);
-
- unsigned int verify = 0;
-
- const int res = gnutls_x509_crt_verify
- (m_data->cert, &(caCert->m_data->cert), 1,
- GNUTLS_VERIFY_ALLOW_X509_V1_CA_CRT,
- &verify);
-
- return (res == 0 && verify == 0);
-}
-
-
-bool X509Certificate_GnuTLS::verifyHostName(const string& hostname) const
-{
- return gnutls_x509_crt_check_hostname(m_data->cert, hostname.c_str()) != 0;
-}
-
-
-const datetime X509Certificate_GnuTLS::getActivationDate() const
-{
- const time_t t = gnutls_x509_crt_get_activation_time(m_data->cert);
- return datetime(t);
-}
-
-
-const datetime X509Certificate_GnuTLS::getExpirationDate() const
-{
- const time_t t = gnutls_x509_crt_get_expiration_time(m_data->cert);
- return datetime(t);
-}
-
-
-const byteArray X509Certificate_GnuTLS::getFingerprint(const DigestAlgorithm algo) const
-{
- gnutls_digest_algorithm galgo;
-
- switch (algo)
- {
- case DIGEST_MD5:
-
- galgo = GNUTLS_DIG_MD5;
- break;
-
- default:
- case DIGEST_SHA1:
-
- galgo = GNUTLS_DIG_SHA;
- break;
- }
-
- size_t bufferSize = 0;
- gnutls_x509_crt_get_fingerprint
- (m_data->cert, galgo, NULL, &bufferSize);
-
- std::vector <byte_t> buffer(bufferSize);
-
- if (gnutls_x509_crt_get_fingerprint
- (m_data->cert, galgo, &buffer[0], &bufferSize) == 0)
- {
- byteArray res;
- res.insert(res.end(), &buffer[0], &buffer[0] + bufferSize);
-
- return res;
- }
-
- return byteArray();
-}
-
-
-const byteArray X509Certificate_GnuTLS::getEncoded() const
-{
- byteArray bytes;
- utility::outputStreamByteArrayAdapter os(bytes);
-
- write(os, FORMAT_DER);
-
- return bytes;
-}
-
-
-const string X509Certificate_GnuTLS::getType() const
-{
- return "X.509";
-}
-
-
-int X509Certificate_GnuTLS::getVersion() const
-{
- return gnutls_x509_crt_get_version(m_data->cert);
-}
-
-
-bool X509Certificate_GnuTLS::equals(shared_ptr <const certificate> other) const
-{
- shared_ptr <const X509Certificate_GnuTLS> otherX509 =
- dynamicCast <const X509Certificate_GnuTLS>(other);
-
- if (!otherX509)
- return false;
-
- const byteArray fp1 = getFingerprint(DIGEST_MD5);
- const byteArray fp2 = otherX509->getFingerprint(DIGEST_MD5);
-
- return fp1 == fp2;
-}
-
-
-} // cert
-} // security
-} // vmime
-
-
-#endif // VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_TLS_SUPPORT && VMIME_TLS_SUPPORT_LIB_IS_GNUTLS
diff --git a/src/security/cert/openssl/X509Certificate_OpenSSL.cpp b/src/security/cert/openssl/X509Certificate_OpenSSL.cpp
deleted file mode 100644
index 5f81b2bf..00000000
--- a/src/security/cert/openssl/X509Certificate_OpenSSL.cpp
+++ /dev/null
@@ -1,574 +0,0 @@
-//
-// VMime library (http://www.vmime.org)
-// Copyright (C) 2002-2013 Vincent Richard <[email protected]>
-//
-// 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 3 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.,
-// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-//
-// Linking this library statically or dynamically with other modules is making
-// a combined work based on this library. Thus, the terms and conditions of
-// the GNU General Public License cover the whole combination.
-//
-
-#include "vmime/config.hpp"
-
-
-#if VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_TLS_SUPPORT && VMIME_TLS_SUPPORT_LIB_IS_OPENSSL
-
-
-#include <cstdio>
-#include <ctime>
-#include <map>
-#include <algorithm>
-
-#include "vmime/security/cert/openssl/X509Certificate_OpenSSL.hpp"
-
-#include "vmime/net/tls/openssl/OpenSSLInitializer.hpp"
-
-#include "vmime/utility/outputStreamByteArrayAdapter.hpp"
-
-#include "vmime/exception.hpp"
-
-#include <openssl/x509.h>
-#include <openssl/x509v3.h>
-#include <openssl/conf.h>
-#include <openssl/bio.h>
-#include <openssl/pem.h>
-#include <openssl/err.h>
-
-
-#ifdef _WIN32
-# define strcasecmp _stricmp
-# define strncasecmp _strnicmp
-#endif
-
-
-namespace vmime {
-namespace security {
-namespace cert {
-
-
-static net::tls::OpenSSLInitializer::autoInitializer openSSLInitializer;
-
-
-#ifndef VMIME_BUILDING_DOC
-
-class monthMap
-{
-public:
-
- monthMap()
- {
- m_monthMap["jan"] = vmime::datetime::JAN;
- m_monthMap["feb"] = vmime::datetime::FEB;
- m_monthMap["mar"] = vmime::datetime::MAR;
- m_monthMap["apr"] = vmime::datetime::APR;
- m_monthMap["may"] = vmime::datetime::MAY;
- m_monthMap["jun"] = vmime::datetime::JUN;
- m_monthMap["jul"] = vmime::datetime::JUL;
- m_monthMap["aug"] = vmime::datetime::AUG;
- m_monthMap["sep"] = vmime::datetime::SEP;
- m_monthMap["oct"] = vmime::datetime::OCT;
- m_monthMap["nov"] = vmime::datetime::NOV;
- m_monthMap["dec"] = vmime::datetime::DEC;
- }
-
- int getMonth(vmime::string mstr)
- {
- std::transform(mstr.begin(), mstr.end(), mstr.begin(), ::tolower);
-
- std::map <vmime::string, vmime::datetime::Months>::const_iterator
- c_it = m_monthMap.find(mstr);
-
- if (c_it != m_monthMap.end())
- return c_it->second;
-
- return -1;
- }
-
-private:
-
- std::map<vmime::string, vmime::datetime::Months> m_monthMap;
-};
-
-static monthMap sg_monthMap;
-
-
-
-struct OpenSSLX509CertificateInternalData
-{
- OpenSSLX509CertificateInternalData()
- {
- cert = 0;
- }
-
- ~OpenSSLX509CertificateInternalData()
- {
- if (cert)
- X509_free(cert);
- }
-
- X509* cert;
-};
-
-#endif // VMIME_BUILDING_DOC
-
-
-X509Certificate_OpenSSL::X509Certificate_OpenSSL()
- : m_data(new OpenSSLX509CertificateInternalData)
-{
-}
-
-
-X509Certificate_OpenSSL::X509Certificate_OpenSSL(X509* cert)
- : m_data(new OpenSSLX509CertificateInternalData)
-{
- m_data->cert = X509_dup(cert);
-}
-
-
-X509Certificate_OpenSSL::X509Certificate_OpenSSL(const X509Certificate_OpenSSL&)
- : X509Certificate(), m_data(NULL)
-{
- // Not used
-}
-
-
-X509Certificate_OpenSSL::~X509Certificate_OpenSSL()
-{
- delete m_data;
-}
-
-
-void* X509Certificate_OpenSSL::getInternalData()
-{
- return &m_data->cert;
-}
-
-
-// static
-shared_ptr <X509Certificate> X509Certificate_OpenSSL::importInternal(X509* cert)
-{
- if (cert)
- return make_shared <X509Certificate_OpenSSL>(reinterpret_cast <X509 *>(cert));
-
- return null;
-}
-
-
-// static
-shared_ptr <X509Certificate> X509Certificate::import(utility::inputStream& is)
-{
- byteArray bytes;
- byte_t chunk[4096];
-
- while (!is.eof())
- {
- const size_t len = is.read(chunk, sizeof(chunk));
- bytes.insert(bytes.end(), chunk, chunk + len);
- }
-
- return import(&bytes[0], bytes.size());
-}
-
-
-// static
-shared_ptr <X509Certificate> X509Certificate::import
- (const byte_t* data, const size_t length)
-{
- shared_ptr <X509Certificate_OpenSSL> cert = make_shared <X509Certificate_OpenSSL>();
-
- BIO* membio = BIO_new_mem_buf(const_cast <byte_t*>(data), static_cast <int>(length));
-
- if (!PEM_read_bio_X509(membio, &(cert->m_data->cert), 0, 0))
- {
- BIO_vfree(membio);
- return null;
- }
-
- BIO_vfree(membio);
-
- return cert;
-}
-
-
-void X509Certificate_OpenSSL::write
- (utility::outputStream& os, const Format format) const
-{
- BIO* membio = 0;
- long dataSize = 0;
- unsigned char* out = 0;
-
- if (format == FORMAT_DER)
- {
- if ((dataSize = i2d_X509(m_data->cert, &out)) < 0)
- goto err;
-
- os.write(reinterpret_cast <byte_t*>(out), dataSize);
- os.flush();
- OPENSSL_free(out);
- }
- else if (format == FORMAT_PEM)
- {
- membio = BIO_new(BIO_s_mem());
- BIO_set_close(membio, BIO_CLOSE);
-
- if (!PEM_write_bio_X509(membio, m_data->cert))
- goto pem_err;
-
- dataSize = BIO_get_mem_data(membio, &out);
- os.write(reinterpret_cast <byte_t*>(out), dataSize);
- os.flush();
- BIO_vfree(membio);
- }
- else
- {
- throw vmime::exceptions::unsupported_certificate_type("Unknown cert type");
- }
-
- return; // #### Early Return ####
-
-pem_err:
- {
- if (membio)
- BIO_vfree(membio);
- }
-
-err:
- {
- char errstr[256];
- long ec = ERR_get_error();
- ERR_error_string(ec, errstr);
- throw vmime::exceptions::certificate_exception(
- "OpenSSLX509Certificate_OpenSSL::write exception - " + string(errstr));
- }
-}
-
-
-const byteArray X509Certificate_OpenSSL::getSerialNumber() const
-{
- ASN1_INTEGER *serial = X509_get_serialNumber(m_data->cert);
- BIGNUM *bnser = ASN1_INTEGER_to_BN(serial, NULL);
- int n = BN_num_bytes(bnser);
- byte_t* outbuf = new byte_t[n];
- BN_bn2bin(bnser, outbuf);
- byteArray ser(outbuf, outbuf + n);
- delete [] outbuf;
- BN_free(bnser);
- return ser;
-}
-
-
-bool X509Certificate_OpenSSL::checkIssuer(shared_ptr <const X509Certificate> cert_) const
-{
- shared_ptr <const X509Certificate_OpenSSL> cert =
- dynamicCast <const X509Certificate_OpenSSL>(cert_);
-
- // Get issuer for this cert
- BIO *out;
- unsigned char *issuer;
-
- out = BIO_new(BIO_s_mem());
- X509_NAME_print_ex(out, X509_get_issuer_name(m_data->cert), 0, XN_FLAG_RFC2253);
- long n = BIO_get_mem_data(out, &issuer);
- vmime::string thisIssuerName((char*)issuer, n);
- BIO_free(out);
-
- // Get subject of issuer
- unsigned char *subject;
- out = BIO_new(BIO_s_mem());
- X509_NAME_print_ex(out, X509_get_subject_name(cert->m_data->cert), 0, XN_FLAG_RFC2253);
- n = BIO_get_mem_data(out, &subject);
- vmime::string subjOfIssuer((char*)subject, n);
- BIO_free(out);
-
- return subjOfIssuer == thisIssuerName;
-}
-
-
-bool X509Certificate_OpenSSL::verify(shared_ptr <const X509Certificate> caCert_) const
-{
- shared_ptr <const X509Certificate_OpenSSL> caCert =
- dynamicCast <const X509Certificate_OpenSSL>(caCert_);
-
-
- bool verified = false;
- bool error = true;
-
- X509_STORE *store = X509_STORE_new();
-
- if (store)
- {
- X509_STORE_CTX *verifyCtx = X509_STORE_CTX_new();
-
- if (verifyCtx)
- {
- if (X509_STORE_add_cert(store, caCert->m_data->cert))
- {
- X509_STORE_CTX_init(verifyCtx, store, m_data->cert, NULL);
-
- int ret = X509_verify_cert(verifyCtx);
-
- if (ret == 1)
- {
- verified = true;
- error = false;
- }
- else if (ret == 0)
- {
- verified = false;
- error = false;
- }
-
- //X509_verify_cert_error_string(vrfy_ctx->error)
-
- X509_STORE_CTX_free(verifyCtx);
- }
- }
-
- X509_STORE_free(store);
- }
-
- return verified && !error;
-}
-
-
-// static
-bool X509Certificate_OpenSSL::cnMatch(const char* cnBuf, const char* host)
-{
- // Right-to-left match, looking for a '*' wildcard
- const bool hasWildcard = (strlen(cnBuf) > 1 && cnBuf[0] == '*' && cnBuf[1] == '.');
- const char* cnBufReverseEndPtr = (cnBuf + (hasWildcard ? 2 : 0));
- const char* hostPtr = host + strlen(host);
- const char* cnPtr = cnBuf + strlen(cnBuf);
-
- bool matches = true;
-
- while (matches && --hostPtr >= host && --cnPtr >= cnBufReverseEndPtr)
- matches = (toupper(*hostPtr) == toupper(*cnPtr));
-
- return matches;
-}
-
-
-bool X509Certificate_OpenSSL::verifyHostName(const string& hostname) const
-{
- // First, check subject common name against hostname
- char CNBuffer[1024];
- CNBuffer[sizeof(CNBuffer) - 1] = '\0';
-
- X509_NAME* xname = X509_get_subject_name(m_data->cert);
-
- if (X509_NAME_get_text_by_NID(xname, NID_commonName, CNBuffer, sizeof(CNBuffer)) != -1)
- {
- if (cnMatch(CNBuffer, hostname.c_str()))
- return true;
- }
-
- // Now, look in subject alternative names
- for (int i = 0, extCount = X509_get_ext_count(m_data->cert) ; i < extCount ; ++i)
- {
- X509_EXTENSION* ext = X509_get_ext(m_data->cert, i);
- const char* extStr = OBJ_nid2sn(OBJ_obj2nid(X509_EXTENSION_get_object(ext)));
-
- if (strcmp(extStr, "subjectAltName") == 0)
- {
-#ifdef _WIN32
- X509V3_EXT_METHOD* method;
-#else
- const X509V3_EXT_METHOD* method;
-#endif
-
- if ((method = X509V3_EXT_get(ext)) != NULL)
- {
- const unsigned char* extVal = ext->value->data;
- void *extValStr;
-
- if (method->it)
- {
- extValStr = ASN1_item_d2i
- (NULL, &extVal, ext->value->length, ASN1_ITEM_ptr(method->it));
- }
- else
- {
- extValStr = method->d2i
- (NULL, &extVal, ext->value->length);
- }
-
- if (extValStr && method->i2v)
- {
- STACK_OF(CONF_VALUE)* val = method->i2v(method, extValStr, NULL);
-
- for (int j = 0 ; j < sk_CONF_VALUE_num(val) ; ++j)
- {
- CONF_VALUE* cnf = sk_CONF_VALUE_value(val, j);
-
- if ((strcasecmp(cnf->name, "DNS") == 0 &&
- strcasecmp(cnf->value, hostname.c_str()) == 0)
- ||
- (strncasecmp(cnf->name, "IP", 2) == 0 &&
- strcasecmp(cnf->value, hostname.c_str()) == 0))
- {
- return true;
- }
- }
- }
- }
- }
- }
-
- return false;
-}
-
-
-const datetime X509Certificate_OpenSSL::convertX509Date(void* time) const
-{
- char* buffer;
- BIO* out = BIO_new(BIO_s_mem());
- BIO_set_close(out, BIO_CLOSE);
-
- ASN1_TIME* asn1_time = reinterpret_cast<ASN1_TIME*>(time);
- ASN1_TIME_print(out, asn1_time);
-
- int sz = BIO_get_mem_data(out, &buffer);
- char* dest = new char[sz + 1];
- dest[sz] = 0;
- memcpy(dest, buffer, sz);
- vmime::string t(dest);
-
- BIO_free(out);
- delete dest;
-
- if (t.size() > 0)
- {
- char month[4] = {0};
- char zone[4] = {0};
- int day, hour, minute, second, year;
- int nrconv = sscanf(t.c_str(), "%s %2d %02d:%02d:%02d %d%s", month, &day, &hour, &minute, &second,&year,zone);
-
- if (nrconv >= 6)
- return datetime(year, sg_monthMap.getMonth(vmime::string(month)), day, hour, minute, second);
- }
-
- // let datetime try and parse it
- return datetime(t);
-}
-
-
-const datetime X509Certificate_OpenSSL::getActivationDate() const
-{
- return convertX509Date(X509_get_notBefore(m_data->cert));
-}
-
-
-const datetime X509Certificate_OpenSSL::getExpirationDate() const
-{
- return convertX509Date(X509_get_notAfter(m_data->cert));
-}
-
-
-const byteArray X509Certificate_OpenSSL::getFingerprint(const DigestAlgorithm algo) const
-{
- BIO *out;
- int j;
- unsigned int n;
- const EVP_MD *digest;
- unsigned char * fingerprint, *result;
- unsigned char md[EVP_MAX_MD_SIZE];
-
- switch (algo)
- {
- case DIGEST_MD5:
-
- digest = EVP_md5();
- break;
-
- default:
- case DIGEST_SHA1:
-
- digest = EVP_sha1();
- break;
- }
-
- out = BIO_new(BIO_s_mem());
- BIO_set_close(out, BIO_CLOSE);
-
- if (X509_digest(m_data->cert, digest, md, &n))
- {
- for (j=0; j<(int)n; j++)
- {
- BIO_printf (out, "%02X",md[j]);
- if (j+1 != (int)n) BIO_printf(out, ":");
- }
- }
-
- n = BIO_get_mem_data(out, &fingerprint);
- result = new unsigned char[n];
- memcpy (result, fingerprint, n);
- BIO_free(out);
-
- byteArray res;
- res.insert(res.end(), &result[0], &result[0] + n);
-
- delete [] result;
-
- return res;
-}
-
-
-const byteArray X509Certificate_OpenSSL::getEncoded() const
-{
- byteArray bytes;
- utility::outputStreamByteArrayAdapter os(bytes);
-
- write(os, FORMAT_DER);
-
- return bytes;
-}
-
-
-const string X509Certificate_OpenSSL::getType() const
-{
- return "X.509";
-}
-
-
-int X509Certificate_OpenSSL::getVersion() const
-{
- return (int)X509_get_version(m_data->cert);
-}
-
-
-bool X509Certificate_OpenSSL::equals(shared_ptr <const certificate> other) const
-{
- shared_ptr <const X509Certificate_OpenSSL> otherX509 =
- dynamicCast <const X509Certificate_OpenSSL>(other);
-
- if (!otherX509)
- return false;
-
- const byteArray fp1 = getFingerprint(DIGEST_MD5);
- const byteArray fp2 = otherX509->getFingerprint(DIGEST_MD5);
-
- return fp1 == fp2;
-}
-
-
-} // cert
-} // security
-} // vmime
-
-
-#endif // VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_TLS_SUPPORT && VMIME_TLS_SUPPORT_LIB_IS_OPENSSL
-