Issue #36: added support for wildcard in Common Name when verifying host name (thanks to Anthony Dervish).

This commit is contained in:
Vincent Richard 2013-04-26 20:58:04 +02:00
parent d6805634d9
commit 3f1c507555
3 changed files with 30 additions and 1 deletions

View File

@ -29,6 +29,7 @@ AUTHORS file.
- Bartek Szurgot <vempirelord@wp.pl, http://baszerr.org> - Bartek Szurgot <vempirelord@wp.pl, http://baszerr.org>
- Achim Brandt <http://sourceforge.net/users/a-brandt/> - Achim Brandt <http://sourceforge.net/users/a-brandt/>
- Mehmet Bozkurt <mehmet.bozkurt78@gmail.com> (OpenSSL support, ICU support) - Mehmet Bozkurt <mehmet.bozkurt78@gmail.com> (OpenSSL support, ICU support)
- Anthony Dervish <antmd@mac.com>
Please apologize if I have forgotten someone here. ;) Send me an email Please apologize if I have forgotten someone here. ;) Send me an email
to <vincent@vmime.org> if you want your name to be listed. to <vincent@vmime.org> if you want your name to be listed.

View File

@ -344,6 +344,24 @@ bool X509Certificate_OpenSSL::verify(ref <const X509Certificate> caCert_) const
} }
// 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 bool X509Certificate_OpenSSL::verifyHostName(const string& hostname) const
{ {
// First, check subject common name against hostname // First, check subject common name against hostname
@ -354,7 +372,7 @@ bool X509Certificate_OpenSSL::verifyHostName(const string& hostname) const
if (X509_NAME_get_text_by_NID(xname, NID_commonName, CNBuffer, sizeof(CNBuffer)) != -1) if (X509_NAME_get_text_by_NID(xname, NID_commonName, CNBuffer, sizeof(CNBuffer)) != -1)
{ {
if (strcasecmp(CNBuffer, hostname.c_str()) == 0) if (cnMatch(CNBuffer, hostname.c_str()))
return true; return true;
} }

View File

@ -85,6 +85,16 @@ public:
private: private:
/** Internal utility function to test whether a hostname matches
* the specified X509 Common Name (wildcard is supported).
*
* @param cnBuf pointer to buffer holding Common Name
* @param host pointer to buffer holding host name
* @return true if the hostname matches the Common Name, or
* false otherwise
*/
static bool cnMatch(const char* cnBuf, const char* host);
/** Internal utility function to convert ASN1_TIME /** Internal utility function to convert ASN1_TIME
* structs to vmime::datetime * structs to vmime::datetime
* *