diff options
author | Benoit Foucher <benoit@zeroc.com> | 2015-04-23 14:16:41 +0200 |
---|---|---|
committer | Benoit Foucher <benoit@zeroc.com> | 2015-04-23 14:16:41 +0200 |
commit | 330329321972e2e10adb04f52e9e7f95cd02ac2e (patch) | |
tree | 55a93b503a537e01765505e99f723fbf0b546bed /cpp/src/IceSSL/SChannelTransceiverI.cpp | |
parent | ICE-6433: config/makedepend.py: replace with sed? (diff) | |
download | ice-330329321972e2e10adb04f52e9e7f95cd02ac2e.tar.bz2 ice-330329321972e2e10adb04f52e9e7f95cd02ac2e.tar.xz ice-330329321972e2e10adb04f52e9e7f95cd02ac2e.zip |
Fixed ICE-6438, ICE-6439 and various inconsistencies between IceSSL implementations
Diffstat (limited to 'cpp/src/IceSSL/SChannelTransceiverI.cpp')
-rw-r--r-- | cpp/src/IceSSL/SChannelTransceiverI.cpp | 123 |
1 files changed, 65 insertions, 58 deletions
diff --git a/cpp/src/IceSSL/SChannelTransceiverI.cpp b/cpp/src/IceSSL/SChannelTransceiverI.cpp index 8f79d63df1d..74d9d840ed2 100644 --- a/cpp/src/IceSSL/SChannelTransceiverI.cpp +++ b/cpp/src/IceSSL/SChannelTransceiverI.cpp @@ -636,81 +636,85 @@ IceSSL::TransceiverI::initialize(IceInternal::Buffer& readBuffer, IceInternal::B return op; } - if(!_incoming || _engine->getVerifyPeer() > 0) + // + // Build the peer certificate chain and verify it. + // + PCCERT_CONTEXT cert = 0; + SECURITY_STATUS err = QueryContextAttributes(&_ssl, SECPKG_ATTR_REMOTE_CERT_CONTEXT, &cert); + if(err && err != SEC_E_NO_CREDENTIALS) + { + throw SecurityException(__FILE__, __LINE__, "IceSSL: certificate verification failure:" + + IceUtilInternal::lastErrorToString()); + } + + if(!cert && ((!_incoming && _engine->getVerifyPeer() > 0) || (_incoming && _engine->getVerifyPeer() == 2))) { // - // Build the peer certificate chain and verify it. + // Clients require server certificate if VerifyPeer > 0 and servers require client + // certificate if VerifyPeer == 2 // - PCCERT_CONTEXT cert = 0; - SECURITY_STATUS err = QueryContextAttributes(&_ssl, SECPKG_ATTR_REMOTE_CERT_CONTEXT, &cert); - if(err && err != SEC_E_NO_CREDENTIALS) + throw SecurityException(__FILE__, __LINE__, "IceSSL: certificate required:" + + IceUtilInternal::lastErrorToString()); + } + else if(cert) // Verify the remote certificate + { + try { - throw SecurityException(__FILE__, __LINE__, "IceSSL: certificate verification failure:" + - IceUtilInternal::lastErrorToString()); - } + CERT_CHAIN_PARA chainP; + memset(&chainP, 0, sizeof(chainP)); + chainP.cbSize = sizeof(chainP); - if(!cert && (!_incoming || _engine->getVerifyPeer() == 2)) - { - // Clients require server certificate if VerifyPeer > 0 - // and servers require client certificate if VerifyPeer == 2 - throw SecurityException(__FILE__, __LINE__, "IceSSL: certificate required:" + - IceUtilInternal::lastErrorToString()); - } - else if(cert) // Verify the remote certificate - { - try + PCCERT_CHAIN_CONTEXT certChain; + if(!CertGetCertificateChain(_engine->chainEngine(), cert, 0, 0, &chainP, + CERT_CHAIN_REVOCATION_CHECK_CACHE_ONLY, 0, &certChain)) { - CERT_CHAIN_PARA chainP; - memset(&chainP, 0, sizeof(chainP)); - chainP.cbSize = sizeof(chainP); - - PCCERT_CHAIN_CONTEXT certChain; - if(!CertGetCertificateChain(_engine->chainEngine(), cert, 0, 0, &chainP, - CERT_CHAIN_REVOCATION_CHECK_CACHE_ONLY, 0, &certChain)) - { - CertFreeCertificateContext(cert); - throw IceUtilInternal::lastErrorToString(); - } + CertFreeCertificateContext(cert); + throw IceUtilInternal::lastErrorToString(); + } - CERT_SIMPLE_CHAIN* simpleChain = certChain->rgpChain[0]; + CERT_SIMPLE_CHAIN* simpleChain = certChain->rgpChain[0]; - string trustError; - if(simpleChain->TrustStatus.dwErrorStatus != CERT_TRUST_NO_ERROR) - { - trustError = trustStatusToString(certChain->TrustStatus.dwErrorStatus); - } + string trustError; + if(simpleChain->TrustStatus.dwErrorStatus != CERT_TRUST_NO_ERROR) + { + trustError = trustStatusToString(certChain->TrustStatus.dwErrorStatus); + } + else + { + _verified = true; + } - CertFreeCertificateChain(certChain); - CertFreeCertificateContext(cert); - if(!trustError.empty()) - { - throw trustError; - } + CertFreeCertificateChain(certChain); + CertFreeCertificateContext(cert); + if(!trustError.empty()) + { + throw trustError; } - catch(const string& reason) + } + catch(const string& reason) + { + if(_engine->getVerifyPeer() == 0) { - if(_engine->getVerifyPeer() == 0) + if(_instance->traceLevel() >= 1) { - if(_instance->traceLevel() >= 1) - { - _instance->logger()->trace(_instance->traceCategory(), - "IceSSL: ignoring certificate verification failure\n" + reason); - } + _instance->logger()->trace(_instance->traceCategory(), + "IceSSL: ignoring certificate verification failure\n" + reason); } - else + } + else + { + ostringstream os; + os << "IceSSL: certificate verification failure\n" << reason; + string msg = os.str(); + if(_instance->traceLevel() >= 1) { - ostringstream os; - os << "IceSSL: certificate verification failure\n" << reason; - string msg = os.str(); - if(_instance->traceLevel() >= 1) - { - _instance->logger()->trace(_instance->traceCategory(), msg); - } - throw SecurityException(__FILE__, __LINE__, msg); + _instance->logger()->trace(_instance->traceCategory(), msg); } + throw SecurityException(__FILE__, __LINE__, msg); } } } + _engine->verifyPeer(_stream->fd(), _host, getNativeConnectionInfo()); _state = StateHandshakeComplete; @@ -971,7 +975,8 @@ IceSSL::TransceiverI::TransceiverI(const InstancePtr& instance, _state(StateHandshakeNotStarted), _bufferedW(0), _sslInitialized(false), - _credentialsInitialized(false) + _credentialsInitialized(false), + _verified(false) { } @@ -991,6 +996,8 @@ IceSSL::TransceiverI::getNativeConnectionInfo() const info->sndSize = IceInternal::getSendBufferSize(_stream->fd()); } + info->verified = _verified; + if(_sslInitialized) { CtxtHandle* ssl = const_cast<CtxtHandle*>(&_ssl); |