1 //
2 // Copyright (c) ZeroC, Inc. All rights reserved.
3 //
4 
5 #include <IceSSL/Config.h>
6 
7 #include <IceSSL/SecureTransportEngineF.h>
8 #include <IceSSL/SecureTransportEngine.h>
9 
10 #include <IceUtil/FileUtil.h>
11 #include <IceUtil/StringUtil.h>
12 #include <IceUtil/MutexPtrLock.h>
13 
14 #include <Ice/LocalException.h>
15 #include <Ice/Properties.h>
16 #include <Ice/Communicator.h>
17 #include <Ice/Logger.h>
18 #include <Ice/LoggerUtil.h>
19 
20 #include <IceSSL/SecureTransportTransceiverI.h>
21 #include <IceSSL/SecureTransportUtil.h>
22 #include <IceSSL/Plugin.h>
23 #include <IceSSL/SSLEngine.h>
24 #include <IceSSL/Util.h>
25 
26 #include <regex.h>
27 
28 using namespace std;
29 using namespace IceUtil;
30 using namespace Ice;
31 using namespace IceInternal;
32 using namespace IceSSL;
33 using namespace IceSSL::SecureTransport;
34 
35 namespace
36 {
37 
38 IceUtil::Mutex* staticMutex = 0;
39 
40 class Init
41 {
42 public:
43 
Init()44     Init()
45     {
46         staticMutex = new IceUtil::Mutex;
47     }
48 
~Init()49     ~Init()
50     {
51         delete staticMutex;
52         staticMutex = 0;
53     }
54 };
55 
56 Init init;
57 
58 class RegExp : public IceUtil::Shared
59 {
60 public:
61 
62     RegExp(const string&);
63     ~RegExp();
64     bool match(const string&);
65 
66 private:
67 
68     regex_t _preg;
69 };
70 typedef IceUtil::Handle<RegExp> RegExpPtr;
71 
RegExp(const string & regexp)72 RegExp::RegExp(const string& regexp)
73 {
74     int err = regcomp(&_preg, regexp.c_str(), REG_EXTENDED | REG_NOSUB);
75     if(err)
76     {
77         throw IceUtil::SyscallException(__FILE__, __LINE__, err);
78     }
79 }
80 
~RegExp()81 RegExp::~RegExp()
82 {
83     regfree(&_preg);
84 }
85 
86 bool
match(const string & value)87 RegExp::match(const string& value)
88 {
89     return regexec(&_preg, value.c_str(), 0, 0, 0) == 0;
90 }
91 
92 struct CipherExpression
93 {
94     bool negation;
95     string cipher;
96     RegExpPtr re;
97 };
98 
99 class CiphersHelper
100 {
101 public:
102 
103     static void initialize();
104     static SSLCipherSuite cipherForName(const string& name);
105     static string cipherName(SSLCipherSuite cipher);
106     static map<string, SSLCipherSuite> ciphers();
107 
108 private:
109 
110     static map<string, SSLCipherSuite> _ciphers;
111 };
112 
113 map<string, SSLCipherSuite> CiphersHelper::_ciphers;
114 
115 //
116 // Initialize a dictionary with the names of ciphers
117 //
118 void
initialize()119 CiphersHelper::initialize()
120 {
121     IceUtilInternal::MutexPtrLock<IceUtil::Mutex> sync(staticMutex);
122     if(_ciphers.empty())
123     {
124         _ciphers["NULL_WITH_NULL_NULL"] = SSL_NULL_WITH_NULL_NULL;
125         _ciphers["RSA_WITH_NULL_MD5"] = SSL_RSA_WITH_NULL_MD5;
126         _ciphers["RSA_WITH_NULL_SHA"] = SSL_RSA_WITH_NULL_SHA;
127         _ciphers["RSA_EXPORT_WITH_RC4_40_MD5"] = SSL_RSA_EXPORT_WITH_RC4_40_MD5;
128         _ciphers["RSA_WITH_RC4_128_MD5"] = SSL_RSA_WITH_RC4_128_MD5;
129         _ciphers["RSA_WITH_RC4_128_SHA"] = SSL_RSA_WITH_RC4_128_SHA;
130         _ciphers["RSA_EXPORT_WITH_RC2_CBC_40_MD5"] = SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5;
131         _ciphers["RSA_WITH_IDEA_CBC_SHA"] = SSL_RSA_WITH_IDEA_CBC_SHA;
132         _ciphers["RSA_EXPORT_WITH_DES40_CBC_SHA"] = SSL_RSA_EXPORT_WITH_DES40_CBC_SHA;
133         _ciphers["RSA_WITH_DES_CBC_SHA"] = SSL_RSA_WITH_DES_CBC_SHA;
134         _ciphers["RSA_WITH_3DES_EDE_CBC_SHA"] = SSL_RSA_WITH_3DES_EDE_CBC_SHA;
135         _ciphers["DH_DSS_EXPORT_WITH_DES40_CBC_SHA"] = SSL_DH_DSS_EXPORT_WITH_DES40_CBC_SHA;
136         _ciphers["DH_DSS_WITH_DES_CBC_SHA"] = SSL_DH_DSS_WITH_DES_CBC_SHA;
137         _ciphers["DH_DSS_WITH_3DES_EDE_CBC_SHA"] = SSL_DH_DSS_WITH_3DES_EDE_CBC_SHA;
138         _ciphers["DH_RSA_EXPORT_WITH_DES40_CBC_SHA"] = SSL_DH_RSA_EXPORT_WITH_DES40_CBC_SHA;
139         _ciphers["DH_RSA_WITH_DES_CBC_SHA"] = SSL_DH_RSA_WITH_DES_CBC_SHA;
140         _ciphers["DH_RSA_WITH_3DES_EDE_CBC_SHA"] = SSL_DH_RSA_WITH_3DES_EDE_CBC_SHA;
141         _ciphers["DHE_DSS_EXPORT_WITH_DES40_CBC_SHA"] = SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA;
142         _ciphers["DHE_DSS_WITH_DES_CBC_SHA"] = SSL_DHE_DSS_WITH_DES_CBC_SHA;
143         _ciphers["DHE_DSS_WITH_3DES_EDE_CBC_SHA"] = SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA;
144         _ciphers["DHE_RSA_EXPORT_WITH_DES40_CBC_SHA"] = SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA;
145         _ciphers["DHE_RSA_WITH_DES_CBC_SHA"] = SSL_DHE_RSA_WITH_DES_CBC_SHA;
146         _ciphers["DHE_RSA_WITH_3DES_EDE_CBC_SHA"] = SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA;
147         _ciphers["DH_anon_EXPORT_WITH_RC4_40_MD5"] = SSL_DH_anon_EXPORT_WITH_RC4_40_MD5;
148         _ciphers["DH_anon_WITH_RC4_128_MD5"] = SSL_DH_anon_WITH_RC4_128_MD5;
149         _ciphers["DH_anon_EXPORT_WITH_DES40_CBC_SHA"] = SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA;
150         _ciphers["DH_anon_WITH_DES_CBC_SHA"] = SSL_DH_anon_WITH_DES_CBC_SHA;
151         _ciphers["DH_anon_WITH_3DES_EDE_CBC_SHA"] = SSL_DH_anon_WITH_3DES_EDE_CBC_SHA;
152         _ciphers["FORTEZZA_DMS_WITH_NULL_SHA"] = SSL_FORTEZZA_DMS_WITH_NULL_SHA;
153         _ciphers["FORTEZZA_DMS_WITH_FORTEZZA_CBC_SHA"] = SSL_FORTEZZA_DMS_WITH_FORTEZZA_CBC_SHA;
154 
155         //
156         // TLS addenda using AES, per RFC 3268
157         //
158         _ciphers["RSA_WITH_AES_128_CBC_SHA"] = TLS_RSA_WITH_AES_128_CBC_SHA;
159         _ciphers["DH_DSS_WITH_AES_128_CBC_SHA"] = TLS_DH_DSS_WITH_AES_128_CBC_SHA;
160         _ciphers["DH_RSA_WITH_AES_128_CBC_SHA"] = TLS_DH_RSA_WITH_AES_128_CBC_SHA;
161         _ciphers["DHE_DSS_WITH_AES_128_CBC_SHA"] = TLS_DHE_DSS_WITH_AES_128_CBC_SHA;
162         _ciphers["DHE_RSA_WITH_AES_128_CBC_SHA"] = TLS_DHE_RSA_WITH_AES_128_CBC_SHA;
163         _ciphers["DH_anon_WITH_AES_128_CBC_SHA"] = TLS_DH_anon_WITH_AES_128_CBC_SHA;
164         _ciphers["RSA_WITH_AES_256_CBC_SHA"] = TLS_RSA_WITH_AES_256_CBC_SHA;
165         _ciphers["DH_DSS_WITH_AES_256_CBC_SHA"] = TLS_DH_DSS_WITH_AES_256_CBC_SHA;
166         _ciphers["DH_RSA_WITH_AES_256_CBC_SHA"] = TLS_DH_RSA_WITH_AES_256_CBC_SHA;
167         _ciphers["DHE_DSS_WITH_AES_256_CBC_SHA"] = TLS_DHE_DSS_WITH_AES_256_CBC_SHA;
168         _ciphers["DHE_RSA_WITH_AES_256_CBC_SHA"] = TLS_DHE_RSA_WITH_AES_256_CBC_SHA;
169         _ciphers["DH_anon_WITH_AES_256_CBC_SHA"] = TLS_DH_anon_WITH_AES_256_CBC_SHA;
170 
171         //
172         // ECDSA addenda, RFC 4492
173         //
174         _ciphers["ECDH_ECDSA_WITH_NULL_SHA"] = TLS_ECDH_ECDSA_WITH_NULL_SHA;
175         _ciphers["ECDH_ECDSA_WITH_RC4_128_SHA"] = TLS_ECDH_ECDSA_WITH_RC4_128_SHA;
176         _ciphers["ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA"] = TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA;
177         _ciphers["ECDH_ECDSA_WITH_AES_128_CBC_SHA"] = TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA;
178         _ciphers["ECDH_ECDSA_WITH_AES_256_CBC_SHA"] = TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA;
179         _ciphers["ECDHE_ECDSA_WITH_NULL_SHA"] = TLS_ECDHE_ECDSA_WITH_NULL_SHA;
180         _ciphers["ECDHE_ECDSA_WITH_RC4_128_SHA"] = TLS_ECDHE_ECDSA_WITH_RC4_128_SHA;
181         _ciphers["ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA"] = TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA;
182         _ciphers["ECDHE_ECDSA_WITH_AES_128_CBC_SHA"] = TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA;
183         _ciphers["ECDHE_ECDSA_WITH_AES_256_CBC_SHA"] = TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA;
184         _ciphers["ECDH_RSA_WITH_NULL_SHA"] = TLS_ECDH_RSA_WITH_NULL_SHA;
185         _ciphers["ECDH_RSA_WITH_RC4_128_SHA"] = TLS_ECDH_RSA_WITH_RC4_128_SHA;
186         _ciphers["ECDH_RSA_WITH_3DES_EDE_CBC_SHA"] = TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA;
187         _ciphers["ECDH_RSA_WITH_AES_128_CBC_SHA"] = TLS_ECDH_RSA_WITH_AES_128_CBC_SHA;
188         _ciphers["ECDH_RSA_WITH_AES_256_CBC_SHA"] = TLS_ECDH_RSA_WITH_AES_256_CBC_SHA;
189         _ciphers["ECDHE_RSA_WITH_NULL_SHA"] = TLS_ECDHE_RSA_WITH_NULL_SHA;
190         _ciphers["ECDHE_RSA_WITH_RC4_128_SHA"] = TLS_ECDHE_RSA_WITH_RC4_128_SHA;
191         _ciphers["ECDHE_RSA_WITH_3DES_EDE_CBC_SHA"] = TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA;
192         _ciphers["ECDHE_RSA_WITH_AES_128_CBC_SHA"] = TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA;
193         _ciphers["ECDHE_RSA_WITH_AES_256_CBC_SHA"] = TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA;
194         _ciphers["ECDH_anon_WITH_NULL_SHA"] = TLS_ECDH_anon_WITH_NULL_SHA;
195         _ciphers["ECDH_anon_WITH_RC4_128_SHA"] = TLS_ECDH_anon_WITH_RC4_128_SHA;
196         _ciphers["ECDH_anon_WITH_3DES_EDE_CBC_SHA"] = TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA;
197         _ciphers["ECDH_anon_WITH_AES_128_CBC_SHA"] = TLS_ECDH_anon_WITH_AES_128_CBC_SHA;
198         _ciphers["ECDH_anon_WITH_AES_256_CBC_SHA"] = TLS_ECDH_anon_WITH_AES_256_CBC_SHA;
199 
200         //
201         // TLS 1.2 addenda, RFC 5246
202         //
203         //_ciphers["NULL_WITH_NULL_NULL"] = TLS_NULL_WITH_NULL_NULL;
204 
205         //
206         // Server provided RSA certificate for key exchange.
207         //
208         //_ciphers["RSA_WITH_NULL_MD5"] = TLS_RSA_WITH_NULL_MD5;
209         //_ciphers["RSA_WITH_NULL_SHA"] = TLS_RSA_WITH_NULL_SHA;
210         //_ciphers["RSA_WITH_RC4_128_MD5"] = TLS_RSA_WITH_RC4_128_MD5;
211         //_ciphers["RSA_WITH_RC4_128_SHA"] = TLS_RSA_WITH_RC4_128_SHA;
212         //_ciphers["RSA_WITH_3DES_EDE_CBC_SHA"] = TLS_RSA_WITH_3DES_EDE_CBC_SHA;
213         _ciphers["RSA_WITH_NULL_SHA256"] = TLS_RSA_WITH_NULL_SHA256;
214         _ciphers["RSA_WITH_AES_128_CBC_SHA256"] = TLS_RSA_WITH_AES_128_CBC_SHA256;
215         _ciphers["RSA_WITH_AES_256_CBC_SHA256"] = TLS_RSA_WITH_AES_256_CBC_SHA256;
216 
217         //
218         // Server-authenticated (and optionally client-authenticated) Diffie-Hellman.
219         //
220         //_ciphers["DH_DSS_WITH_3DES_EDE_CBC_SHA"] = TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA;
221         //_ciphers["DH_RSA_WITH_3DES_EDE_CBC_SHA"] = TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA;
222         //_ciphers["DHE_DSS_WITH_3DES_EDE_CBC_SHA"] = TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA;
223         //_ciphers["DHE_RSA_WITH_3DES_EDE_CBC_SHA"] = TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA;
224         _ciphers["DH_DSS_WITH_AES_128_CBC_SHA256"] = TLS_DH_DSS_WITH_AES_128_CBC_SHA256;
225         _ciphers["DH_RSA_WITH_AES_128_CBC_SHA256"] = TLS_DH_RSA_WITH_AES_128_CBC_SHA256;
226         _ciphers["DHE_DSS_WITH_AES_128_CBC_SHA256"] = TLS_DHE_DSS_WITH_AES_128_CBC_SHA256;
227         _ciphers["DHE_RSA_WITH_AES_128_CBC_SHA256"] = TLS_DHE_RSA_WITH_AES_128_CBC_SHA256;
228         _ciphers["DH_DSS_WITH_AES_256_CBC_SHA256"] = TLS_DH_DSS_WITH_AES_256_CBC_SHA256;
229         _ciphers["DH_RSA_WITH_AES_256_CBC_SHA256"] = TLS_DH_RSA_WITH_AES_256_CBC_SHA256;
230         _ciphers["DHE_DSS_WITH_AES_256_CBC_SHA256"] = TLS_DHE_DSS_WITH_AES_256_CBC_SHA256;
231         _ciphers["DHE_RSA_WITH_AES_256_CBC_SHA256"] = TLS_DHE_RSA_WITH_AES_256_CBC_SHA256;
232 
233         //
234         // Completely anonymous Diffie-Hellman
235         //
236         //_ciphers["DH_anon_WITH_RC4_128_MD5"] = TLS_DH_anon_WITH_RC4_128_MD5;
237         //_ciphers["DH_anon_WITH_3DES_EDE_CBC_SHA"] = TLS_DH_anon_WITH_3DES_EDE_CBC_SHA;
238         _ciphers["DH_anon_WITH_AES_128_CBC_SHA256"] = TLS_DH_anon_WITH_AES_128_CBC_SHA256;
239         _ciphers["DH_anon_WITH_AES_256_CBC_SHA256"] = TLS_DH_anon_WITH_AES_256_CBC_SHA256;
240 
241         //
242         // Addendum from RFC 4279, TLS PSK
243         //
244         _ciphers["PSK_WITH_RC4_128_SHA"] = TLS_PSK_WITH_RC4_128_SHA;
245         _ciphers["PSK_WITH_3DES_EDE_CBC_SHA"] = TLS_PSK_WITH_3DES_EDE_CBC_SHA;
246         _ciphers["PSK_WITH_AES_128_CBC_SHA"] = TLS_PSK_WITH_AES_128_CBC_SHA;
247         _ciphers["PSK_WITH_AES_256_CBC_SHA"] = TLS_PSK_WITH_AES_256_CBC_SHA;
248         _ciphers["DHE_PSK_WITH_RC4_128_SHA"] = TLS_DHE_PSK_WITH_RC4_128_SHA;
249         _ciphers["DHE_PSK_WITH_3DES_EDE_CBC_SHA"] = TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA;
250         _ciphers["DHE_PSK_WITH_AES_128_CBC_SHA"] = TLS_DHE_PSK_WITH_AES_128_CBC_SHA;
251         _ciphers["DHE_PSK_WITH_AES_256_CBC_SHA"] = TLS_DHE_PSK_WITH_AES_256_CBC_SHA;
252         _ciphers["RSA_PSK_WITH_RC4_128_SHA"] = TLS_RSA_PSK_WITH_RC4_128_SHA;
253         _ciphers["RSA_PSK_WITH_3DES_EDE_CBC_SHA"] = TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA;
254         _ciphers["RSA_PSK_WITH_AES_128_CBC_SHA"] = TLS_RSA_PSK_WITH_AES_128_CBC_SHA;
255         _ciphers["RSA_PSK_WITH_AES_256_CBC_SHA"] = TLS_RSA_PSK_WITH_AES_256_CBC_SHA;
256 
257         //
258         // RFC 4785 - Pre-Shared Key (PSK) Ciphersuites with NULL Encryption
259         //
260         _ciphers["PSK_WITH_NULL_SHA"] = TLS_PSK_WITH_NULL_SHA;
261         _ciphers["DHE_PSK_WITH_NULL_SHA"] = TLS_DHE_PSK_WITH_NULL_SHA;
262         _ciphers["RSA_PSK_WITH_NULL_SHA"] = TLS_RSA_PSK_WITH_NULL_SHA;
263 
264         //
265         // Addenda from rfc 5288 AES Galois Counter Mode (GCM) Cipher Suites for TLS.
266         //
267         _ciphers["RSA_WITH_AES_128_GCM_SHA256"] = TLS_RSA_WITH_AES_128_GCM_SHA256;
268         _ciphers["RSA_WITH_AES_256_GCM_SHA384"] = TLS_RSA_WITH_AES_256_GCM_SHA384;
269         _ciphers["DHE_RSA_WITH_AES_128_GCM_SHA256"] = TLS_DHE_RSA_WITH_AES_128_GCM_SHA256;
270         _ciphers["DHE_RSA_WITH_AES_256_GCM_SHA384"] = TLS_DHE_RSA_WITH_AES_256_GCM_SHA384;
271         _ciphers["DH_RSA_WITH_AES_128_GCM_SHA256"] = TLS_DH_RSA_WITH_AES_128_GCM_SHA256;
272         _ciphers["DH_RSA_WITH_AES_256_GCM_SHA384"] = TLS_DH_RSA_WITH_AES_256_GCM_SHA384;
273         _ciphers["DHE_DSS_WITH_AES_128_GCM_SHA256"] = TLS_DHE_DSS_WITH_AES_128_GCM_SHA256;
274         _ciphers["DHE_DSS_WITH_AES_256_GCM_SHA384"] = TLS_DHE_DSS_WITH_AES_256_GCM_SHA384;
275         _ciphers["DH_DSS_WITH_AES_128_GCM_SHA256"] = TLS_DH_DSS_WITH_AES_128_GCM_SHA256;
276         _ciphers["DH_DSS_WITH_AES_256_GCM_SHA384"] = TLS_DH_DSS_WITH_AES_256_GCM_SHA384;
277         _ciphers["DH_anon_WITH_AES_128_GCM_SHA256"] = TLS_DH_anon_WITH_AES_128_GCM_SHA256;
278         _ciphers["DH_anon_WITH_AES_256_GCM_SHA384"] = TLS_DH_anon_WITH_AES_256_GCM_SHA384;
279 
280         //
281         // RFC 5487 - PSK with SHA-256/384 and AES GCM
282         //
283         _ciphers["PSK_WITH_AES_128_GCM_SHA256"] = TLS_PSK_WITH_AES_128_GCM_SHA256;
284         _ciphers["PSK_WITH_AES_256_GCM_SHA384"] = TLS_PSK_WITH_AES_256_GCM_SHA384;
285         _ciphers["DHE_PSK_WITH_AES_128_GCM_SHA256"] = TLS_DHE_PSK_WITH_AES_128_GCM_SHA256;
286         _ciphers["DHE_PSK_WITH_AES_256_GCM_SHA384"] = TLS_DHE_PSK_WITH_AES_256_GCM_SHA384;
287         _ciphers["RSA_PSK_WITH_AES_128_GCM_SHA256"] = TLS_RSA_PSK_WITH_AES_128_GCM_SHA256;
288         _ciphers["RSA_PSK_WITH_AES_256_GCM_SHA384"] = TLS_RSA_PSK_WITH_AES_256_GCM_SHA384;
289 
290         _ciphers["PSK_WITH_AES_128_CBC_SHA256"] = TLS_PSK_WITH_AES_128_CBC_SHA256;
291         _ciphers["PSK_WITH_AES_256_CBC_SHA384"] = TLS_PSK_WITH_AES_256_CBC_SHA384;
292         _ciphers["PSK_WITH_NULL_SHA256"] = TLS_PSK_WITH_NULL_SHA256;
293         _ciphers["PSK_WITH_NULL_SHA384"] = TLS_PSK_WITH_NULL_SHA384;
294 
295         _ciphers["DHE_PSK_WITH_AES_128_CBC_SHA256"] = TLS_DHE_PSK_WITH_AES_128_CBC_SHA256;
296         _ciphers["DHE_PSK_WITH_AES_256_CBC_SHA384"] = TLS_DHE_PSK_WITH_AES_256_CBC_SHA384;
297         _ciphers["DHE_PSK_WITH_NULL_SHA256"] = TLS_DHE_PSK_WITH_NULL_SHA256;
298         _ciphers["DHE_PSK_WITH_NULL_SHA384"] = TLS_DHE_PSK_WITH_NULL_SHA384;
299 
300         _ciphers["RSA_PSK_WITH_AES_128_CBC_SHA256"] = TLS_RSA_PSK_WITH_AES_128_CBC_SHA256;
301         _ciphers["RSA_PSK_WITH_AES_256_CBC_SHA384"] = TLS_RSA_PSK_WITH_AES_256_CBC_SHA384;
302         _ciphers["RSA_PSK_WITH_NULL_SHA256"] = TLS_RSA_PSK_WITH_NULL_SHA256;
303         _ciphers["RSA_PSK_WITH_NULL_SHA384"] = TLS_RSA_PSK_WITH_NULL_SHA384;
304 
305         //
306         // Addenda from rfc 5289  Elliptic Curve Cipher Suites with HMAC SHA-256/384.
307         //
308         _ciphers["ECDHE_ECDSA_WITH_AES_128_CBC_SHA256"] = TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256;
309         _ciphers["ECDHE_ECDSA_WITH_AES_256_CBC_SHA384"] = TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384;
310         _ciphers["ECDH_ECDSA_WITH_AES_128_CBC_SHA256"] = TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256;
311         _ciphers["ECDH_ECDSA_WITH_AES_256_CBC_SHA384"] = TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384;
312         _ciphers["ECDHE_RSA_WITH_AES_128_CBC_SHA256"] = TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256;
313         _ciphers["ECDHE_RSA_WITH_AES_256_CBC_SHA384"] = TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384;
314         _ciphers["ECDH_RSA_WITH_AES_128_CBC_SHA256"] = TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256;
315         _ciphers["ECDH_RSA_WITH_AES_256_CBC_SHA384"] = TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384;
316 
317         //
318         // Addenda from rfc 5289  Elliptic Curve Cipher Suites with SHA-256/384 and AES Galois Counter Mode (GCM)
319         //
320         _ciphers["ECDHE_ECDSA_WITH_AES_128_GCM_SHA256"] = TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256;
321         _ciphers["ECDHE_ECDSA_WITH_AES_256_GCM_SHA384"] = TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384;
322         _ciphers["ECDH_ECDSA_WITH_AES_128_GCM_SHA256"] = TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256;
323         _ciphers["ECDH_ECDSA_WITH_AES_256_GCM_SHA384"] = TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384;
324         _ciphers["ECDHE_RSA_WITH_AES_128_GCM_SHA256"] = TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256;
325         _ciphers["ECDHE_RSA_WITH_AES_256_GCM_SHA384"] = TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384;
326         _ciphers["ECDH_RSA_WITH_AES_128_GCM_SHA256"] = TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256;
327         _ciphers["ECDH_RSA_WITH_AES_256_GCM_SHA384"] = TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384;
328 
329         //
330         // RFC 5746 - Secure Renegotiation
331         //
332         _ciphers["EMPTY_RENEGOTIATION_INFO_SCSV"] = TLS_EMPTY_RENEGOTIATION_INFO_SCSV;
333 
334         //
335         // Tags for SSL 2 cipher kinds that are not specified for SSL 3.
336         //
337         _ciphers["RSA_WITH_RC2_CBC_MD5"] = SSL_RSA_WITH_RC2_CBC_MD5;
338         _ciphers["RSA_WITH_IDEA_CBC_MD5"] = SSL_RSA_WITH_IDEA_CBC_MD5;
339         _ciphers["RSA_WITH_DES_CBC_MD5"] = SSL_RSA_WITH_DES_CBC_MD5;
340         _ciphers["RSA_WITH_3DES_EDE_CBC_MD5"] = SSL_RSA_WITH_3DES_EDE_CBC_MD5;
341         _ciphers["NO_SUCH_CIPHERSUITE"] = SSL_NO_SUCH_CIPHERSUITE;
342 
343         //
344         // TLS 1.3 standard cipher suites
345         //
346         _ciphers["TLS_AES_128_GCM_SHA256"] = TLS_AES_128_GCM_SHA256;
347         _ciphers["TLS_AES_256_GCM_SHA384"] = TLS_AES_256_GCM_SHA384;
348         _ciphers["TLS_CHACHA20_POLY1305_SHA256"] = TLS_CHACHA20_POLY1305_SHA256;
349         _ciphers["TLS_AES_128_CCM_SHA256"] = TLS_AES_128_CCM_SHA256;
350         _ciphers["TLS_AES_128_CCM_8_SHA256"] = TLS_AES_128_CCM_8_SHA256;
351 
352     }
353 }
354 
355 SSLCipherSuite
cipherForName(const string & name)356 CiphersHelper::cipherForName(const string& name)
357 {
358     map<string, SSLCipherSuite>::const_iterator i = _ciphers.find(name);
359     if(i == _ciphers.end() || i->second == SSL_NO_SUCH_CIPHERSUITE)
360     {
361         throw PluginInitializationException(__FILE__, __LINE__, "IceSSL: no such cipher " + name);
362     }
363     return i->second;
364 }
365 
366 //
367 // Retrive the name of a cipher, SSLCipherSuite inlude duplicated values for TLS/SSL
368 // protocol ciphers, for example SSL_RSA_WITH_RC4_128_MD5/TLS_RSA_WITH_RC4_128_MD5
369 // are represeted by the same SSLCipherSuite value, the names return by this method
370 // doesn't include a protocol prefix.
371 //
372 string
cipherName(SSLCipherSuite cipher)373 CiphersHelper::cipherName(SSLCipherSuite cipher)
374 {
375     switch(cipher)
376     {
377         case SSL_NULL_WITH_NULL_NULL:
378             return "NULL_WITH_NULL_NULL";
379         case SSL_RSA_WITH_NULL_MD5:
380             return "RSA_WITH_NULL_MD5";
381         case SSL_RSA_WITH_NULL_SHA:
382             return "RSA_WITH_NULL_SHA";
383         case SSL_RSA_EXPORT_WITH_RC4_40_MD5:
384             return "RSA_EXPORT_WITH_RC4_40_MD5";
385         case SSL_RSA_WITH_RC4_128_MD5:
386             return "RSA_WITH_RC4_128_MD5";
387         case SSL_RSA_WITH_RC4_128_SHA:
388             return "RSA_WITH_RC4_128_SHA";
389         case SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5:
390             return "RSA_EXPORT_WITH_RC2_CBC_40_MD5";
391         case SSL_RSA_WITH_IDEA_CBC_SHA:
392             return "RSA_WITH_IDEA_CBC_SHA";
393         case SSL_RSA_EXPORT_WITH_DES40_CBC_SHA:
394             return "RSA_EXPORT_WITH_DES40_CBC_SHA";
395         case SSL_RSA_WITH_DES_CBC_SHA:
396             return "RSA_WITH_DES_CBC_SHA";
397         case SSL_RSA_WITH_3DES_EDE_CBC_SHA:
398             return "RSA_WITH_3DES_EDE_CBC_SHA";
399         case SSL_DH_DSS_EXPORT_WITH_DES40_CBC_SHA:
400             return "DH_DSS_EXPORT_WITH_DES40_CBC_SHA";
401         case SSL_DH_DSS_WITH_DES_CBC_SHA:
402             return "DH_DSS_WITH_DES_CBC_SHA";
403         case SSL_DH_DSS_WITH_3DES_EDE_CBC_SHA:
404             return "DH_DSS_WITH_3DES_EDE_CBC_SHA";
405         case SSL_DH_RSA_EXPORT_WITH_DES40_CBC_SHA:
406             return "DH_RSA_EXPORT_WITH_DES40_CBC_SHA";
407         case SSL_DH_RSA_WITH_DES_CBC_SHA:
408             return "DH_RSA_WITH_DES_CBC_SHA";
409         case SSL_DH_RSA_WITH_3DES_EDE_CBC_SHA:
410             return "DH_RSA_WITH_3DES_EDE_CBC_SHA";
411         case SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA:
412             return "DHE_DSS_EXPORT_WITH_DES40_CBC_SHA";
413         case SSL_DHE_DSS_WITH_DES_CBC_SHA:
414             return "DHE_DSS_WITH_DES_CBC_SHA";
415         case SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA:
416             return "DHE_DSS_WITH_3DES_EDE_CBC_SHA";
417         case SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA:
418             return "DHE_RSA_EXPORT_WITH_DES40_CBC_SHA";
419         case SSL_DHE_RSA_WITH_DES_CBC_SHA:
420             return "DHE_RSA_WITH_DES_CBC_SHA";
421         case SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA:
422             return "DHE_RSA_WITH_3DES_EDE_CBC_SHA";
423         case SSL_DH_anon_EXPORT_WITH_RC4_40_MD5:
424             return "DH_anon_EXPORT_WITH_RC4_40_MD5";
425         case SSL_DH_anon_WITH_RC4_128_MD5:
426             return "DH_anon_WITH_RC4_128_MD5";
427         case SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA:
428             return "DH_anon_EXPORT_WITH_DES40_CBC_SHA";
429         case SSL_DH_anon_WITH_DES_CBC_SHA:
430             return "DH_anon_WITH_DES_CBC_SHA";
431         case SSL_DH_anon_WITH_3DES_EDE_CBC_SHA:
432             return "DH_anon_WITH_3DES_EDE_CBC_SHA";
433         case SSL_FORTEZZA_DMS_WITH_NULL_SHA:
434             return "FORTEZZA_DMS_WITH_NULL_SHA";
435         case SSL_FORTEZZA_DMS_WITH_FORTEZZA_CBC_SHA:
436             return "FORTEZZA_DMS_WITH_FORTEZZA_CBC_SHA";
437 
438         //
439         // TLS addenda using AES, per RFC 3268
440         //
441         case TLS_RSA_WITH_AES_128_CBC_SHA:
442             return "RSA_WITH_AES_128_CBC_SHA";
443         case TLS_DH_DSS_WITH_AES_128_CBC_SHA:
444             return "DH_DSS_WITH_AES_128_CBC_SHA";
445         case TLS_DH_RSA_WITH_AES_128_CBC_SHA:
446             return "DH_RSA_WITH_AES_128_CBC_SHA";
447         case TLS_DHE_DSS_WITH_AES_128_CBC_SHA:
448             return "DHE_DSS_WITH_AES_128_CBC_SHA";
449         case TLS_DHE_RSA_WITH_AES_128_CBC_SHA:
450             return "DHE_RSA_WITH_AES_128_CBC_SHA";
451         case TLS_DH_anon_WITH_AES_128_CBC_SHA:
452             return "DH_anon_WITH_AES_128_CBC_SHA";
453         case TLS_RSA_WITH_AES_256_CBC_SHA:
454             return "RSA_WITH_AES_256_CBC_SHA";
455         case TLS_DH_DSS_WITH_AES_256_CBC_SHA:
456             return "DH_DSS_WITH_AES_256_CBC_SHA";
457         case TLS_DH_RSA_WITH_AES_256_CBC_SHA:
458             return "DH_RSA_WITH_AES_256_CBC_SHA";
459         case TLS_DHE_DSS_WITH_AES_256_CBC_SHA:
460             return "DHE_DSS_WITH_AES_256_CBC_SHA";
461         case TLS_DHE_RSA_WITH_AES_256_CBC_SHA:
462             return "DHE_RSA_WITH_AES_256_CBC_SHA";
463         case TLS_DH_anon_WITH_AES_256_CBC_SHA:
464             return "DH_anon_WITH_AES_256_CBC_SHA";
465 
466         //
467         // ECDSA addenda, RFC 4492
468         //
469         case TLS_ECDH_ECDSA_WITH_NULL_SHA:
470             return "ECDH_ECDSA_WITH_NULL_SHA";
471         case TLS_ECDH_ECDSA_WITH_RC4_128_SHA:
472             return "ECDH_ECDSA_WITH_RC4_128_SHA";
473         case TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA:
474             return "ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA";
475         case TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA:
476             return "ECDH_ECDSA_WITH_AES_128_CBC_SHA";
477         case TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA:
478             return "ECDH_ECDSA_WITH_AES_256_CBC_SHA";
479         case TLS_ECDHE_ECDSA_WITH_NULL_SHA:
480             return "ECDHE_ECDSA_WITH_NULL_SHA";
481         case TLS_ECDHE_ECDSA_WITH_RC4_128_SHA:
482             return "ECDHE_ECDSA_WITH_RC4_128_SHA";
483         case TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA:
484             return "ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA";
485         case TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA:
486             return "ECDHE_ECDSA_WITH_AES_128_CBC_SHA";
487         case TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA:
488             return "ECDHE_ECDSA_WITH_AES_256_CBC_SHA";
489         case TLS_ECDH_RSA_WITH_NULL_SHA:
490             return "ECDH_RSA_WITH_NULL_SHA";
491         case TLS_ECDH_RSA_WITH_RC4_128_SHA:
492             return "ECDH_RSA_WITH_RC4_128_SHA";
493         case TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA:
494             return "ECDH_RSA_WITH_3DES_EDE_CBC_SHA";
495         case TLS_ECDH_RSA_WITH_AES_128_CBC_SHA:
496             return "ECDH_RSA_WITH_AES_128_CBC_SHA";
497         case TLS_ECDH_RSA_WITH_AES_256_CBC_SHA:
498             return "ECDH_RSA_WITH_AES_256_CBC_SHA";
499         case TLS_ECDHE_RSA_WITH_NULL_SHA:
500             return "ECDHE_RSA_WITH_NULL_SHA";
501         case TLS_ECDHE_RSA_WITH_RC4_128_SHA:
502             return "ECDHE_RSA_WITH_RC4_128_SHA";
503         case TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA:
504             return "ECDHE_RSA_WITH_3DES_EDE_CBC_SHA";
505         case TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA:
506             return "ECDHE_RSA_WITH_AES_128_CBC_SHA";
507         case TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA:
508             return "ECDHE_RSA_WITH_AES_256_CBC_SHA";
509         case TLS_ECDH_anon_WITH_NULL_SHA:
510             return "ECDH_anon_WITH_NULL_SHA";
511         case TLS_ECDH_anon_WITH_RC4_128_SHA:
512             return "ECDH_anon_WITH_RC4_128_SHA";
513         case TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA:
514             return "ECDH_anon_WITH_3DES_EDE_CBC_SHA";
515         case TLS_ECDH_anon_WITH_AES_128_CBC_SHA:
516             return "ECDH_anon_WITH_AES_128_CBC_SHA";
517         case TLS_ECDH_anon_WITH_AES_256_CBC_SHA:
518             return "ECDH_anon_WITH_AES_256_CBC_SHA";
519 
520         //
521         // TLS 1.2 addenda, RFC 5246
522         //
523         //case TLS_NULL_WITH_NULL_NULL:
524         //    return "NULL_WITH_NULL_NULL";
525 
526         //
527         // Server provided RSA certificate for key exchange.
528         //
529         //case TLS_RSA_WITH_NULL_MD5:
530         //    return "RSA_WITH_NULL_MD5";
531         //case TLS_RSA_WITH_NULL_SHA:
532         //    return "RSA_WITH_NULL_SHA";
533         //case TLS_RSA_WITH_RC4_128_MD5:
534         //    return "RSA_WITH_RC4_128_MD5";
535         //case TLS_RSA_WITH_RC4_128_SHA:
536         //    return "RSA_WITH_RC4_128_SHA";
537         //case TLS_RSA_WITH_3DES_EDE_CBC_SHA:
538         //    return "RSA_WITH_3DES_EDE_CBC_SHA";
539         case TLS_RSA_WITH_NULL_SHA256:
540             return "RSA_WITH_NULL_SHA256";
541         case TLS_RSA_WITH_AES_128_CBC_SHA256:
542             return "RSA_WITH_AES_128_CBC_SHA256";
543         case TLS_RSA_WITH_AES_256_CBC_SHA256:
544             return "RSA_WITH_AES_256_CBC_SHA256";
545 
546         //
547         // Server-authenticated (and optionally client-authenticated) Diffie-Hellman.
548         //
549         //case TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA:
550         //    return "DH_DSS_WITH_3DES_EDE_CBC_SHA";
551         //case TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA:
552         //    return "DH_RSA_WITH_3DES_EDE_CBC_SHA";
553         //case TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA:
554         //    return "DHE_DSS_WITH_3DES_EDE_CBC_SHA";
555         //case TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA:
556         //    return "DHE_RSA_WITH_3DES_EDE_CBC_SHA";
557         case TLS_DH_DSS_WITH_AES_128_CBC_SHA256:
558             return "DH_DSS_WITH_AES_128_CBC_SHA256";
559         case TLS_DH_RSA_WITH_AES_128_CBC_SHA256:
560             return "DH_RSA_WITH_AES_128_CBC_SHA256";
561         case TLS_DHE_DSS_WITH_AES_128_CBC_SHA256:
562             return "DHE_DSS_WITH_AES_128_CBC_SHA256";
563         case TLS_DHE_RSA_WITH_AES_128_CBC_SHA256:
564             return "DHE_RSA_WITH_AES_128_CBC_SHA256";
565         case TLS_DH_DSS_WITH_AES_256_CBC_SHA256:
566             return "DH_DSS_WITH_AES_256_CBC_SHA256";
567         case TLS_DH_RSA_WITH_AES_256_CBC_SHA256:
568             return "DH_RSA_WITH_AES_256_CBC_SHA256";
569         case TLS_DHE_DSS_WITH_AES_256_CBC_SHA256:
570             return "DHE_DSS_WITH_AES_256_CBC_SHA256";
571         case TLS_DHE_RSA_WITH_AES_256_CBC_SHA256:
572             return "DHE_RSA_WITH_AES_256_CBC_SHA256";
573 
574         //
575         // Completely anonymous Diffie-Hellman
576         //
577         //case TLS_DH_anon_WITH_RC4_128_MD5:
578         //    return "DH_anon_WITH_RC4_128_MD5";
579         //case TLS_DH_anon_WITH_3DES_EDE_CBC_SHA:
580         //    return "DH_anon_WITH_3DES_EDE_CBC_SHA";
581         case TLS_DH_anon_WITH_AES_128_CBC_SHA256:
582             return "DH_anon_WITH_AES_128_CBC_SHA256";
583         case TLS_DH_anon_WITH_AES_256_CBC_SHA256:
584             return "DH_anon_WITH_AES_256_CBC_SHA256";
585 
586         //
587         // Addendum from RFC 4279, TLS PSK
588         //
589         case TLS_PSK_WITH_RC4_128_SHA:
590             return "PSK_WITH_RC4_128_SHA";
591         case TLS_PSK_WITH_3DES_EDE_CBC_SHA:
592             return "PSK_WITH_3DES_EDE_CBC_SHA";
593         case TLS_PSK_WITH_AES_128_CBC_SHA:
594             return "PSK_WITH_AES_128_CBC_SHA";
595         case TLS_PSK_WITH_AES_256_CBC_SHA:
596             return "PSK_WITH_AES_256_CBC_SHA";
597         case TLS_DHE_PSK_WITH_RC4_128_SHA:
598             return "DHE_PSK_WITH_RC4_128_SHA";
599         case TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA:
600             return "DHE_PSK_WITH_3DES_EDE_CBC_SHA";
601         case TLS_DHE_PSK_WITH_AES_128_CBC_SHA:
602             return "DHE_PSK_WITH_AES_128_CBC_SHA";
603         case TLS_DHE_PSK_WITH_AES_256_CBC_SHA:
604             return "DHE_PSK_WITH_AES_256_CBC_SHA";
605         case TLS_RSA_PSK_WITH_RC4_128_SHA:
606             return "RSA_PSK_WITH_RC4_128_SHA";
607         case TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA:
608             return "RSA_PSK_WITH_3DES_EDE_CBC_SHA";
609         case TLS_RSA_PSK_WITH_AES_128_CBC_SHA:
610             return "RSA_PSK_WITH_AES_128_CBC_SHA";
611         case TLS_RSA_PSK_WITH_AES_256_CBC_SHA:
612             return "RSA_PSK_WITH_AES_256_CBC_SHA";
613 
614         //
615         // RFC 4785 - Pre-Shared Key (PSK) Ciphersuites with NULL Encryption
616         //
617         case TLS_PSK_WITH_NULL_SHA:
618             return "PSK_WITH_NULL_SHA";
619         case TLS_DHE_PSK_WITH_NULL_SHA:
620             return "DHE_PSK_WITH_NULL_SHA";
621         case TLS_RSA_PSK_WITH_NULL_SHA:
622             return "RSA_PSK_WITH_NULL_SHA";
623 
624         //
625         // Addenda from rfc 5288 AES Galois Counter Mode (GCM) Cipher Suites for TLS.
626         //
627         case TLS_RSA_WITH_AES_128_GCM_SHA256:
628             return "RSA_WITH_AES_128_GCM_SHA256";
629         case TLS_RSA_WITH_AES_256_GCM_SHA384:
630             return "RSA_WITH_AES_256_GCM_SHA384";
631         case TLS_DHE_RSA_WITH_AES_128_GCM_SHA256:
632             return "DHE_RSA_WITH_AES_128_GCM_SHA256";
633         case TLS_DHE_RSA_WITH_AES_256_GCM_SHA384:
634             return "DHE_RSA_WITH_AES_256_GCM_SHA384";
635         case TLS_DH_RSA_WITH_AES_128_GCM_SHA256:
636             return "DH_RSA_WITH_AES_128_GCM_SHA256";
637         case TLS_DH_RSA_WITH_AES_256_GCM_SHA384:
638             return "DH_RSA_WITH_AES_256_GCM_SHA384";
639         case TLS_DHE_DSS_WITH_AES_128_GCM_SHA256:
640             return "DHE_DSS_WITH_AES_128_GCM_SHA256";
641         case TLS_DHE_DSS_WITH_AES_256_GCM_SHA384:
642             return "DHE_DSS_WITH_AES_256_GCM_SHA384";
643         case TLS_DH_DSS_WITH_AES_128_GCM_SHA256:
644             return "DH_DSS_WITH_AES_128_GCM_SHA256";
645         case TLS_DH_DSS_WITH_AES_256_GCM_SHA384:
646             return "DH_DSS_WITH_AES_256_GCM_SHA384";
647         case TLS_DH_anon_WITH_AES_128_GCM_SHA256:
648             return "DH_anon_WITH_AES_128_GCM_SHA256";
649         case TLS_DH_anon_WITH_AES_256_GCM_SHA384:
650             return "DH_anon_WITH_AES_256_GCM_SHA384";
651 
652         //
653         // RFC 5487 - PSK with SHA-256/384 and AES GCM
654         //
655         case TLS_PSK_WITH_AES_128_GCM_SHA256:
656             return "PSK_WITH_AES_128_GCM_SHA256";
657         case TLS_PSK_WITH_AES_256_GCM_SHA384:
658             return "PSK_WITH_AES_256_GCM_SHA384";
659         case TLS_DHE_PSK_WITH_AES_128_GCM_SHA256:
660             return "DHE_PSK_WITH_AES_128_GCM_SHA256";
661         case TLS_DHE_PSK_WITH_AES_256_GCM_SHA384:
662             return "DHE_PSK_WITH_AES_256_GCM_SHA384";
663         case TLS_RSA_PSK_WITH_AES_128_GCM_SHA256:
664             return "RSA_PSK_WITH_AES_128_GCM_SHA256";
665         case TLS_RSA_PSK_WITH_AES_256_GCM_SHA384:
666             return "RSA_PSK_WITH_AES_256_GCM_SHA384";
667 
668         case TLS_PSK_WITH_AES_128_CBC_SHA256:
669             return "PSK_WITH_AES_128_CBC_SHA256";
670         case TLS_PSK_WITH_AES_256_CBC_SHA384:
671             return "PSK_WITH_AES_256_CBC_SHA384";
672         case TLS_PSK_WITH_NULL_SHA256:
673             return "WITH_NULL_SHA256";
674         case TLS_PSK_WITH_NULL_SHA384:
675             return "PSK_WITH_NULL_SHA384";
676 
677         case TLS_DHE_PSK_WITH_AES_128_CBC_SHA256:
678             return "DHE_PSK_WITH_AES_128_CBC_SHA256";
679         case TLS_DHE_PSK_WITH_AES_256_CBC_SHA384:
680             return "DHE_PSK_WITH_AES_256_CBC_SHA384";
681         case TLS_DHE_PSK_WITH_NULL_SHA256:
682             return "DHE_PSK_WITH_NULL_SHA256";
683         case TLS_DHE_PSK_WITH_NULL_SHA384:
684             return "DHE_PSK_WITH_NULL_SHA384";
685 
686         case TLS_RSA_PSK_WITH_AES_128_CBC_SHA256:
687             return "RSA_PSK_WITH_AES_128_CBC_SHA256";
688         case TLS_RSA_PSK_WITH_AES_256_CBC_SHA384:
689             return "RSA_PSK_WITH_AES_256_CBC_SHA384";
690         case TLS_RSA_PSK_WITH_NULL_SHA256:
691             return "RSA_PSK_WITH_NULL_SHA256";
692         case TLS_RSA_PSK_WITH_NULL_SHA384:
693             return "RSA_PSK_WITH_NULL_SHA384";
694 
695         //
696         // Addenda from rfc 5289  Elliptic Curve Cipher Suites with HMAC SHA-256/384.
697         //
698         case TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256:
699             return "ECDHE_ECDSA_WITH_AES_128_CBC_SHA256";
700         case TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384:
701             return "ECDHE_ECDSA_WITH_AES_256_CBC_SHA384";
702         case TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256:
703             return "ECDH_ECDSA_WITH_AES_128_CBC_SHA256";
704         case TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384:
705             return "ECDH_ECDSA_WITH_AES_256_CBC_SHA384";
706         case TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256:
707             return "ECDHE_RSA_WITH_AES_128_CBC_SHA256";
708         case TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384:
709             return "ECDHE_RSA_WITH_AES_256_CBC_SHA384";
710         case TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256:
711             return "ECDH_RSA_WITH_AES_128_CBC_SHA256";
712         case TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384:
713             return "ECDH_RSA_WITH_AES_256_CBC_SHA384";
714 
715         //
716         // Addenda from rfc 5289  Elliptic Curve Cipher Suites with SHA-256/384 and AES Galois Counter Mode (GCM)
717         //
718         case TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256:
719             return "ECDHE_ECDSA_WITH_AES_128_GCM_SHA256";
720         case TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384:
721             return "ECDHE_ECDSA_WITH_AES_256_GCM_SHA384";
722         case TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256:
723             return "ECDH_ECDSA_WITH_AES_128_GCM_SHA256";
724         case TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384:
725             return "ECDH_ECDSA_WITH_AES_256_GCM_SHA384";
726         case TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256:
727             return "ECDHE_RSA_WITH_AES_128_GCM_SHA256";
728         case TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384:
729             return "ECDHE_RSA_WITH_AES_256_GCM_SHA384";
730         case TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256:
731             return "ECDH_RSA_WITH_AES_128_GCM_SHA256";
732         case TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384:
733             return "ECDH_RSA_WITH_AES_256_GCM_SHA384";
734 
735         //
736         // RFC 5746 - Secure Renegotiation
737         //
738         case TLS_EMPTY_RENEGOTIATION_INFO_SCSV:
739             return "EMPTY_RENEGOTIATION_INFO_SCSV";
740 
741         //
742         // Tags for SSL 2 cipher kinds that are not specified for SSL 3.
743         //
744         case SSL_RSA_WITH_RC2_CBC_MD5:
745             return "RSA_WITH_RC2_CBC_MD5";
746         case SSL_RSA_WITH_IDEA_CBC_MD5:
747             return "RSA_WITH_IDEA_CBC_MD5";
748         case SSL_RSA_WITH_DES_CBC_MD5:
749             return "RSA_WITH_DES_CBC_MD5";
750         case SSL_RSA_WITH_3DES_EDE_CBC_MD5:
751             return "RSA_WITH_3DES_EDE_CBC_MD5";
752 
753         //
754         //TLS 1.3 standard cipher suites
755         //
756         case TLS_AES_128_GCM_SHA256:
757             return "TLS_AES_128_GCM_SHA256";
758         case TLS_AES_256_GCM_SHA384:
759             return "TLS_AES_256_GCM_SHA384";
760         case TLS_CHACHA20_POLY1305_SHA256:
761             return "TLS_CHACHA20_POLY1305_SHA256";
762         case TLS_AES_128_CCM_SHA256:
763             return "TLS_AES_128_CCM_SHA256";
764         case TLS_AES_128_CCM_8_SHA256:
765             return "TLS_AES_128_CCM_8_SHA256";
766 
767         default:
768             return "";
769     }
770 }
771 
772 map<string, SSLCipherSuite>
ciphers()773 CiphersHelper::ciphers()
774 {
775     return _ciphers;
776 }
777 
778 SSLProtocol
parseProtocol(const string & p)779 parseProtocol(const string& p)
780 {
781     const string prot = IceUtilInternal::toUpper(p);
782     if(prot == "SSL3" || prot == "SSLV3")
783     {
784         return kSSLProtocol3;
785     }
786     else if(prot == "TLS" || prot == "TLS1" || prot == "TLSV1" || prot == "TLS1_0" || prot == "TLSV1_0")
787     {
788         return kTLSProtocol1;
789     }
790     else if(prot == "TLS1_1" || prot == "TLSV1_1")
791     {
792         return kTLSProtocol11;
793     }
794     else if(prot == "TLS1_2" || prot == "TLSV1_2")
795     {
796         return kTLSProtocol12;
797     }
798     else if(prot == "TLS1_3" || prot == "TLSV1_3")
799     {
800         return kTLSProtocol13;
801     }
802     else
803     {
804         throw PluginInitializationException(__FILE__, __LINE__, "IceSSL: unrecognized protocol `" + p + "'");
805     }
806 }
807 
808 }
809 
810 IceUtil::Shared*
upCast(IceSSL::SecureTransport::SSLEngine * p)811 IceSSL::SecureTransport::upCast(IceSSL::SecureTransport::SSLEngine* p)
812 {
813     return p;
814 }
815 
SSLEngine(const Ice::CommunicatorPtr & communicator)816 IceSSL::SecureTransport::SSLEngine::SSLEngine(const Ice::CommunicatorPtr& communicator) :
817     IceSSL::SSLEngine(communicator),
818     _certificateAuthorities(0),
819     _chain(0),
820     _protocolVersionMax(kSSLProtocolUnknown),
821     _protocolVersionMin(kSSLProtocolUnknown)
822 {
823 }
824 
825 //
826 // Setup the engine.
827 //
828 void
initialize()829 IceSSL::SecureTransport::SSLEngine::initialize()
830 {
831     IceUtil::Mutex::Lock lock(_mutex);
832     if(_initialized)
833     {
834         return;
835     }
836 
837     IceSSL::SSLEngine::initialize();
838 
839     const PropertiesPtr properties = communicator()->getProperties();
840 
841     //
842     // Check for a default directory. We look in this directory for
843     // files mentioned in the configuration.
844     //
845     const string defaultDir = properties->getProperty("IceSSL.DefaultDir");
846 
847     //
848     // Load the CA certificates used to authenticate peers into
849     // _certificateAuthorities array.
850     //
851     try
852     {
853         string caFile = properties->getProperty("IceSSL.CAs");
854         if(caFile.empty())
855         {
856             caFile = properties->getProperty("IceSSL.CertAuthFile");
857         }
858         if(!caFile.empty())
859         {
860             string resolved;
861             if(!checkPath(caFile, defaultDir, false, resolved))
862             {
863                 throw PluginInitializationException(__FILE__, __LINE__,
864                                                     "IceSSL: CA certificate file not found:\n" + caFile);
865             }
866             _certificateAuthorities.reset(loadCACertificates(resolved));
867         }
868         else if(properties->getPropertyAsInt("IceSSL.UsePlatformCAs") <= 0)
869         {
870             // Setup an empty list of Root CAs to not use the system root CAs.
871             _certificateAuthorities.reset(CFArrayCreate(0, 0, 0, 0));
872         }
873     }
874     catch(const CertificateReadException& ce)
875     {
876         throw PluginInitializationException(__FILE__, __LINE__, ce.reason);
877     }
878 
879     const string password = properties->getProperty("IceSSL.Password");
880     const int passwordRetryMax = properties->getPropertyAsIntWithDefault("IceSSL.PasswordRetryMax", 3);
881     PasswordPromptPtr passwordPrompt = getPasswordPrompt();
882 
883     string certFile = properties->getProperty("IceSSL.CertFile");
884     string findCert = properties->getProperty("IceSSL.FindCert");
885     string keychain = properties->getProperty("IceSSL.Keychain");
886     string keychainPassword = properties->getProperty("IceSSL.KeychainPassword");
887 
888     if(!certFile.empty())
889     {
890         vector<string> files;
891         if(!IceUtilInternal::splitString(certFile, IceUtilInternal::pathsep, files) || files.size() > 2)
892         {
893             throw PluginInitializationException(__FILE__, __LINE__,
894                                                 "IceSSL: invalid value for IceSSL.CertFile:\n" + certFile);
895         }
896         vector<string> keyFiles;
897         {
898             string keyFile = properties->getProperty("IceSSL.KeyFile");
899             if(!keyFile.empty())
900             {
901                 if(!IceUtilInternal::splitString(keyFile, IceUtilInternal::pathsep, keyFiles) || keyFiles.size() > 2)
902                 {
903                     throw PluginInitializationException(__FILE__, __LINE__,
904                                                         "IceSSL: invalid value for IceSSL.KeyFile:\n" + keyFile);
905                 }
906                 if(files.size() != keyFiles.size())
907                 {
908                     throw PluginInitializationException(__FILE__, __LINE__,
909                                                         "IceSSL: IceSSL.KeyFile does not agree with IceSSL.CertFile");
910                 }
911             }
912         }
913 
914         for(size_t i = 0; i < files.size(); ++i)
915         {
916             string file = files[i];
917             string keyFile = keyFiles.empty() ? "" : keyFiles[i];
918             string resolved;
919 
920             if(!checkPath(file, defaultDir, false, resolved))
921             {
922                 throw PluginInitializationException(__FILE__, __LINE__,
923                                                     "IceSSL: certificate file not found:\n" + file);
924             }
925             file = resolved;
926 
927             if(!keyFile.empty())
928             {
929                 if(!checkPath(keyFile, defaultDir, false, resolved))
930                 {
931                     throw PluginInitializationException(__FILE__, __LINE__, "IceSSL: key file not found:\n" + keyFile);
932                 }
933                 keyFile = resolved;
934             }
935 
936             try
937             {
938                 _chain.reset(loadCertificateChain(file, keyFile, keychain, keychainPassword, password, passwordPrompt,
939                                                   passwordRetryMax));
940                 break;
941             }
942             catch(const CertificateReadException& ce)
943             {
944                 //
945                 // If this is the last certificate rethrow the exception as PluginInitializationException,
946                 // otherwise try the next certificate.
947                 //
948                 if(i == files.size() - 1)
949                 {
950                     throw PluginInitializationException(__FILE__, __LINE__, ce.reason);
951                 }
952             }
953         }
954     }
955     else if(!findCert.empty())
956     {
957         _chain.reset(findCertificateChain(keychain, keychainPassword, findCert));
958     }
959 
960     //
961     // DiffieHellmanParams in DER format.
962     //
963 #if defined(ICE_USE_SECURE_TRANSPORT_MACOS)
964     string dhFile = properties->getProperty("IceSSL.DHParams");
965     if(!dhFile.empty())
966     {
967         string resolved;
968         if(!checkPath(dhFile, defaultDir, false, resolved))
969         {
970             throw PluginInitializationException(__FILE__, __LINE__, "IceSSL: DH params file not found:\n" + dhFile);
971         }
972 
973         readFile(resolved, _dhParams);
974     }
975 #endif
976 
977     //
978     // Establish the cipher list.
979     //
980     const string ciphers = properties->getProperty("IceSSL.Ciphers");
981     CiphersHelper::initialize();
982 
983     if(!ciphers.empty())
984     {
985         parseCiphers(ciphers);
986     }
987 
988     if(securityTraceLevel() >= 1)
989     {
990         ostringstream os;
991         os << "enabling SSL ciphersuites:";
992 
993         if(_ciphers.empty())
994         {
995             map<string, SSLCipherSuite> enabled = CiphersHelper::ciphers();
996             for(map<string, SSLCipherSuite>::const_iterator i = enabled.begin(); i != enabled.end(); ++i)
997             {
998                 os << "\n " << i->first;
999             }
1000         }
1001         else
1002         {
1003             for(vector<SSLCipherSuite>::const_iterator i = _ciphers.begin(); i != _ciphers.end(); ++i)
1004             {
1005                 os << "\n " << getCipherName(*i);
1006             }
1007         }
1008         getLogger()->trace(securityTraceCategory(), os.str());
1009     }
1010 
1011     //
1012     // Parse protocols
1013     //
1014     const string protocolVersionMax = properties->getProperty("IceSSL.ProtocolVersionMax");
1015     if(!protocolVersionMax.empty())
1016     {
1017         _protocolVersionMax = parseProtocol(protocolVersionMax);
1018     }
1019 
1020     //
1021     // The default min protocol version is set to TLS1.0 to avoid security issues with SSLv3
1022     //
1023     const string protocolVersionMin = properties->getPropertyWithDefault("IceSSL.ProtocolVersionMin", "tls1_0");
1024     if(!protocolVersionMin.empty())
1025     {
1026         _protocolVersionMin = parseProtocol(protocolVersionMin);
1027     }
1028     _initialized = true;
1029 }
1030 
1031 //
1032 // Destroy the engine.
1033 //
1034 void
destroy()1035 IceSSL::SecureTransport::SSLEngine::destroy()
1036 {
1037 }
1038 
1039 IceInternal::TransceiverPtr
createTransceiver(const InstancePtr & instance,const IceInternal::TransceiverPtr & delegate,const string & hostOrAdapterName,bool incoming)1040 IceSSL::SecureTransport::SSLEngine::createTransceiver(const InstancePtr& instance,
1041                                                       const IceInternal::TransceiverPtr& delegate,
1042                                                       const string& hostOrAdapterName,
1043                                                       bool incoming)
1044 {
1045     return new IceSSL::SecureTransport::TransceiverI(instance, delegate, hostOrAdapterName, incoming);
1046 }
1047 
1048 SSLContextRef
newContext(bool incoming)1049 IceSSL::SecureTransport::SSLEngine::newContext(bool incoming)
1050 {
1051     SSLContextRef ssl = SSLCreateContext(kCFAllocatorDefault, incoming ? kSSLServerSide : kSSLClientSide,
1052                                          kSSLStreamType);
1053     if(!ssl)
1054     {
1055         throw SecurityException(__FILE__, __LINE__, "IceSSL: unable to create SSL context");
1056     }
1057 
1058     OSStatus err = noErr;
1059     if(incoming)
1060     {
1061         switch(getVerifyPeer())
1062         {
1063             case 0:
1064             {
1065                 SSLSetClientSideAuthenticate(ssl, kNeverAuthenticate);
1066                 break;
1067             }
1068             case 1:
1069             {
1070                 SSLSetClientSideAuthenticate(ssl, kTryAuthenticate);
1071                 break;
1072             }
1073             case 2:
1074             {
1075                 SSLSetClientSideAuthenticate(ssl, kAlwaysAuthenticate);
1076                 break;
1077             }
1078             default:
1079             {
1080                 assert(false);
1081                 break;
1082             }
1083         }
1084 
1085 #if defined(ICE_USE_SECURE_TRANSPORT_MACOS)
1086         if(!_dhParams.empty())
1087         {
1088             if((err = SSLSetDiffieHellmanParams(ssl, &_dhParams[0], _dhParams.size())))
1089             {
1090                 throw SecurityException(__FILE__, __LINE__,
1091                                         "IceSSL: unable to create the trust object:\n" + sslErrorToString(err));
1092             }
1093         }
1094 #endif
1095     }
1096 
1097     if(_chain && (err = SSLSetCertificate(ssl, _chain.get())))
1098     {
1099         throw SecurityException(__FILE__, __LINE__,
1100                                 "IceSSL: error while setting the SSL context certificate:\n" + sslErrorToString(err));
1101     }
1102 
1103     if(!_ciphers.empty())
1104     {
1105         if((err = SSLSetEnabledCiphers(ssl, &_ciphers[0], _ciphers.size())))
1106         {
1107             throw SecurityException(__FILE__, __LINE__, "IceSSL: error while setting ciphers:\n" + sslErrorToString(err));
1108         }
1109     }
1110 
1111     if((err = SSLSetSessionOption(ssl, incoming ? kSSLSessionOptionBreakOnClientAuth :
1112                                                   kSSLSessionOptionBreakOnServerAuth,
1113                                   true)))
1114     {
1115         throw SecurityException(__FILE__, __LINE__, "IceSSL: error while setting SSL option:\n" + sslErrorToString(err));
1116     }
1117 
1118     if(_protocolVersionMax != kSSLProtocolUnknown)
1119     {
1120         if((err = SSLSetProtocolVersionMax(ssl, _protocolVersionMax)))
1121         {
1122             throw SecurityException(__FILE__, __LINE__,
1123                                     "IceSSL: error while setting SSL protocol version max:\n" + sslErrorToString(err));
1124         }
1125     }
1126 
1127     if(_protocolVersionMin != kSSLProtocolUnknown)
1128     {
1129         if((err = SSLSetProtocolVersionMin(ssl, _protocolVersionMin)))
1130         {
1131             throw SecurityException(__FILE__, __LINE__,
1132                                     "IceSSL: error while setting SSL protocol version min:\n" + sslErrorToString(err));
1133         }
1134     }
1135 
1136     return ssl;
1137 }
1138 
1139 CFArrayRef
getCertificateAuthorities() const1140 IceSSL::SecureTransport::SSLEngine::getCertificateAuthorities() const
1141 {
1142     return _certificateAuthorities.get();
1143 }
1144 
1145 string
getCipherName(SSLCipherSuite cipher) const1146 IceSSL::SecureTransport::SSLEngine::getCipherName(SSLCipherSuite cipher) const
1147 {
1148     return CiphersHelper::cipherName(cipher);
1149 }
1150 
1151 void
parseCiphers(const string & ciphers)1152 IceSSL::SecureTransport::SSLEngine::parseCiphers(const string& ciphers)
1153 {
1154     vector<string> tokens;
1155     vector<CipherExpression> cipherExpressions;
1156 
1157     bool allCiphers = false;
1158     IceUtilInternal::splitString(ciphers, " \t", tokens);
1159     for(vector<string>::const_iterator i = tokens.begin(); i != tokens.end(); ++i)
1160     {
1161         string token(*i);
1162         if(token == "ALL")
1163         {
1164             if(i != tokens.begin())
1165             {
1166                 throw PluginInitializationException(__FILE__, __LINE__,
1167                                                     "IceSSL: `ALL' must be first in cipher list `" + ciphers + "'");
1168             }
1169             allCiphers = true;
1170         }
1171         else if(token == "NONE")
1172         {
1173             if(i != tokens.begin())
1174             {
1175                 throw PluginInitializationException(__FILE__, __LINE__,
1176                                                     "IceSSL: `NONE' must be first in cipher list `" + ciphers + "'");
1177             }
1178         }
1179         else
1180         {
1181             CipherExpression ce;
1182             if(token.find('!') == 0)
1183             {
1184                 ce.negation = true;
1185                 if(token.size() > 1)
1186                 {
1187                     token = token.substr(1);
1188                 }
1189                 else
1190                 {
1191                     throw PluginInitializationException(__FILE__, __LINE__,
1192                                                         "IceSSL: invalid cipher expression `" + token + "'");
1193                 }
1194             }
1195             else
1196             {
1197                 ce.negation = false;
1198             }
1199 
1200             if(token.find('(') == 0)
1201             {
1202                 if(token.rfind(')') != token.size() - 1)
1203                 {
1204                     throw PluginInitializationException(__FILE__, __LINE__,
1205                                                         "IceSSL: invalid cipher expression `" + token + "'");
1206                 }
1207 
1208                 try
1209                 {
1210                     ce.re = new RegExp(token.substr(1, token.size() - 2));
1211                 }
1212                 catch(const Ice::SyscallException&)
1213                 {
1214                     throw PluginInitializationException(__FILE__, __LINE__,
1215                                                         "IceSSL: invalid cipher expression `" + token + "'");
1216                 }
1217             }
1218             else
1219             {
1220                 ce.cipher = token;
1221             }
1222 
1223             cipherExpressions.push_back(ce);
1224         }
1225     }
1226 
1227     //
1228     // Context used to get the cipher list
1229     //
1230     UniqueRef<SSLContextRef> ctx(SSLCreateContext(kCFAllocatorDefault, kSSLServerSide, kSSLStreamType));
1231     size_t numSupportedCiphers = 0;
1232     SSLGetNumberSupportedCiphers(ctx.get(), &numSupportedCiphers);
1233 
1234     vector<SSLCipherSuite> supported;
1235     supported.resize(numSupportedCiphers);
1236 
1237     OSStatus err = SSLGetSupportedCiphers(ctx.get(), &supported[0], &numSupportedCiphers);
1238     if(err)
1239     {
1240         throw PluginInitializationException(__FILE__, __LINE__,
1241                                             "IceSSL: unable to get supported ciphers list:\n" + sslErrorToString(err));
1242     }
1243 
1244     vector<SSLCipherSuite> enabled;
1245     if(allCiphers)
1246     {
1247         enabled = supported;
1248     }
1249 
1250     for(vector<CipherExpression>::const_iterator i = cipherExpressions.begin(); i != cipherExpressions.end(); ++i)
1251     {
1252         CipherExpression ce = *i;
1253         if(ce.negation)
1254         {
1255             for(vector<SSLCipherSuite>::iterator j = enabled.begin(); j != enabled.end();)
1256             {
1257                 string name = CiphersHelper::cipherName(*j);
1258                 if((ce.cipher.empty() && ce.re->match(name)) || ce.cipher == name)
1259                 {
1260                     j = enabled.erase(j);
1261                 }
1262                 else
1263                 {
1264                     ++j;
1265                 }
1266             }
1267         }
1268         else
1269         {
1270             if(ce.cipher.empty())
1271             {
1272                 for(vector<SSLCipherSuite>::const_iterator j = supported.begin(); j != supported.end(); ++j)
1273                 {
1274                     SSLCipherSuite cipher = *j;
1275                     string name = CiphersHelper::cipherName(cipher);
1276                     if(ce.re->match(name))
1277                     {
1278                         vector<SSLCipherSuite>::const_iterator k = find(enabled.begin(), enabled.end(), cipher);
1279                         if(k == enabled.end())
1280                         {
1281                             enabled.push_back(cipher);
1282                         }
1283                     }
1284                 }
1285             }
1286             else
1287             {
1288                 SSLCipherSuite cipher = CiphersHelper::cipherForName(ce.cipher);
1289                 vector<SSLCipherSuite>::const_iterator k = find(enabled.begin(), enabled.end(), cipher);
1290                 if(k == enabled.end())
1291                 {
1292                     enabled.push_back(cipher);
1293                 }
1294             }
1295         }
1296     }
1297     _ciphers = enabled;
1298 
1299     if(_ciphers.empty())
1300     {
1301         throw PluginInitializationException(__FILE__, __LINE__,
1302                                             "IceSSL: invalid value for IceSSL.Ciphers:\n" + ciphers +
1303                                             "\nThe result cipher list does not contain any entries");
1304     }
1305 }
1306