aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVincent Richard <[email protected]>2013-04-26 18:58:04 +0000
committerVincent Richard <[email protected]>2013-04-26 18:58:04 +0000
commit3f1c50755582b17225ad91b66baa5dc4032f9834 (patch)
treea3e38920afd149780bc47b5a7149eb38cd547495
parentFixed invalid buffer access. (diff)
downloadvmime-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--AUTHORS1
-rw-r--r--src/security/cert/openssl/X509Certificate_OpenSSL.cpp20
-rw-r--r--vmime/security/cert/openssl/X509Certificate_OpenSSL.hpp10
3 files changed, 30 insertions, 1 deletions
diff --git a/AUTHORS b/AUTHORS
index 42b43b4b..1ddeb3d4 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -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
*