fixed GH #2603:Remove incorrect upper size limits for SSL certificates in NetSSL_Win

This commit is contained in:
Günter Obiltschnig 2019-08-16 22:02:56 +02:00
parent 1282d757dc
commit 98d9c62efa
2 changed files with 15 additions and 17 deletions

View File

@ -39,7 +39,7 @@ const std::string Context::CERT_STORE_USERDS("USERDS");
Context::Context(Usage usage, Context::Context(Usage usage,
const std::string& certNameOrPath, const std::string& certNameOrPath,
VerificationMode verMode, VerificationMode verMode,
int options, int options,
const std::string& certStore): const std::string& certStore):
@ -193,7 +193,6 @@ void Context::importCertificate()
Poco::File certFile(_certNameOrPath); Poco::File certFile(_certNameOrPath);
if (!certFile.exists()) throw Poco::FileNotFoundException(_certNameOrPath); if (!certFile.exists()) throw Poco::FileNotFoundException(_certNameOrPath);
Poco::File::FileSize size = certFile.getSize(); Poco::File::FileSize size = certFile.getSize();
if (size > 4096) throw Poco::DataFormatException("PKCS #12 certificate file too large", _certNameOrPath);
Poco::Buffer<char> buffer(static_cast<std::size_t>(size)); Poco::Buffer<char> buffer(static_cast<std::size_t>(size));
Poco::FileInputStream istr(_certNameOrPath); Poco::FileInputStream istr(_certNameOrPath);
istr.read(buffer.begin(), buffer.size()); istr.read(buffer.begin(), buffer.size());
@ -208,7 +207,7 @@ void Context::importCertificate(const char* pBuffer, std::size_t size)
SSLManager::instance().PrivateKeyPassphraseRequired.notify(&SSLManager::instance(), password); SSLManager::instance().PrivateKeyPassphraseRequired.notify(&SSLManager::instance(), password);
std::wstring wpassword; std::wstring wpassword;
Poco::UnicodeConverter::toUTF16(password, wpassword); Poco::UnicodeConverter::toUTF16(password, wpassword);
// clear UTF-8 password // clear UTF-8 password
std::fill(const_cast<char*>(password.data()), const_cast<char*>(password.data() + password.size()), 'X'); std::fill(const_cast<char*>(password.data()), const_cast<char*>(password.data() + password.size()), 'X');
@ -217,7 +216,7 @@ void Context::importCertificate(const char* pBuffer, std::size_t size)
blob.pbData = reinterpret_cast<BYTE*>(const_cast<char*>(pBuffer)); blob.pbData = reinterpret_cast<BYTE*>(const_cast<char*>(pBuffer));
HCERTSTORE hTempStore = PFXImportCertStore(&blob, wpassword.data(), PKCS12_ALLOW_OVERWRITE_KEY | PKCS12_INCLUDE_EXTENDED_PROPERTIES); HCERTSTORE hTempStore = PFXImportCertStore(&blob, wpassword.data(), PKCS12_ALLOW_OVERWRITE_KEY | PKCS12_INCLUDE_EXTENDED_PROPERTIES);
// clear UTF-16 password // clear UTF-16 password
std::fill(const_cast<wchar_t*>(wpassword.data()), const_cast<wchar_t*>(wpassword.data() + password.size()), L'X'); std::fill(const_cast<wchar_t*>(wpassword.data()), const_cast<wchar_t*>(wpassword.data() + password.size()), L'X');
@ -302,7 +301,7 @@ void Context::acquireSchannelCredentials(CredHandle& credHandle) const
if (!_extendedCertificateVerification) if (!_extendedCertificateVerification)
schannelCred.dwFlags |= SCH_CRED_NO_SERVERNAME_CHECK; schannelCred.dwFlags |= SCH_CRED_NO_SERVERNAME_CHECK;
} }
#if defined(SCH_USE_STRONG_CRYPTO) #if defined(SCH_USE_STRONG_CRYPTO)
if (_options & Context::OPT_USE_STRONG_CRYPTO) if (_options & Context::OPT_USE_STRONG_CRYPTO)
schannelCred.dwFlags |= SCH_USE_STRONG_CRYPTO; schannelCred.dwFlags |= SCH_USE_STRONG_CRYPTO;
@ -315,7 +314,7 @@ void Context::acquireSchannelCredentials(CredHandle& credHandle) const
SECURITY_STATUS status = _securityFunctions.AcquireCredentialsHandleW( SECURITY_STATUS status = _securityFunctions.AcquireCredentialsHandleW(
NULL, NULL,
UNISP_NAME_W, UNISP_NAME_W,
isForServerUse() ? SECPKG_CRED_INBOUND : SECPKG_CRED_OUTBOUND, isForServerUse() ? SECPKG_CRED_INBOUND : SECPKG_CRED_OUTBOUND,
NULL, NULL,
&schannelCred, &schannelCred,
NULL, NULL,
@ -335,7 +334,7 @@ DWORD Context::proto() const
switch (_usage) switch (_usage)
{ {
case Context::CLIENT_USE: case Context::CLIENT_USE:
return SP_PROT_SSL3_CLIENT return SP_PROT_SSL3_CLIENT
| SP_PROT_TLS1_CLIENT | SP_PROT_TLS1_CLIENT
#if defined(SP_PROT_TLS1_1) #if defined(SP_PROT_TLS1_1)
| SP_PROT_TLS1_1_CLIENT | SP_PROT_TLS1_1_CLIENT
@ -345,7 +344,7 @@ DWORD Context::proto() const
#endif #endif
; ;
case Context::SERVER_USE: case Context::SERVER_USE:
return SP_PROT_SSL3_SERVER return SP_PROT_SSL3_SERVER
| SP_PROT_TLS1_SERVER | SP_PROT_TLS1_SERVER
#if defined(SP_PROT_TLS1_1) #if defined(SP_PROT_TLS1_1)
| SP_PROT_TLS1_1_SERVER | SP_PROT_TLS1_1_SERVER

View File

@ -79,7 +79,7 @@ X509Certificate::X509Certificate(PCCERT_CONTEXT pCert, bool shared):
_pCert(pCert) _pCert(pCert)
{ {
poco_check_ptr(_pCert); poco_check_ptr(_pCert);
if (shared) if (shared)
{ {
_pCert = CertDuplicateCertificateContext(_pCert); _pCert = CertDuplicateCertificateContext(_pCert);
@ -219,7 +219,7 @@ std::string X509Certificate::subjectName(NID nid) const
void X509Certificate::extractNames(std::string& cmnName, std::set<std::string>& domainNames) const void X509Certificate::extractNames(std::string& cmnName, std::set<std::string>& domainNames) const
{ {
domainNames.clear(); domainNames.clear();
cmnName = commonName(); cmnName = commonName();
PCERT_EXTENSION pExt = _pCert->pCertInfo->rgExtension; PCERT_EXTENSION pExt = _pCert->pCertInfo->rgExtension;
for (int i = 0; i < _pCert->pCertInfo->cExtension; i++, pExt++) for (int i = 0; i < _pCert->pCertInfo->cExtension; i++, pExt++)
@ -233,7 +233,7 @@ void X509Certificate::extractNames(std::string& cmnName, std::set<std::string>&
Poco::Buffer<char> buffer(256); Poco::Buffer<char> buffer(256);
DWORD bufferSize = buffer.sizeBytes(); DWORD bufferSize = buffer.sizeBytes();
BOOL rc = CryptDecodeObjectEx( BOOL rc = CryptDecodeObjectEx(
X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
pExt->pszObjId, pExt->pszObjId,
pExt->Value.pbData, pExt->Value.pbData,
pExt->Value.cbData, pExt->Value.cbData,
@ -245,7 +245,7 @@ void X509Certificate::extractNames(std::string& cmnName, std::set<std::string>&
{ {
buffer.resize(bufferSize); buffer.resize(bufferSize);
rc = CryptDecodeObjectEx( rc = CryptDecodeObjectEx(
X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
pExt->pszObjId, pExt->pszObjId,
pExt->Value.pbData, pExt->Value.pbData,
pExt->Value.cbData, pExt->Value.cbData,
@ -280,7 +280,7 @@ Poco::DateTime X509Certificate::validFrom() const
return Poco::DateTime(ts); return Poco::DateTime(ts);
} }
Poco::DateTime X509Certificate::expiresOn() const Poco::DateTime X509Certificate::expiresOn() const
{ {
Poco::Timestamp ts = Poco::Timestamp::fromFileTimeNP(_pCert->pCertInfo->NotAfter.dwLowDateTime, _pCert->pCertInfo->NotAfter.dwHighDateTime); Poco::Timestamp ts = Poco::Timestamp::fromFileTimeNP(_pCert->pCertInfo->NotAfter.dwLowDateTime, _pCert->pCertInfo->NotAfter.dwHighDateTime);
@ -383,7 +383,7 @@ void X509Certificate::loadCertificate(const std::string& certName, const std::st
cert_rdn.rgRDNAttr = &cert_rdn_attr; cert_rdn.rgRDNAttr = &cert_rdn_attr;
_pCert = CertFindCertificateInStore(hCertStore, X509_ASN_ENCODING, 0, CERT_FIND_SUBJECT_ATTR, &cert_rdn, NULL); _pCert = CertFindCertificateInStore(hCertStore, X509_ASN_ENCODING, 0, CERT_FIND_SUBJECT_ATTR, &cert_rdn, NULL);
if (!_pCert) if (!_pCert)
{ {
CertCloseStore(hCertStore, 0); CertCloseStore(hCertStore, 0);
throw NoCertificateException(Poco::format("Failed to find certificate %s in store %s", certName, certStoreName)); throw NoCertificateException(Poco::format("Failed to find certificate %s in store %s", certName, certStoreName));
@ -397,7 +397,6 @@ void X509Certificate::importCertificate(const std::string& certPath)
Poco::File certFile(certPath); Poco::File certFile(certPath);
if (!certFile.exists()) throw Poco::FileNotFoundException(certPath); if (!certFile.exists()) throw Poco::FileNotFoundException(certPath);
Poco::File::FileSize size = certFile.getSize(); Poco::File::FileSize size = certFile.getSize();
if (size > 4096) throw Poco::DataFormatException("certificate file too large", certPath);
if (size < 32) throw Poco::DataFormatException("certificate file too small", certPath); if (size < 32) throw Poco::DataFormatException("certificate file too small", certPath);
Poco::Buffer<char> buffer(static_cast<std::size_t>(size)); Poco::Buffer<char> buffer(static_cast<std::size_t>(size));
Poco::FileInputStream istr(certPath); Poco::FileInputStream istr(certPath);
@ -445,7 +444,7 @@ void X509Certificate::importPEMCertificate(const char* pBuffer, std::size_t size
char* derEnd = derBegin; char* derEnd = derBegin;
int ch = dec.get(); int ch = dec.get();
while (ch != -1) while (ch != -1)
{ {
*derEnd++ = static_cast<char>(ch); *derEnd++ = static_cast<char>(ch);
ch = dec.get(); ch = dec.get();
@ -472,7 +471,7 @@ bool X509Certificate::verify(const std::string& hostName) const
bool X509Certificate::verify(const Poco::Net::X509Certificate& certificate, const std::string& hostName) bool X509Certificate::verify(const Poco::Net::X509Certificate& certificate, const std::string& hostName)
{ {
std::string commonName; std::string commonName;
std::set<std::string> dnsNames; std::set<std::string> dnsNames;
certificate.extractNames(commonName, dnsNames); certificate.extractNames(commonName, dnsNames);