diff options
author | Vincent Richard <[email protected]> | 2013-04-26 18:58:04 +0000 |
---|---|---|
committer | Vincent Richard <[email protected]> | 2013-04-26 18:58:04 +0000 |
commit | 3f1c50755582b17225ad91b66baa5dc4032f9834 (patch) | |
tree | a3e38920afd149780bc47b5a7149eb38cd547495 | |
parent | Fixed invalid buffer access. (diff) | |
download | vmime-3f1c50755582b17225ad91b66baa5dc4032f9834.tar.gz vmime-3f1c50755582b17225ad91b66baa5dc4032f9834.zip |
Issue #36: added support for wildcard in Common Name when verifying host name (thanks to Anthony Dervish).
-rw-r--r-- | AUTHORS | 1 | ||||
-rw-r--r-- | src/security/cert/openssl/X509Certificate_OpenSSL.cpp | 20 | ||||
-rw-r--r-- | vmime/security/cert/openssl/X509Certificate_OpenSSL.hpp | 10 |
3 files changed, 30 insertions, 1 deletions
@@ -29,6 +29,7 @@ AUTHORS file. - Bartek Szurgot <[email protected], http://baszerr.org> - Achim Brandt <http://sourceforge.net/users/a-brandt/> - Mehmet Bozkurt <[email protected]> (OpenSSL support, ICU support) + - Anthony Dervish <[email protected]> Please apologize if I have forgotten someone here. ;) Send me an email to <[email protected]> if you want your name to be listed. diff --git a/src/security/cert/openssl/X509Certificate_OpenSSL.cpp b/src/security/cert/openssl/X509Certificate_OpenSSL.cpp index af38d503..056631ec 100644 --- a/src/security/cert/openssl/X509Certificate_OpenSSL.cpp +++ b/src/security/cert/openssl/X509Certificate_OpenSSL.cpp @@ -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 { // 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 (strcasecmp(CNBuffer, hostname.c_str()) == 0) + if (cnMatch(CNBuffer, hostname.c_str())) return true; } diff --git a/vmime/security/cert/openssl/X509Certificate_OpenSSL.hpp b/vmime/security/cert/openssl/X509Certificate_OpenSSL.hpp index de8ad949..60ecda08 100644 --- a/vmime/security/cert/openssl/X509Certificate_OpenSSL.hpp +++ b/vmime/security/cert/openssl/X509Certificate_OpenSSL.hpp @@ -85,6 +85,16 @@ public: 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 * structs to vmime::datetime * |