4848#include " Poco/RegularExpression.h"
4949#include < openssl/x509v3.h>
5050#include < openssl/err.h>
51+ #include < set>
5152
5253
5354using Poco::IOException;
@@ -66,6 +67,9 @@ namespace Poco {
6667namespace Net {
6768
6869
70+ static void getCertNames (X509 *, std::string& commonName, std::set<std::string>& DNSNames);
71+
72+
6973SecureSocketImpl::SecureSocketImpl ():_pBIO(0 ), _pSSL(0 )
7074{
7175}
@@ -420,43 +424,10 @@ long SecureSocketImpl::postConnectionCheck(SSLManager::ContextPtr pContext, X509
420424 return X509_V_ERR_APPLICATION_VERIFICATION ;
421425 }
422426
423- bool ok = false ;
424-
425- if ((extcount = X509_get_ext_count (cert)) > 0 )
426- {
427- for (int i = 0 ; i < extcount && !ok; ++i)
428- {
429- const char * extstr = 0 ;
430- X509_EXTENSION * ext;
431- ext = X509_get_ext (cert, i);
432- extstr = OBJ_nid2sn (OBJ_obj2nid (X509_EXTENSION_get_object (ext)));
433-
434- if (!strcmp (extstr, " subjectAltName" ))
435- {
436- X509V3_EXT_METHOD * meth = X509V3_EXT_get (ext);
437- if (!meth)
438- break ;
439-
440- #if OPENSSL_VERSION_NUMBER >= 0x00908000
441- const unsigned char * pData = ext->value ->data ;
442- const unsigned char ** ppData = &pData;
443- #else
444- unsigned char * pData = ext->value ->data ;
445- unsigned char ** ppData = &pData;
446- #endif
447- STACK_OF (CONF_VALUE )* val = meth->i2v (meth, meth->d2i (0 , ppData, ext->value ->length ), 0 );
448-
449- for (int j = 0 ; j < sk_CONF_VALUE_num (val) && !ok; ++j)
450- {
451- CONF_VALUE * nval = sk_CONF_VALUE_value (val, j);
452- if (!strcmp (nval->name , " DNS" ) && !strcmp (nval->value , host))
453- {
454- ok = true ;
455- }
456- }
457- }
458- }
459- }
427+ std::string commonName;
428+ std::set<std::string> dnsNames;
429+ getCertNames (cert, commonName, dnsNames);
430+ bool ok = (dnsNames.find (hostName) != dnsNames.end ());
460431
461432 char data[256 ];
462433 if (!ok && (subj = X509_get_subject_name (cert)) && X509_NAME_get_text_by_NID (subj, NID_commonName, data, 256 ) > 0 )
@@ -618,4 +589,48 @@ bool SecureSocketImpl::matchByAlias(const std::string& alias, const HostEntry& h
618589}
619590
620591
592+ static void
593+ getCertNames (X509 *certificate,
594+ std::string& common_name,
595+ std::set<std::string>& DNS_names)
596+ {
597+ DNS_names.clear ();
598+ common_name.clear ();
599+ if (certificate == 0 )
600+ {
601+ return ;
602+ }
603+
604+ if (STACK_OF (GENERAL_NAME ) * names = static_cast <STACK_OF (GENERAL_NAME )
605+ *>
606+ (X509_get_ext_d2i (certificate, NID_subject_alt_name, 0 , 0 )))
607+ {
608+ for (int i = 0 ; i < sk_GENERAL_NAME_num (names); ++i)
609+ {
610+ const GENERAL_NAME *name = sk_GENERAL_NAME_value (names, i);
611+ if (name->type == GEN_DNS )
612+ {
613+ const char *data = reinterpret_cast <char *>
614+ (ASN1_STRING_data (name->d .ia5 ));
615+ size_t len = ASN1_STRING_length (name->d .ia5 );
616+ DNS_names.insert (std::string (data, len));
617+ }
618+ }
619+ GENERAL_NAMES_free (names);
620+ }
621+
622+ if (X509_NAME * subj = X509_get_subject_name (certificate))
623+ {
624+ char buffer[256 ];
625+ X509_NAME_get_text_by_NID (subj, NID_commonName,
626+ buffer, sizeof buffer);
627+ common_name = std::string (buffer);
628+ if (DNS_names.empty ())
629+ {
630+ DNS_names.insert (common_name);
631+ }
632+ }
633+ }
634+
635+
621636} } // namespace Poco::Net
0 commit comments