zeroc-ice 3.8.0 → 3.8.2
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/Operation.cpp +22 -6
- data/dist/IceRuby/Slice.cpp +1 -1
- data/dist/ice/cpp/include/Ice/Communicator.h +4 -4
- data/dist/ice/cpp/include/Ice/Config.h +2 -2
- data/dist/ice/cpp/include/Ice/Connection.h +3 -3
- data/dist/ice/cpp/include/Ice/Endpoint.h +2 -2
- data/dist/ice/cpp/include/Ice/Exception.h +1 -1
- data/dist/ice/cpp/include/Ice/Initialize.h +1 -1
- data/dist/ice/cpp/include/Ice/LocalExceptions.h +22 -1
- data/dist/ice/cpp/include/Ice/Logger.h +3 -3
- data/dist/ice/cpp/include/Ice/NativePropertiesAdmin.h +2 -0
- data/dist/ice/cpp/include/Ice/ObjectAdapter.h +3 -3
- data/dist/ice/cpp/include/Ice/ObserverHelper.h +1 -0
- data/dist/ice/cpp/include/Ice/OutputStream.h +27 -5
- data/dist/ice/cpp/include/Ice/Properties.h +3 -3
- data/dist/ice/cpp/include/Ice/Proxy.h +1 -1
- data/dist/ice/cpp/include/Ice/SSL/ClientAuthenticationOptions.h +10 -2
- data/dist/ice/cpp/include/Ice/SSL/ServerAuthenticationOptions.h +10 -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 +9 -11
- data/dist/ice/cpp/include/generated/Ice/LocatorRegistry.h +2 -2
- data/dist/ice/cpp/include/generated/Ice/Metrics.h +7 -7
- data/dist/ice/cpp/include/generated/Ice/OperationMode.h +2 -2
- data/dist/ice/cpp/include/generated/Ice/Process.h +2 -2
- data/dist/ice/cpp/include/generated/Ice/PropertiesAdmin.h +2 -2
- data/dist/ice/cpp/include/generated/Ice/PropertyDict.h +2 -2
- data/dist/ice/cpp/include/generated/Ice/RemoteLogger.h +2 -2
- data/dist/ice/cpp/include/generated/Ice/ReplyStatus.h +8 -4
- data/dist/ice/cpp/include/generated/Ice/Router.h +7 -7
- 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 +2 -2
- data/dist/ice/cpp/include/generated/IceLocatorDiscovery/Lookup.h +2 -2
- data/dist/ice/cpp/src/Ice/CollocatedRequestHandler.cpp +5 -3
- data/dist/ice/cpp/src/Ice/ConnectionFactory.h +8 -8
- data/dist/ice/cpp/src/Ice/ConnectionI.cpp +28 -11
- data/dist/ice/cpp/src/Ice/ConnectionI.h +1 -1
- data/dist/ice/cpp/src/Ice/Demangle.cpp +1 -0
- data/dist/ice/cpp/src/Ice/FileUtil.cpp +3 -67
- data/dist/ice/cpp/src/Ice/FileUtil.h +0 -3
- data/dist/ice/cpp/src/Ice/IPEndpointI.cpp +4 -0
- data/dist/ice/cpp/src/Ice/IncomingRequest.cpp +1 -1
- data/dist/ice/cpp/src/Ice/InputStream.cpp +28 -17
- data/dist/ice/cpp/src/Ice/LocalException.cpp +1 -1
- data/dist/ice/cpp/src/Ice/LocalExceptions.cpp +6 -0
- data/dist/ice/cpp/src/Ice/OutgoingAsync.cpp +1 -1
- 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 +80 -115
- data/dist/ice/cpp/src/Ice/PropertyNames.cpp +3 -2
- data/dist/ice/cpp/src/Ice/ProxyFunctions.cpp +4 -4
- data/dist/ice/cpp/src/Ice/Reference.cpp +15 -15
- data/dist/ice/cpp/src/Ice/ReferenceFactory.cpp +16 -13
- data/dist/ice/cpp/src/Ice/ResourceConfig.h +2 -2
- data/dist/ice/cpp/src/Ice/SSL/OpenSSLEngine.cpp +29 -20
- data/dist/ice/cpp/src/Ice/SSL/OpenSSLEngine.h +1 -2
- data/dist/ice/cpp/src/Ice/SSL/OpenSSLTransceiverI.cpp +14 -3
- data/dist/ice/cpp/src/Ice/SSL/RFC2253.cpp +3 -3
- data/dist/ice/cpp/src/Ice/SSL/SSLEndpointI.cpp +1 -1
- data/dist/ice/cpp/src/Ice/SSL/SSLEngine.h +4 -10
- data/dist/ice/cpp/src/Ice/SSL/SSLUtil.cpp +21 -2
- data/dist/ice/cpp/src/Ice/SSL/SSLUtil.h +15 -1
- data/dist/ice/cpp/src/Ice/SSL/SchannelEngine.cpp +67 -48
- data/dist/ice/cpp/src/Ice/SSL/SchannelEngine.h +1 -5
- data/dist/ice/cpp/src/Ice/SSL/SchannelTransceiverI.cpp +14 -2
- data/dist/ice/cpp/src/Ice/SSL/SecureTransportEngine.cpp +111 -15
- data/dist/ice/cpp/src/Ice/SSL/SecureTransportEngine.h +7 -2
- data/dist/ice/cpp/src/Ice/SSL/SecureTransportTransceiverI.h +1 -1
- data/dist/ice/cpp/src/Ice/SSL/SecureTransportUtil.cpp +3 -16
- data/dist/ice/cpp/src/Ice/SSL/TrustManager.cpp +12 -1
- data/dist/ice/cpp/src/Ice/ServantManager.h +1 -1
- data/dist/ice/cpp/src/Ice/StringConverter.cpp +4 -0
- data/dist/ice/cpp/src/Ice/TcpEndpointI.cpp +2 -2
- data/dist/ice/cpp/src/Ice/UdpEndpointI.cpp +2 -2
- 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 +118 -7
- data/dist/ice/cpp/src/Ice/WSTransceiver.h +12 -1
- 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/LocatorI.cpp +2 -2
- data/dist/ice/cpp/src/IceDiscovery/LookupI.cpp +4 -3
- data/dist/ice/cpp/src/IceDiscovery/LookupI.h +2 -1
- data/dist/ice/cpp/src/IceDiscovery/generated/Lookup.cpp +2 -2
- data/dist/ice/cpp/src/IceLocatorDiscovery/PluginI.cpp +6 -18
- data/dist/ice/cpp/src/IceLocatorDiscovery/generated/Lookup.cpp +2 -2
- data/dist/ice/cpp/src/Slice/DocCommentParser.cpp +6 -6
- data/dist/ice/cpp/src/Slice/DocCommentParser.h +4 -2
- data/dist/ice/cpp/src/Slice/FileTracker.h +1 -0
- data/dist/ice/cpp/src/Slice/Grammar.cpp +261 -264
- data/dist/ice/cpp/src/Slice/MetadataValidation.cpp +39 -7
- data/dist/ice/cpp/src/Slice/MetadataValidation.h +3 -2
- data/dist/ice/cpp/src/Slice/Parser.cpp +192 -155
- data/dist/ice/cpp/src/Slice/Parser.h +44 -9
- data/dist/ice/cpp/src/Slice/Preprocessor.cpp +76 -20
- data/dist/ice/cpp/src/Slice/Preprocessor.h +0 -1
- data/dist/ice/cpp/src/Slice/Scanner.cpp +1 -1
- data/dist/ice/cpp/src/Slice/SliceUtil.cpp +44 -58
- data/dist/ice/cpp/src/Slice/StringLiteralUtil.cpp +3 -10
- data/dist/ice/cpp/src/Slice/Util.h +7 -3
- data/dist/ice/cpp/src/slice2rb/Main.cpp +2 -2
- data/dist/ice/cpp/src/slice2rb/Ruby.cpp +1 -1
- data/dist/ice/cpp/src/slice2rb/RubyUtil.cpp +10 -8
- data/dist/ice/cpp/src/slice2rb/RubyUtil.h +10 -13
- data/dist/ice/mcpp/directive.c +5 -2
- data/dist/ice/mcpp/mcpp_main.c +1 -1
- data/dist/ice/mcpp/support.c +6 -6
- data/dist/ice/mcpp/system.c +5 -5
- 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 +1 -1
- data/dist/ice/slice/Ice/OperationMode.ice +8 -0
- data/dist/ice/slice/Ice/Process.ice +3 -0
- data/dist/ice/slice/Ice/ReplyStatus.ice +13 -0
- data/dist/lib/Glacier2/Metrics.rb +1 -1
- data/dist/lib/Glacier2/PermissionsVerifier.rb +3 -3
- data/dist/lib/Glacier2/Router.rb +8 -8
- 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/Context.rb +1 -1
- data/dist/lib/Ice/EndpointTypes.rb +1 -1
- data/dist/lib/Ice/Identity.rb +1 -1
- 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 +1 -1
- 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 +6 -6
- data/dist/lib/Ice/ReplyStatus.rb +3 -2
- data/dist/lib/Ice/Router.rb +5 -5
- data/dist/lib/Ice/SliceChecksumDict.rb +1 -1
- data/dist/lib/Ice/Version.rb +1 -1
- data/dist/lib/IceBox/ServiceManager.rb +8 -8
- data/dist/lib/IceGrid/Admin.rb +83 -83
- 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 +13 -13
- data/dist/lib/IceGrid/Session.rb +6 -6
- 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/ice.gemspec +1 -1
- metadata +2 -1
|
@@ -20,7 +20,6 @@
|
|
|
20
20
|
#include <openssl/err.h>
|
|
21
21
|
#include <openssl/ssl.h>
|
|
22
22
|
|
|
23
|
-
#include <iostream>
|
|
24
23
|
#include <mutex>
|
|
25
24
|
|
|
26
25
|
using namespace std;
|
|
@@ -41,10 +40,14 @@ namespace
|
|
|
41
40
|
{
|
|
42
41
|
bool defaultVerificationCallback(bool ok, X509_STORE_CTX*, const Ice::SSL::ConnectionInfoPtr&) { return ok; }
|
|
43
42
|
|
|
43
|
+
/// Returns nullptr if SSL_CTX_new fails; the caller is responsible for checking the return value.
|
|
44
44
|
SSL_CTX* defaultSSLContextSelectionCallback(const string&)
|
|
45
45
|
{
|
|
46
46
|
SSL_CTX* defaultSSLContext = SSL_CTX_new(TLS_method());
|
|
47
|
-
|
|
47
|
+
if (defaultSSLContext)
|
|
48
|
+
{
|
|
49
|
+
SSL_CTX_set_default_verify_paths(defaultSSLContext);
|
|
50
|
+
}
|
|
48
51
|
return defaultSSLContext;
|
|
49
52
|
}
|
|
50
53
|
}
|
|
@@ -90,7 +93,13 @@ OpenSSL::TransceiverI::initialize(IceInternal::Buffer& readBuffer, IceInternal::
|
|
|
90
93
|
}
|
|
91
94
|
SSL_set_bio(_ssl, bio, bio);
|
|
92
95
|
|
|
93
|
-
SSL_set_ex_data(_ssl, 0, this)
|
|
96
|
+
if (!SSL_set_ex_data(_ssl, 0, this))
|
|
97
|
+
{
|
|
98
|
+
throw SecurityException(
|
|
99
|
+
__FILE__,
|
|
100
|
+
__LINE__,
|
|
101
|
+
"SSL transport: error setting ex data:\n" + _engine->sslErrors());
|
|
102
|
+
}
|
|
94
103
|
SSL_set_verify(_ssl, SSL_get_verify_mode(_ssl), Ice_SSL_opensslVerifyCallback);
|
|
95
104
|
// Enable SNI by default for outgoing connections. The SNI host name is always empty for incoming connections.
|
|
96
105
|
if (!_host.empty() && !IceInternal::isIpAddress(_host) && !SSL_set_tlsext_host_name(_ssl, _host.c_str()))
|
|
@@ -108,6 +117,8 @@ OpenSSL::TransceiverI::initialize(IceInternal::Buffer& readBuffer, IceInternal::
|
|
|
108
117
|
|
|
109
118
|
while (!SSL_is_init_finished(_ssl))
|
|
110
119
|
{
|
|
120
|
+
// Clear the error queue before the TLS I/O operation; SSL_get_error requires an empty queue to work reliably.
|
|
121
|
+
ERR_clear_error();
|
|
111
122
|
int ret = _incoming ? SSL_accept(_ssl) : SSL_connect(_ssl);
|
|
112
123
|
|
|
113
124
|
if (ret <= 0)
|
|
@@ -146,7 +146,7 @@ RFC2253::unescape(const string& data)
|
|
|
146
146
|
{
|
|
147
147
|
throw ParseException(__FILE__, __LINE__, "unescape: invalid escape sequence");
|
|
148
148
|
}
|
|
149
|
-
if (special.find(data[pos]) != string::npos || data[pos]
|
|
149
|
+
if (special.find(data[pos]) != string::npos || data[pos] == '\\' || data[pos] == '"')
|
|
150
150
|
{
|
|
151
151
|
result += data[pos];
|
|
152
152
|
++pos;
|
|
@@ -185,7 +185,7 @@ static char
|
|
|
185
185
|
unescapeHex(const string& data, size_t pos)
|
|
186
186
|
{
|
|
187
187
|
assert(pos < data.size());
|
|
188
|
-
if (pos + 2
|
|
188
|
+
if (pos + 2 > data.size())
|
|
189
189
|
{
|
|
190
190
|
throw Ice::ParseException(__FILE__, __LINE__, "unescape: invalid hex pair");
|
|
191
191
|
}
|
|
@@ -431,7 +431,7 @@ parsePair(const string& data, size_t& pos)
|
|
|
431
431
|
throw Ice::ParseException(__FILE__, __LINE__, "invalid escape format (unexpected end of data)");
|
|
432
432
|
}
|
|
433
433
|
|
|
434
|
-
if (special.find(data[pos]) != string::npos || data[pos]
|
|
434
|
+
if (special.find(data[pos]) != string::npos || data[pos] == '\\' || data[pos] == '"')
|
|
435
435
|
{
|
|
436
436
|
result += data[pos];
|
|
437
437
|
++pos;
|
|
@@ -232,7 +232,7 @@ Ice::SSL::EndpointI::endpoint(const IceInternal::EndpointIPtr& delEndp) const
|
|
|
232
232
|
{
|
|
233
233
|
if (delEndp.get() == _delegate.get())
|
|
234
234
|
{
|
|
235
|
-
return
|
|
235
|
+
return static_pointer_cast<EndpointI>(const_cast<EndpointI*>(this)->shared_from_this());
|
|
236
236
|
}
|
|
237
237
|
else
|
|
238
238
|
{
|
|
@@ -23,7 +23,7 @@ namespace Ice::SSL
|
|
|
23
23
|
{
|
|
24
24
|
public:
|
|
25
25
|
SSLEngine(const IceInternal::InstancePtr&);
|
|
26
|
-
~SSLEngine();
|
|
26
|
+
virtual ~SSLEngine();
|
|
27
27
|
|
|
28
28
|
[[nodiscard]] Ice::LoggerPtr getLogger() const;
|
|
29
29
|
[[nodiscard]] Ice::PropertiesPtr getProperties() const;
|
|
@@ -34,9 +34,6 @@ namespace Ice::SSL
|
|
|
34
34
|
// Setup the engine.
|
|
35
35
|
virtual void initialize() = 0;
|
|
36
36
|
|
|
37
|
-
// Destroy the engine.
|
|
38
|
-
virtual void destroy() = 0;
|
|
39
|
-
|
|
40
37
|
// Verify peer certificate.
|
|
41
38
|
virtual void verifyPeer(const ConnectionInfoPtr&) const;
|
|
42
39
|
|
|
@@ -57,12 +54,9 @@ namespace Ice::SSL
|
|
|
57
54
|
private:
|
|
58
55
|
const IceInternal::InstancePtr _instance;
|
|
59
56
|
const TrustManagerPtr _trustManager;
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
bool _checkCertName;
|
|
64
|
-
int _verifyPeer;
|
|
65
|
-
int _securityTraceLevel;
|
|
57
|
+
bool _checkCertName{false};
|
|
58
|
+
int _verifyPeer{0};
|
|
59
|
+
int _securityTraceLevel{0};
|
|
66
60
|
std::string _securityTraceCategory;
|
|
67
61
|
const bool _revocationCheckCacheOnly{false};
|
|
68
62
|
const int _revocationCheck{0};
|
|
@@ -67,6 +67,12 @@ Ice::SSL::parseBytes(const string& arg, vector<unsigned char>& buffer)
|
|
|
67
67
|
}
|
|
68
68
|
v = s.str();
|
|
69
69
|
|
|
70
|
+
// Each byte requires exactly two hex digits; reject odd-length strings.
|
|
71
|
+
if (v.size() % 2 != 0)
|
|
72
|
+
{
|
|
73
|
+
return false;
|
|
74
|
+
}
|
|
75
|
+
|
|
70
76
|
// Convert the bytes.
|
|
71
77
|
for (size_t i = 0, length = v.size(); i + 2 <= length;)
|
|
72
78
|
{
|
|
@@ -86,7 +92,12 @@ Ice::SSL::readFile(const string& file, vector<char>& buffer)
|
|
|
86
92
|
}
|
|
87
93
|
|
|
88
94
|
is.seekg(0, is.end);
|
|
89
|
-
|
|
95
|
+
streampos size = is.tellg();
|
|
96
|
+
if (size == streampos{-1})
|
|
97
|
+
{
|
|
98
|
+
throw CertificateReadException(__FILE__, __LINE__, "error determining file size: " + file);
|
|
99
|
+
}
|
|
100
|
+
buffer.resize(static_cast<size_t>(size));
|
|
90
101
|
is.seekg(0, is.beg);
|
|
91
102
|
|
|
92
103
|
if (!buffer.empty())
|
|
@@ -345,7 +356,7 @@ Ice::SSL::getSubjectAltNames(PCCERT_CONTEXT cert)
|
|
|
345
356
|
os << ".";
|
|
346
357
|
}
|
|
347
358
|
}
|
|
348
|
-
altNames.push_back(make_pair(
|
|
359
|
+
altNames.push_back(make_pair(AltNameIP, os.str()));
|
|
349
360
|
}
|
|
350
361
|
//
|
|
351
362
|
// TODO IPv6 Address support.
|
|
@@ -473,6 +484,10 @@ namespace
|
|
|
473
484
|
string convertX509NameToString(X509_name_st* name)
|
|
474
485
|
{
|
|
475
486
|
BIO* out = BIO_new(BIO_s_mem());
|
|
487
|
+
if (!out)
|
|
488
|
+
{
|
|
489
|
+
throw CertificateEncodingException(__FILE__, __LINE__, "SSL transport: error allocating BIO");
|
|
490
|
+
}
|
|
476
491
|
X509_NAME_print_ex(out, name, 0, XN_FLAG_RFC2253);
|
|
477
492
|
BUF_MEM* p;
|
|
478
493
|
BIO_get_mem_ptr(out, &p);
|
|
@@ -621,6 +636,10 @@ string
|
|
|
621
636
|
Ice::SSL::encodeCertificate(X509* certificate)
|
|
622
637
|
{
|
|
623
638
|
BIO* out = BIO_new(BIO_s_mem());
|
|
639
|
+
if (!out)
|
|
640
|
+
{
|
|
641
|
+
throw CertificateEncodingException(__FILE__, __LINE__, "SSL transport: error allocating BIO");
|
|
642
|
+
}
|
|
624
643
|
int i = PEM_write_bio_X509(out, certificate);
|
|
625
644
|
if (i <= 0)
|
|
626
645
|
{
|
|
@@ -34,7 +34,7 @@ namespace Ice::SSL
|
|
|
34
34
|
const int AltNameDirectory = 4;
|
|
35
35
|
// const int AltNameEDIPartyName = 5;
|
|
36
36
|
const int AltNameURL = 6;
|
|
37
|
-
const int
|
|
37
|
+
const int AltNameIP = 7;
|
|
38
38
|
// const AltNameObjectIdentifier = 8;
|
|
39
39
|
|
|
40
40
|
// Read a file into memory buffer.
|
|
@@ -46,6 +46,8 @@ namespace Ice::SSL
|
|
|
46
46
|
// Determine if a directory exists, with an optional parent directory.
|
|
47
47
|
std::optional<std::string> resolveDirPath(const std::string& path, const std::string& parentDir = "");
|
|
48
48
|
|
|
49
|
+
/// Parse a hex string (e.g., "AB:CD:EF" or "ABCDEF") into a byte buffer. Spaces and colons are ignored.
|
|
50
|
+
/// @return `false` if the string contains invalid characters or has an odd number of hex digits.
|
|
49
51
|
bool parseBytes(const std::string&, std::vector<unsigned char>&);
|
|
50
52
|
|
|
51
53
|
#if defined(ICE_USE_SCHANNEL)
|
|
@@ -57,6 +59,10 @@ namespace Ice::SSL
|
|
|
57
59
|
{
|
|
58
60
|
public:
|
|
59
61
|
ScopedCertificate(PCCERT_CONTEXT certificate) : _certificate(certificate) {}
|
|
62
|
+
ScopedCertificate(const ScopedCertificate&) = delete;
|
|
63
|
+
ScopedCertificate& operator=(const ScopedCertificate&) = delete;
|
|
64
|
+
ScopedCertificate(ScopedCertificate&&) = delete;
|
|
65
|
+
ScopedCertificate& operator=(ScopedCertificate&&) = delete;
|
|
60
66
|
~ScopedCertificate();
|
|
61
67
|
PCCERT_CONTEXT get() const { return _certificate; }
|
|
62
68
|
|
|
@@ -74,6 +80,10 @@ namespace Ice::SSL
|
|
|
74
80
|
{
|
|
75
81
|
public:
|
|
76
82
|
ScopedCertificate(SecCertificateRef certificate) : _certificate(certificate) {}
|
|
83
|
+
ScopedCertificate(const ScopedCertificate&) = delete;
|
|
84
|
+
ScopedCertificate& operator=(const ScopedCertificate&) = delete;
|
|
85
|
+
ScopedCertificate(ScopedCertificate&&) = delete;
|
|
86
|
+
ScopedCertificate& operator=(ScopedCertificate&&) = delete;
|
|
77
87
|
~ScopedCertificate();
|
|
78
88
|
[[nodiscard]] SecCertificateRef get() const { return _certificate; }
|
|
79
89
|
|
|
@@ -91,6 +101,10 @@ namespace Ice::SSL
|
|
|
91
101
|
{
|
|
92
102
|
public:
|
|
93
103
|
ScopedCertificate(X509* certificate) : _certificate(certificate) {}
|
|
104
|
+
ScopedCertificate(const ScopedCertificate&) = delete;
|
|
105
|
+
ScopedCertificate& operator=(const ScopedCertificate&) = delete;
|
|
106
|
+
ScopedCertificate(ScopedCertificate&&) = delete;
|
|
107
|
+
ScopedCertificate& operator=(ScopedCertificate&&) = delete;
|
|
94
108
|
~ScopedCertificate();
|
|
95
109
|
[[nodiscard]] X509* get() const { return _certificate; }
|
|
96
110
|
|
|
@@ -14,7 +14,6 @@
|
|
|
14
14
|
|
|
15
15
|
#include <wincrypt.h>
|
|
16
16
|
|
|
17
|
-
#include <iostream>
|
|
18
17
|
#include <mutex>
|
|
19
18
|
|
|
20
19
|
#ifndef SECURITY_FLAG_IGNORE_CERT_CN_INVALID
|
|
@@ -668,7 +667,7 @@ namespace
|
|
|
668
667
|
vector<string> dnsNames;
|
|
669
668
|
for (vector<pair<int, string>>::const_iterator p = subjectAltNames.begin(); p != subjectAltNames.end(); ++p)
|
|
670
669
|
{
|
|
671
|
-
if (p->first ==
|
|
670
|
+
if (p->first == AltNameIP)
|
|
672
671
|
{
|
|
673
672
|
ipAddresses.push_back(IceInternal::toLower(p->second));
|
|
674
673
|
}
|
|
@@ -693,7 +692,19 @@ namespace
|
|
|
693
692
|
// name dnsNames.
|
|
694
693
|
if (dnsNames.empty())
|
|
695
694
|
{
|
|
696
|
-
|
|
695
|
+
DistinguishedName d{list<pair<string, string>>{}};
|
|
696
|
+
try
|
|
697
|
+
{
|
|
698
|
+
d = DistinguishedName(getSubjectName(cert));
|
|
699
|
+
}
|
|
700
|
+
catch (const Ice::ParseException& ex)
|
|
701
|
+
{
|
|
702
|
+
throw SecurityException(
|
|
703
|
+
__FILE__,
|
|
704
|
+
__LINE__,
|
|
705
|
+
"SSL transport: certificate verification failure:\nunable to parse certificate DN:\n" +
|
|
706
|
+
string{ex.what()});
|
|
707
|
+
}
|
|
697
708
|
string dn = IceInternal::toLower(string(d));
|
|
698
709
|
string cn = "cn=" + addrLower;
|
|
699
710
|
string::size_type pos = dn.find(cn);
|
|
@@ -732,6 +743,56 @@ Schannel::SSLEngine::SSLEngine(const IceInternal::InstancePtr& instance)
|
|
|
732
743
|
{
|
|
733
744
|
}
|
|
734
745
|
|
|
746
|
+
Schannel::SSLEngine::~SSLEngine()
|
|
747
|
+
{
|
|
748
|
+
// Best-effort cleanup. We catch every exception (e.g. std::bad_alloc from the per-cert vector
|
|
749
|
+
// allocation below) so nothing escapes the destructor and triggers std::terminate.
|
|
750
|
+
try
|
|
751
|
+
{
|
|
752
|
+
if (_chainEngine && _chainEngine != HCCE_CURRENT_USER && _chainEngine != HCCE_LOCAL_MACHINE)
|
|
753
|
+
{
|
|
754
|
+
CertFreeCertificateChainEngine(_chainEngine);
|
|
755
|
+
}
|
|
756
|
+
|
|
757
|
+
if (_rootStore)
|
|
758
|
+
{
|
|
759
|
+
CertCloseStore(_rootStore, 0);
|
|
760
|
+
}
|
|
761
|
+
|
|
762
|
+
for (vector<PCCERT_CONTEXT>::const_iterator i = _importedCerts.begin(); i != _importedCerts.end(); ++i)
|
|
763
|
+
{
|
|
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);
|
|
779
|
+
}
|
|
780
|
+
|
|
781
|
+
for (vector<PCCERT_CONTEXT>::const_iterator i = _allCerts.begin(); i != _allCerts.end(); ++i)
|
|
782
|
+
{
|
|
783
|
+
CertFreeCertificateContext(*i);
|
|
784
|
+
}
|
|
785
|
+
|
|
786
|
+
for (vector<HCERTSTORE>::const_iterator i = _stores.begin(); i != _stores.end(); ++i)
|
|
787
|
+
{
|
|
788
|
+
CertCloseStore(*i, 0);
|
|
789
|
+
}
|
|
790
|
+
}
|
|
791
|
+
catch (...)
|
|
792
|
+
{
|
|
793
|
+
}
|
|
794
|
+
}
|
|
795
|
+
|
|
735
796
|
void
|
|
736
797
|
Schannel::SSLEngine::initialize()
|
|
737
798
|
{
|
|
@@ -969,7 +1030,7 @@ Schannel::SSLEngine::initialize()
|
|
|
969
1030
|
if (strcmp(keyInfo->Algorithm.pszObjId, szOID_RSA_RSA))
|
|
970
1031
|
{
|
|
971
1032
|
ostringstream os;
|
|
972
|
-
os << "SSL transport:
|
|
1033
|
+
os << "SSL transport: unknown key algorithm: '" << keyInfo->Algorithm.pszObjId << "'";
|
|
973
1034
|
throw InitializationException(__FILE__, __LINE__, os.str());
|
|
974
1035
|
}
|
|
975
1036
|
|
|
@@ -1199,49 +1260,6 @@ Schannel::SSLEngine::getCipherName(ALG_ID cipher) const
|
|
|
1199
1260
|
}
|
|
1200
1261
|
}
|
|
1201
1262
|
|
|
1202
|
-
void
|
|
1203
|
-
Schannel::SSLEngine::destroy()
|
|
1204
|
-
{
|
|
1205
|
-
if (_chainEngine && _chainEngine != HCCE_CURRENT_USER && _chainEngine != HCCE_LOCAL_MACHINE)
|
|
1206
|
-
{
|
|
1207
|
-
CertFreeCertificateChainEngine(_chainEngine);
|
|
1208
|
-
}
|
|
1209
|
-
|
|
1210
|
-
if (_rootStore)
|
|
1211
|
-
{
|
|
1212
|
-
CertCloseStore(_rootStore, 0);
|
|
1213
|
-
}
|
|
1214
|
-
|
|
1215
|
-
for (vector<PCCERT_CONTEXT>::const_iterator i = _importedCerts.begin(); i != _importedCerts.end(); ++i)
|
|
1216
|
-
{
|
|
1217
|
-
// Retrieve the certificate CERT_KEY_PROV_INFO_PROP_ID property, we use the CRYPT_KEY_PROV_INFO data to remove
|
|
1218
|
-
// the key set associated with the certificate.
|
|
1219
|
-
DWORD length = 0;
|
|
1220
|
-
if (!CertGetCertificateContextProperty(*i, CERT_KEY_PROV_INFO_PROP_ID, 0, &length))
|
|
1221
|
-
{
|
|
1222
|
-
continue;
|
|
1223
|
-
}
|
|
1224
|
-
vector<char> buf(length);
|
|
1225
|
-
if (!CertGetCertificateContextProperty(*i, CERT_KEY_PROV_INFO_PROP_ID, &buf[0], &length))
|
|
1226
|
-
{
|
|
1227
|
-
continue;
|
|
1228
|
-
}
|
|
1229
|
-
CRYPT_KEY_PROV_INFO* key = reinterpret_cast<CRYPT_KEY_PROV_INFO*>(&buf[0]);
|
|
1230
|
-
HCRYPTPROV prov = 0;
|
|
1231
|
-
CryptAcquireContextW(&prov, key->pwszContainerName, key->pwszProvName, key->dwProvType, CRYPT_DELETEKEYSET);
|
|
1232
|
-
}
|
|
1233
|
-
|
|
1234
|
-
for (vector<PCCERT_CONTEXT>::const_iterator i = _allCerts.begin(); i != _allCerts.end(); ++i)
|
|
1235
|
-
{
|
|
1236
|
-
CertFreeCertificateContext(*i);
|
|
1237
|
-
}
|
|
1238
|
-
|
|
1239
|
-
for (vector<HCERTSTORE>::const_iterator i = _stores.begin(); i != _stores.end(); ++i)
|
|
1240
|
-
{
|
|
1241
|
-
CertCloseStore(*i, 0);
|
|
1242
|
-
}
|
|
1243
|
-
}
|
|
1244
|
-
|
|
1245
1263
|
Ice::SSL::ClientAuthenticationOptions
|
|
1246
1264
|
Schannel::SSLEngine::createClientAuthenticationOptions(const string& host) const
|
|
1247
1265
|
{
|
|
@@ -1408,7 +1426,8 @@ Schannel::SSLEngine::validationCallback(
|
|
|
1408
1426
|
extraPolicyPara.dwAuthType = incoming ? AUTHTYPE_CLIENT : AUTHTYPE_SERVER;
|
|
1409
1427
|
// Disable because the policy only matches the CN of the certificate, not the SAN.
|
|
1410
1428
|
extraPolicyPara.fdwChecks = SECURITY_FLAG_IGNORE_CERT_CN_INVALID;
|
|
1411
|
-
|
|
1429
|
+
wstring hostW = Ice::stringToWstring(host);
|
|
1430
|
+
extraPolicyPara.pwszServerName = const_cast<wchar_t*>(hostW.c_str());
|
|
1412
1431
|
|
|
1413
1432
|
CERT_CHAIN_POLICY_PARA policyPara;
|
|
1414
1433
|
memset(&policyPara, 0, sizeof(policyPara));
|
|
@@ -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
|
|
@@ -124,6 +124,11 @@ Schannel::TransceiverI::sslHandshake(SecBuffer* initialBuffer)
|
|
|
124
124
|
{
|
|
125
125
|
assert(!initialBuffer); // Always null for the initial handshake.
|
|
126
126
|
_credentials = _localCredentialsSelectionCallback(_incoming ? _adapterName : _host);
|
|
127
|
+
|
|
128
|
+
// Set hRootStore for AcquireCredentialsHandle. Schannel uses hRootStore on the server side to specify
|
|
129
|
+
// the CAs trusted for client authentication (sent in the CertificateRequest message). This is not used
|
|
130
|
+
// for certificate validation — the transport handles validation separately using the chain engine.
|
|
131
|
+
// If the callback already provided an hRootStore, keep it; otherwise fall back to trustedRootCertificates.
|
|
127
132
|
if (_rootStore && !_credentials.hRootStore)
|
|
128
133
|
{
|
|
129
134
|
_credentials.hRootStore = CertDuplicateStore(_rootStore);
|
|
@@ -145,8 +150,6 @@ Schannel::TransceiverI::sslHandshake(SecBuffer* initialBuffer)
|
|
|
145
150
|
_credentials.paCred = &_allCerts[0];
|
|
146
151
|
}
|
|
147
152
|
|
|
148
|
-
_credentials.hRootStore = _rootStore;
|
|
149
|
-
|
|
150
153
|
err = AcquireCredentialsHandle(
|
|
151
154
|
0,
|
|
152
155
|
const_cast<char*>(UNISP_NAME),
|
|
@@ -549,6 +552,15 @@ Schannel::TransceiverI::decryptMessage(IceInternal::Buffer& buffer)
|
|
|
549
552
|
}
|
|
550
553
|
else if (err == SEC_I_RENEGOTIATE)
|
|
551
554
|
{
|
|
555
|
+
if (_incoming)
|
|
556
|
+
{
|
|
557
|
+
// Reject peer-initiated TLS renegotiation on the server side: it is a CPU-asymmetric
|
|
558
|
+
// denial-of-service primitive on TLS 1.2 and is removed entirely in TLS 1.3.
|
|
559
|
+
throw ProtocolException(
|
|
560
|
+
__FILE__,
|
|
561
|
+
__LINE__,
|
|
562
|
+
"SSL transport: peer-initiated TLS renegotiation is not supported on the server side.");
|
|
563
|
+
}
|
|
552
564
|
if (_sslConnectionRenegotiating)
|
|
553
565
|
{
|
|
554
566
|
throw ProtocolException(
|
|
@@ -9,10 +9,17 @@
|
|
|
9
9
|
#include "Ice/Logger.h"
|
|
10
10
|
#include "Ice/Properties.h"
|
|
11
11
|
#include "Ice/SSL/SSLException.h"
|
|
12
|
+
#include "Ice/UUID.h"
|
|
12
13
|
#include "SSLEngine.h"
|
|
13
14
|
#include "SSLUtil.h"
|
|
14
15
|
#include "SecureTransportUtil.h"
|
|
15
16
|
|
|
17
|
+
#include <cerrno>
|
|
18
|
+
#include <climits>
|
|
19
|
+
#include <cstring>
|
|
20
|
+
#include <unistd.h>
|
|
21
|
+
#include <vector>
|
|
22
|
+
|
|
16
23
|
// Disable deprecation warnings from SecureTransport APIs
|
|
17
24
|
#include "../DisableWarnings.h"
|
|
18
25
|
|
|
@@ -547,6 +554,43 @@ namespace
|
|
|
547
554
|
}
|
|
548
555
|
}
|
|
549
556
|
}
|
|
557
|
+
|
|
558
|
+
#if defined(ICE_USE_SECURE_TRANSPORT_MACOS)
|
|
559
|
+
// Creates a private temporary directory to hold a short-lived keychain, and returns its path.
|
|
560
|
+
// Uses confstr(_CS_DARWIN_USER_TEMP_DIR) rather than $TMPDIR so the location can't be
|
|
561
|
+
// redirected through the process environment.
|
|
562
|
+
string createTemporaryKeychainDirectory()
|
|
563
|
+
{
|
|
564
|
+
char base[PATH_MAX];
|
|
565
|
+
size_t len = confstr(_CS_DARWIN_USER_TEMP_DIR, base, sizeof(base));
|
|
566
|
+
if (len == 0 || len > sizeof(base))
|
|
567
|
+
{
|
|
568
|
+
int error = errno;
|
|
569
|
+
|
|
570
|
+
ostringstream os;
|
|
571
|
+
os << "SSL transport: confstr(_CS_DARWIN_USER_TEMP_DIR) failed";
|
|
572
|
+
if (error != 0)
|
|
573
|
+
{
|
|
574
|
+
os << ": " << strerror(error);
|
|
575
|
+
}
|
|
576
|
+
throw InitializationException(__FILE__, __LINE__, os.str());
|
|
577
|
+
}
|
|
578
|
+
|
|
579
|
+
string tmpl = string{base} + "ice-keychain-XXXXXX";
|
|
580
|
+
vector<char> buffer(tmpl.begin(), tmpl.end());
|
|
581
|
+
buffer.push_back('\0');
|
|
582
|
+
|
|
583
|
+
char* dir = mkdtemp(buffer.data());
|
|
584
|
+
if (dir == nullptr)
|
|
585
|
+
{
|
|
586
|
+
int error = errno;
|
|
587
|
+
ostringstream os;
|
|
588
|
+
os << "SSL transport: mkdtemp failed: " << strerror(error);
|
|
589
|
+
throw InitializationException(__FILE__, __LINE__, os.str());
|
|
590
|
+
}
|
|
591
|
+
return dir;
|
|
592
|
+
}
|
|
593
|
+
#endif
|
|
550
594
|
}
|
|
551
595
|
|
|
552
596
|
SecureTransport::SSLEngine::SSLEngine(const IceInternal::InstancePtr& instance)
|
|
@@ -556,7 +600,25 @@ SecureTransport::SSLEngine::SSLEngine(const IceInternal::InstancePtr& instance)
|
|
|
556
600
|
{
|
|
557
601
|
}
|
|
558
602
|
|
|
559
|
-
SecureTransport::SSLEngine::~SSLEngine()
|
|
603
|
+
SecureTransport::SSLEngine::~SSLEngine()
|
|
604
|
+
{
|
|
605
|
+
#if defined(ICE_USE_SECURE_TRANSPORT_MACOS)
|
|
606
|
+
if (!_temporaryKeychainDir.empty())
|
|
607
|
+
{
|
|
608
|
+
// Remove the temporary keychain and its enclosing directory created by initialize().
|
|
609
|
+
// The cleanup lives in the destructor (not destroy()) so it also runs when initialize()
|
|
610
|
+
// throws after the directory has been created.
|
|
611
|
+
_chain.reset();
|
|
612
|
+
const string keychainPath = _temporaryKeychainDir + "/ice.keychain";
|
|
613
|
+
UniqueRef<SecKeychainRef> keychain;
|
|
614
|
+
if (SecKeychainOpen(keychainPath.c_str(), &keychain.get()) == noErr && keychain.get())
|
|
615
|
+
{
|
|
616
|
+
SecKeychainDelete(keychain.get());
|
|
617
|
+
}
|
|
618
|
+
rmdir(_temporaryKeychainDir.c_str());
|
|
619
|
+
}
|
|
620
|
+
#endif
|
|
621
|
+
}
|
|
560
622
|
|
|
561
623
|
//
|
|
562
624
|
// Setup the engine.
|
|
@@ -636,6 +698,18 @@ SecureTransport::SSLEngine::initialize()
|
|
|
636
698
|
keyFile = *resolved;
|
|
637
699
|
}
|
|
638
700
|
|
|
701
|
+
#if defined(ICE_USE_SECURE_TRANSPORT_MACOS)
|
|
702
|
+
if (keychain.empty())
|
|
703
|
+
{
|
|
704
|
+
// Import the certificate into a temporary keychain rather than the user's login keychain.
|
|
705
|
+
// A private key in the login keychain cannot complete a forward-secret (ECDHE) handshake
|
|
706
|
+
// on the server side. The keychain and its enclosing directory are removed by the destructor.
|
|
707
|
+
_temporaryKeychainDir = createTemporaryKeychainDirectory();
|
|
708
|
+
keychain = _temporaryKeychainDir + "/ice.keychain";
|
|
709
|
+
keychainPassword = Ice::generateUUID();
|
|
710
|
+
}
|
|
711
|
+
#endif
|
|
712
|
+
|
|
639
713
|
try
|
|
640
714
|
{
|
|
641
715
|
_chain.reset(loadCertificateChain(certFile, keyFile, keychain, keychainPassword, password));
|
|
@@ -651,14 +725,6 @@ SecureTransport::SSLEngine::initialize()
|
|
|
651
725
|
}
|
|
652
726
|
}
|
|
653
727
|
|
|
654
|
-
//
|
|
655
|
-
// Destroy the engine.
|
|
656
|
-
//
|
|
657
|
-
void
|
|
658
|
-
SecureTransport::SSLEngine::destroy()
|
|
659
|
-
{
|
|
660
|
-
}
|
|
661
|
-
|
|
662
728
|
ClientAuthenticationOptions
|
|
663
729
|
SecureTransport::SSLEngine::createClientAuthenticationOptions(const string& host) const
|
|
664
730
|
{
|
|
@@ -721,15 +787,15 @@ SecureTransport::SSLEngine::createServerAuthenticationOptions() const
|
|
|
721
787
|
SSLContextRef
|
|
722
788
|
SecureTransport::SSLEngine::newContext(bool incoming) const
|
|
723
789
|
{
|
|
724
|
-
SSLContextRef ssl
|
|
725
|
-
SSLCreateContext(kCFAllocatorDefault, incoming ? kSSLServerSide : kSSLClientSide, kSSLStreamType);
|
|
726
|
-
if (!ssl)
|
|
790
|
+
UniqueRef<SSLContextRef> ssl(
|
|
791
|
+
SSLCreateContext(kCFAllocatorDefault, incoming ? kSSLServerSide : kSSLClientSide, kSSLStreamType));
|
|
792
|
+
if (!ssl.get())
|
|
727
793
|
{
|
|
728
794
|
throw SecurityException(__FILE__, __LINE__, "SSL transport: unable to create SSL context");
|
|
729
795
|
}
|
|
730
796
|
|
|
731
797
|
OSStatus err = SSLSetSessionOption(
|
|
732
|
-
ssl,
|
|
798
|
+
ssl.get(),
|
|
733
799
|
incoming ? kSSLSessionOptionBreakOnClientAuth : kSSLSessionOptionBreakOnServerAuth,
|
|
734
800
|
true);
|
|
735
801
|
|
|
@@ -741,7 +807,34 @@ SecureTransport::SSLEngine::newContext(bool incoming) const
|
|
|
741
807
|
"SSL transport: error while setting SSL option:\n" + sslErrorToString(err));
|
|
742
808
|
}
|
|
743
809
|
|
|
744
|
-
|
|
810
|
+
// Require TLS 1.2 or later. SecureTransport otherwise negotiates down to TLS 1.0 on macOS.
|
|
811
|
+
err = SSLSetProtocolVersionMin(ssl.get(), kTLSProtocol12);
|
|
812
|
+
if (err != noErr)
|
|
813
|
+
{
|
|
814
|
+
throw SecurityException(
|
|
815
|
+
__FILE__,
|
|
816
|
+
__LINE__,
|
|
817
|
+
"SSL transport: error while setting the minimum protocol version:\n" + sslErrorToString(err));
|
|
818
|
+
}
|
|
819
|
+
|
|
820
|
+
// Enable only forward-secret cipher suites: the Mozilla "Intermediate" recommendation for TLS 1.2
|
|
821
|
+
// intersected with what SecureTransport can negotiate — ECDHE key exchange with AES-GCM.
|
|
822
|
+
// SecureTransport's own default set also includes static-RSA suites (no forward secrecy) and 3DES.
|
|
823
|
+
const SSLCipherSuite ciphers[] = {
|
|
824
|
+
TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
|
|
825
|
+
TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
|
|
826
|
+
TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
|
|
827
|
+
TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384};
|
|
828
|
+
err = SSLSetEnabledCiphers(ssl.get(), ciphers, sizeof(ciphers) / sizeof(SSLCipherSuite));
|
|
829
|
+
if (err != noErr)
|
|
830
|
+
{
|
|
831
|
+
throw SecurityException(
|
|
832
|
+
__FILE__,
|
|
833
|
+
__LINE__,
|
|
834
|
+
"SSL transport: error while setting ciphers:\n" + sslErrorToString(err));
|
|
835
|
+
}
|
|
836
|
+
|
|
837
|
+
return ssl.release();
|
|
745
838
|
}
|
|
746
839
|
|
|
747
840
|
bool
|
|
@@ -750,7 +843,10 @@ SecureTransport::SSLEngine::validationCallback(SecTrustRef trust, const Connecti
|
|
|
750
843
|
{
|
|
751
844
|
OSStatus err = noErr;
|
|
752
845
|
UniqueRef<CFErrorRef> trustErr;
|
|
753
|
-
|
|
846
|
+
if (!trust)
|
|
847
|
+
{
|
|
848
|
+
throw SecurityException(__FILE__, __LINE__, "SSL transport: peer trust is null");
|
|
849
|
+
}
|
|
754
850
|
|
|
755
851
|
// Do not allow to fetch missing intermediate certificates from the network.
|
|
756
852
|
if ((err = SecTrustSetNetworkFetchAllowed(trust, false)))
|
|
@@ -20,10 +20,9 @@ namespace Ice::SSL::SecureTransport
|
|
|
20
20
|
{
|
|
21
21
|
public:
|
|
22
22
|
SSLEngine(const IceInternal::InstancePtr&);
|
|
23
|
-
~SSLEngine();
|
|
23
|
+
~SSLEngine() override;
|
|
24
24
|
|
|
25
25
|
void initialize() final;
|
|
26
|
-
void destroy() final;
|
|
27
26
|
|
|
28
27
|
[[nodiscard]] Ice::SSL::ClientAuthenticationOptions
|
|
29
28
|
createClientAuthenticationOptions(const std::string& host) const final;
|
|
@@ -37,6 +36,12 @@ namespace Ice::SSL::SecureTransport
|
|
|
37
36
|
private:
|
|
38
37
|
IceInternal::UniqueRef<CFArrayRef> _certificateAuthorities;
|
|
39
38
|
IceInternal::UniqueRef<CFArrayRef> _chain;
|
|
39
|
+
|
|
40
|
+
# if defined(ICE_USE_SECURE_TRANSPORT_MACOS)
|
|
41
|
+
// Path of the temporary directory holding the imported certificate's keychain, removed by the destructor.
|
|
42
|
+
// Empty when IceSSL.Keychain is set or no certificate is configured.
|
|
43
|
+
std::string _temporaryKeychainDir;
|
|
44
|
+
# endif
|
|
40
45
|
};
|
|
41
46
|
}
|
|
42
47
|
#endif
|
|
@@ -72,7 +72,7 @@ namespace Ice::SSL::SecureTransport
|
|
|
72
72
|
SSLWantWrite = 0x2
|
|
73
73
|
};
|
|
74
74
|
|
|
75
|
-
mutable std::uint8_t _tflags;
|
|
75
|
+
mutable std::uint8_t _tflags{0};
|
|
76
76
|
IceInternal::UniqueRef<SecCertificateRef> _peerCertificate;
|
|
77
77
|
size_t _buffered;
|
|
78
78
|
std::function<void(SSLContextRef, const std::string&)> _sslNewSessionCallback;
|