diff options
Diffstat (limited to 'cpp')
-rw-r--r-- | cpp/src/Ice/msbuild/iceuwp++11/iceuwp++11.vcxproj.filters | 9 | ||||
-rwxr-xr-x | cpp/src/IceSSL/Certificate.cpp | 94 | ||||
-rw-r--r-- | cpp/src/IceSSL/SSLEngine.cpp | 24 | ||||
-rw-r--r-- | cpp/src/IceSSL/SSLEngine.h | 18 | ||||
-rwxr-xr-x | cpp/src/IceSSL/Util.cpp | 135 | ||||
-rw-r--r-- | cpp/src/IceSSL/Util.h | 3 | ||||
-rwxr-xr-x | cpp/src/IceSSL/WinRTEngine.cpp | 37 | ||||
-rwxr-xr-x | cpp/src/IceSSL/WinRTTransceiverI.cpp | 182 | ||||
-rwxr-xr-x | cpp/src/IceSSL/WinRTTransceiverI.h | 2 | ||||
-rw-r--r-- | cpp/src/IceSSL/msbuild/icessluwp++11/icessluwp++11.vcxproj | 4 | ||||
-rw-r--r-- | cpp/src/IceSSL/msbuild/icessluwp++11/icessluwp++11.vcxproj.filters | 16 |
11 files changed, 479 insertions, 45 deletions
diff --git a/cpp/src/Ice/msbuild/iceuwp++11/iceuwp++11.vcxproj.filters b/cpp/src/Ice/msbuild/iceuwp++11/iceuwp++11.vcxproj.filters index 5a48cd6767d..84cf9cc5098 100644 --- a/cpp/src/Ice/msbuild/iceuwp++11/iceuwp++11.vcxproj.filters +++ b/cpp/src/Ice/msbuild/iceuwp++11/iceuwp++11.vcxproj.filters @@ -1087,7 +1087,6 @@ <ClCompile Include="..\..\Timer.cpp"> <Filter>Source Files</Filter> </ClCompile> - <ClCompile Include="..\..\TcpEndpointI.cpp" /> <ClCompile Include="..\..\TcpAcceptor.cpp"> <Filter>Source Files</Filter> </ClCompile> @@ -1100,6 +1099,12 @@ <ClCompile Include="..\..\StreamSocket.cpp"> <Filter>Source Files</Filter> </ClCompile> + <ClCompile Include="..\..\TcpEndpointI.cpp"> + <Filter>Source Files</Filter> + </ClCompile> + <ClCompile Include="..\..\WindowsStringConverter.cpp"> + <Filter>Source Files</Filter> + </ClCompile> </ItemGroup> <ItemGroup> <IceBuilder Include="..\..\..\..\..\slice\Ice\BuiltinSequences.ice"> @@ -1924,4 +1929,4 @@ <Filter>Header Files\x64\Release</Filter> </ClInclude> </ItemGroup> -</Project> +</Project>
\ No newline at end of file diff --git a/cpp/src/IceSSL/Certificate.cpp b/cpp/src/IceSSL/Certificate.cpp index 8ecfd8c0dc0..3f4eb05bed9 100755 --- a/cpp/src/IceSSL/Certificate.cpp +++ b/cpp/src/IceSSL/Certificate.cpp @@ -28,6 +28,9 @@ # pragma GCC diagnostic ignored "-Wold-style-cast" #elif defined(ICE_USE_SECURE_TRANSPORT) # include <Security/Security.h> +#elif defined(ICE_OS_WINRT) +# include <ppltasks.h> +# include <nserror.h> #endif #ifdef __SUNPRO_CC @@ -49,6 +52,15 @@ using namespace std; using namespace Ice; using namespace IceSSL; +#ifdef ICE_OS_WINRT +using namespace concurrency; +using namespace Platform; +using namespace Windows::Foundation; +using namespace Windows::Storage; +using namespace Windows::Storage::Streams; +using namespace Windows::Security::Cryptography; +#endif + #if defined(ICE_USE_SECURE_TRANSPORT) || defined(ICE_USE_SCHANNEL) // @@ -599,19 +611,19 @@ vector<pair<int, string> > certificateAltNames(Windows::Security::Cryptography::Certificates::SubjectAlternativeNameInfo^ subAltNames) { vector<pair<int, string> > altNames; - for (auto iter = subAltNames->EmailName->First(); iter->HasCurrent; iter->MoveNext()) + for(auto iter = subAltNames->EmailName->First(); iter->HasCurrent; iter->MoveNext()) { altNames.push_back(make_pair(AltNameEmail, wstringToString(iter->Current->Data()))); } - for (auto iter = subAltNames->DnsName->First(); iter->HasCurrent; iter->MoveNext()) + for(auto iter = subAltNames->DnsName->First(); iter->HasCurrent; iter->MoveNext()) { altNames.push_back(make_pair(AltNameDNS, wstringToString(iter->Current->Data()))); } - for (auto iter = subAltNames->Url->First(); iter->HasCurrent; iter->MoveNext()) + for(auto iter = subAltNames->Url->First(); iter->HasCurrent; iter->MoveNext()) { altNames.push_back(make_pair(AltNameURL, wstringToString(iter->Current->Data()))); } - for (auto iter = subAltNames->IPAddress->First(); iter->HasCurrent; iter->MoveNext()) + for(auto iter = subAltNames->IPAddress->First(); iter->HasCurrent; iter->MoveNext()) { altNames.push_back(make_pair(AltNAmeIP, wstringToString(iter->Current->Data()))); } @@ -1035,7 +1047,7 @@ Certificate::Certificate(X509CertificateRef cert) : _cert(cert) throw IceUtil::IllegalArgumentException(__FILE__, __LINE__, "Invalid certificate reference"); } -#ifdef ICE_USE_SCHANNEL +#if defined(ICE_USE_SCHANNEL) _certInfo = 0; try { @@ -1055,9 +1067,7 @@ Certificate::Certificate(X509CertificateRef cert) : _cert(cert) _cert = 0; throw; } -#endif - -#if defined(ICE_USE_SECURE_TRANSPORT_IOS) +#elif defined(ICE_USE_SECURE_TRANSPORT_IOS) _subject = NULL; _issuer = NULL; #endif @@ -1125,8 +1135,39 @@ Certificate::load(const string& file) BIO_free(cert); return ICE_MAKE_SHARED(Certificate, x); #elif defined(ICE_OS_WINRT) - // TODO - return ICE_NULLPTR; + promise<shared_ptr<Certificate>> result; + create_task(StorageFile::GetFileFromApplicationUriAsync( + ref new Uri(ref new String(stringToWstring(file).c_str())))).then([](StorageFile^ file) + { + return FileIO::ReadBufferAsync(file); + }, + task_continuation_context::use_arbitrary()).then([&result, &file](task<IBuffer^> previous) + { + try + { + result.set_value(make_shared<Certificate>(ref new Certificates::Certificate(previous.get()))); + } + catch(Platform::Exception^ ex) + { + try + { + if(HRESULT_CODE(ex->HResult) == ERROR_FILE_NOT_FOUND) + { + throw CertificateReadException(__FILE__, __LINE__, "certificate file not found:\n" + file); + } + else + { + throw Ice::SyscallException(__FILE__, __LINE__, ex->HResult); + } + } + catch(...) + { + result.set_exception(current_exception()); + } + } + }, + task_continuation_context::use_arbitrary()); + return result.get_future().get(); #else # error "Unknown platform" #endif @@ -1198,8 +1239,25 @@ Certificate::decode(const string& encoding) BIO_free(cert); return ICE_MAKE_SHARED(Certificate, x); #elif defined(ICE_OS_WINRT) - // TODO - return ICE_NULLPTR; + string::size_type size, startpos, endpos = 0; + startpos = encoding.find("-----BEGIN CERTIFICATE-----", endpos); + if (startpos != string::npos) + { + startpos += sizeof("-----BEGIN CERTIFICATE-----"); + endpos = encoding.find("-----END CERTIFICATE-----", startpos); + size = endpos - startpos; + } + else + { + startpos = 0; + endpos = string::npos; + size = encoding.size(); + } + + vector<unsigned char> data(IceInternal::Base64::decode(string(&encoding[startpos], size))); + auto writer = ref new DataWriter(); + writer->WriteBytes(Platform::ArrayReference<unsigned char>(&data[0], data.size())); + return make_shared<Certificate>(ref new Certificates::Certificate(writer->DetachBuffer())); #else # error "Unknown platform" #endif @@ -1461,7 +1519,7 @@ Certificate::encode() const #elif defined(ICE_OS_WINRT) auto reader = Windows::Storage::Streams::DataReader::FromBuffer(_cert->GetCertificateBlob()); std::vector<unsigned char> data(reader->UnconsumedBufferLength); - if (!data.empty()) + if(!data.empty()) { reader->ReadBytes(Platform::ArrayReference<unsigned char>(&data[0], static_cast<unsigned int>(data.size()))); } @@ -1646,9 +1704,9 @@ Certificate::getSubjectDN() const } else { - string s = "CN="; - s += fromCFString(UniqueRef<CFStringRef>(SecCertificateCopySubjectSummary(_cert)).get()); - return DistinguishedName(s); + ostringstream os; + os << "CN=" << fromCFString(UniqueRef<CFStringRef>(SecCertificateCopySubjectSummary(_cert)).get()); + return DistinguishedName(os.str()); } #elif defined(ICE_USE_SECURE_TRANSPORT_MACOS) return getX509Name(_cert, kSecOIDX509V1SubjectName); @@ -1657,7 +1715,9 @@ Certificate::getSubjectDN() const #elif defined(ICE_USE_OPENSSL) return DistinguishedName(RFC2253::parseStrict(convertX509NameToString(X509_get_subject_name(_cert)))); #elif defined(ICE_OS_WINRT) - return DistinguishedName(wstringToString(_cert->Subject->Data())); + ostringstream os; + os << "CN=" << wstringToString(_cert->Subject->Data()); + return DistinguishedName(os.str()); #else # error "Unknown platform" #endif diff --git a/cpp/src/IceSSL/SSLEngine.cpp b/cpp/src/IceSSL/SSLEngine.cpp index ed286df2b5b..4f8f927495f 100644 --- a/cpp/src/IceSSL/SSLEngine.cpp +++ b/cpp/src/IceSSL/SSLEngine.cpp @@ -291,3 +291,27 @@ IceSSL::SSLEngine::verifyPeer(const string& address, const NativeConnectionInfoP throw ex; } } + +bool +IceSSL::SSLEngine::getCheckCertName() const +{ + return _checkCertName; +} + +int +IceSSL::SSLEngine::getVerifyPeer() const +{ + return _verifyPeer; +} + +int +IceSSL::SSLEngine::securityTraceLevel() const +{ + return _securityTraceLevel; +} + +std::string +IceSSL::SSLEngine::securityTraceCategory() const +{ + return _securityTraceCategory; +} diff --git a/cpp/src/IceSSL/SSLEngine.h b/cpp/src/IceSSL/SSLEngine.h index 25748c71c78..c8b84fcd31b 100644 --- a/cpp/src/IceSSL/SSLEngine.h +++ b/cpp/src/IceSSL/SSLEngine.h @@ -40,6 +40,8 @@ # include <sspi.h> # include <schannel.h> # undef SECURITY_WIN32 +#elif defined(ICE_OS_WINRT) +# include <mutex> #endif namespace IceSSL @@ -81,10 +83,10 @@ public: std::string getPassword() const; void setPassword(const std::string& password); - bool getCheckCertName() const { return _checkCertName; } - int getVerifyPeer() const { return _verifyPeer; } - int securityTraceLevel() const { return _securityTraceLevel; } - std::string securityTraceCategory() const { return _securityTraceCategory; } + bool getCheckCertName() const; + int getVerifyPeer() const; + int securityTraceLevel() const; + std::string securityTraceCategory() const; private: @@ -234,6 +236,13 @@ public: virtual void initialize(); virtual bool initialized() const; virtual void destroy(); + virtual std::shared_ptr<Certificate> certificate(); + +private: + + std::shared_ptr<Certificate> _certificate; + bool _initialized; + std::mutex _mutex; }; #else // OpenSSL @@ -263,7 +272,6 @@ private: enum Protocols { SSLv3 = 0x01, TLSv1_0 = 0x02, TLSv1_1 = 0x04, TLSv1_2 = 0x08 }; int parseProtocols(const Ice::StringSeq&) const; - bool _initialized; SSL_CTX* _ctx; std::string _defaultDir; diff --git a/cpp/src/IceSSL/Util.cpp b/cpp/src/IceSSL/Util.cpp index 5b592797842..67a81e09740 100755 --- a/cpp/src/IceSSL/Util.cpp +++ b/cpp/src/IceSSL/Util.cpp @@ -23,6 +23,11 @@ #include <Ice/StringConverter.h> #include <fstream> +#ifdef ICE_OS_WINRT +# include <ppltasks.h> +#endif +using namespace IceUtilInternal; + #ifdef ICE_USE_OPENSSL # include <openssl/err.h> // @@ -36,6 +41,17 @@ using namespace Ice; using namespace IceUtil; using namespace IceSSL; +#ifdef ICE_OS_WINRT +using namespace concurrency; +using namespace Platform; +using namespace Windows::Foundation; +using namespace Windows::Foundation::Collections; +using namespace Windows::Storage; +using namespace Windows::Storage::Streams; +using namespace Windows::Security::Cryptography; +using namespace Windows::Security::Cryptography::Core; +using namespace Windows::Security::Cryptography::Certificates; +#endif #ifdef ICE_CPP11_MAPPING IceSSL::CertificateVerifier::CertificateVerifier(std::function<bool(const std::shared_ptr<NativeConnectionInfo>&)> v) : @@ -1677,6 +1693,125 @@ IceSSL::findCertificates(const string& location, const string& name, const strin } return certs; } +#elif defined (ICE_OS_WINRT) +IVectorView<Certificates::Certificate^>^ +IceSSL::findCertificates(const string& name, const string& value) +{ + CertificateQuery^ query = ref new CertificateQuery(); + query->StoreName = ref new String(stringToWstring(name).c_str()); + query->IncludeDuplicates = true; + + if(value != "*") + { + if(value.find(':', 0) == string::npos) + { + throw PluginInitializationException(__FILE__, __LINE__, "IceSSL: no key in `" + value + "'"); + } + size_t start = 0; + size_t pos; + while((pos = value.find(':', start)) != string::npos) + { + string field = IceUtilInternal::toUpper(IceUtilInternal::trim(value.substr(start, pos - start))); + if(field != "ISSUER" && field != "THUMBPRINT" && field != "FRIENDLYNAME") + { + throw PluginInitializationException(__FILE__, __LINE__, "IceSSL: unknown key in `" + value + "'"); + } + + start = pos + 1; + while(start < value.size() && (value[start] == ' ' || value[start] == '\t')) + { + ++start; + } + + if(start == value.size()) + { + throw PluginInitializationException(__FILE__, __LINE__, "IceSSL: missing argument in `" + value + "'"); + } + + string arg; + if(value[start] == '"' || value[start] == '\'') + { + size_t end = start; + ++end; + while(end < value.size()) + { + if(value[end] == value[start] && value[end - 1] != '\\') + { + break; + } + ++end; + } + if(end == value.size() || value[end] != value[start]) + { + throw PluginInitializationException(__FILE__, __LINE__, "IceSSL: unmatched quote in `" + value + "'"); + } + ++start; + arg = value.substr(start, end - start); + start = end + 1; + } + else + { + size_t end = value.find_first_of(" \t", start); + if(end == string::npos) + { + arg = value.substr(start); + start = value.size(); + } + else + { + arg = value.substr(start, end - start); + start = end + 1; + } + } + + if(field == "ISSUER") + { + query->IssuerName = ref new String(stringToWstring(arg).c_str()); + } + else if(field == "FRIENDLYNAME") + { + query->FriendlyName = ref new String(stringToWstring(arg).c_str()); + } + else if(field == "THUMBPRINT") + { + vector<BYTE> buffer; + if(!parseBytes(arg, buffer)) + { + throw PluginInitializationException(__FILE__, __LINE__, + "IceSSL: invalid `IceSSL.FindCert' property: can't decode the value"); + } + query->Thumbprint = ref new Array<unsigned char>(&buffer[0], static_cast<unsigned int>(buffer.size())); + } + } + } + + std::promise<IVectorView<Certificates::Certificate^>^> p; + HRESULT error = 0; + create_task(CertificateStores::FindAllAsync(query)).then( + [&](task<IVectorView<Certificates::Certificate^>^> previous) + { + try + { + p.set_value(previous.get()); + } + catch(Platform::Exception^ err) + { + try + { + Ice::SyscallException ex(__FILE__, __LINE__); + ex.error = err->HResult; + throw ex; + } + catch(...) + { + p.set_exception(current_exception()); + } + } + }, + task_continuation_context::use_arbitrary()); + + return p.get_future().get(); +} #endif void diff --git a/cpp/src/IceSSL/Util.h b/cpp/src/IceSSL/Util.h index 1ff3b12aab5..59ff813a1a8 100644 --- a/cpp/src/IceSSL/Util.h +++ b/cpp/src/IceSSL/Util.h @@ -202,6 +202,9 @@ CFArrayRef findCertificateChain(const std::string&, const std::string&, const st #elif defined(ICE_USE_SCHANNEL) std::vector<PCCERT_CONTEXT> findCertificates(const std::string&, const std::string&, const std::string&, std::vector<HCERTSTORE>&); +#elif defined(ICE_OS_WINRT) +Windows::Foundation::Collections::IVectorView<Windows::Security::Cryptography::Certificates::Certificate^>^ +findCertificates(const std::string&, const std::string&); #endif // diff --git a/cpp/src/IceSSL/WinRTEngine.cpp b/cpp/src/IceSSL/WinRTEngine.cpp index a6dc675c581..651fd2ace53 100755 --- a/cpp/src/IceSSL/WinRTEngine.cpp +++ b/cpp/src/IceSSL/WinRTEngine.cpp @@ -12,26 +12,59 @@ #ifdef ICE_OS_WINRT #include <IceSSL/SSLEngine.h> +#include <Ice/Communicator.h> +#include <Ice/Properties.h> #include <IceUtil/Shared.h> +#include <string> + IceUtil::Shared* IceSSL::upCast(IceSSL::WinRTEngine* p) { return p; } +using namespace std; using namespace IceSSL; WinRTEngine::WinRTEngine(const Ice::CommunicatorPtr& communicator) : SSLEngine(communicator) { - } void WinRTEngine::initialize() { + lock_guard<mutex> lock(_mutex); + if(_initialized) + { + return; + } + + SSLEngine::initialize(); + + const auto properties = communicator()->getProperties(); + + // + // Load client certificate + // + string findCert = properties->getProperty("IceSSL.FindCert"); + if(!findCert.empty()) + { + auto certs = findCertificates(properties->getPropertyWithDefault("IceSSL.CertStore", "My"), findCert); + if(certs->Size > 0) + { + _certificate = make_shared<IceSSL::Certificate>(certs->GetAt(0)); + } + } + _initialized = true; } bool WinRTEngine::initialized() const { - return true; + return _initialized; +} + +shared_ptr<Certificate> +WinRTEngine::certificate() +{ + return _certificate; } void diff --git a/cpp/src/IceSSL/WinRTTransceiverI.cpp b/cpp/src/IceSSL/WinRTTransceiverI.cpp index d9bca2912a9..6aad729e957 100755 --- a/cpp/src/IceSSL/WinRTTransceiverI.cpp +++ b/cpp/src/IceSSL/WinRTTransceiverI.cpp @@ -14,14 +14,94 @@ #include <IceSSL/WinRTTransceiverI.h> #include <IceSSL/Instance.h> #include <IceSSL/SSLEngine.h> +#include <Ice/Logger.h> +#include <ppltasks.h> using namespace std; using namespace Ice; using namespace IceSSL; +using namespace concurrency; using namespace Platform; using namespace Windows::Networking; using namespace Windows::Networking::Sockets; +using namespace Windows::Foundation::Collections; +using namespace Windows::Security::Cryptography::Certificates; + +namespace +{ + +std::string +validationResultToString(ChainValidationResult result) +{ + switch (result) + { + case ChainValidationResult::Success: + { + return "The certificate chain was verified."; + } + case ChainValidationResult::Untrusted: + { + return "A certificate in the chain is not trusted."; + } + case ChainValidationResult::Revoked: + { + return "A certificate in the chain has been revoked."; + } + case ChainValidationResult::Expired: + { + return "A certificate in the chain has expired."; + } + case ChainValidationResult::IncompleteChain: + { + return "The certificate chain is missing one or more certificates."; + } + case ChainValidationResult::InvalidSignature: + { + return "The signature of a certificate in the chain cannot be verified."; + } + case ChainValidationResult::WrongUsage: + { + return "A certificate in the chain is being used for a purpose other than one specified by its CA."; + } + case ChainValidationResult::InvalidName: + { + return "A certificate in the chain has a name that is not valid. The name is either not included in " + "the permitted list or is explicitly excluded."; + } + case ChainValidationResult::InvalidCertificateAuthorityPolicy: + { + return "A certificate in the chain has a policy that is not valid."; + } + case ChainValidationResult::BasicConstraintsError: + { + return "The basic constraint extension of a certificate in the chain has not been observed."; + } + case ChainValidationResult::UnknownCriticalExtension: + { + return "A certificate in the chain contains an unknown extension that is marked \"critical\"."; + } + case ChainValidationResult::RevocationInformationMissing: + { + return "No installed or registered DLL was found to verify revocation."; + } + case ChainValidationResult::RevocationFailure: + { + return "Unable to connect to the revocation server."; + } + case ChainValidationResult::OtherErrors: + { + return "An unexpected error occurred while validating the certificate chain."; + } + default: + { + assert(false); + return ""; + } + } +} + +} IceInternal::NativeInfoPtr IceSSL::TransceiverI::getNativeInfo() @@ -50,6 +130,89 @@ IceSSL::TransceiverI::initialize(IceInternal::Buffer& readBuffer, IceInternal::B else if(!_upgraded) { _upgraded = true; + try + { + auto fd = safe_cast<StreamSocket^>(_delegate->getNativeInfo()->fd()); + if (fd->Information->ServerCertificate) + { + // + // Build the certificate chain + // + auto params = ref new ChainBuildingParameters(); + params->AuthorityInformationAccessEnabled = false; + params->CurrentTimeValidationEnabled = true; + params->NetworkRetrievalEnabled = false; + params->RevocationCheckEnabled = false; + + promise<CertificateChain^> p; + + create_task(fd->Information->ServerCertificate->BuildChainAsync( + fd->Information->ServerIntermediateCertificates, params)).then( + [&](task<CertificateChain^> previous) + { + try + { + p.set_value(previous.get()); + } + catch (Platform::Exception^ ex) + { + try + { + throw SyscallException(__FILE__, __LINE__, ex->HResult); + } + catch(...) + { + p.set_exception(current_exception()); + } + } + }); + + _chain = p.get_future().get(); + + ChainValidationResult result = _chain->Validate(); + // + // Ignore InvalidName errors here SSLEngine::verifyPeer already checks that + // using IceSSL.CheckCertName settings. + // + if(result != ChainValidationResult::InvalidName && result != ChainValidationResult::Success) + { + if(_engine->getVerifyPeer() == 0) + { + if(_instance->traceLevel() >= 1) + { + _instance->logger()->trace(_instance->traceCategory(), + "IceSSL: ignoring certificate verification failure\n" + + validationResultToString(result)); + } + } + else + { + throw SecurityException(__FILE__, __LINE__, + "IceSSL: certificate validation error:\n" + validationResultToString(result)); + } + } + else + { + _verified = true; + } + } + else if((!_incoming && _engine->getVerifyPeer() > 0) || (_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"); + } + + _engine->verifyPeer(_host, dynamic_pointer_cast<IceSSL::NativeConnectionInfo>(getInfo()), toString()); + } + catch(Platform::Exception^ ex) + { + ostringstream os; + os << "IceSSL: certificate verification failure:\n" << wstringToString(ex->Message->Data()); + throw SecurityException(__FILE__, __LINE__, os.str()); + } } return IceInternal::SocketOperationNone; } @@ -85,6 +248,18 @@ IceSSL::TransceiverI::startWrite(IceInternal::Buffer& buf) { StreamSocket^ stream = safe_cast<StreamSocket^>(_delegate->getNativeInfo()->fd()); HostName^ host = ref new HostName(ref new String(IceUtil::stringToWstring(_host).c_str())); + + // + // We ignre SSL invalid name errors at this point, the certificate name will be later verify + // by SSLEngine veryPeer implementation. + // + stream->Control->IgnorableServerCertificateErrors->Append(ChainValidationResult::InvalidName); + + if(_engine->certificate()) + { + stream->Control->ClientCertificate = _engine->certificate()->getCert(); + } + try { Windows::Foundation::IAsyncAction^ action = stream->UpgradeToSslAsync(SocketProtectionLevel::Tls12, host); @@ -151,11 +326,13 @@ IceSSL::TransceiverI::getInfo() const StreamSocket^ stream = safe_cast<StreamSocket^>(_delegate->getNativeInfo()->fd()); info->nativeCerts.push_back(ICE_MAKE_SHARED(Certificate, stream->Information->ServerCertificate)); info->certs.push_back(info->nativeCerts.back()->encode()); - for(auto iter = stream->Information->ServerIntermediateCertificates->First(); iter->HasCurrent; iter->MoveNext()) + auto certs = _chain ? _chain->GetCertificates(true) : stream->Information->ServerIntermediateCertificates; + for(auto iter = certs->First(); iter->HasCurrent; iter->MoveNext()) { info->nativeCerts.push_back(ICE_MAKE_SHARED(Certificate, iter->Current)); info->certs.push_back(info->nativeCerts.back()->encode()); } + info->verified = _verified; info->adapterName = _adapterName; info->incoming = _incoming; info->underlying = _delegate->getInfo(); @@ -184,7 +361,8 @@ IceSSL::TransceiverI::TransceiverI(const InstancePtr& instance, _incoming(incoming), _delegate(delegate), _connected(false), - _upgraded(false) + _upgraded(false), + _verified(false) { } diff --git a/cpp/src/IceSSL/WinRTTransceiverI.h b/cpp/src/IceSSL/WinRTTransceiverI.h index 29d285175a6..71429198022 100755 --- a/cpp/src/IceSSL/WinRTTransceiverI.h +++ b/cpp/src/IceSSL/WinRTTransceiverI.h @@ -67,6 +67,8 @@ private: bool _connected; bool _upgraded; + bool _verified; + Windows::Security::Cryptography::Certificates::CertificateChain^ _chain; }; typedef IceUtil::Handle<TransceiverI> TransceiverIPtr; diff --git a/cpp/src/IceSSL/msbuild/icessluwp++11/icessluwp++11.vcxproj b/cpp/src/IceSSL/msbuild/icessluwp++11/icessluwp++11.vcxproj index 6b376e66034..8e4a2dd18fb 100644 --- a/cpp/src/IceSSL/msbuild/icessluwp++11/icessluwp++11.vcxproj +++ b/cpp/src/IceSSL/msbuild/icessluwp++11/icessluwp++11.vcxproj @@ -318,10 +318,6 @@ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild> <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">true</ExcludedFromBuild> </ClInclude> - <ClInclude Include="..\..\uwp\AcceptorI.h" /> - <ClInclude Include="..\..\uwp\ConnectorI.h" /> - <ClInclude Include="..\..\uwp\EndpointI.h" /> - <ClInclude Include="..\..\uwp\TransceiverI.h" /> </ItemGroup> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> <Import Project="$(IceBuilderCppTargets)" Condition="Exists('$(IceBuilderCppTargets)')" /> diff --git a/cpp/src/IceSSL/msbuild/icessluwp++11/icessluwp++11.vcxproj.filters b/cpp/src/IceSSL/msbuild/icessluwp++11/icessluwp++11.vcxproj.filters index 17f262f778e..e3eed3add57 100644 --- a/cpp/src/IceSSL/msbuild/icessluwp++11/icessluwp++11.vcxproj.filters +++ b/cpp/src/IceSSL/msbuild/icessluwp++11/icessluwp++11.vcxproj.filters @@ -144,21 +144,11 @@ <ClCompile Include="..\..\WinRTEngine.cpp"> <Filter>Source Files</Filter> </ClCompile> - <ClCompile Include="..\..\RFC2253.cpp" /> + <ClCompile Include="..\..\RFC2253.cpp"> + <Filter>Source Files</Filter> + </ClCompile> </ItemGroup> <ItemGroup> - <ClInclude Include="..\..\uwp\AcceptorI.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="..\..\uwp\ConnectorI.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="..\..\uwp\EndpointI.h"> - <Filter>Header Files</Filter> - </ClInclude> - <ClInclude Include="..\..\uwp\TransceiverI.h"> - <Filter>Header Files</Filter> - </ClInclude> <ClInclude Include="..\..\..\..\include\generated\uwp\Win32\Debug\IceSSL\ConnectionInfo.h"> <Filter>Header Files\Win32\Debug</Filter> </ClInclude> |