mirror of
https://github.com/pocoproject/poco.git
synced 2025-03-25 16:13:42 +01:00
fixed cert chain verification and samples
This commit is contained in:
parent
e271b1a970
commit
f65d98f9c1
@ -78,7 +78,6 @@ HTTPSession::~HTTPSession()
|
|||||||
}
|
}
|
||||||
catch (...)
|
catch (...)
|
||||||
{
|
{
|
||||||
poco_unexpected();
|
|
||||||
}
|
}
|
||||||
delete _pException;
|
delete _pException;
|
||||||
}
|
}
|
||||||
|
@ -188,7 +188,7 @@ protected:
|
|||||||
void performServerHandshake();
|
void performServerHandshake();
|
||||||
bool serverHandshakeLoop(PCtxtHandle phContext, PCredHandle phCred, bool requireClientAuth, bool doInitialRead, bool newContext);
|
bool serverHandshakeLoop(PCtxtHandle phContext, PCredHandle phCred, bool requireClientAuth, bool doInitialRead, bool newContext);
|
||||||
void clientVerifyCertificate(const std::string& hostName);
|
void clientVerifyCertificate(const std::string& hostName);
|
||||||
void verifyCertificateChainClient(PCCERT_CONTEXT pServerCert, PCCERT_CHAIN_CONTEXT pChainContext);
|
void verifyCertificateChainClient(PCCERT_CONTEXT pServerCert);
|
||||||
void serverVerifyCertificate();
|
void serverVerifyCertificate();
|
||||||
LONG serverDisconnect(PCredHandle phCreds, CtxtHandle* phContext);
|
LONG serverDisconnect(PCredHandle phCreds, CtxtHandle* phContext);
|
||||||
LONG clientDisconnect(PCredHandle phCreds, CtxtHandle* phContext);
|
LONG clientDisconnect(PCredHandle phCreds, CtxtHandle* phContext);
|
||||||
|
@ -3,7 +3,9 @@
|
|||||||
HTTPSTimeServer.format = %W, %e %b %y %H:%M:%S %Z
|
HTTPSTimeServer.format = %W, %e %b %y %H:%M:%S %Z
|
||||||
HTTPSTimeServer.port = 9443
|
HTTPSTimeServer.port = 9443
|
||||||
|
|
||||||
schannel.server.certificateName = ${system.nodeName}
|
schannel.server.certificatePath = ${application.configDir}any.pfx
|
||||||
|
schannel.server.privateKeyPassphraseHandler.name = KeyFileHandler
|
||||||
|
schannel.server.privateKeyPassphraseHandler.options.password = secret
|
||||||
schannel.server.verificationMode = none
|
schannel.server.verificationMode = none
|
||||||
schannel.server.useMachineStore = false
|
schannel.server.useMachineStore = false
|
||||||
schannel.server.useStrongCrypto = true
|
schannel.server.useStrongCrypto = true
|
||||||
|
BIN
NetSSL_Win/samples/HTTPSTimeServer/any.pfx
Normal file
BIN
NetSSL_Win/samples/HTTPSTimeServer/any.pfx
Normal file
Binary file not shown.
@ -18,6 +18,7 @@
|
|||||||
#include "Poco/Net/StringPartSource.h"
|
#include "Poco/Net/StringPartSource.h"
|
||||||
#include "Poco/Net/SSLManager.h"
|
#include "Poco/Net/SSLManager.h"
|
||||||
#include "Poco/Net/ConsoleCertificateHandler.h"
|
#include "Poco/Net/ConsoleCertificateHandler.h"
|
||||||
|
#include "Poco/Net/PrivateKeyPassphraseHandler.h"
|
||||||
#include "Poco/SharedPtr.h"
|
#include "Poco/SharedPtr.h"
|
||||||
#include "Poco/Path.h"
|
#include "Poco/Path.h"
|
||||||
#include "Poco/Exception.h"
|
#include "Poco/Exception.h"
|
||||||
@ -83,7 +84,7 @@ int main(int argc, char** argv)
|
|||||||
// Note: we must create the passphrase handler prior Context
|
// Note: we must create the passphrase handler prior Context
|
||||||
SharedPtr<InvalidCertificateHandler> pCert = new ConsoleCertificateHandler(false); // ask the user via console
|
SharedPtr<InvalidCertificateHandler> pCert = new ConsoleCertificateHandler(false); // ask the user via console
|
||||||
Context::Ptr pContext = new Context(Context::CLIENT_USE, "");
|
Context::Ptr pContext = new Context(Context::CLIENT_USE, "");
|
||||||
SSLManager::instance().initializeClient(pCert, pContext);
|
SSLManager::instance().initializeClient(0, pCert, pContext);
|
||||||
|
|
||||||
MailMessage message;
|
MailMessage message;
|
||||||
message.setSender(sender);
|
message.setSender(sender);
|
||||||
|
@ -75,7 +75,7 @@ int main(int argc, char** argv)
|
|||||||
|
|
||||||
SharedPtr<InvalidCertificateHandler> pCertHandler = new ConsoleCertificateHandler(false); // ask the user via console
|
SharedPtr<InvalidCertificateHandler> pCertHandler = new ConsoleCertificateHandler(false); // ask the user via console
|
||||||
Context::Ptr pContext = new Context(Context::CLIENT_USE, "");
|
Context::Ptr pContext = new Context(Context::CLIENT_USE, "");
|
||||||
SSLManager::instance().initializeClient(pCertHandler, pContext);
|
SSLManager::instance().initializeClient(0, pCertHandler, pContext);
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
@ -1175,15 +1175,24 @@ void SecureSocketImpl::clientVerifyCertificate(const std::string& hostName)
|
|||||||
if (!args.getIgnoreError())
|
if (!args.getIgnoreError())
|
||||||
throw InvalidCertificateException("Host name verification failed");
|
throw InvalidCertificateException("Host name verification failed");
|
||||||
}
|
}
|
||||||
int iRc = CertVerifyTimeValidity(NULL, _pPeerCertificate->pCertInfo);
|
|
||||||
if (iRc != 0)
|
LONG rc = CertVerifyTimeValidity(0, _pPeerCertificate->pCertInfo);
|
||||||
|
if (rc != 0)
|
||||||
{
|
{
|
||||||
VerificationErrorArgs args(cert, 0, SEC_E_CERT_EXPIRED, "The certificate is expired");
|
VerificationErrorArgs args(cert, 0, SEC_E_CERT_EXPIRED, "The certificate is not yet, or no longer valid");
|
||||||
SSLManager::instance().ClientVerificationError(this, args);
|
SSLManager::instance().ClientVerificationError(this, args);
|
||||||
if (!args.getIgnoreError())
|
if (!args.getIgnoreError())
|
||||||
throw InvalidCertificateException("Expired certificate");
|
throw InvalidCertificateException("Expired certificate");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
verifyCertificateChainClient(_pPeerCertificate);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void SecureSocketImpl::verifyCertificateChainClient(PCCERT_CONTEXT pServerCert)
|
||||||
|
{
|
||||||
|
X509Certificate cert(pServerCert, true);
|
||||||
|
|
||||||
CERT_CHAIN_PARA chainPara;
|
CERT_CHAIN_PARA chainPara;
|
||||||
PCCERT_CHAIN_CONTEXT pChainContext = NULL;
|
PCCERT_CHAIN_CONTEXT pChainContext = NULL;
|
||||||
std::memset(&chainPara, 0, sizeof(chainPara));
|
std::memset(&chainPara, 0, sizeof(chainPara));
|
||||||
@ -1199,24 +1208,15 @@ void SecureSocketImpl::clientVerifyCertificate(const std::string& hostName)
|
|||||||
NULL,
|
NULL,
|
||||||
&pChainContext))
|
&pChainContext))
|
||||||
{
|
{
|
||||||
CertFreeCertificateChain(pChainContext);
|
throw SSLException("Cannot get certificate chain", GetLastError());
|
||||||
throw SSLException("Failed to get certificate chain", GetLastError());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
verifyCertificateChainClient(_pPeerCertificate, pChainContext);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void SecureSocketImpl::verifyCertificateChainClient(PCCERT_CONTEXT pServerCert, PCCERT_CHAIN_CONTEXT pChainContext)
|
|
||||||
{
|
|
||||||
X509Certificate cert(pServerCert, true);
|
|
||||||
|
|
||||||
HTTPSPolicyCallbackData polHttps;
|
HTTPSPolicyCallbackData polHttps;
|
||||||
std::memset(&polHttps, 0, sizeof(HTTPSPolicyCallbackData));
|
std::memset(&polHttps, 0, sizeof(HTTPSPolicyCallbackData));
|
||||||
polHttps.cbStruct = sizeof(HTTPSPolicyCallbackData);
|
polHttps.cbStruct = sizeof(HTTPSPolicyCallbackData);
|
||||||
polHttps.dwAuthType = AUTHTYPE_SERVER;
|
polHttps.dwAuthType = AUTHTYPE_SERVER;
|
||||||
polHttps.fdwChecks = SECURITY_FLAG_IGNORE_UNKNOWN_CA; // we do our own CA verification!
|
polHttps.fdwChecks = SECURITY_FLAG_IGNORE_UNKNOWN_CA; // we do our own check later on
|
||||||
polHttps.pwszServerName = 0;// not supported on Win98, ME! but ignored on client side anyway
|
polHttps.pwszServerName = 0;
|
||||||
|
|
||||||
CERT_CHAIN_POLICY_PARA polPara;
|
CERT_CHAIN_POLICY_PARA polPara;
|
||||||
std::memset(&polPara, 0, sizeof(polPara));
|
std::memset(&polPara, 0, sizeof(polPara));
|
||||||
@ -1238,12 +1238,11 @@ void SecureSocketImpl::verifyCertificateChainClient(PCCERT_CONTEXT pServerCert,
|
|||||||
if (!args.getIgnoreError())
|
if (!args.getIgnoreError())
|
||||||
{
|
{
|
||||||
CertFreeCertificateChain(pChainContext);
|
CertFreeCertificateChain(pChainContext);
|
||||||
throw SSLException("Failed to verify certificate chain");
|
throw SSLException("Cannot verify certificate chain");
|
||||||
}
|
}
|
||||||
else return;
|
else return;
|
||||||
}
|
}
|
||||||
|
else if (polStatus.dwError)
|
||||||
if (polStatus.dwError)
|
|
||||||
{
|
{
|
||||||
VerificationErrorArgs args(cert, polStatus.lElementIndex, polStatus.dwError, Utility::formatError(polStatus.dwError));
|
VerificationErrorArgs args(cert, polStatus.lElementIndex, polStatus.dwError, Utility::formatError(polStatus.dwError));
|
||||||
SSLManager::instance().ClientVerificationError(this, args);
|
SSLManager::instance().ClientVerificationError(this, args);
|
||||||
@ -1257,13 +1256,15 @@ void SecureSocketImpl::verifyCertificateChainClient(PCCERT_CONTEXT pServerCert,
|
|||||||
|
|
||||||
// now verify CA's
|
// now verify CA's
|
||||||
HCERTSTORE trustedCerts = _pContext->certificateStore();
|
HCERTSTORE trustedCerts = _pContext->certificateStore();
|
||||||
Poco::Buffer<PCERT_CONTEXT> certs(pChainContext->cChain);
|
|
||||||
for (DWORD i = 0; i < pChainContext->cChain; i++)
|
for (DWORD i = 0; i < pChainContext->cChain; i++)
|
||||||
{
|
{
|
||||||
certs[i] = (PCERT_CONTEXT)(pChainContext->rgpChain[i]->rgpElement[0]->pCertContext);
|
std::vector<PCCERT_CONTEXT> certs;
|
||||||
// each issuer of the pCert must be a member of the trustedCerts store
|
for (DWORD k = 0; k < pChainContext->rgpChain[i]->cElement; k++)
|
||||||
PCCERT_CONTEXT pResult = CertFindCertificateInStore(trustedCerts, certs[i]->dwCertEncodingType, 0, CERT_FIND_ISSUER_OF, certs[i], 0);
|
{
|
||||||
|
certs.push_back(pChainContext->rgpChain[i]->rgpElement[k]->pCertContext);
|
||||||
|
}
|
||||||
|
// verify that the root of the chain can be found in the trusted store
|
||||||
|
PCCERT_CONTEXT pResult = CertFindCertificateInStore(trustedCerts, certs.back()->dwCertEncodingType, 0, CERT_FIND_ISSUER_OF, certs.back(), 0);
|
||||||
if (!pResult)
|
if (!pResult)
|
||||||
{
|
{
|
||||||
poco_assert_dbg (GetLastError() == CRYPT_E_NOT_FOUND);
|
poco_assert_dbg (GetLastError() == CRYPT_E_NOT_FOUND);
|
||||||
@ -1276,34 +1277,36 @@ void SecureSocketImpl::verifyCertificateChainClient(PCCERT_CONTEXT pServerCert,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
CertFreeCertificateContext(pResult);
|
CertFreeCertificateContext(pResult);
|
||||||
}
|
|
||||||
|
|
||||||
#if !defined(_WIN32_WCE)
|
#if !defined(_WIN32_WCE)
|
||||||
// check if cert is revoked
|
// check if cert is revoked
|
||||||
if (_pContext->options() & Context::OPT_PERFORM_REVOCATION_CHECK)
|
if (_pContext->options() & Context::OPT_PERFORM_REVOCATION_CHECK)
|
||||||
{
|
|
||||||
CERT_REVOCATION_STATUS revStat;
|
|
||||||
revStat.cbSize = sizeof(CERT_REVOCATION_STATUS);
|
|
||||||
|
|
||||||
PCERT_CONTEXT* pCerts = certs.begin();
|
|
||||||
BOOL rc = CertVerifyRevocation(
|
|
||||||
X509_ASN_ENCODING,
|
|
||||||
CERT_CONTEXT_REVOCATION_TYPE,
|
|
||||||
pChainContext->cChain,
|
|
||||||
(void **)pCerts,
|
|
||||||
CERT_VERIFY_REV_CHAIN_FLAG,
|
|
||||||
NULL,
|
|
||||||
&revStat);
|
|
||||||
|
|
||||||
if (!rc)
|
|
||||||
{
|
{
|
||||||
VerificationErrorArgs args(cert, revStat.dwIndex, revStat.dwReason, Utility::formatError(revStat.dwError));
|
CERT_REVOCATION_STATUS revStat;
|
||||||
SSLManager::instance().ClientVerificationError(this, args);
|
revStat.cbSize = sizeof(CERT_REVOCATION_STATUS);
|
||||||
if (!args.getIgnoreError())
|
|
||||||
|
BOOL ok = CertVerifyRevocation(
|
||||||
|
X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
|
||||||
|
CERT_CONTEXT_REVOCATION_TYPE,
|
||||||
|
certs.size(),
|
||||||
|
(void**) &certs[0],
|
||||||
|
CERT_VERIFY_REV_CHAIN_FLAG,
|
||||||
|
NULL,
|
||||||
|
&revStat);
|
||||||
|
|
||||||
|
// Revocation check of the root certificate may fail due to missing CRL points, etc.
|
||||||
|
// We ignore all errors checking the root certificate except CRYPT_E_REVOKED.
|
||||||
|
if (!ok && (revStat.dwIndex < certs.size() - 1 || revStat.dwError == CRYPT_E_REVOKED))
|
||||||
{
|
{
|
||||||
CertFreeCertificateChain(pChainContext);
|
VerificationErrorArgs args(cert, revStat.dwIndex, revStat.dwReason, Utility::formatError(revStat.dwError));
|
||||||
throw SSLException("Failed to verify revoked certificate chain");
|
SSLManager::instance().ClientVerificationError(this, args);
|
||||||
|
if (!args.getIgnoreError())
|
||||||
|
{
|
||||||
|
CertFreeCertificateChain(pChainContext);
|
||||||
|
throw SSLException("Failed to verify revoked certificate chain");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
else break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -1321,10 +1324,10 @@ void SecureSocketImpl::serverVerifyCertificate()
|
|||||||
DWORD status = SEC_E_OK;
|
DWORD status = SEC_E_OK;
|
||||||
X509Certificate cert(_pPeerCertificate, true);
|
X509Certificate cert(_pPeerCertificate, true);
|
||||||
|
|
||||||
int iRc = CertVerifyTimeValidity(NULL, _pPeerCertificate->pCertInfo);
|
LONG rc = CertVerifyTimeValidity(0, _pPeerCertificate->pCertInfo);
|
||||||
if (iRc != 0)
|
if (rc != 0)
|
||||||
{
|
{
|
||||||
VerificationErrorArgs args(cert, 0, SEC_E_CERT_EXPIRED, "The certificate is expired");
|
VerificationErrorArgs args(cert, 0, SEC_E_CERT_EXPIRED, "The certificate is not yet, or no longer valid");
|
||||||
SSLManager::instance().ServerVerificationError(this, args);
|
SSLManager::instance().ServerVerificationError(this, args);
|
||||||
|
|
||||||
if (!args.getIgnoreError())
|
if (!args.getIgnoreError())
|
||||||
@ -1348,14 +1351,7 @@ void SecureSocketImpl::serverVerifyCertificate()
|
|||||||
NULL,
|
NULL,
|
||||||
&pChainContext))
|
&pChainContext))
|
||||||
{
|
{
|
||||||
VerificationErrorArgs args(cert, 0, GetLastError(), "The certificate chain is expired");
|
throw SSLException("Cannot get certificate chain", GetLastError());
|
||||||
SSLManager::instance().ServerVerificationError(this, args);
|
|
||||||
if (pChainContext) CertFreeCertificateChain(pChainContext);
|
|
||||||
if (!args.getIgnoreError())
|
|
||||||
{
|
|
||||||
throw SSLException("The certificate chain is expired");
|
|
||||||
}
|
|
||||||
else return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
HTTPSPolicyCallbackData polHttps;
|
HTTPSPolicyCallbackData polHttps;
|
||||||
@ -1363,7 +1359,7 @@ void SecureSocketImpl::serverVerifyCertificate()
|
|||||||
polHttps.cbStruct = sizeof(HTTPSPolicyCallbackData);
|
polHttps.cbStruct = sizeof(HTTPSPolicyCallbackData);
|
||||||
polHttps.dwAuthType = AUTHTYPE_CLIENT;
|
polHttps.dwAuthType = AUTHTYPE_CLIENT;
|
||||||
polHttps.fdwChecks = 0;
|
polHttps.fdwChecks = 0;
|
||||||
polHttps.pwszServerName = NULL;
|
polHttps.pwszServerName = 0;
|
||||||
|
|
||||||
CERT_CHAIN_POLICY_PARA policyPara;
|
CERT_CHAIN_POLICY_PARA policyPara;
|
||||||
std::memset(&policyPara, 0, sizeof(policyPara));
|
std::memset(&policyPara, 0, sizeof(policyPara));
|
||||||
@ -1378,18 +1374,17 @@ void SecureSocketImpl::serverVerifyCertificate()
|
|||||||
{
|
{
|
||||||
VerificationErrorArgs args(cert, 0, GetLastError(), "Failed to verify certificate chain");
|
VerificationErrorArgs args(cert, 0, GetLastError(), "Failed to verify certificate chain");
|
||||||
SSLManager::instance().ServerVerificationError(this, args);
|
SSLManager::instance().ServerVerificationError(this, args);
|
||||||
if (pChainContext) CertFreeCertificateChain(pChainContext);
|
CertFreeCertificateChain(pChainContext);
|
||||||
if (!args.getIgnoreError())
|
if (!args.getIgnoreError())
|
||||||
throw SSLException("Failed to verify certificate chain");
|
throw SSLException("Cannot verify certificate chain");
|
||||||
else
|
else
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
else if (policyStatus.dwError)
|
||||||
if (policyStatus.dwError)
|
|
||||||
{
|
{
|
||||||
VerificationErrorArgs args(cert, policyStatus.lElementIndex, status, Utility::formatError(policyStatus.dwError));
|
VerificationErrorArgs args(cert, policyStatus.lElementIndex, status, Utility::formatError(policyStatus.dwError));
|
||||||
SSLManager::instance().ServerVerificationError(this, args);
|
SSLManager::instance().ServerVerificationError(this, args);
|
||||||
if (pChainContext) CertFreeCertificateChain(pChainContext);
|
CertFreeCertificateChain(pChainContext);
|
||||||
if (!args.getIgnoreError())
|
if (!args.getIgnoreError())
|
||||||
throw SSLException("Failed to verify certificate chain");
|
throw SSLException("Failed to verify certificate chain");
|
||||||
else
|
else
|
||||||
@ -1397,36 +1392,37 @@ void SecureSocketImpl::serverVerifyCertificate()
|
|||||||
}
|
}
|
||||||
|
|
||||||
#if !defined(_WIN32_WCE)
|
#if !defined(_WIN32_WCE)
|
||||||
PCERT_CONTEXT *pCerts = new PCERT_CONTEXT[pChainContext->cChain];
|
// perform revocation checking
|
||||||
for (DWORD i = 0; i < pChainContext->cChain; i++)
|
for (DWORD i = 0; i < pChainContext->cChain; i++)
|
||||||
{
|
{
|
||||||
pCerts[i] = (PCERT_CONTEXT)(pChainContext->rgpChain[i]->rgpElement[0]->pCertContext);
|
std::vector<PCCERT_CONTEXT> certs;
|
||||||
}
|
for (DWORD k = 0; k < pChainContext->rgpChain[i]->cElement; k++)
|
||||||
|
|
||||||
CERT_REVOCATION_STATUS revStat;
|
|
||||||
revStat.cbSize = sizeof(CERT_REVOCATION_STATUS);
|
|
||||||
|
|
||||||
BOOL bRc = CertVerifyRevocation(
|
|
||||||
X509_ASN_ENCODING,
|
|
||||||
CERT_CONTEXT_REVOCATION_TYPE,
|
|
||||||
pChainContext->cChain,
|
|
||||||
(void **)pCerts,
|
|
||||||
CERT_VERIFY_REV_CHAIN_FLAG,
|
|
||||||
NULL,
|
|
||||||
&revStat);
|
|
||||||
if (!bRc)
|
|
||||||
{
|
|
||||||
VerificationErrorArgs args(cert, revStat.dwIndex, revStat.dwReason, Utility::formatError(revStat.dwReason));
|
|
||||||
SSLManager::instance().ServerVerificationError(this, args);
|
|
||||||
if (!args.getIgnoreError())
|
|
||||||
{
|
{
|
||||||
CertFreeCertificateChain(pChainContext);
|
certs.push_back(pChainContext->rgpChain[i]->rgpElement[k]->pCertContext);
|
||||||
delete [] pCerts;
|
}
|
||||||
throw SSLException("Failed to verify certificate chain");
|
|
||||||
|
CERT_REVOCATION_STATUS revStat;
|
||||||
|
revStat.cbSize = sizeof(CERT_REVOCATION_STATUS);
|
||||||
|
|
||||||
|
BOOL ok = CertVerifyRevocation(
|
||||||
|
X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
|
||||||
|
CERT_CONTEXT_REVOCATION_TYPE,
|
||||||
|
certs.size(),
|
||||||
|
(void**) &certs[0],
|
||||||
|
CERT_VERIFY_REV_CHAIN_FLAG,
|
||||||
|
NULL,
|
||||||
|
&revStat);
|
||||||
|
if (!ok && (revStat.dwIndex < certs.size() - 1 || revStat.dwError == CRYPT_E_REVOKED))
|
||||||
|
{
|
||||||
|
VerificationErrorArgs args(cert, revStat.dwIndex, revStat.dwReason, Utility::formatError(revStat.dwReason));
|
||||||
|
SSLManager::instance().ServerVerificationError(this, args);
|
||||||
|
if (!args.getIgnoreError())
|
||||||
|
{
|
||||||
|
CertFreeCertificateChain(pChainContext);
|
||||||
|
throw SSLException("Failed to verify certificate chain");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
delete [] pCerts;
|
|
||||||
#endif
|
#endif
|
||||||
if (pChainContext)
|
if (pChainContext)
|
||||||
{
|
{
|
||||||
@ -1439,8 +1435,6 @@ LONG SecureSocketImpl::clientDisconnect(PCredHandle phCreds, CtxtHandle* phConte
|
|||||||
{
|
{
|
||||||
if (phContext->dwLower == 0 && phContext->dwUpper == 0)
|
if (phContext->dwLower == 0 && phContext->dwUpper == 0)
|
||||||
{
|
{
|
||||||
// handshake has never been done
|
|
||||||
poco_assert_dbg (_needHandshake);
|
|
||||||
return SEC_E_OK;
|
return SEC_E_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user