zeroc-ice 3.8.1 → 3.8.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/dist/IceRuby/Communicator.cpp +26 -9
- data/dist/IceRuby/Config.h +0 -12
- data/dist/IceRuby/Connection.cpp +18 -9
- data/dist/IceRuby/DefaultSliceLoader.h +1 -1
- data/dist/IceRuby/Endpoint.cpp +21 -8
- data/dist/IceRuby/Operation.cpp +29 -11
- data/dist/IceRuby/Properties.cpp +3 -4
- data/dist/IceRuby/Proxy.cpp +11 -19
- data/dist/IceRuby/RubySliceLoader.cpp +1 -1
- data/dist/IceRuby/RubySliceLoader.h +6 -0
- data/dist/IceRuby/Types.cpp +162 -138
- data/dist/IceRuby/Types.h +68 -28
- data/dist/IceRuby/Util.cpp +14 -78
- data/dist/IceRuby/Util.h +7 -17
- data/dist/ice/cpp/include/Ice/Communicator.h +31 -8
- data/dist/ice/cpp/include/Ice/Config.h +2 -2
- data/dist/ice/cpp/include/Ice/Connection.h +24 -8
- data/dist/ice/cpp/include/Ice/CtrlCHandler.h +1 -1
- data/dist/ice/cpp/include/Ice/Demangle.h +1 -1
- data/dist/ice/cpp/include/Ice/Endpoint.h +4 -4
- data/dist/ice/cpp/include/Ice/Initialize.h +4 -4
- data/dist/ice/cpp/include/Ice/InputStream.h +5 -5
- data/dist/ice/cpp/include/Ice/Instrumentation.h +13 -7
- data/dist/ice/cpp/include/Ice/LocalExceptions.h +26 -5
- data/dist/ice/cpp/include/Ice/Logger.h +7 -0
- data/dist/ice/cpp/include/Ice/LoggerUtil.h +1 -1
- data/dist/ice/cpp/include/Ice/Object.h +10 -8
- data/dist/ice/cpp/include/Ice/ObjectAdapter.h +1 -1
- data/dist/ice/cpp/include/Ice/OutgoingAsync.h +5 -2
- data/dist/ice/cpp/include/Ice/OutgoingResponse.h +2 -1
- data/dist/ice/cpp/include/Ice/OutputStream.h +14 -11
- data/dist/ice/cpp/include/Ice/PluginFactory.h +1 -1
- data/dist/ice/cpp/include/Ice/Properties.h +3 -3
- data/dist/ice/cpp/include/Ice/Proxy.h +192 -50
- data/dist/ice/cpp/include/Ice/SSL/ClientAuthenticationOptions.h +3 -3
- data/dist/ice/cpp/include/Ice/SSL/EndpointInfo.h +1 -1
- data/dist/ice/cpp/include/Ice/SSL/ServerAuthenticationOptions.h +5 -5
- data/dist/ice/cpp/include/Ice/ServantLocator.h +1 -1
- data/dist/ice/cpp/include/Ice/Service.h +2 -5
- data/dist/ice/cpp/include/Ice/SliceLoader.h +1 -1
- data/dist/ice/cpp/include/Ice/SlicedData.h +5 -3
- data/dist/ice/cpp/include/Ice/StreamHelpers.h +1 -1
- data/dist/ice/cpp/include/Ice/StreamableTraits.h +2 -2
- data/dist/ice/cpp/include/Ice/StringConverter.h +2 -3
- data/dist/ice/cpp/include/Ice/StringUtil.h +2 -7
- data/dist/ice/cpp/include/Ice/UUID.h +1 -0
- data/dist/ice/cpp/include/Ice/Value.h +2 -2
- data/dist/ice/cpp/include/generated/Ice/BuiltinSequences.h +2 -2
- data/dist/ice/cpp/include/generated/Ice/Context.h +2 -2
- data/dist/ice/cpp/include/generated/Ice/EndpointTypes.h +2 -2
- data/dist/ice/cpp/include/generated/Ice/Identity.h +2 -2
- data/dist/ice/cpp/include/generated/Ice/Locator.h +57 -23
- data/dist/ice/cpp/include/generated/Ice/LocatorRegistry.h +38 -11
- data/dist/ice/cpp/include/generated/Ice/Metrics.h +99 -44
- data/dist/ice/cpp/include/generated/Ice/OperationMode.h +2 -2
- data/dist/ice/cpp/include/generated/Ice/Process.h +34 -8
- data/dist/ice/cpp/include/generated/Ice/PropertiesAdmin.h +42 -11
- data/dist/ice/cpp/include/generated/Ice/PropertyDict.h +2 -2
- data/dist/ice/cpp/include/generated/Ice/RemoteLogger.h +93 -40
- data/dist/ice/cpp/include/generated/Ice/ReplyStatus.h +8 -4
- data/dist/ice/cpp/include/generated/Ice/Router.h +55 -19
- data/dist/ice/cpp/include/generated/Ice/SliceChecksumDict.h +2 -2
- data/dist/ice/cpp/include/generated/Ice/Version.h +2 -2
- data/dist/ice/cpp/include/generated/IceDiscovery/Lookup.h +66 -14
- data/dist/ice/cpp/include/generated/IceLocatorDiscovery/Lookup.h +34 -8
- data/dist/ice/cpp/src/Ice/AddDefaultPluginFactories_all.cpp +1 -1
- data/dist/ice/cpp/src/Ice/Base64.cpp +47 -137
- data/dist/ice/cpp/src/Ice/Base64.h +2 -2
- data/dist/ice/cpp/src/Ice/BatchRequestQueue.cpp +28 -13
- data/dist/ice/cpp/src/Ice/BatchRequestQueue.h +5 -1
- data/dist/ice/cpp/src/Ice/Buffer.cpp +1 -1
- data/dist/ice/cpp/src/Ice/CollocatedRequestHandler.cpp +6 -4
- data/dist/ice/cpp/src/Ice/CollocatedRequestHandler.h +1 -1
- data/dist/ice/cpp/src/Ice/Communicator.cpp +4 -3
- data/dist/ice/cpp/src/Ice/CommunicatorFlushBatchAsync.cpp +8 -0
- data/dist/ice/cpp/src/Ice/ConnectRequestHandler.cpp +5 -15
- data/dist/ice/cpp/src/Ice/ConnectRequestHandler.h +1 -1
- data/dist/ice/cpp/src/Ice/ConnectionFactory.cpp +6 -8
- data/dist/ice/cpp/src/Ice/ConnectionFactory.h +0 -3
- data/dist/ice/cpp/src/Ice/ConnectionI.cpp +121 -108
- data/dist/ice/cpp/src/Ice/ConnectionI.h +12 -9
- data/dist/ice/cpp/src/Ice/ConsoleUtil.cpp +1 -1
- data/dist/ice/cpp/src/Ice/DefaultsAndOverrides.cpp +10 -14
- data/dist/ice/cpp/src/Ice/EndpointI.h +1 -1
- data/dist/ice/cpp/src/Ice/FileUtil.cpp +15 -79
- data/dist/ice/cpp/src/Ice/FileUtil.h +0 -3
- data/dist/ice/cpp/src/Ice/FixedRequestHandler.cpp +1 -1
- data/dist/ice/cpp/src/Ice/FixedRequestHandler.h +1 -1
- data/dist/ice/cpp/src/Ice/HttpParser.h +0 -2
- data/dist/ice/cpp/src/Ice/IPEndpointI.cpp +4 -0
- data/dist/ice/cpp/src/Ice/IdleTimeoutTransceiverDecorator.cpp +6 -3
- data/dist/ice/cpp/src/Ice/IncomingRequest.cpp +2 -4
- data/dist/ice/cpp/src/Ice/InputStream.cpp +50 -33
- data/dist/ice/cpp/src/Ice/Instance.cpp +73 -50
- data/dist/ice/cpp/src/Ice/Instance.h +1 -6
- data/dist/ice/cpp/src/Ice/LocalExceptions.cpp +7 -1
- data/dist/ice/cpp/src/Ice/LocatorInfo.cpp +2 -2
- data/dist/ice/cpp/src/Ice/LoggerAdminI.cpp +13 -18
- data/dist/ice/cpp/src/Ice/LoggerI.cpp +1 -1
- data/dist/ice/cpp/src/Ice/LoggerI.h +2 -2
- data/dist/ice/cpp/src/Ice/MetricsAdminI.h +6 -1
- data/dist/ice/cpp/src/Ice/MetricsObserverI.h +22 -18
- data/dist/ice/cpp/src/Ice/NativePropertiesAdmin.cpp +5 -2
- data/dist/ice/cpp/src/Ice/Network.cpp +168 -103
- data/dist/ice/cpp/src/Ice/Network.h +12 -7
- data/dist/ice/cpp/src/Ice/NetworkProxy.cpp +17 -6
- data/dist/ice/cpp/src/Ice/NetworkProxy.h +2 -1
- data/dist/ice/cpp/src/Ice/Object.cpp +1 -1
- data/dist/ice/cpp/src/Ice/ObjectAdapterI.cpp +56 -19
- data/dist/ice/cpp/src/Ice/OpaqueEndpointI.cpp +10 -10
- data/dist/ice/cpp/src/Ice/Options.cpp +7 -2
- data/dist/ice/cpp/src/Ice/OutgoingAsync.cpp +2 -2
- data/dist/ice/cpp/src/Ice/OutgoingResponse.cpp +127 -127
- data/dist/ice/cpp/src/Ice/OutgoingResponseInternal.h +21 -0
- data/dist/ice/cpp/src/Ice/OutputStream.cpp +50 -65
- data/dist/ice/cpp/src/Ice/PluginManagerI.cpp +7 -1
- data/dist/ice/cpp/src/Ice/Properties.cpp +26 -16
- data/dist/ice/cpp/src/Ice/PropertyNames.cpp +2 -1
- data/dist/ice/cpp/src/Ice/PropertyUtil.cpp +1 -1
- data/dist/ice/cpp/src/Ice/ProtocolInstance.cpp +0 -11
- data/dist/ice/cpp/src/Ice/ProtocolInstance.h +1 -2
- data/dist/ice/cpp/src/Ice/Proxy.cpp +9 -1
- data/dist/ice/cpp/src/Ice/ProxyAsync.cpp +110 -13
- data/dist/ice/cpp/src/Ice/ProxyFunctions.cpp +4 -4
- data/dist/ice/cpp/src/Ice/Random.cpp +68 -7
- data/dist/ice/cpp/src/Ice/Random.h +6 -2
- data/dist/ice/cpp/src/Ice/Reference.cpp +37 -26
- data/dist/ice/cpp/src/Ice/Reference.h +3 -0
- data/dist/ice/cpp/src/Ice/ReferenceFactory.cpp +26 -13
- data/dist/ice/cpp/src/Ice/RequestHandler.h +3 -1
- data/dist/ice/cpp/src/Ice/RequestHandlerCache.cpp +1 -1
- data/dist/ice/cpp/src/Ice/RequestHandlerCache.h +1 -1
- data/dist/ice/cpp/src/Ice/ResourceConfig.h +3 -3
- data/dist/ice/cpp/src/Ice/RetryQueue.cpp +8 -12
- data/dist/ice/cpp/src/Ice/SHA1.cpp +11 -11
- data/dist/ice/cpp/src/Ice/SSL/DistinguishedName.cpp +0 -6
- data/dist/ice/cpp/src/Ice/SSL/DistinguishedName.h +0 -6
- data/dist/ice/cpp/src/Ice/SSL/OpenSSLEngine.cpp +27 -12
- data/dist/ice/cpp/src/Ice/SSL/OpenSSLEngine.h +1 -2
- data/dist/ice/cpp/src/Ice/SSL/OpenSSLTransceiverI.cpp +77 -27
- data/dist/ice/cpp/src/Ice/SSL/OpenSSLTransceiverI.h +2 -1
- data/dist/ice/cpp/src/Ice/SSL/RFC2253.cpp +2 -2
- data/dist/ice/cpp/src/Ice/SSL/SSLEndpointI.cpp +1 -1
- data/dist/ice/cpp/src/Ice/SSL/SSLEngine.h +1 -4
- data/dist/ice/cpp/src/Ice/SSL/SSLUtil.cpp +39 -34
- data/dist/ice/cpp/src/Ice/SSL/SchannelEngine.cpp +165 -80
- data/dist/ice/cpp/src/Ice/SSL/SchannelEngine.h +1 -5
- data/dist/ice/cpp/src/Ice/SSL/SchannelTransceiverI.cpp +73 -33
- data/dist/ice/cpp/src/Ice/SSL/SchannelTransceiverI.h +0 -1
- data/dist/ice/cpp/src/Ice/SSL/SecureTransportEngine.cpp +110 -17
- data/dist/ice/cpp/src/Ice/SSL/SecureTransportEngine.h +7 -2
- data/dist/ice/cpp/src/Ice/SSL/SecureTransportTransceiverI.cpp +9 -3
- data/dist/ice/cpp/src/Ice/SSL/SecureTransportUtil.cpp +73 -51
- data/dist/ice/cpp/src/Ice/SSL/SecureTransportUtil.h +0 -8
- data/dist/ice/cpp/src/Ice/Selector.cpp +13 -11
- data/dist/ice/cpp/src/Ice/ServantManager.cpp +3 -3
- data/dist/ice/cpp/src/Ice/Service.cpp +33 -115
- data/dist/ice/cpp/src/Ice/StreamSocket.cpp +33 -40
- data/dist/ice/cpp/src/Ice/StreamSocket.h +4 -4
- data/dist/ice/cpp/src/Ice/StringConverter.cpp +1 -1
- data/dist/ice/cpp/src/Ice/StringUtil.cpp +12 -21
- data/dist/ice/cpp/src/Ice/SysLoggerI.cpp +136 -100
- data/dist/ice/cpp/src/Ice/SysLoggerI.h +7 -3
- data/dist/ice/cpp/src/Ice/SystemdJournalI.cpp +1 -1
- data/dist/ice/cpp/src/Ice/TcpAcceptor.cpp +7 -7
- data/dist/ice/cpp/src/Ice/TcpAcceptor.h +2 -1
- data/dist/ice/cpp/src/Ice/TcpBufSize.h +40 -0
- data/dist/ice/cpp/src/Ice/TcpConnector.cpp +5 -2
- data/dist/ice/cpp/src/Ice/TcpConnector.h +2 -0
- data/dist/ice/cpp/src/Ice/TcpEndpointI.cpp +2 -2
- data/dist/ice/cpp/src/Ice/TcpTransceiver.cpp +6 -2
- data/dist/ice/cpp/src/Ice/ThreadPool.cpp +2 -8
- data/dist/ice/cpp/src/Ice/ThreadPool.h +0 -2
- data/dist/ice/cpp/src/Ice/Timer.cpp +7 -3
- data/dist/ice/cpp/src/Ice/UUID.cpp +1 -2
- data/dist/ice/cpp/src/Ice/UdpEndpointI.cpp +6 -3
- data/dist/ice/cpp/src/Ice/UdpTransceiver.cpp +136 -123
- data/dist/ice/cpp/src/Ice/UdpTransceiver.h +3 -4
- data/dist/ice/cpp/src/Ice/WSAcceptor.cpp +8 -3
- data/dist/ice/cpp/src/Ice/WSAcceptor.h +5 -1
- data/dist/ice/cpp/src/Ice/WSEndpoint.cpp +45 -2
- data/dist/ice/cpp/src/Ice/WSTransceiver.cpp +214 -34
- data/dist/ice/cpp/src/Ice/WSTransceiver.h +13 -2
- data/dist/ice/cpp/src/Ice/generated/BuiltinSequences.cpp +2 -2
- data/dist/ice/cpp/src/Ice/generated/Context.cpp +2 -2
- data/dist/ice/cpp/src/Ice/generated/EndpointTypes.cpp +2 -2
- data/dist/ice/cpp/src/Ice/generated/Identity.cpp +2 -2
- data/dist/ice/cpp/src/Ice/generated/Locator.cpp +2 -2
- data/dist/ice/cpp/src/Ice/generated/LocatorRegistry.cpp +2 -2
- data/dist/ice/cpp/src/Ice/generated/Metrics.cpp +2 -2
- data/dist/ice/cpp/src/Ice/generated/OperationMode.cpp +2 -2
- data/dist/ice/cpp/src/Ice/generated/Process.cpp +2 -2
- data/dist/ice/cpp/src/Ice/generated/PropertiesAdmin.cpp +2 -2
- data/dist/ice/cpp/src/Ice/generated/PropertyDict.cpp +2 -2
- data/dist/ice/cpp/src/Ice/generated/RemoteLogger.cpp +2 -2
- data/dist/ice/cpp/src/Ice/generated/ReplyStatus.cpp +4 -2
- data/dist/ice/cpp/src/Ice/generated/Router.cpp +2 -2
- data/dist/ice/cpp/src/Ice/generated/SliceChecksumDict.cpp +2 -2
- data/dist/ice/cpp/src/Ice/generated/Version.cpp +2 -2
- data/dist/ice/cpp/src/IceDiscovery/LookupI.cpp +47 -9
- data/dist/ice/cpp/src/IceDiscovery/LookupI.h +8 -3
- data/dist/ice/cpp/src/IceDiscovery/generated/Lookup.cpp +2 -2
- data/dist/ice/cpp/src/IceLocatorDiscovery/PluginI.cpp +43 -14
- data/dist/ice/cpp/src/IceLocatorDiscovery/generated/Lookup.cpp +2 -2
- data/dist/ice/cpp/src/Slice/DocCommentParser.cpp +32 -26
- data/dist/ice/cpp/src/Slice/DocCommentParser.h +6 -4
- data/dist/ice/cpp/src/Slice/FileTracker.cpp +3 -11
- data/dist/ice/cpp/src/Slice/FileTracker.h +0 -2
- data/dist/ice/cpp/src/Slice/Grammar.cpp +211 -210
- data/dist/ice/cpp/src/Slice/MetadataValidation.cpp +34 -14
- data/dist/ice/cpp/src/Slice/MetadataValidation.h +3 -2
- data/dist/ice/cpp/src/Slice/Parser.cpp +145 -97
- data/dist/ice/cpp/src/Slice/Parser.h +22 -8
- data/dist/ice/cpp/src/Slice/Preprocessor.cpp +77 -29
- data/dist/ice/cpp/src/Slice/Preprocessor.h +0 -3
- data/dist/ice/cpp/src/Slice/Scanner.cpp +3 -3
- data/dist/ice/cpp/src/Slice/SliceUtil.cpp +203 -172
- data/dist/ice/cpp/src/Slice/StringLiteralUtil.cpp +0 -2
- data/dist/ice/cpp/src/Slice/Util.h +21 -12
- data/dist/ice/cpp/src/slice2rb/Ruby.cpp +7 -3
- data/dist/ice/cpp/src/slice2rb/RubyUtil.cpp +26 -20
- data/dist/ice/cpp/src/slice2rb/RubyUtil.h +10 -13
- data/dist/ice/slice/Glacier2/Router.ice +3 -3
- data/dist/ice/slice/Ice/Identity.ice +3 -0
- data/dist/ice/slice/Ice/Locator.ice +6 -5
- data/dist/ice/slice/Ice/LocatorRegistry.ice +3 -0
- data/dist/ice/slice/Ice/Metrics.ice +7 -6
- data/dist/ice/slice/Ice/OperationMode.ice +8 -0
- data/dist/ice/slice/Ice/Process.ice +3 -0
- data/dist/ice/slice/Ice/RemoteLogger.ice +5 -5
- data/dist/ice/slice/Ice/ReplyStatus.ice +13 -0
- data/dist/ice/slice/IceGrid/Admin.ice +9 -9
- data/dist/ice/slice/IceGrid/Descriptor.ice +5 -5
- data/dist/ice/slice/IceStorm/Metrics.ice +1 -1
- data/dist/lib/Glacier2/Metrics.rb +1 -1
- data/dist/lib/Glacier2/PermissionsVerifier.rb +3 -3
- data/dist/lib/Glacier2/Router.rb +9 -9
- data/dist/lib/Glacier2/SSLInfo.rb +1 -1
- data/dist/lib/Glacier2/Session.rb +15 -15
- data/dist/lib/Ice/BuiltinSequences.rb +1 -1
- data/dist/lib/Ice/CompressBatch.rb +1 -2
- data/dist/lib/Ice/Context.rb +1 -1
- data/dist/lib/Ice/EndpointSelectionType.rb +1 -2
- data/dist/lib/Ice/EndpointTypes.rb +1 -1
- data/dist/lib/Ice/Identity.rb +1 -1
- data/dist/lib/Ice/IdentitySpaceship.rb +1 -0
- data/dist/lib/Ice/LocalExceptions.rb +3 -0
- data/dist/lib/Ice/Locator.rb +5 -5
- data/dist/lib/Ice/LocatorRegistry.rb +4 -4
- data/dist/lib/Ice/Metrics.rb +7 -7
- data/dist/lib/Ice/OperationMode.rb +2 -3
- data/dist/lib/Ice/Process.rb +3 -3
- data/dist/lib/Ice/PropertiesAdmin.rb +4 -4
- data/dist/lib/Ice/PropertyDict.rb +1 -1
- data/dist/lib/Ice/ProxyFunctions.rb +8 -4
- data/dist/lib/Ice/RemoteLogger.rb +7 -8
- data/dist/lib/Ice/ReplyStatus.rb +4 -4
- data/dist/lib/Ice/Router.rb +5 -5
- data/dist/lib/Ice/SliceChecksumDict.rb +1 -1
- data/dist/lib/Ice/SliceUtil.rb +2 -2
- data/dist/lib/Ice/Struct.rb +1 -0
- data/dist/lib/Ice/ToStringMode.rb +1 -2
- data/dist/lib/Ice/Value.rb +2 -2
- data/dist/lib/Ice/Version.rb +1 -1
- data/dist/lib/IceBox/ServiceManager.rb +8 -8
- data/dist/lib/IceGrid/Admin.rb +85 -86
- data/dist/lib/IceGrid/Descriptor.rb +1 -1
- data/dist/lib/IceGrid/Exception.rb +1 -1
- data/dist/lib/IceGrid/FileParser.rb +2 -2
- data/dist/lib/IceGrid/Registry.rb +14 -15
- data/dist/lib/IceGrid/Session.rb +7 -7
- data/dist/lib/IceGrid/UserAccountMapper.rb +2 -2
- data/dist/lib/IceStorm/IceStorm.rb +16 -16
- data/dist/lib/IceStorm/Metrics.rb +1 -1
- data/extconf.rb +1 -1
- data/ice.gemspec +3 -3
- metadata +5 -5
- data/dist/ice/cpp/src/Ice/DLLMain.cpp +0 -40
- data/dist/ice/cpp/src/Ice/UndefSysMacros.h +0 -37
|
@@ -459,21 +459,28 @@ namespace
|
|
|
459
459
|
throw InitializationException(
|
|
460
460
|
__FILE__,
|
|
461
461
|
__LINE__,
|
|
462
|
-
"SSL transport: invalid value '" + value + "' for
|
|
462
|
+
"SSL transport: invalid value '" + value + "' for 'IceSSL.FindCert' property:\n" +
|
|
463
463
|
IceInternal::lastErrorToString());
|
|
464
464
|
}
|
|
465
465
|
|
|
466
466
|
vector<BYTE> buffer(length);
|
|
467
|
-
if (!CertStrToNameW(
|
|
467
|
+
if (!CertStrToNameW(
|
|
468
|
+
X509_ASN_ENCODING,
|
|
469
|
+
argW.c_str(),
|
|
470
|
+
flags[i],
|
|
471
|
+
0,
|
|
472
|
+
buffer.data(),
|
|
473
|
+
&length,
|
|
474
|
+
0))
|
|
468
475
|
{
|
|
469
476
|
throw InitializationException(
|
|
470
477
|
__FILE__,
|
|
471
478
|
__LINE__,
|
|
472
|
-
"SSL transport: invalid value '" + value + "' for
|
|
479
|
+
"SSL transport: invalid value '" + value + "' for 'IceSSL.FindCert' property:\n" +
|
|
473
480
|
IceInternal::lastErrorToString());
|
|
474
481
|
}
|
|
475
482
|
|
|
476
|
-
CERT_NAME_BLOB name = {length,
|
|
483
|
+
CERT_NAME_BLOB name = {length, buffer.data()};
|
|
477
484
|
|
|
478
485
|
DWORD findType = field == "SUBJECTDN" ? CERT_FIND_SUBJECT_NAME : CERT_FIND_ISSUER_NAME;
|
|
479
486
|
addMatchingCertificates(store, tmpStore, findType, &name);
|
|
@@ -487,10 +494,10 @@ namespace
|
|
|
487
494
|
throw InitializationException(
|
|
488
495
|
__FILE__,
|
|
489
496
|
__LINE__,
|
|
490
|
-
"SSL transport: invalid 'IceSSL.FindCert' property:
|
|
497
|
+
"SSL transport: invalid 'IceSSL.FindCert' property: cannot decode the value");
|
|
491
498
|
}
|
|
492
499
|
|
|
493
|
-
CRYPT_HASH_BLOB hash = {static_cast<DWORD>(buffer.size()),
|
|
500
|
+
CRYPT_HASH_BLOB hash = {static_cast<DWORD>(buffer.size()), buffer.data()};
|
|
494
501
|
DWORD findType = field == "THUMBPRINT" ? CERT_FIND_HASH : CERT_FIND_KEY_IDENTIFIER;
|
|
495
502
|
addMatchingCertificates(store, tmpStore, findType, &hash);
|
|
496
503
|
}
|
|
@@ -502,7 +509,7 @@ namespace
|
|
|
502
509
|
throw InitializationException(
|
|
503
510
|
__FILE__,
|
|
504
511
|
__LINE__,
|
|
505
|
-
"SSL transport: invalid value '" + value + "' for
|
|
512
|
+
"SSL transport: invalid value '" + value + "' for 'IceSSL.FindCert' property");
|
|
506
513
|
}
|
|
507
514
|
|
|
508
515
|
// CRYPT_INTEGER_BLOB stores serial data in little-endian format, parseBytes returns big-endian
|
|
@@ -510,7 +517,7 @@ namespace
|
|
|
510
517
|
std::vector<BYTE> serialData(buffer.size());
|
|
511
518
|
std::reverse_copy(std::begin(buffer), std::end(buffer), std::begin(serialData));
|
|
512
519
|
|
|
513
|
-
CRYPT_INTEGER_BLOB serial = {static_cast<DWORD>(serialData.size()),
|
|
520
|
+
CRYPT_INTEGER_BLOB serial = {static_cast<DWORD>(serialData.size()), serialData.data()};
|
|
514
521
|
PCCERT_CONTEXT next = nullptr;
|
|
515
522
|
do
|
|
516
523
|
{
|
|
@@ -568,9 +575,12 @@ namespace
|
|
|
568
575
|
0,
|
|
569
576
|
CERT_FIND_ANY,
|
|
570
577
|
0,
|
|
571
|
-
next)) !=
|
|
578
|
+
next)) != nullptr)
|
|
572
579
|
{
|
|
573
|
-
|
|
580
|
+
// CertFindCertificateInStore frees the context passed as pPrevCertContext on the next iteration
|
|
581
|
+
// (and frees the last one when it returns null). Duplicate the context to keep an owned reference
|
|
582
|
+
// that remains valid after enumeration; these duplicates are released in the destructor.
|
|
583
|
+
certs.push_back(CertDuplicateCertificateContext(next));
|
|
574
584
|
}
|
|
575
585
|
} while (next);
|
|
576
586
|
stores.push_back(store);
|
|
@@ -598,7 +608,13 @@ namespace
|
|
|
598
608
|
if (startpos != string::npos)
|
|
599
609
|
{
|
|
600
610
|
endpos = strbuf.find("-----END CERTIFICATE-----", startpos);
|
|
601
|
-
|
|
611
|
+
if (endpos == string::npos)
|
|
612
|
+
{
|
|
613
|
+
ostringstream os;
|
|
614
|
+
os << "SSL transport: malformed PEM certificate (missing END marker): '" << file << "'";
|
|
615
|
+
throw InitializationException(__FILE__, __LINE__, os.str());
|
|
616
|
+
}
|
|
617
|
+
size = endpos - startpos + strlen("-----END CERTIFICATE-----");
|
|
602
618
|
}
|
|
603
619
|
else if (first)
|
|
604
620
|
{
|
|
@@ -618,7 +634,7 @@ namespace
|
|
|
618
634
|
&buffer[startpos],
|
|
619
635
|
static_cast<DWORD>(size),
|
|
620
636
|
CRYPT_STRING_ANY,
|
|
621
|
-
|
|
637
|
+
outBuffer.data(),
|
|
622
638
|
&outLength,
|
|
623
639
|
0,
|
|
624
640
|
0))
|
|
@@ -633,7 +649,7 @@ namespace
|
|
|
633
649
|
if (!CertAddEncodedCertificateToStore(
|
|
634
650
|
store,
|
|
635
651
|
X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
|
|
636
|
-
|
|
652
|
+
outBuffer.data(),
|
|
637
653
|
outLength,
|
|
638
654
|
CERT_STORE_ADD_NEW,
|
|
639
655
|
first ? cert : 0))
|
|
@@ -688,7 +704,7 @@ namespace
|
|
|
688
704
|
}
|
|
689
705
|
else
|
|
690
706
|
{
|
|
691
|
-
// If subjectAlt is empty compare it to the subject CN, otherwise compare it to the
|
|
707
|
+
// If subjectAlt is empty compare it to the subject CN, otherwise compare it to the subject alt
|
|
692
708
|
// name dnsNames.
|
|
693
709
|
if (dnsNames.empty())
|
|
694
710
|
{
|
|
@@ -734,6 +750,34 @@ namespace
|
|
|
734
750
|
throw SecurityException(__FILE__, __LINE__, msg);
|
|
735
751
|
}
|
|
736
752
|
}
|
|
753
|
+
|
|
754
|
+
// Deletes the key container referenced by the certificate's CERT_KEY_PROV_INFO property, if it has one.
|
|
755
|
+
// With CRYPT_DELETEKEYSET, CryptAcquireContextW deletes the key container; the returned handle is undefined
|
|
756
|
+
// and must not be released. Machine key containers live in a separate store, so CRYPT_MACHINE_KEYSET must be
|
|
757
|
+
// carried over from the provider info or the container is not found.
|
|
758
|
+
void deleteKeyContainer(PCCERT_CONTEXT cert)
|
|
759
|
+
{
|
|
760
|
+
DWORD length = 0;
|
|
761
|
+
if (!CertGetCertificateContextProperty(cert, CERT_KEY_PROV_INFO_PROP_ID, nullptr, &length))
|
|
762
|
+
{
|
|
763
|
+
return;
|
|
764
|
+
}
|
|
765
|
+
|
|
766
|
+
vector<char> buf(length);
|
|
767
|
+
if (!CertGetCertificateContextProperty(cert, CERT_KEY_PROV_INFO_PROP_ID, buf.data(), &length))
|
|
768
|
+
{
|
|
769
|
+
return;
|
|
770
|
+
}
|
|
771
|
+
|
|
772
|
+
const CRYPT_KEY_PROV_INFO* keyProvInfo = reinterpret_cast<const CRYPT_KEY_PROV_INFO*>(buf.data());
|
|
773
|
+
HCRYPTPROV prov = 0;
|
|
774
|
+
CryptAcquireContextW(
|
|
775
|
+
&prov,
|
|
776
|
+
keyProvInfo->pwszContainerName,
|
|
777
|
+
keyProvInfo->pwszProvName,
|
|
778
|
+
keyProvInfo->dwProvType,
|
|
779
|
+
(keyProvInfo->dwFlags & CRYPT_MACHINE_KEYSET) | CRYPT_DELETEKEYSET);
|
|
780
|
+
}
|
|
737
781
|
}
|
|
738
782
|
|
|
739
783
|
Schannel::SSLEngine::SSLEngine(const IceInternal::InstancePtr& instance)
|
|
@@ -743,14 +787,57 @@ Schannel::SSLEngine::SSLEngine(const IceInternal::InstancePtr& instance)
|
|
|
743
787
|
{
|
|
744
788
|
}
|
|
745
789
|
|
|
790
|
+
Schannel::SSLEngine::~SSLEngine()
|
|
791
|
+
{
|
|
792
|
+
// Best-effort cleanup. We catch every exception (e.g. std::bad_alloc from the per-cert vector
|
|
793
|
+
// allocation below) so nothing escapes the destructor and triggers std::terminate.
|
|
794
|
+
try
|
|
795
|
+
{
|
|
796
|
+
if (_chainEngine && _chainEngine != HCCE_CURRENT_USER && _chainEngine != HCCE_LOCAL_MACHINE)
|
|
797
|
+
{
|
|
798
|
+
CertFreeCertificateChainEngine(_chainEngine);
|
|
799
|
+
}
|
|
800
|
+
|
|
801
|
+
if (_rootStore)
|
|
802
|
+
{
|
|
803
|
+
CertCloseStore(_rootStore, 0);
|
|
804
|
+
}
|
|
805
|
+
|
|
806
|
+
// Remove the key containers created for the certificates Ice imported. Certificates found in a system store
|
|
807
|
+
// are not listed in _importedCerts: their key containers belong to the user or the machine and must be kept.
|
|
808
|
+
for (vector<PCCERT_CONTEXT>::const_iterator i = _importedCerts.begin(); i != _importedCerts.end(); ++i)
|
|
809
|
+
{
|
|
810
|
+
deleteKeyContainer(*i);
|
|
811
|
+
}
|
|
812
|
+
|
|
813
|
+
for (vector<PCCERT_CONTEXT>::const_iterator i = _allCerts.begin(); i != _allCerts.end(); ++i)
|
|
814
|
+
{
|
|
815
|
+
CertFreeCertificateContext(*i);
|
|
816
|
+
}
|
|
817
|
+
|
|
818
|
+
for (vector<HCERTSTORE>::const_iterator i = _stores.begin(); i != _stores.end(); ++i)
|
|
819
|
+
{
|
|
820
|
+
#ifdef NDEBUG
|
|
821
|
+
CertCloseStore(*i, 0);
|
|
822
|
+
#else
|
|
823
|
+
// In debug builds, close the store with CERT_CLOSE_STORE_CHECK_FLAG to assert that every certificate
|
|
824
|
+
// context obtained from it was freed. The call returns false (last error CRYPT_E_PENDING_CLOSE) if any
|
|
825
|
+
// context is still outstanding, which catches certificate-reference leaks early.
|
|
826
|
+
const BOOL allContextsFreed = CertCloseStore(*i, CERT_CLOSE_STORE_CHECK_FLAG);
|
|
827
|
+
assert(allContextsFreed && "SSL transport: certificate context leaked (store closed with live contexts)");
|
|
828
|
+
#endif
|
|
829
|
+
}
|
|
830
|
+
}
|
|
831
|
+
catch (...)
|
|
832
|
+
{
|
|
833
|
+
}
|
|
834
|
+
}
|
|
835
|
+
|
|
746
836
|
void
|
|
747
837
|
Schannel::SSLEngine::initialize()
|
|
748
838
|
{
|
|
749
|
-
//
|
|
750
|
-
//
|
|
751
|
-
// avoid crashes occurring with last Schannel updates see:
|
|
752
|
-
// https://github.com/zeroc-ice/ice/issues/242
|
|
753
|
-
//
|
|
839
|
+
// We use a global mutex for the initialization of Schannel to avoid crashes observed with some Schannel
|
|
840
|
+
// updates.
|
|
754
841
|
lock_guard globalLock(globalMutex);
|
|
755
842
|
|
|
756
843
|
Ice::SSL::SSLEngine::initialize();
|
|
@@ -856,7 +943,7 @@ Schannel::SSLEngine::initialize()
|
|
|
856
943
|
|
|
857
944
|
CRYPT_DATA_BLOB pfxBlob;
|
|
858
945
|
pfxBlob.cbData = static_cast<DWORD>(buffer.size());
|
|
859
|
-
pfxBlob.pbData = reinterpret_cast<BYTE*>(
|
|
946
|
+
pfxBlob.pbData = reinterpret_cast<BYTE*>(buffer.data());
|
|
860
947
|
|
|
861
948
|
PCCERT_CONTEXT cert = nullptr;
|
|
862
949
|
DWORD importFlags = (certStoreLocation == "LocalMachine") ? CRYPT_MACHINE_KEYSET : CRYPT_USER_KEYSET;
|
|
@@ -902,10 +989,10 @@ Schannel::SSLEngine::initialize()
|
|
|
902
989
|
}
|
|
903
990
|
if (!cert)
|
|
904
991
|
{
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
992
|
+
// Read the error before closing the store, otherwise it reports the close instead of the lookup.
|
|
993
|
+
const string error = lastErrorToString();
|
|
994
|
+
CertCloseStore(store, 0);
|
|
995
|
+
throw InitializationException(__FILE__, __LINE__, "SSL transport: certificate error:\n" + error);
|
|
909
996
|
}
|
|
910
997
|
_allCerts.push_back(cert);
|
|
911
998
|
_stores.push_back(store);
|
|
@@ -946,10 +1033,10 @@ Schannel::SSLEngine::initialize()
|
|
|
946
1033
|
|
|
947
1034
|
// Convert the PEM encoded buffer to DER binary format.
|
|
948
1035
|
if (!CryptStringToBinary(
|
|
949
|
-
|
|
1036
|
+
buffer.data(),
|
|
950
1037
|
static_cast<DWORD>(buffer.size()),
|
|
951
1038
|
CRYPT_STRING_BASE64HEADER,
|
|
952
|
-
|
|
1039
|
+
outBuffer.data(),
|
|
953
1040
|
&outLength,
|
|
954
1041
|
0,
|
|
955
1042
|
0))
|
|
@@ -962,6 +1049,10 @@ Schannel::SSLEngine::initialize()
|
|
|
962
1049
|
PCRYPT_PRIVATE_KEY_INFO keyInfo = nullptr;
|
|
963
1050
|
BYTE* key = nullptr;
|
|
964
1051
|
HCRYPTKEY hKey = 0;
|
|
1052
|
+
HCRYPTPROV cryptProv = 0;
|
|
1053
|
+
wstring keySetName;
|
|
1054
|
+
DWORD contextFlags = 0;
|
|
1055
|
+
bool keySetCreated = false;
|
|
965
1056
|
try
|
|
966
1057
|
{
|
|
967
1058
|
// First try to decode as a PKCS#8 key, if that fails try PKCS#1.
|
|
@@ -969,7 +1060,7 @@ Schannel::SSLEngine::initialize()
|
|
|
969
1060
|
if (CryptDecodeObjectEx(
|
|
970
1061
|
X509_ASN_ENCODING,
|
|
971
1062
|
PKCS_PRIVATE_KEY_INFO,
|
|
972
|
-
|
|
1063
|
+
outBuffer.data(),
|
|
973
1064
|
outLength,
|
|
974
1065
|
CRYPT_DECODE_ALLOC_FLAG,
|
|
975
1066
|
0,
|
|
@@ -1008,7 +1099,7 @@ Schannel::SSLEngine::initialize()
|
|
|
1008
1099
|
if (!CryptDecodeObjectEx(
|
|
1009
1100
|
X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
|
|
1010
1101
|
PKCS_RSA_PRIVATE_KEY,
|
|
1011
|
-
|
|
1102
|
+
outBuffer.data(),
|
|
1012
1103
|
outLength,
|
|
1013
1104
|
CRYPT_DECODE_ALLOC_FLAG,
|
|
1014
1105
|
0,
|
|
@@ -1022,10 +1113,9 @@ Schannel::SSLEngine::initialize()
|
|
|
1022
1113
|
}
|
|
1023
1114
|
|
|
1024
1115
|
// Create a new RSA key set to store our key.
|
|
1025
|
-
|
|
1026
|
-
HCRYPTPROV cryptProv = 0;
|
|
1116
|
+
keySetName = Ice::stringToWstring(generateUUID());
|
|
1027
1117
|
|
|
1028
|
-
|
|
1118
|
+
contextFlags = CRYPT_NEWKEYSET;
|
|
1029
1119
|
if (certStoreLocation == "LocalMachine")
|
|
1030
1120
|
{
|
|
1031
1121
|
contextFlags |= CRYPT_MACHINE_KEYSET;
|
|
@@ -1043,6 +1133,7 @@ Schannel::SSLEngine::initialize()
|
|
|
1043
1133
|
__LINE__,
|
|
1044
1134
|
"SSL transport: error acquiring cryptographic context:\n" + lastErrorToString());
|
|
1045
1135
|
}
|
|
1136
|
+
keySetCreated = true;
|
|
1046
1137
|
|
|
1047
1138
|
// Import the private key.
|
|
1048
1139
|
if (!CryptImportKey(cryptProv, key, outLength, 0, 0, &hKey))
|
|
@@ -1056,6 +1147,8 @@ Schannel::SSLEngine::initialize()
|
|
|
1056
1147
|
|
|
1057
1148
|
CryptDestroyKey(hKey);
|
|
1058
1149
|
hKey = 0;
|
|
1150
|
+
CryptReleaseContext(cryptProv, 0);
|
|
1151
|
+
cryptProv = 0;
|
|
1059
1152
|
|
|
1060
1153
|
// Create a new memory store to place the certificate.
|
|
1061
1154
|
store = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0, 0, 0);
|
|
@@ -1073,8 +1166,11 @@ Schannel::SSLEngine::initialize()
|
|
|
1073
1166
|
CRYPT_KEY_PROV_INFO keyProvInfo;
|
|
1074
1167
|
memset(&keyProvInfo, 0, sizeof(keyProvInfo));
|
|
1075
1168
|
keyProvInfo.pwszContainerName = const_cast<wchar_t*>(keySetName.c_str());
|
|
1076
|
-
|
|
1169
|
+
// The provider name and flags must match the ones the container was created with above, otherwise
|
|
1170
|
+
// neither the private key nor the container can be found again.
|
|
1171
|
+
keyProvInfo.pwszProvName = const_cast<wchar_t*>(MS_ENHANCED_PROV_W);
|
|
1077
1172
|
keyProvInfo.dwProvType = PROV_RSA_FULL;
|
|
1173
|
+
keyProvInfo.dwFlags = contextFlags & CRYPT_MACHINE_KEYSET;
|
|
1078
1174
|
keyProvInfo.dwKeySpec = AT_KEYEXCHANGE;
|
|
1079
1175
|
if (!CertSetCertificateContextProperty(cert, CERT_KEY_PROV_INFO_PROP_ID, 0, &keyProvInfo))
|
|
1080
1176
|
{
|
|
@@ -1105,6 +1201,24 @@ Schannel::SSLEngine::initialize()
|
|
|
1105
1201
|
CryptDestroyKey(hKey);
|
|
1106
1202
|
}
|
|
1107
1203
|
|
|
1204
|
+
if (cryptProv)
|
|
1205
|
+
{
|
|
1206
|
+
CryptReleaseContext(cryptProv, 0);
|
|
1207
|
+
}
|
|
1208
|
+
|
|
1209
|
+
if (keySetCreated)
|
|
1210
|
+
{
|
|
1211
|
+
// With CRYPT_DELETEKEYSET, CryptAcquireContextW deletes the key container; the returned
|
|
1212
|
+
// handle is undefined and must not be released.
|
|
1213
|
+
HCRYPTPROV prov = 0;
|
|
1214
|
+
CryptAcquireContextW(
|
|
1215
|
+
&prov,
|
|
1216
|
+
keySetName.c_str(),
|
|
1217
|
+
MS_ENHANCED_PROV_W,
|
|
1218
|
+
PROV_RSA_FULL,
|
|
1219
|
+
(contextFlags & CRYPT_MACHINE_KEYSET) | CRYPT_DELETEKEYSET);
|
|
1220
|
+
}
|
|
1221
|
+
|
|
1108
1222
|
if (cert)
|
|
1109
1223
|
{
|
|
1110
1224
|
CertFreeCertificateContext(cert);
|
|
@@ -1210,49 +1324,6 @@ Schannel::SSLEngine::getCipherName(ALG_ID cipher) const
|
|
|
1210
1324
|
}
|
|
1211
1325
|
}
|
|
1212
1326
|
|
|
1213
|
-
void
|
|
1214
|
-
Schannel::SSLEngine::destroy()
|
|
1215
|
-
{
|
|
1216
|
-
if (_chainEngine && _chainEngine != HCCE_CURRENT_USER && _chainEngine != HCCE_LOCAL_MACHINE)
|
|
1217
|
-
{
|
|
1218
|
-
CertFreeCertificateChainEngine(_chainEngine);
|
|
1219
|
-
}
|
|
1220
|
-
|
|
1221
|
-
if (_rootStore)
|
|
1222
|
-
{
|
|
1223
|
-
CertCloseStore(_rootStore, 0);
|
|
1224
|
-
}
|
|
1225
|
-
|
|
1226
|
-
for (vector<PCCERT_CONTEXT>::const_iterator i = _importedCerts.begin(); i != _importedCerts.end(); ++i)
|
|
1227
|
-
{
|
|
1228
|
-
// Retrieve the certificate CERT_KEY_PROV_INFO_PROP_ID property, we use the CRYPT_KEY_PROV_INFO data to remove
|
|
1229
|
-
// the key set associated with the certificate.
|
|
1230
|
-
DWORD length = 0;
|
|
1231
|
-
if (!CertGetCertificateContextProperty(*i, CERT_KEY_PROV_INFO_PROP_ID, 0, &length))
|
|
1232
|
-
{
|
|
1233
|
-
continue;
|
|
1234
|
-
}
|
|
1235
|
-
vector<char> buf(length);
|
|
1236
|
-
if (!CertGetCertificateContextProperty(*i, CERT_KEY_PROV_INFO_PROP_ID, &buf[0], &length))
|
|
1237
|
-
{
|
|
1238
|
-
continue;
|
|
1239
|
-
}
|
|
1240
|
-
CRYPT_KEY_PROV_INFO* key = reinterpret_cast<CRYPT_KEY_PROV_INFO*>(&buf[0]);
|
|
1241
|
-
HCRYPTPROV prov = 0;
|
|
1242
|
-
CryptAcquireContextW(&prov, key->pwszContainerName, key->pwszProvName, key->dwProvType, CRYPT_DELETEKEYSET);
|
|
1243
|
-
}
|
|
1244
|
-
|
|
1245
|
-
for (vector<PCCERT_CONTEXT>::const_iterator i = _allCerts.begin(); i != _allCerts.end(); ++i)
|
|
1246
|
-
{
|
|
1247
|
-
CertFreeCertificateContext(*i);
|
|
1248
|
-
}
|
|
1249
|
-
|
|
1250
|
-
for (vector<HCERTSTORE>::const_iterator i = _stores.begin(); i != _stores.end(); ++i)
|
|
1251
|
-
{
|
|
1252
|
-
CertCloseStore(*i, 0);
|
|
1253
|
-
}
|
|
1254
|
-
}
|
|
1255
|
-
|
|
1256
1327
|
Ice::SSL::ClientAuthenticationOptions
|
|
1257
1328
|
Schannel::SSLEngine::createClientAuthenticationOptions(const string& host) const
|
|
1258
1329
|
{
|
|
@@ -1260,15 +1331,22 @@ Schannel::SSLEngine::createClientAuthenticationOptions(const string& host) const
|
|
|
1260
1331
|
.clientCredentialsSelectionCallback =
|
|
1261
1332
|
[this](const string&)
|
|
1262
1333
|
{
|
|
1334
|
+
// The transport takes ownership of the returned paCred contexts and releases them when the connection
|
|
1335
|
+
// is closed (see ClientAuthenticationOptions). Bump the reference count of each certificate so the
|
|
1336
|
+
// reference handed to the transport is independent of the engine's _allCerts, which outlives the
|
|
1337
|
+
// individual connections.
|
|
1263
1338
|
for (const auto& cert : _allCerts)
|
|
1264
1339
|
{
|
|
1265
|
-
CertDuplicateCertificateContext
|
|
1340
|
+
// CertDuplicateCertificateContext returns the same pointer with an incremented reference count and
|
|
1341
|
+
// cannot fail for a non-null context; the assert guards that invariant.
|
|
1342
|
+
[[maybe_unused]] PCCERT_CONTEXT duplicate = CertDuplicateCertificateContext(cert);
|
|
1343
|
+
assert(duplicate == cert);
|
|
1266
1344
|
}
|
|
1267
1345
|
|
|
1268
1346
|
return SCH_CREDENTIALS{
|
|
1269
1347
|
.dwVersion = SCH_CREDENTIALS_VERSION,
|
|
1270
1348
|
.cCreds = static_cast<DWORD>(_allCerts.size()),
|
|
1271
|
-
.paCred = const_cast<PCCERT_CONTEXT*>(_allCerts.
|
|
1349
|
+
.paCred = const_cast<PCCERT_CONTEXT*>(_allCerts.data()),
|
|
1272
1350
|
.dwFlags = SCH_CRED_NO_DEFAULT_CREDS | SCH_CRED_NO_SERVERNAME_CHECK | SCH_USE_STRONG_CRYPTO};
|
|
1273
1351
|
},
|
|
1274
1352
|
.trustedRootCertificates = _rootStore,
|
|
@@ -1305,17 +1383,24 @@ Schannel::SSLEngine::createServerAuthenticationOptions() const
|
|
|
1305
1383
|
[this](const string&)
|
|
1306
1384
|
{
|
|
1307
1385
|
{
|
|
1386
|
+
// The transport takes ownership of the returned paCred contexts and releases them when the
|
|
1387
|
+
// connection is closed (see ServerAuthenticationOptions). Bump the reference count of each
|
|
1388
|
+
// certificate so the reference handed to the transport is independent of the engine's _allCerts,
|
|
1389
|
+
// which outlives the individual connections.
|
|
1308
1390
|
for (const auto& cert : _allCerts)
|
|
1309
1391
|
{
|
|
1310
|
-
CertDuplicateCertificateContext
|
|
1392
|
+
// CertDuplicateCertificateContext returns the same pointer with an incremented reference count
|
|
1393
|
+
// and cannot fail for a non-null context; the assert guards that invariant.
|
|
1394
|
+
[[maybe_unused]] PCCERT_CONTEXT duplicate = CertDuplicateCertificateContext(cert);
|
|
1395
|
+
assert(duplicate == cert);
|
|
1311
1396
|
}
|
|
1312
1397
|
|
|
1313
1398
|
return SCH_CREDENTIALS{
|
|
1314
1399
|
.dwVersion = SCH_CREDENTIALS_VERSION,
|
|
1315
1400
|
.cCreds = static_cast<DWORD>(_allCerts.size()),
|
|
1316
|
-
.paCred = const_cast<PCCERT_CONTEXT*>(_allCerts.
|
|
1401
|
+
.paCred = const_cast<PCCERT_CONTEXT*>(_allCerts.data()),
|
|
1317
1402
|
// Don't set SCH_SEND_ROOT_CERT as it seems to cause problems with Java certificate validation and
|
|
1318
|
-
// Schannel doesn't
|
|
1403
|
+
// Schannel doesn't seem to send the root certificate either way.
|
|
1319
1404
|
.dwFlags = SCH_CRED_NO_SYSTEM_MAPPER | SCH_USE_STRONG_CRYPTO};
|
|
1320
1405
|
}
|
|
1321
1406
|
},
|
|
@@ -22,17 +22,13 @@ namespace Ice::SSL::Schannel
|
|
|
22
22
|
{
|
|
23
23
|
public:
|
|
24
24
|
SSLEngine(const IceInternal::InstancePtr&);
|
|
25
|
+
~SSLEngine() override;
|
|
25
26
|
|
|
26
27
|
//
|
|
27
28
|
// Setup the engine.
|
|
28
29
|
//
|
|
29
30
|
void initialize() final;
|
|
30
31
|
|
|
31
|
-
//
|
|
32
|
-
// Destroy the engine.
|
|
33
|
-
//
|
|
34
|
-
void destroy() final;
|
|
35
|
-
|
|
36
32
|
[[nodiscard]] std::string getCipherName(ALG_ID) const;
|
|
37
33
|
|
|
38
34
|
[[nodiscard]] Ice::SSL::ClientAuthenticationOptions
|
|
@@ -93,7 +93,7 @@ namespace
|
|
|
93
93
|
return SCH_CREDENTIALS{
|
|
94
94
|
.dwVersion = SCH_CREDENTIALS_VERSION,
|
|
95
95
|
// Don't set SCH_SEND_ROOT_CERT as it seems to cause problems with Java certificate validation and
|
|
96
|
-
// Schannel doesn't
|
|
96
|
+
// Schannel doesn't seem to send the root certificate either way.
|
|
97
97
|
.dwFlags = SCH_CRED_NO_SYSTEM_MAPPER | SCH_USE_STRONG_CRYPTO};
|
|
98
98
|
}
|
|
99
99
|
}
|
|
@@ -136,18 +136,31 @@ Schannel::TransceiverI::sslHandshake(SecBuffer* initialBuffer)
|
|
|
136
136
|
|
|
137
137
|
if (_credentials.cCreds > 0)
|
|
138
138
|
{
|
|
139
|
-
|
|
139
|
+
if (!_credentials.paCred)
|
|
140
140
|
{
|
|
141
|
-
|
|
141
|
+
throw SecurityException(
|
|
142
|
+
__FILE__,
|
|
143
|
+
__LINE__,
|
|
144
|
+
"SSL transport: the provided SCH_CREDENTIALS sets cCreds but paCred is null.");
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
// The credentials callback transfers ownership of the paCred contexts to the transport (see
|
|
148
|
+
// ClientAuthenticationOptions / ServerAuthenticationOptions). Record ownership of every context
|
|
149
|
+
// before validating below, so close() releases the full transferred set even if validation throws
|
|
150
|
+
// (CertFreeCertificateContext(nullptr) is a no-op). They are released in close().
|
|
151
|
+
_allCerts.assign(_credentials.paCred, _credentials.paCred + _credentials.cCreds);
|
|
152
|
+
_credentials.paCred = _allCerts.data();
|
|
153
|
+
|
|
154
|
+
for (PCCERT_CONTEXT certificate : _allCerts)
|
|
155
|
+
{
|
|
156
|
+
if (!certificate)
|
|
142
157
|
{
|
|
143
158
|
throw SecurityException(
|
|
144
159
|
__FILE__,
|
|
145
160
|
__LINE__,
|
|
146
161
|
"SSL transport: invalid null certificate in the provided SCH_CREDENTIALS.");
|
|
147
162
|
}
|
|
148
|
-
_allCerts.push_back(CertDuplicateCertificateContext(_credentials.paCred[i]));
|
|
149
163
|
}
|
|
150
|
-
_credentials.paCred = &_allCerts[0];
|
|
151
164
|
}
|
|
152
165
|
|
|
153
166
|
err = AcquireCredentialsHandle(
|
|
@@ -197,6 +210,10 @@ Schannel::TransceiverI::sslHandshake(SecBuffer* initialBuffer)
|
|
|
197
210
|
0);
|
|
198
211
|
if (err != SEC_E_OK && err != SEC_I_CONTINUE_NEEDED)
|
|
199
212
|
{
|
|
213
|
+
if (outBuffer.pvBuffer)
|
|
214
|
+
{
|
|
215
|
+
FreeContextBuffer(outBuffer.pvBuffer);
|
|
216
|
+
}
|
|
200
217
|
ostringstream os;
|
|
201
218
|
os << "SSL transport: handshake failure:\n" << IceInternal::errorToString(err);
|
|
202
219
|
throw SecurityException(__FILE__, __LINE__, os.str());
|
|
@@ -295,6 +312,15 @@ Schannel::TransceiverI::sslHandshake(SecBuffer* initialBuffer)
|
|
|
295
312
|
}
|
|
296
313
|
else if (err != SEC_I_CONTINUE_NEEDED && err != SEC_E_OK)
|
|
297
314
|
{
|
|
315
|
+
if (outBuffers[0].pvBuffer) // token
|
|
316
|
+
{
|
|
317
|
+
FreeContextBuffer(outBuffers[0].pvBuffer);
|
|
318
|
+
}
|
|
319
|
+
if (outBuffers[1].pvBuffer) // alert
|
|
320
|
+
{
|
|
321
|
+
FreeContextBuffer(outBuffers[1].pvBuffer);
|
|
322
|
+
}
|
|
323
|
+
|
|
298
324
|
ostringstream os;
|
|
299
325
|
os << "SSL handshake failure:\n" << IceInternal::errorToString(err);
|
|
300
326
|
throw SecurityException(__FILE__, __LINE__, os.str());
|
|
@@ -552,6 +578,15 @@ Schannel::TransceiverI::decryptMessage(IceInternal::Buffer& buffer)
|
|
|
552
578
|
}
|
|
553
579
|
else if (err == SEC_I_RENEGOTIATE)
|
|
554
580
|
{
|
|
581
|
+
if (_incoming)
|
|
582
|
+
{
|
|
583
|
+
// Reject peer-initiated TLS renegotiation on the server side: it is a CPU-asymmetric
|
|
584
|
+
// denial-of-service primitive on TLS 1.2 and is removed entirely in TLS 1.3.
|
|
585
|
+
throw ProtocolException(
|
|
586
|
+
__FILE__,
|
|
587
|
+
__LINE__,
|
|
588
|
+
"SSL transport: peer-initiated TLS renegotiation is not supported on the server side.");
|
|
589
|
+
}
|
|
555
590
|
if (_sslConnectionRenegotiating)
|
|
556
591
|
{
|
|
557
592
|
throw ProtocolException(
|
|
@@ -570,7 +605,15 @@ Schannel::TransceiverI::decryptMessage(IceInternal::Buffer& buffer)
|
|
|
570
605
|
memcpy(_extraBuffer.i, extraBuffer->pvBuffer, extraBuffer->cbBuffer);
|
|
571
606
|
_extraBuffer.i += extraBuffer->cbBuffer;
|
|
572
607
|
}
|
|
573
|
-
|
|
608
|
+
// Unlike the SEC_E_OK path below, we deliberately leave _readBuffer untouched here: sslHandshake resumes
|
|
609
|
+
// the handshake from the data still buffered in _readBuffer and moves the trailing post-renegotiation
|
|
610
|
+
// records back to its front, which is how the application data following the renegotiation is recovered.
|
|
611
|
+
// Resetting _readBuffer.i here would underflow that memmove.
|
|
612
|
+
// Return the application data already copied into the caller's buffer during this call (it may be non-zero
|
|
613
|
+
// because earlier records in the same batch were decrypted before this renegotiation request). The caller
|
|
614
|
+
// must advance buf.i by this amount before performing the re-handshake, otherwise the next decryptMessage
|
|
615
|
+
// overwrites these bytes and the plaintext is silently lost.
|
|
616
|
+
return i - buffer.i;
|
|
574
617
|
}
|
|
575
618
|
else if (err == SEC_I_CONTEXT_EXPIRED)
|
|
576
619
|
{
|
|
@@ -794,6 +837,9 @@ Schannel::TransceiverI::read(IceInternal::Buffer& buf)
|
|
|
794
837
|
}
|
|
795
838
|
|
|
796
839
|
size_t decrypted = decryptMessage(buf);
|
|
840
|
+
// Account for the bytes decryptMessage copied into buf right away, so a renegotiation in the middle of the
|
|
841
|
+
// batch does not drop the plaintext already extracted before it.
|
|
842
|
+
buf.i += decrypted;
|
|
797
843
|
if (_sslConnectionRenegotiating)
|
|
798
844
|
{
|
|
799
845
|
// The peer has requested a renegotiation.
|
|
@@ -819,8 +865,6 @@ Schannel::TransceiverI::read(IceInternal::Buffer& buf)
|
|
|
819
865
|
}
|
|
820
866
|
continue;
|
|
821
867
|
}
|
|
822
|
-
|
|
823
|
-
buf.i += decrypted;
|
|
824
868
|
}
|
|
825
869
|
_delegate->getNativeInfo()->ready(
|
|
826
870
|
IceInternal::SocketOperationRead,
|
|
@@ -890,10 +934,14 @@ Schannel::TransceiverI::finishRead(IceInternal::Buffer& buf)
|
|
|
890
934
|
_delegate->finishRead(_readBuffer);
|
|
891
935
|
if (_state == StateHandshakeComplete)
|
|
892
936
|
{
|
|
893
|
-
|
|
894
|
-
|
|
937
|
+
std::byte* const start = buf.i;
|
|
938
|
+
// Decrypt the buffered data into buf, advancing buf.i as we go so that a renegotiation in the middle of the
|
|
939
|
+
// batch does not drop or overwrite the plaintext already extracted. The loop guard matches decryptMessage's
|
|
940
|
+
// precondition: there is buffered (_readBuffer) or unprocessed data left to decrypt.
|
|
941
|
+
while (buf.i != buf.b.end() && (_readBuffer.i != _readBuffer.b.begin() || !_readUnprocessed.b.empty()))
|
|
895
942
|
{
|
|
896
|
-
decrypted = decryptMessage(buf);
|
|
943
|
+
size_t decrypted = decryptMessage(buf);
|
|
944
|
+
buf.i += decrypted;
|
|
897
945
|
if (_sslConnectionRenegotiating)
|
|
898
946
|
{
|
|
899
947
|
// The peer has requested a renegotiation.
|
|
@@ -903,31 +951,23 @@ Schannel::TransceiverI::finishRead(IceInternal::Buffer& buf)
|
|
|
903
951
|
_extraBuffer.b.begin()};
|
|
904
952
|
IceInternal::SocketOperation op = sslHandshake(&extraBuffer);
|
|
905
953
|
_extraBuffer.b.clear();
|
|
906
|
-
if (op
|
|
954
|
+
if (op != IceInternal::SocketOperationNone)
|
|
907
955
|
{
|
|
908
|
-
|
|
909
|
-
if (buf.i != buf.b.begin())
|
|
910
|
-
{
|
|
911
|
-
continue;
|
|
912
|
-
}
|
|
913
|
-
break;
|
|
956
|
+
throw ConnectionLostException(__FILE__, __LINE__);
|
|
914
957
|
}
|
|
915
|
-
|
|
958
|
+
_sslConnectionRenegotiating = false;
|
|
959
|
+
continue;
|
|
960
|
+
}
|
|
961
|
+
if (decrypted == 0)
|
|
962
|
+
{
|
|
963
|
+
// Not enough buffered data to decrypt a complete record; wait for the next read.
|
|
964
|
+
break;
|
|
916
965
|
}
|
|
917
|
-
break;
|
|
918
966
|
}
|
|
919
967
|
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
buf.i
|
|
923
|
-
_delegate->getNativeInfo()->ready(
|
|
924
|
-
IceInternal::SocketOperationRead,
|
|
925
|
-
!_readUnprocessed.b.empty() || _readBuffer.i != _readBuffer.b.begin());
|
|
926
|
-
}
|
|
927
|
-
else
|
|
928
|
-
{
|
|
929
|
-
_delegate->getNativeInfo()->ready(IceInternal::SocketOperationRead, false);
|
|
930
|
-
}
|
|
968
|
+
_delegate->getNativeInfo()->ready(
|
|
969
|
+
IceInternal::SocketOperationRead,
|
|
970
|
+
buf.i != start && (!_readUnprocessed.b.empty() || _readBuffer.i != _readBuffer.b.begin()));
|
|
931
971
|
}
|
|
932
972
|
}
|
|
933
973
|
|
|
@@ -1065,8 +1105,8 @@ Schannel::TransceiverI::TransceiverI(
|
|
|
1065
1105
|
false); // Whether or not revocation checks only uses cached information.
|
|
1066
1106
|
};
|
|
1067
1107
|
}
|
|
1068
|
-
// If the user provides a validation callback is up to the callback to validate the certificate chain.
|
|
1069
|
-
// If the user doesn't set the trusted root certificates, we use Schannel default behavior,
|
|
1108
|
+
// If the user provides a validation callback, it is up to the callback to validate the certificate chain.
|
|
1109
|
+
// If the user doesn't set the trusted root certificates, we use Schannel default behavior, which uses the system
|
|
1070
1110
|
// trusted root certificates.
|
|
1071
1111
|
}
|
|
1072
1112
|
|
|
@@ -95,7 +95,6 @@ namespace Ice::SSL::Schannel
|
|
|
95
95
|
std::function<SCH_CREDENTIALS(const std::string&)> _localCredentialsSelectionCallback;
|
|
96
96
|
std::function<void(CtxtHandle context, const std::string& host)> _sslNewSessionCallback;
|
|
97
97
|
SecPkgContext_StreamSizes _sizes;
|
|
98
|
-
std::string _cipher;
|
|
99
98
|
PCCERT_CONTEXT _peerCertificate;
|
|
100
99
|
std::function<bool(CtxtHandle, const Ice::SSL::ConnectionInfoPtr&)> _remoteCertificateValidationCallback;
|
|
101
100
|
bool _clientCertificateRequired;
|