Control: tag -1 + patch Hi,
Here a patch backported from official POCO tarball, version 1.4.7 where the problem was fixed by upstream. Greetings -- Maxime Chatelle (xakz) gpg: 5111 3F15 362E 13C6 CCDE 03BE BFBA B6E3 24AE 0C5B
diff -urNad poco-1.3.6p1~/NetSSL_OpenSSL/include/Poco/Net/X509Certificate.h poco-1.3.6p1/NetSSL_OpenSSL/include/Poco/Net/X509Certificate.h --- poco-1.3.6p1~/NetSSL_OpenSSL/include/Poco/Net/X509Certificate.h 2009-12-21 19:15:02.000000000 +0100 +++ poco-1.3.6p1/NetSSL_OpenSSL/include/Poco/Net/X509Certificate.h 2014-11-07 22:09:56.519596616 +0100 @@ -102,7 +102,7 @@ protected: static bool containsWildcards(const std::string& commonName); - static bool matchByAlias(const std::string& alias, const HostEntry& heData); + static bool matchWildcard(const std::string& wildcard, const std::string& hostName); private: enum diff -urNad poco-1.3.6p1~/NetSSL_OpenSSL/src/X509Certificate.cpp poco-1.3.6p1/NetSSL_OpenSSL/src/X509Certificate.cpp --- poco-1.3.6p1~/NetSSL_OpenSSL/src/X509Certificate.cpp 2009-12-21 19:15:02.000000000 +0100 +++ poco-1.3.6p1/NetSSL_OpenSSL/src/X509Certificate.cpp 2014-11-07 22:11:30.847592322 +0100 @@ -107,51 +107,47 @@ std::string commonName; std::set<std::string> dnsNames; certificate.extractNames(commonName, dnsNames); + if (!commonName.empty()) dnsNames.insert(commonName); bool ok = (dnsNames.find(hostName) != dnsNames.end()); - - char buffer[NAME_BUFFER_SIZE]; - X509_NAME* subj = 0; - if (!ok && (subj = X509_get_subject_name(const_cast<X509*>(certificate.certificate()))) && X509_NAME_get_text_by_NID(subj, NID_commonName, buffer, sizeof(buffer)) > 0) + if (!ok) { - buffer[NAME_BUFFER_SIZE - 1] = 0; - std::string commonName(buffer); // commonName can contain wildcards like *.appinf.com - try + for (std::set<std::string>::const_iterator it = dnsNames.begin(); !ok && it != dnsNames.end(); ++it) { - // two cases: strData contains wildcards or not - if (containsWildcards(commonName)) - { - // a compare by IPAddress is not possible with wildcards - // only allow compare by name - const HostEntry& heData = DNS::resolve(hostName); - ok = matchByAlias(commonName, heData); - } - else + try { - // it depends on hostName if we compare by IP or by alias - IPAddress ip; - if (IPAddress::tryParse(hostName, ip)) + // two cases: strData contains wildcards or not + if (containsWildcards(*it)) { - // compare by IP - const HostEntry& heData = DNS::resolve(commonName); - const HostEntry::AddressList& addr = heData.addresses(); - HostEntry::AddressList::const_iterator it = addr.begin(); - HostEntry::AddressList::const_iterator itEnd = addr.end(); - for (; it != itEnd && !ok; ++it) - { - ok = (*it == ip); - } + // a compare by IPAddress is not possible with wildcards + // only allow compare by name + ok = matchWildcard(*it, hostName); } else { - // compare by name - const HostEntry& heData = DNS::resolve(hostName); - ok = matchByAlias(commonName, heData); + // it depends on hostName if we compare by IP or by alias + IPAddress ip; + if (IPAddress::tryParse(hostName, ip)) + { + // compare by IP + const HostEntry& heData = DNS::resolve(*it); + const HostEntry::AddressList& addr = heData.addresses(); + HostEntry::AddressList::const_iterator it = addr.begin(); + HostEntry::AddressList::const_iterator itEnd = addr.end(); + for (; it != itEnd && !ok; ++it) + { + ok = (*it == ip); + } + } + else + { + ok = Poco::icompare(*it, hostName) == 0; + } } } - } - catch (HostNotFoundException&) - { - return X509_V_ERR_APPLICATION_VERIFICATION; + catch (HostNotFoundException&) + { + return X509_V_ERR_APPLICATION_VERIFICATION; + } } } @@ -169,24 +165,19 @@ } -bool X509Certificate::matchByAlias(const std::string& alias, const HostEntry& heData) +bool X509Certificate::matchWildcard(const std::string& wildcard, const std::string& hostName) { // fix wildcards - std::string aliasRep = Poco::replace(alias, "*", ".*"); - Poco::replaceInPlace(aliasRep, "..*", ".*"); - Poco::replaceInPlace(aliasRep, "?", ".?"); - Poco::replaceInPlace(aliasRep, "..?", ".?"); - // compare by name - Poco::RegularExpression expr(aliasRep); - bool found = false; - const HostEntry::AliasList& aliases = heData.aliases(); - HostEntry::AliasList::const_iterator it = aliases.begin(); - HostEntry::AliasList::const_iterator itEnd = aliases.end(); - for (; it != itEnd && !found; ++it) - { - found = expr.match(*it); - } - return found; + std::string wildcardExpr("^"); + wildcardExpr += Poco::replace(wildcard, ".", "\\."); + Poco::replaceInPlace(wildcardExpr, "*", ".*"); + Poco::replaceInPlace(wildcardExpr, "..*", ".*"); + Poco::replaceInPlace(wildcardExpr, "?", ".?"); + Poco::replaceInPlace(wildcardExpr, "..?", ".?"); + wildcardExpr += "$"; + + Poco::RegularExpression expr(wildcardExpr, Poco::RegularExpression::RE_CASELESS); + return expr.match(hostName); }