zeroc-ice 3.8.2 → 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.
Files changed (256) hide show
  1. checksums.yaml +4 -4
  2. data/dist/IceRuby/Communicator.cpp +26 -9
  3. data/dist/IceRuby/Config.h +0 -12
  4. data/dist/IceRuby/Connection.cpp +18 -9
  5. data/dist/IceRuby/DefaultSliceLoader.h +1 -1
  6. data/dist/IceRuby/Endpoint.cpp +21 -8
  7. data/dist/IceRuby/Operation.cpp +7 -5
  8. data/dist/IceRuby/Properties.cpp +3 -4
  9. data/dist/IceRuby/Proxy.cpp +11 -19
  10. data/dist/IceRuby/RubySliceLoader.cpp +1 -1
  11. data/dist/IceRuby/RubySliceLoader.h +6 -0
  12. data/dist/IceRuby/Types.cpp +162 -138
  13. data/dist/IceRuby/Types.h +68 -28
  14. data/dist/IceRuby/Util.cpp +14 -78
  15. data/dist/IceRuby/Util.h +7 -17
  16. data/dist/ice/cpp/include/Ice/Communicator.h +31 -8
  17. data/dist/ice/cpp/include/Ice/Config.h +2 -2
  18. data/dist/ice/cpp/include/Ice/Connection.h +24 -8
  19. data/dist/ice/cpp/include/Ice/CtrlCHandler.h +1 -1
  20. data/dist/ice/cpp/include/Ice/Demangle.h +1 -1
  21. data/dist/ice/cpp/include/Ice/Endpoint.h +4 -4
  22. data/dist/ice/cpp/include/Ice/Initialize.h +4 -4
  23. data/dist/ice/cpp/include/Ice/InputStream.h +5 -5
  24. data/dist/ice/cpp/include/Ice/Instrumentation.h +13 -7
  25. data/dist/ice/cpp/include/Ice/LocalExceptions.h +5 -5
  26. data/dist/ice/cpp/include/Ice/Logger.h +7 -0
  27. data/dist/ice/cpp/include/Ice/LoggerUtil.h +1 -1
  28. data/dist/ice/cpp/include/Ice/Object.h +10 -8
  29. data/dist/ice/cpp/include/Ice/ObjectAdapter.h +1 -1
  30. data/dist/ice/cpp/include/Ice/OutgoingAsync.h +5 -2
  31. data/dist/ice/cpp/include/Ice/OutgoingResponse.h +2 -1
  32. data/dist/ice/cpp/include/Ice/OutputStream.h +7 -6
  33. data/dist/ice/cpp/include/Ice/PluginFactory.h +1 -1
  34. data/dist/ice/cpp/include/Ice/Properties.h +3 -3
  35. data/dist/ice/cpp/include/Ice/Proxy.h +192 -50
  36. data/dist/ice/cpp/include/Ice/SSL/ClientAuthenticationOptions.h +3 -3
  37. data/dist/ice/cpp/include/Ice/SSL/EndpointInfo.h +1 -1
  38. data/dist/ice/cpp/include/Ice/SSL/ServerAuthenticationOptions.h +5 -5
  39. data/dist/ice/cpp/include/Ice/ServantLocator.h +1 -1
  40. data/dist/ice/cpp/include/Ice/Service.h +2 -5
  41. data/dist/ice/cpp/include/Ice/SliceLoader.h +1 -1
  42. data/dist/ice/cpp/include/Ice/SlicedData.h +5 -3
  43. data/dist/ice/cpp/include/Ice/StreamHelpers.h +1 -1
  44. data/dist/ice/cpp/include/Ice/StreamableTraits.h +2 -2
  45. data/dist/ice/cpp/include/Ice/StringConverter.h +2 -3
  46. data/dist/ice/cpp/include/Ice/StringUtil.h +2 -7
  47. data/dist/ice/cpp/include/Ice/UUID.h +1 -0
  48. data/dist/ice/cpp/include/Ice/Value.h +2 -2
  49. data/dist/ice/cpp/include/generated/Ice/BuiltinSequences.h +2 -2
  50. data/dist/ice/cpp/include/generated/Ice/Context.h +2 -2
  51. data/dist/ice/cpp/include/generated/Ice/EndpointTypes.h +2 -2
  52. data/dist/ice/cpp/include/generated/Ice/Identity.h +2 -2
  53. data/dist/ice/cpp/include/generated/Ice/Locator.h +50 -14
  54. data/dist/ice/cpp/include/generated/Ice/LocatorRegistry.h +38 -11
  55. data/dist/ice/cpp/include/generated/Ice/Metrics.h +94 -39
  56. data/dist/ice/cpp/include/generated/Ice/OperationMode.h +2 -2
  57. data/dist/ice/cpp/include/generated/Ice/Process.h +34 -8
  58. data/dist/ice/cpp/include/generated/Ice/PropertiesAdmin.h +42 -11
  59. data/dist/ice/cpp/include/generated/Ice/PropertyDict.h +2 -2
  60. data/dist/ice/cpp/include/generated/Ice/RemoteLogger.h +93 -40
  61. data/dist/ice/cpp/include/generated/Ice/ReplyStatus.h +2 -2
  62. data/dist/ice/cpp/include/generated/Ice/Router.h +50 -14
  63. data/dist/ice/cpp/include/generated/Ice/SliceChecksumDict.h +2 -2
  64. data/dist/ice/cpp/include/generated/Ice/Version.h +2 -2
  65. data/dist/ice/cpp/include/generated/IceDiscovery/Lookup.h +66 -14
  66. data/dist/ice/cpp/include/generated/IceLocatorDiscovery/Lookup.h +34 -8
  67. data/dist/ice/cpp/src/Ice/AddDefaultPluginFactories_all.cpp +1 -1
  68. data/dist/ice/cpp/src/Ice/Base64.cpp +47 -137
  69. data/dist/ice/cpp/src/Ice/Base64.h +2 -2
  70. data/dist/ice/cpp/src/Ice/BatchRequestQueue.cpp +28 -13
  71. data/dist/ice/cpp/src/Ice/BatchRequestQueue.h +5 -1
  72. data/dist/ice/cpp/src/Ice/Buffer.cpp +1 -1
  73. data/dist/ice/cpp/src/Ice/CollocatedRequestHandler.cpp +1 -1
  74. data/dist/ice/cpp/src/Ice/CollocatedRequestHandler.h +1 -1
  75. data/dist/ice/cpp/src/Ice/Communicator.cpp +4 -3
  76. data/dist/ice/cpp/src/Ice/CommunicatorFlushBatchAsync.cpp +8 -0
  77. data/dist/ice/cpp/src/Ice/ConnectRequestHandler.cpp +5 -15
  78. data/dist/ice/cpp/src/Ice/ConnectRequestHandler.h +1 -1
  79. data/dist/ice/cpp/src/Ice/ConnectionFactory.cpp +6 -8
  80. data/dist/ice/cpp/src/Ice/ConnectionFactory.h +0 -3
  81. data/dist/ice/cpp/src/Ice/ConnectionI.cpp +94 -99
  82. data/dist/ice/cpp/src/Ice/ConnectionI.h +11 -8
  83. data/dist/ice/cpp/src/Ice/ConsoleUtil.cpp +1 -1
  84. data/dist/ice/cpp/src/Ice/DefaultsAndOverrides.cpp +10 -14
  85. data/dist/ice/cpp/src/Ice/EndpointI.h +1 -1
  86. data/dist/ice/cpp/src/Ice/FileUtil.cpp +12 -12
  87. data/dist/ice/cpp/src/Ice/FixedRequestHandler.cpp +1 -1
  88. data/dist/ice/cpp/src/Ice/FixedRequestHandler.h +1 -1
  89. data/dist/ice/cpp/src/Ice/HttpParser.h +0 -2
  90. data/dist/ice/cpp/src/Ice/IdleTimeoutTransceiverDecorator.cpp +6 -3
  91. data/dist/ice/cpp/src/Ice/IncomingRequest.cpp +1 -3
  92. data/dist/ice/cpp/src/Ice/InputStream.cpp +23 -19
  93. data/dist/ice/cpp/src/Ice/Instance.cpp +73 -50
  94. data/dist/ice/cpp/src/Ice/Instance.h +1 -6
  95. data/dist/ice/cpp/src/Ice/LocalExceptions.cpp +1 -1
  96. data/dist/ice/cpp/src/Ice/LocatorInfo.cpp +2 -2
  97. data/dist/ice/cpp/src/Ice/LoggerAdminI.cpp +13 -18
  98. data/dist/ice/cpp/src/Ice/LoggerI.cpp +1 -1
  99. data/dist/ice/cpp/src/Ice/LoggerI.h +2 -2
  100. data/dist/ice/cpp/src/Ice/MetricsAdminI.h +6 -1
  101. data/dist/ice/cpp/src/Ice/MetricsObserverI.h +22 -18
  102. data/dist/ice/cpp/src/Ice/NativePropertiesAdmin.cpp +5 -2
  103. data/dist/ice/cpp/src/Ice/Network.cpp +168 -103
  104. data/dist/ice/cpp/src/Ice/Network.h +12 -7
  105. data/dist/ice/cpp/src/Ice/NetworkProxy.cpp +17 -6
  106. data/dist/ice/cpp/src/Ice/NetworkProxy.h +2 -1
  107. data/dist/ice/cpp/src/Ice/Object.cpp +1 -1
  108. data/dist/ice/cpp/src/Ice/ObjectAdapterI.cpp +56 -19
  109. data/dist/ice/cpp/src/Ice/OpaqueEndpointI.cpp +10 -10
  110. data/dist/ice/cpp/src/Ice/Options.cpp +7 -2
  111. data/dist/ice/cpp/src/Ice/OutgoingAsync.cpp +1 -1
  112. data/dist/ice/cpp/src/Ice/OutputStream.cpp +4 -4
  113. data/dist/ice/cpp/src/Ice/PluginManagerI.cpp +7 -1
  114. data/dist/ice/cpp/src/Ice/Properties.cpp +26 -16
  115. data/dist/ice/cpp/src/Ice/PropertyUtil.cpp +1 -1
  116. data/dist/ice/cpp/src/Ice/ProtocolInstance.cpp +0 -11
  117. data/dist/ice/cpp/src/Ice/ProtocolInstance.h +1 -2
  118. data/dist/ice/cpp/src/Ice/Proxy.cpp +9 -1
  119. data/dist/ice/cpp/src/Ice/ProxyAsync.cpp +110 -13
  120. data/dist/ice/cpp/src/Ice/Random.cpp +68 -7
  121. data/dist/ice/cpp/src/Ice/Random.h +6 -2
  122. data/dist/ice/cpp/src/Ice/Reference.cpp +22 -11
  123. data/dist/ice/cpp/src/Ice/Reference.h +3 -0
  124. data/dist/ice/cpp/src/Ice/ReferenceFactory.cpp +10 -0
  125. data/dist/ice/cpp/src/Ice/RequestHandler.h +3 -1
  126. data/dist/ice/cpp/src/Ice/RequestHandlerCache.cpp +1 -1
  127. data/dist/ice/cpp/src/Ice/RequestHandlerCache.h +1 -1
  128. data/dist/ice/cpp/src/Ice/ResourceConfig.h +3 -3
  129. data/dist/ice/cpp/src/Ice/RetryQueue.cpp +8 -12
  130. data/dist/ice/cpp/src/Ice/SHA1.cpp +11 -11
  131. data/dist/ice/cpp/src/Ice/SSL/DistinguishedName.cpp +0 -6
  132. data/dist/ice/cpp/src/Ice/SSL/DistinguishedName.h +0 -6
  133. data/dist/ice/cpp/src/Ice/SSL/OpenSSLEngine.cpp +15 -1
  134. data/dist/ice/cpp/src/Ice/SSL/OpenSSLTransceiverI.cpp +77 -27
  135. data/dist/ice/cpp/src/Ice/SSL/OpenSSLTransceiverI.h +2 -1
  136. data/dist/ice/cpp/src/Ice/SSL/RFC2253.cpp +2 -2
  137. data/dist/ice/cpp/src/Ice/SSL/SSLUtil.cpp +39 -34
  138. data/dist/ice/cpp/src/Ice/SSL/SchannelEngine.cpp +130 -52
  139. data/dist/ice/cpp/src/Ice/SSL/SchannelTransceiverI.cpp +64 -33
  140. data/dist/ice/cpp/src/Ice/SSL/SchannelTransceiverI.h +0 -1
  141. data/dist/ice/cpp/src/Ice/SSL/SecureTransportEngine.cpp +3 -3
  142. data/dist/ice/cpp/src/Ice/SSL/SecureTransportTransceiverI.cpp +9 -3
  143. data/dist/ice/cpp/src/Ice/SSL/SecureTransportUtil.cpp +73 -51
  144. data/dist/ice/cpp/src/Ice/SSL/SecureTransportUtil.h +0 -8
  145. data/dist/ice/cpp/src/Ice/Selector.cpp +13 -11
  146. data/dist/ice/cpp/src/Ice/ServantManager.cpp +3 -3
  147. data/dist/ice/cpp/src/Ice/Service.cpp +33 -115
  148. data/dist/ice/cpp/src/Ice/StreamSocket.cpp +33 -40
  149. data/dist/ice/cpp/src/Ice/StreamSocket.h +4 -4
  150. data/dist/ice/cpp/src/Ice/StringConverter.cpp +1 -1
  151. data/dist/ice/cpp/src/Ice/StringUtil.cpp +12 -21
  152. data/dist/ice/cpp/src/Ice/SysLoggerI.cpp +136 -100
  153. data/dist/ice/cpp/src/Ice/SysLoggerI.h +7 -3
  154. data/dist/ice/cpp/src/Ice/SystemdJournalI.cpp +1 -1
  155. data/dist/ice/cpp/src/Ice/TcpAcceptor.cpp +7 -7
  156. data/dist/ice/cpp/src/Ice/TcpAcceptor.h +2 -1
  157. data/dist/ice/cpp/src/Ice/TcpBufSize.h +40 -0
  158. data/dist/ice/cpp/src/Ice/TcpConnector.cpp +5 -2
  159. data/dist/ice/cpp/src/Ice/TcpConnector.h +2 -0
  160. data/dist/ice/cpp/src/Ice/TcpTransceiver.cpp +6 -2
  161. data/dist/ice/cpp/src/Ice/ThreadPool.cpp +2 -8
  162. data/dist/ice/cpp/src/Ice/ThreadPool.h +0 -2
  163. data/dist/ice/cpp/src/Ice/Timer.cpp +7 -3
  164. data/dist/ice/cpp/src/Ice/UUID.cpp +1 -2
  165. data/dist/ice/cpp/src/Ice/UdpEndpointI.cpp +4 -1
  166. data/dist/ice/cpp/src/Ice/UdpTransceiver.cpp +136 -123
  167. data/dist/ice/cpp/src/Ice/UdpTransceiver.h +3 -4
  168. data/dist/ice/cpp/src/Ice/WSTransceiver.cpp +96 -27
  169. data/dist/ice/cpp/src/Ice/WSTransceiver.h +1 -1
  170. data/dist/ice/cpp/src/Ice/generated/BuiltinSequences.cpp +2 -2
  171. data/dist/ice/cpp/src/Ice/generated/Context.cpp +2 -2
  172. data/dist/ice/cpp/src/Ice/generated/EndpointTypes.cpp +2 -2
  173. data/dist/ice/cpp/src/Ice/generated/Identity.cpp +2 -2
  174. data/dist/ice/cpp/src/Ice/generated/Locator.cpp +2 -2
  175. data/dist/ice/cpp/src/Ice/generated/LocatorRegistry.cpp +2 -2
  176. data/dist/ice/cpp/src/Ice/generated/Metrics.cpp +2 -2
  177. data/dist/ice/cpp/src/Ice/generated/OperationMode.cpp +2 -2
  178. data/dist/ice/cpp/src/Ice/generated/Process.cpp +2 -2
  179. data/dist/ice/cpp/src/Ice/generated/PropertiesAdmin.cpp +2 -2
  180. data/dist/ice/cpp/src/Ice/generated/PropertyDict.cpp +2 -2
  181. data/dist/ice/cpp/src/Ice/generated/RemoteLogger.cpp +2 -2
  182. data/dist/ice/cpp/src/Ice/generated/ReplyStatus.cpp +2 -2
  183. data/dist/ice/cpp/src/Ice/generated/Router.cpp +2 -2
  184. data/dist/ice/cpp/src/Ice/generated/SliceChecksumDict.cpp +2 -2
  185. data/dist/ice/cpp/src/Ice/generated/Version.cpp +2 -2
  186. data/dist/ice/cpp/src/IceDiscovery/LookupI.cpp +47 -9
  187. data/dist/ice/cpp/src/IceDiscovery/LookupI.h +8 -3
  188. data/dist/ice/cpp/src/IceDiscovery/generated/Lookup.cpp +2 -2
  189. data/dist/ice/cpp/src/IceLocatorDiscovery/PluginI.cpp +43 -14
  190. data/dist/ice/cpp/src/IceLocatorDiscovery/generated/Lookup.cpp +2 -2
  191. data/dist/ice/cpp/src/Slice/DocCommentParser.cpp +26 -20
  192. data/dist/ice/cpp/src/Slice/DocCommentParser.h +2 -2
  193. data/dist/ice/cpp/src/Slice/FileTracker.cpp +3 -11
  194. data/dist/ice/cpp/src/Slice/FileTracker.h +0 -2
  195. data/dist/ice/cpp/src/Slice/Grammar.cpp +211 -210
  196. data/dist/ice/cpp/src/Slice/MetadataValidation.cpp +10 -9
  197. data/dist/ice/cpp/src/Slice/Parser.cpp +28 -20
  198. data/dist/ice/cpp/src/Slice/Parser.h +3 -4
  199. data/dist/ice/cpp/src/Slice/Preprocessor.cpp +3 -11
  200. data/dist/ice/cpp/src/Slice/Preprocessor.h +0 -2
  201. data/dist/ice/cpp/src/Slice/Scanner.cpp +3 -3
  202. data/dist/ice/cpp/src/Slice/SliceUtil.cpp +197 -114
  203. data/dist/ice/cpp/src/Slice/StringLiteralUtil.cpp +0 -2
  204. data/dist/ice/cpp/src/Slice/Util.h +21 -9
  205. data/dist/ice/cpp/src/slice2rb/Ruby.cpp +7 -3
  206. data/dist/ice/cpp/src/slice2rb/RubyUtil.cpp +16 -12
  207. data/dist/ice/cpp/src/slice2rb/RubyUtil.h +3 -3
  208. data/dist/ice/slice/Glacier2/Router.ice +3 -3
  209. data/dist/ice/slice/Ice/Metrics.ice +6 -5
  210. data/dist/ice/slice/Ice/RemoteLogger.ice +5 -5
  211. data/dist/ice/slice/IceGrid/Admin.ice +9 -9
  212. data/dist/ice/slice/IceGrid/Descriptor.ice +5 -5
  213. data/dist/ice/slice/IceStorm/Metrics.ice +1 -1
  214. data/dist/lib/Glacier2/Metrics.rb +1 -1
  215. data/dist/lib/Glacier2/PermissionsVerifier.rb +1 -1
  216. data/dist/lib/Glacier2/Router.rb +2 -2
  217. data/dist/lib/Glacier2/SSLInfo.rb +1 -1
  218. data/dist/lib/Glacier2/Session.rb +1 -1
  219. data/dist/lib/Ice/BuiltinSequences.rb +1 -1
  220. data/dist/lib/Ice/CompressBatch.rb +1 -2
  221. data/dist/lib/Ice/Context.rb +1 -1
  222. data/dist/lib/Ice/EndpointSelectionType.rb +1 -2
  223. data/dist/lib/Ice/EndpointTypes.rb +1 -1
  224. data/dist/lib/Ice/Identity.rb +1 -1
  225. data/dist/lib/Ice/IdentitySpaceship.rb +1 -0
  226. data/dist/lib/Ice/Locator.rb +1 -1
  227. data/dist/lib/Ice/LocatorRegistry.rb +1 -1
  228. data/dist/lib/Ice/Metrics.rb +1 -1
  229. data/dist/lib/Ice/OperationMode.rb +2 -3
  230. data/dist/lib/Ice/Process.rb +1 -1
  231. data/dist/lib/Ice/PropertiesAdmin.rb +1 -1
  232. data/dist/lib/Ice/PropertyDict.rb +1 -1
  233. data/dist/lib/Ice/RemoteLogger.rb +2 -3
  234. data/dist/lib/Ice/ReplyStatus.rb +2 -3
  235. data/dist/lib/Ice/Router.rb +1 -1
  236. data/dist/lib/Ice/SliceChecksumDict.rb +1 -1
  237. data/dist/lib/Ice/SliceUtil.rb +2 -2
  238. data/dist/lib/Ice/Struct.rb +1 -0
  239. data/dist/lib/Ice/ToStringMode.rb +1 -2
  240. data/dist/lib/Ice/Value.rb +2 -2
  241. data/dist/lib/Ice/Version.rb +1 -1
  242. data/dist/lib/IceBox/ServiceManager.rb +1 -1
  243. data/dist/lib/IceGrid/Admin.rb +3 -4
  244. data/dist/lib/IceGrid/Descriptor.rb +1 -1
  245. data/dist/lib/IceGrid/Exception.rb +1 -1
  246. data/dist/lib/IceGrid/FileParser.rb +1 -1
  247. data/dist/lib/IceGrid/Registry.rb +2 -3
  248. data/dist/lib/IceGrid/Session.rb +2 -2
  249. data/dist/lib/IceGrid/UserAccountMapper.rb +1 -1
  250. data/dist/lib/IceStorm/IceStorm.rb +1 -1
  251. data/dist/lib/IceStorm/Metrics.rb +1 -1
  252. data/extconf.rb +1 -1
  253. data/ice.gemspec +3 -3
  254. metadata +4 -5
  255. data/dist/ice/cpp/src/Ice/DLLMain.cpp +0 -40
  256. 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 `IceSSL.FindCert' property:\n" +
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(X509_ASN_ENCODING, argW.c_str(), flags[i], 0, &buffer[0], &length, 0))
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 `IceSSL.FindCert' property:\n" +
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, &buffer[0]};
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: can't decode the value");
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()), &buffer[0]};
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 `IceSSL.FindCert' property");
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()), &serialData[0]};
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)) != 0)
578
+ next)) != nullptr)
572
579
  {
573
- certs.push_back(next);
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
- size = endpos - startpos + sizeof("-----END CERTIFICATE-----");
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
- &outBuffer[0],
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
- &outBuffer[0],
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 to the subject alt
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)
@@ -759,23 +803,11 @@ Schannel::SSLEngine::~SSLEngine()
759
803
  CertCloseStore(_rootStore, 0);
760
804
  }
761
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.
762
808
  for (vector<PCCERT_CONTEXT>::const_iterator i = _importedCerts.begin(); i != _importedCerts.end(); ++i)
763
809
  {
764
- // Retrieve the certificate CERT_KEY_PROV_INFO_PROP_ID property, we use the CRYPT_KEY_PROV_INFO data to
765
- // remove the key set associated with the certificate.
766
- DWORD length = 0;
767
- if (!CertGetCertificateContextProperty(*i, CERT_KEY_PROV_INFO_PROP_ID, 0, &length))
768
- {
769
- continue;
770
- }
771
- vector<char> buf(length);
772
- if (!CertGetCertificateContextProperty(*i, CERT_KEY_PROV_INFO_PROP_ID, &buf[0], &length))
773
- {
774
- continue;
775
- }
776
- CRYPT_KEY_PROV_INFO* key = reinterpret_cast<CRYPT_KEY_PROV_INFO*>(&buf[0]);
777
- HCRYPTPROV prov = 0;
778
- CryptAcquireContextW(&prov, key->pwszContainerName, key->pwszProvName, key->dwProvType, CRYPT_DELETEKEYSET);
810
+ deleteKeyContainer(*i);
779
811
  }
780
812
 
781
813
  for (vector<PCCERT_CONTEXT>::const_iterator i = _allCerts.begin(); i != _allCerts.end(); ++i)
@@ -785,7 +817,15 @@ Schannel::SSLEngine::~SSLEngine()
785
817
 
786
818
  for (vector<HCERTSTORE>::const_iterator i = _stores.begin(); i != _stores.end(); ++i)
787
819
  {
820
+ #ifdef NDEBUG
788
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
789
829
  }
790
830
  }
791
831
  catch (...)
@@ -796,11 +836,8 @@ Schannel::SSLEngine::~SSLEngine()
796
836
  void
797
837
  Schannel::SSLEngine::initialize()
798
838
  {
799
- //
800
- // BUGFIX: we use a global mutex for the initialization of Schannel to
801
- // avoid crashes occurring with last Schannel updates see:
802
- // https://github.com/zeroc-ice/ice/issues/242
803
- //
839
+ // We use a global mutex for the initialization of Schannel to avoid crashes observed with some Schannel
840
+ // updates.
804
841
  lock_guard globalLock(globalMutex);
805
842
 
806
843
  Ice::SSL::SSLEngine::initialize();
@@ -906,7 +943,7 @@ Schannel::SSLEngine::initialize()
906
943
 
907
944
  CRYPT_DATA_BLOB pfxBlob;
908
945
  pfxBlob.cbData = static_cast<DWORD>(buffer.size());
909
- pfxBlob.pbData = reinterpret_cast<BYTE*>(&buffer[0]);
946
+ pfxBlob.pbData = reinterpret_cast<BYTE*>(buffer.data());
910
947
 
911
948
  PCCERT_CONTEXT cert = nullptr;
912
949
  DWORD importFlags = (certStoreLocation == "LocalMachine") ? CRYPT_MACHINE_KEYSET : CRYPT_USER_KEYSET;
@@ -952,10 +989,10 @@ Schannel::SSLEngine::initialize()
952
989
  }
953
990
  if (!cert)
954
991
  {
955
- throw InitializationException(
956
- __FILE__,
957
- __LINE__,
958
- "SSL transport: certificate error:\n" + lastErrorToString());
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);
959
996
  }
960
997
  _allCerts.push_back(cert);
961
998
  _stores.push_back(store);
@@ -996,10 +1033,10 @@ Schannel::SSLEngine::initialize()
996
1033
 
997
1034
  // Convert the PEM encoded buffer to DER binary format.
998
1035
  if (!CryptStringToBinary(
999
- &buffer[0],
1036
+ buffer.data(),
1000
1037
  static_cast<DWORD>(buffer.size()),
1001
1038
  CRYPT_STRING_BASE64HEADER,
1002
- &outBuffer[0],
1039
+ outBuffer.data(),
1003
1040
  &outLength,
1004
1041
  0,
1005
1042
  0))
@@ -1012,6 +1049,10 @@ Schannel::SSLEngine::initialize()
1012
1049
  PCRYPT_PRIVATE_KEY_INFO keyInfo = nullptr;
1013
1050
  BYTE* key = nullptr;
1014
1051
  HCRYPTKEY hKey = 0;
1052
+ HCRYPTPROV cryptProv = 0;
1053
+ wstring keySetName;
1054
+ DWORD contextFlags = 0;
1055
+ bool keySetCreated = false;
1015
1056
  try
1016
1057
  {
1017
1058
  // First try to decode as a PKCS#8 key, if that fails try PKCS#1.
@@ -1019,7 +1060,7 @@ Schannel::SSLEngine::initialize()
1019
1060
  if (CryptDecodeObjectEx(
1020
1061
  X509_ASN_ENCODING,
1021
1062
  PKCS_PRIVATE_KEY_INFO,
1022
- &outBuffer[0],
1063
+ outBuffer.data(),
1023
1064
  outLength,
1024
1065
  CRYPT_DECODE_ALLOC_FLAG,
1025
1066
  0,
@@ -1058,7 +1099,7 @@ Schannel::SSLEngine::initialize()
1058
1099
  if (!CryptDecodeObjectEx(
1059
1100
  X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
1060
1101
  PKCS_RSA_PRIVATE_KEY,
1061
- &outBuffer[0],
1102
+ outBuffer.data(),
1062
1103
  outLength,
1063
1104
  CRYPT_DECODE_ALLOC_FLAG,
1064
1105
  0,
@@ -1072,10 +1113,9 @@ Schannel::SSLEngine::initialize()
1072
1113
  }
1073
1114
 
1074
1115
  // Create a new RSA key set to store our key.
1075
- const wstring keySetName = Ice::stringToWstring(generateUUID());
1076
- HCRYPTPROV cryptProv = 0;
1116
+ keySetName = Ice::stringToWstring(generateUUID());
1077
1117
 
1078
- DWORD contextFlags = CRYPT_NEWKEYSET;
1118
+ contextFlags = CRYPT_NEWKEYSET;
1079
1119
  if (certStoreLocation == "LocalMachine")
1080
1120
  {
1081
1121
  contextFlags |= CRYPT_MACHINE_KEYSET;
@@ -1093,6 +1133,7 @@ Schannel::SSLEngine::initialize()
1093
1133
  __LINE__,
1094
1134
  "SSL transport: error acquiring cryptographic context:\n" + lastErrorToString());
1095
1135
  }
1136
+ keySetCreated = true;
1096
1137
 
1097
1138
  // Import the private key.
1098
1139
  if (!CryptImportKey(cryptProv, key, outLength, 0, 0, &hKey))
@@ -1106,6 +1147,8 @@ Schannel::SSLEngine::initialize()
1106
1147
 
1107
1148
  CryptDestroyKey(hKey);
1108
1149
  hKey = 0;
1150
+ CryptReleaseContext(cryptProv, 0);
1151
+ cryptProv = 0;
1109
1152
 
1110
1153
  // Create a new memory store to place the certificate.
1111
1154
  store = CertOpenStore(CERT_STORE_PROV_MEMORY, 0, 0, 0, 0);
@@ -1123,8 +1166,11 @@ Schannel::SSLEngine::initialize()
1123
1166
  CRYPT_KEY_PROV_INFO keyProvInfo;
1124
1167
  memset(&keyProvInfo, 0, sizeof(keyProvInfo));
1125
1168
  keyProvInfo.pwszContainerName = const_cast<wchar_t*>(keySetName.c_str());
1126
- keyProvInfo.pwszProvName = const_cast<wchar_t*>(MS_DEF_PROV_W);
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);
1127
1172
  keyProvInfo.dwProvType = PROV_RSA_FULL;
1173
+ keyProvInfo.dwFlags = contextFlags & CRYPT_MACHINE_KEYSET;
1128
1174
  keyProvInfo.dwKeySpec = AT_KEYEXCHANGE;
1129
1175
  if (!CertSetCertificateContextProperty(cert, CERT_KEY_PROV_INFO_PROP_ID, 0, &keyProvInfo))
1130
1176
  {
@@ -1155,6 +1201,24 @@ Schannel::SSLEngine::initialize()
1155
1201
  CryptDestroyKey(hKey);
1156
1202
  }
1157
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
+
1158
1222
  if (cert)
1159
1223
  {
1160
1224
  CertFreeCertificateContext(cert);
@@ -1267,15 +1331,22 @@ Schannel::SSLEngine::createClientAuthenticationOptions(const string& host) const
1267
1331
  .clientCredentialsSelectionCallback =
1268
1332
  [this](const string&)
1269
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.
1270
1338
  for (const auto& cert : _allCerts)
1271
1339
  {
1272
- CertDuplicateCertificateContext(cert);
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);
1273
1344
  }
1274
1345
 
1275
1346
  return SCH_CREDENTIALS{
1276
1347
  .dwVersion = SCH_CREDENTIALS_VERSION,
1277
1348
  .cCreds = static_cast<DWORD>(_allCerts.size()),
1278
- .paCred = const_cast<PCCERT_CONTEXT*>(_allCerts.size() > 0 ? &_allCerts[0] : nullptr),
1349
+ .paCred = const_cast<PCCERT_CONTEXT*>(_allCerts.data()),
1279
1350
  .dwFlags = SCH_CRED_NO_DEFAULT_CREDS | SCH_CRED_NO_SERVERNAME_CHECK | SCH_USE_STRONG_CRYPTO};
1280
1351
  },
1281
1352
  .trustedRootCertificates = _rootStore,
@@ -1312,17 +1383,24 @@ Schannel::SSLEngine::createServerAuthenticationOptions() const
1312
1383
  [this](const string&)
1313
1384
  {
1314
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.
1315
1390
  for (const auto& cert : _allCerts)
1316
1391
  {
1317
- CertDuplicateCertificateContext(cert);
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);
1318
1396
  }
1319
1397
 
1320
1398
  return SCH_CREDENTIALS{
1321
1399
  .dwVersion = SCH_CREDENTIALS_VERSION,
1322
1400
  .cCreds = static_cast<DWORD>(_allCerts.size()),
1323
- .paCred = const_cast<PCCERT_CONTEXT*>(_allCerts.size() > 0 ? &_allCerts[0] : nullptr),
1401
+ .paCred = const_cast<PCCERT_CONTEXT*>(_allCerts.data()),
1324
1402
  // Don't set SCH_SEND_ROOT_CERT as it seems to cause problems with Java certificate validation and
1325
- // Schannel doesn't seems to send the root certificate either way.
1403
+ // Schannel doesn't seem to send the root certificate either way.
1326
1404
  .dwFlags = SCH_CRED_NO_SYSTEM_MAPPER | SCH_USE_STRONG_CRYPTO};
1327
1405
  }
1328
1406
  },
@@ -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 seems to send the root certificate either way.
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
- for (DWORD i = 0; i < _credentials.cCreds; ++i)
139
+ if (!_credentials.paCred)
140
140
  {
141
- if (!_credentials.paCred[i])
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());
@@ -579,7 +605,15 @@ Schannel::TransceiverI::decryptMessage(IceInternal::Buffer& buffer)
579
605
  memcpy(_extraBuffer.i, extraBuffer->pvBuffer, extraBuffer->cbBuffer);
580
606
  _extraBuffer.i += extraBuffer->cbBuffer;
581
607
  }
582
- return 0;
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;
583
617
  }
584
618
  else if (err == SEC_I_CONTEXT_EXPIRED)
585
619
  {
@@ -803,6 +837,9 @@ Schannel::TransceiverI::read(IceInternal::Buffer& buf)
803
837
  }
804
838
 
805
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;
806
843
  if (_sslConnectionRenegotiating)
807
844
  {
808
845
  // The peer has requested a renegotiation.
@@ -828,8 +865,6 @@ Schannel::TransceiverI::read(IceInternal::Buffer& buf)
828
865
  }
829
866
  continue;
830
867
  }
831
-
832
- buf.i += decrypted;
833
868
  }
834
869
  _delegate->getNativeInfo()->ready(
835
870
  IceInternal::SocketOperationRead,
@@ -899,10 +934,14 @@ Schannel::TransceiverI::finishRead(IceInternal::Buffer& buf)
899
934
  _delegate->finishRead(_readBuffer);
900
935
  if (_state == StateHandshakeComplete)
901
936
  {
902
- size_t decrypted;
903
- while (true)
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()))
904
942
  {
905
- decrypted = decryptMessage(buf);
943
+ size_t decrypted = decryptMessage(buf);
944
+ buf.i += decrypted;
906
945
  if (_sslConnectionRenegotiating)
907
946
  {
908
947
  // The peer has requested a renegotiation.
@@ -912,31 +951,23 @@ Schannel::TransceiverI::finishRead(IceInternal::Buffer& buf)
912
951
  _extraBuffer.b.begin()};
913
952
  IceInternal::SocketOperation op = sslHandshake(&extraBuffer);
914
953
  _extraBuffer.b.clear();
915
- if (op == IceInternal::SocketOperationNone)
954
+ if (op != IceInternal::SocketOperationNone)
916
955
  {
917
- _sslConnectionRenegotiating = false;
918
- if (buf.i != buf.b.begin())
919
- {
920
- continue;
921
- }
922
- break;
956
+ throw ConnectionLostException(__FILE__, __LINE__);
923
957
  }
924
- throw ConnectionLostException(__FILE__, __LINE__);
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;
925
965
  }
926
- break;
927
966
  }
928
967
 
929
- if (decrypted > 0)
930
- {
931
- buf.i += decrypted;
932
- _delegate->getNativeInfo()->ready(
933
- IceInternal::SocketOperationRead,
934
- !_readUnprocessed.b.empty() || _readBuffer.i != _readBuffer.b.begin());
935
- }
936
- else
937
- {
938
- _delegate->getNativeInfo()->ready(IceInternal::SocketOperationRead, false);
939
- }
968
+ _delegate->getNativeInfo()->ready(
969
+ IceInternal::SocketOperationRead,
970
+ buf.i != start && (!_readUnprocessed.b.empty() || _readBuffer.i != _readBuffer.b.begin()));
940
971
  }
941
972
  }
942
973
 
@@ -1074,8 +1105,8 @@ Schannel::TransceiverI::TransceiverI(
1074
1105
  false); // Whether or not revocation checks only uses cached information.
1075
1106
  };
1076
1107
  }
1077
- // If the user provides a validation callback is up to the callback to validate the certificate chain.
1078
- // If the user doesn't set the trusted root certificates, we use Schannel default behavior, with uses the system
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
1079
1110
  // trusted root certificates.
1080
1111
  }
1081
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;
@@ -34,8 +34,8 @@ namespace
34
34
  //
35
35
  // Retrieve the name of a cipher, SSLCipherSuite includes duplicated values for TLS/SSL
36
36
  // protocol ciphers, for example SSL_RSA_WITH_RC4_128_MD5/TLS_RSA_WITH_RC4_128_MD5
37
- // are represented by the same SSLCipherSuite value, the names return by this method
38
- // doesn't include a protocol prefix.
37
+ // are represented by the same SSLCipherSuite value: the names returned by this method
38
+ // don't include a protocol prefix.
39
39
  //
40
40
  string cipherName(SSLCipherSuite cipher)
41
41
  {
@@ -337,7 +337,7 @@ namespace
337
337
  case TLS_PSK_WITH_AES_256_CBC_SHA384:
338
338
  return "PSK_WITH_AES_256_CBC_SHA384";
339
339
  case TLS_PSK_WITH_NULL_SHA256:
340
- return "WITH_NULL_SHA256";
340
+ return "PSK_WITH_NULL_SHA256";
341
341
  case TLS_PSK_WITH_NULL_SHA384:
342
342
  return "PSK_WITH_NULL_SHA384";
343
343
 
@@ -229,7 +229,7 @@ Ice::SSL::SecureTransport::TransceiverI::initialize(IceInternal::Buffer& readBuf
229
229
  continue; // Call SSLHandshake to resume the handshake.
230
230
  }
231
231
  }
232
- // Let it fall through, this will raise a SecurityException with the SSLCopyPeerTrust error.
232
+ // Let it fall through, this will throw a ProtocolException with the SSLCopyPeerTrust error.
233
233
  }
234
234
  else if (err == errSSLClosedGraceful || err == errSSLClosedAbort)
235
235
  {
@@ -245,6 +245,12 @@ Ice::SSL::SecureTransport::TransceiverI::initialize(IceInternal::Buffer& readBuf
245
245
 
246
246
  assert(_ssl);
247
247
 
248
+ if (!_peerCertificate)
249
+ {
250
+ _engine->verifyPeer(dynamic_pointer_cast<ConnectionInfo>(getInfo(_incoming, _adapterName, "")));
251
+ }
252
+ // else verifyPeer is called from the certificate validation callback.
253
+
248
254
  if (_instance->engine()->securityTraceLevel() >= 1)
249
255
  {
250
256
  Trace out(_instance->logger(), _engine->securityTraceCategory());
@@ -345,7 +351,7 @@ Ice::SSL::SecureTransport::TransceiverI::write(IceInternal::Buffer& buf)
345
351
  }
346
352
 
347
353
  //
348
- // SSL protocol errors are defined in SecureTransport.h are in the range
354
+ // SSL protocol errors defined in SecureTransport.h are in the range
349
355
  // -9800 to -9849
350
356
  //
351
357
  if (err <= -9800 && err >= -9849)
@@ -418,7 +424,7 @@ Ice::SSL::SecureTransport::TransceiverI::read(IceInternal::Buffer& buf)
418
424
  }
419
425
 
420
426
  //
421
- // SSL protocol errors are defined in SecureTransport.h are in the range
427
+ // SSL protocol errors defined in SecureTransport.h are in the range
422
428
  // -9800 to -9849
423
429
  //
424
430
  if (err <= -9800 && err >= -9849)