Return more details about the certificate.

This commit is contained in:
Vincent Richard 2014-01-09 20:25:43 +01:00
parent fa399699d5
commit 9cad1aa646
5 changed files with 85 additions and 6 deletions

View File

@ -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.

View File

@ -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";

View File

@ -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;

View File

@ -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";

View File

@ -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;