aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVincent Richard <[email protected]>2014-01-09 19:25:43 +0000
committerVincent Richard <[email protected]>2014-01-09 19:25:43 +0000
commit9cad1aa646f602b5ddbb3d86fc37d80f8e00fcec (patch)
treeafeb9c510043591e364126c8113694bd3dcc004f
parentUse non-blocking send in GNU TLS push callback. (diff)
downloadvmime-9cad1aa646f602b5ddbb3d86fc37d80f8e00fcec.tar.gz
vmime-9cad1aa646f602b5ddbb3d86fc37d80f8e00fcec.zip
Return more details about the certificate.
-rw-r--r--src/vmime/security/cert/X509Certificate.hpp13
-rw-r--r--src/vmime/security/cert/gnutls/X509Certificate_GnuTLS.cpp43
-rw-r--r--src/vmime/security/cert/gnutls/X509Certificate_GnuTLS.hpp5
-rw-r--r--src/vmime/security/cert/openssl/X509Certificate_OpenSSL.cpp25
-rw-r--r--src/vmime/security/cert/openssl/X509Certificate_OpenSSL.hpp5
5 files changed, 85 insertions, 6 deletions
diff --git a/src/vmime/security/cert/X509Certificate.hpp b/src/vmime/security/cert/X509Certificate.hpp
index 215a86cf..90e26d1f 100644
--- a/src/vmime/security/cert/X509Certificate.hpp
+++ b/src/vmime/security/cert/X509Certificate.hpp
@@ -101,6 +101,13 @@ public:
*/
virtual const byteArray getSerialNumber() const = 0;
+ /** Returns the distinguished name of the issuer of this certificate.
+ * Eg. "C=US,O=VeriSign\, Inc.,OU=Class 1 Public Primary Certification Authority"
+ *
+ * @return distinguished name of the certificate issuer, as a string
+ */
+ const string getIssuerString() const;
+
/** Checks if this certificate has the given issuer.
*
* @param issuer certificate of a possible issuer
@@ -119,9 +126,13 @@ public:
/** Verify certificate's subject name against the given hostname.
*
* @param hostname DNS name of the server
+ * @param nonMatchingNames if not NULL, will contain the names that do
+ * not match the identities in the certificate
* @return true if the match is successful, false otherwise
*/
- virtual bool verifyHostName(const string& hostname) const = 0;
+ virtual bool verifyHostName
+ (const string& hostname,
+ std::vector <std::string>* nonMatchingNames = NULL) const = 0;
/** Gets the expiration date of this certificate. This is the date
* at which this certificate will not be valid anymore.
diff --git a/src/vmime/security/cert/gnutls/X509Certificate_GnuTLS.cpp b/src/vmime/security/cert/gnutls/X509Certificate_GnuTLS.cpp
index f96ddddb..9e32b3dd 100644
--- a/src/vmime/security/cert/gnutls/X509Certificate_GnuTLS.cpp
+++ b/src/vmime/security/cert/gnutls/X509Certificate_GnuTLS.cpp
@@ -187,9 +187,36 @@ bool X509Certificate_GnuTLS::verify(shared_ptr <const X509Certificate> caCert_)
}
-bool X509Certificate_GnuTLS::verifyHostName(const string& hostname) const
+bool X509Certificate_GnuTLS::verifyHostName
+ (const string& hostname, std::vector <std::string>* nonMatchingNames) const
{
- return gnutls_x509_crt_check_hostname(m_data->cert, hostname.c_str()) != 0;
+ if (gnutls_x509_crt_check_hostname(m_data->cert, hostname.c_str()) != 0)
+ return true;
+
+ if (nonMatchingNames)
+ {
+ const int MAX_CN = 256;
+ const char* OID_X520_COMMON_NAME = "2.5.4.3";
+
+ char dnsName[MAX_CN];
+ size_t dnsNameLength;
+
+ dnsNameLength = sizeof(dnsName);
+
+ if (gnutls_x509_crt_get_dn_by_oid(m_data->cert, OID_X520_COMMON_NAME, 0, 0, dnsName, &dnsNameLength) >= 0)
+ nonMatchingNames->push_back(dnsName);
+
+ for (int i = 0, ret = 0 ; ret >= 0 ; ++i)
+ {
+ dnsNameLength = sizeof(dnsName);
+ ret = gnutls_x509_crt_get_subject_alt_name(m_data->cert, i, dnsName, &dnsNameLength, NULL);
+
+ if (ret == GNUTLS_SAN_DNSNAME)
+ nonMatchingNames->push_back(dnsName);
+ }
+ }
+
+ return false;
}
@@ -255,6 +282,18 @@ const byteArray X509Certificate_GnuTLS::getEncoded() const
}
+const string X509Certificate_GnuTLS::getIssuerString() const
+{
+ char buffer[4096];
+ size_t bufferSize = sizeof(buffer);
+
+ if (gnutls_x509_crt_get_issuer_dn(m_data->cert, buffer, &bufferSize) != GNUTLS_E_SUCCESS)
+ return "";
+
+ return buffer;
+}
+
+
const string X509Certificate_GnuTLS::getType() const
{
return "X.509";
diff --git a/src/vmime/security/cert/gnutls/X509Certificate_GnuTLS.hpp b/src/vmime/security/cert/gnutls/X509Certificate_GnuTLS.hpp
index 76ee6d4d..d7d72338 100644
--- a/src/vmime/security/cert/gnutls/X509Certificate_GnuTLS.hpp
+++ b/src/vmime/security/cert/gnutls/X509Certificate_GnuTLS.hpp
@@ -56,11 +56,14 @@ public:
const byteArray getSerialNumber() const;
+ const string getIssuerString() const;
bool checkIssuer(shared_ptr <const X509Certificate> issuer) const;
bool verify(shared_ptr <const X509Certificate> caCert) const;
- bool verifyHostName(const string& hostname) const;
+ bool verifyHostName
+ (const string& hostname,
+ std::vector <std::string>* nonMatchingNames = NULL) const;
const datetime getExpirationDate() const;
const datetime getActivationDate() const;
diff --git a/src/vmime/security/cert/openssl/X509Certificate_OpenSSL.cpp b/src/vmime/security/cert/openssl/X509Certificate_OpenSSL.cpp
index 5f81b2bf..737bcb2e 100644
--- a/src/vmime/security/cert/openssl/X509Certificate_OpenSSL.cpp
+++ b/src/vmime/security/cert/openssl/X509Certificate_OpenSSL.cpp
@@ -362,7 +362,8 @@ bool X509Certificate_OpenSSL::cnMatch(const char* cnBuf, const char* host)
}
-bool X509Certificate_OpenSSL::verifyHostName(const string& hostname) const
+bool X509Certificate_OpenSSL::verifyHostName
+ (const string& hostname, std::vector <std::string>* nonMatchingNames) const
{
// First, check subject common name against hostname
char CNBuffer[1024];
@@ -374,6 +375,9 @@ bool X509Certificate_OpenSSL::verifyHostName(const string& hostname) const
{
if (cnMatch(CNBuffer, hostname.c_str()))
return true;
+
+ if (nonMatchingNames)
+ nonMatchingNames->push_back(CNBuffer);
}
// Now, look in subject alternative names
@@ -422,6 +426,9 @@ bool X509Certificate_OpenSSL::verifyHostName(const string& hostname) const
{
return true;
}
+
+ if (nonMatchingNames)
+ nonMatchingNames->push_back(cnf->value);
}
}
}
@@ -538,6 +545,22 @@ const byteArray X509Certificate_OpenSSL::getEncoded() const
}
+const string X509Certificate_OpenSSL::getIssuerString() const
+{
+ // Get issuer for this cert
+ BIO* out = BIO_new(BIO_s_mem());
+ X509_NAME_print_ex(out, X509_get_issuer_name(m_data->cert), 0, XN_FLAG_RFC2253);
+
+ unsigned char* issuer;
+ const int n = BIO_get_mem_data(out, &issuer);
+
+ vmime::string name(reinterpret_cast <char*>(issuer), n);
+ BIO_free(out);
+
+ return name;
+}
+
+
const string X509Certificate_OpenSSL::getType() const
{
return "X.509";
diff --git a/src/vmime/security/cert/openssl/X509Certificate_OpenSSL.hpp b/src/vmime/security/cert/openssl/X509Certificate_OpenSSL.hpp
index bddb4b6c..dbb1b03c 100644
--- a/src/vmime/security/cert/openssl/X509Certificate_OpenSSL.hpp
+++ b/src/vmime/security/cert/openssl/X509Certificate_OpenSSL.hpp
@@ -59,11 +59,14 @@ public:
const byteArray getSerialNumber() const;
+ const string getIssuerString() const;
bool checkIssuer(shared_ptr <const X509Certificate> issuer) const;
bool verify(shared_ptr <const X509Certificate> caCert) const;
- bool verifyHostName(const string& hostname) const;
+ bool verifyHostName
+ (const string& hostname,
+ std::vector <std::string>* nonMatchingNames = NULL) const;
const datetime getExpirationDate() const;
const datetime getActivationDate() const;