2 * Mac OS X Secure Transport implementation of the schannel (SSL/TLS) provider.
4 * Copyright 2005 Juan Lang
5 * Copyright 2008 Henri Verbeet
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
27 #include "wine/port.h"
31 #ifdef HAVE_SECURITY_SECURITY_H
32 #include <Security/Security.h>
33 #define GetCurrentThread GetCurrentThread_Mac
34 #define LoadResource LoadResource_Mac
35 #include <CoreServices/CoreServices.h>
36 #undef GetCurrentThread
41 #define WIN32_NO_STATUS
47 #include "secur32_priv.h"
48 #include "wine/debug.h"
50 #if defined(HAVE_SECURITY_SECURITY_H) && !defined(SONAME_LIBGNUTLS)
52 WINE_DEFAULT_DEBUG_CHANNEL(secur32
);
54 static const struct schan_callbacks
*callbacks
;
56 #if MAC_OS_X_VERSION_MAX_ALLOWED < 1060
57 /* Defined in <Security/CipherSuite.h> in the 10.6 SDK or later. */
59 TLS_ECDH_ECDSA_WITH_NULL_SHA
= 0xC001,
60 TLS_ECDH_ECDSA_WITH_RC4_128_SHA
= 0xC002,
61 TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA
= 0xC003,
62 TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA
= 0xC004,
63 TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA
= 0xC005,
64 TLS_ECDHE_ECDSA_WITH_NULL_SHA
= 0xC006,
65 TLS_ECDHE_ECDSA_WITH_RC4_128_SHA
= 0xC007,
66 TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA
= 0xC008,
67 TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA
= 0xC009,
68 TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA
= 0xC00A,
69 TLS_ECDH_RSA_WITH_NULL_SHA
= 0xC00B,
70 TLS_ECDH_RSA_WITH_RC4_128_SHA
= 0xC00C,
71 TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA
= 0xC00D,
72 TLS_ECDH_RSA_WITH_AES_128_CBC_SHA
= 0xC00E,
73 TLS_ECDH_RSA_WITH_AES_256_CBC_SHA
= 0xC00F,
74 TLS_ECDHE_RSA_WITH_NULL_SHA
= 0xC010,
75 TLS_ECDHE_RSA_WITH_RC4_128_SHA
= 0xC011,
76 TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA
= 0xC012,
77 TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA
= 0xC013,
78 TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA
= 0xC014,
79 TLS_ECDH_anon_WITH_NULL_SHA
= 0xC015,
80 TLS_ECDH_anon_WITH_RC4_128_SHA
= 0xC016,
81 TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA
= 0xC017,
82 TLS_ECDH_anon_WITH_AES_128_CBC_SHA
= 0xC018,
83 TLS_ECDH_anon_WITH_AES_256_CBC_SHA
= 0xC019,
87 #if MAC_OS_X_VERSION_MAX_ALLOWED < 1080
88 /* Defined in <Security/CipherSuite.h> in the 10.8 SDK or later. */
90 TLS_NULL_WITH_NULL_NULL
= 0x0000,
91 TLS_RSA_WITH_NULL_MD5
= 0x0001,
92 TLS_RSA_WITH_NULL_SHA
= 0x0002,
93 TLS_RSA_WITH_RC4_128_MD5
= 0x0004,
94 TLS_RSA_WITH_RC4_128_SHA
= 0x0005,
95 TLS_RSA_WITH_3DES_EDE_CBC_SHA
= 0x000A,
96 TLS_RSA_WITH_NULL_SHA256
= 0x003B,
97 TLS_RSA_WITH_AES_128_CBC_SHA256
= 0x003C,
98 TLS_RSA_WITH_AES_256_CBC_SHA256
= 0x003D,
99 TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA
= 0x000D,
100 TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA
= 0x0010,
101 TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA
= 0x0013,
102 TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA
= 0x0016,
103 TLS_DH_DSS_WITH_AES_128_CBC_SHA256
= 0x003E,
104 TLS_DH_RSA_WITH_AES_128_CBC_SHA256
= 0x003F,
105 TLS_DHE_DSS_WITH_AES_128_CBC_SHA256
= 0x0040,
106 TLS_DHE_RSA_WITH_AES_128_CBC_SHA256
= 0x0067,
107 TLS_DH_DSS_WITH_AES_256_CBC_SHA256
= 0x0068,
108 TLS_DH_RSA_WITH_AES_256_CBC_SHA256
= 0x0069,
109 TLS_DHE_DSS_WITH_AES_256_CBC_SHA256
= 0x006A,
110 TLS_DHE_RSA_WITH_AES_256_CBC_SHA256
= 0x006B,
111 TLS_DH_anon_WITH_RC4_128_MD5
= 0x0018,
112 TLS_DH_anon_WITH_3DES_EDE_CBC_SHA
= 0x001B,
113 TLS_DH_anon_WITH_AES_128_CBC_SHA256
= 0x006C,
114 TLS_DH_anon_WITH_AES_256_CBC_SHA256
= 0x006D,
115 TLS_RSA_WITH_AES_128_GCM_SHA256
= 0x009C,
116 TLS_RSA_WITH_AES_256_GCM_SHA384
= 0x009D,
117 TLS_DHE_RSA_WITH_AES_128_GCM_SHA256
= 0x009E,
118 TLS_DHE_RSA_WITH_AES_256_GCM_SHA384
= 0x009F,
119 TLS_DH_RSA_WITH_AES_128_GCM_SHA256
= 0x00A0,
120 TLS_DH_RSA_WITH_AES_256_GCM_SHA384
= 0x00A1,
121 TLS_DHE_DSS_WITH_AES_128_GCM_SHA256
= 0x00A2,
122 TLS_DHE_DSS_WITH_AES_256_GCM_SHA384
= 0x00A3,
123 TLS_DH_DSS_WITH_AES_128_GCM_SHA256
= 0x00A4,
124 TLS_DH_DSS_WITH_AES_256_GCM_SHA384
= 0x00A5,
125 TLS_DH_anon_WITH_AES_128_GCM_SHA256
= 0x00A6,
126 TLS_DH_anon_WITH_AES_256_GCM_SHA384
= 0x00A7,
127 TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256
= 0xC023,
128 TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384
= 0xC024,
129 TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256
= 0xC025,
130 TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384
= 0xC026,
131 TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256
= 0xC027,
132 TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384
= 0xC028,
133 TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256
= 0xC029,
134 TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384
= 0xC02A,
135 TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
= 0xC02B,
136 TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
= 0xC02C,
137 TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256
= 0xC02D,
138 TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384
= 0xC02E,
139 TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
= 0xC02F,
140 TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
= 0xC030,
141 TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256
= 0xC031,
142 TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384
= 0xC032,
143 TLS_EMPTY_RENEGOTIATION_INFO_SCSV
= 0x00FF,
146 /* Defined in <Security/SecureTransport.h> in the 10.8 SDK or later. */
148 kTLSProtocol11
= 7, /* TLS 1.1 */
149 kTLSProtocol12
= 8, /* TLS 1.2 */
153 #if MAC_OS_X_VERSION_MAX_ALLOWED < 1090
154 /* Defined in <Security/CipherSuite.h> in the 10.9 SDK or later. */
156 TLS_PSK_WITH_RC4_128_SHA
= 0x008A,
157 TLS_PSK_WITH_3DES_EDE_CBC_SHA
= 0x008B,
158 TLS_PSK_WITH_AES_128_CBC_SHA
= 0x008C,
159 TLS_PSK_WITH_AES_256_CBC_SHA
= 0x008D,
160 TLS_DHE_PSK_WITH_RC4_128_SHA
= 0x008E,
161 TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA
= 0x008F,
162 TLS_DHE_PSK_WITH_AES_128_CBC_SHA
= 0x0090,
163 TLS_DHE_PSK_WITH_AES_256_CBC_SHA
= 0x0091,
164 TLS_RSA_PSK_WITH_RC4_128_SHA
= 0x0092,
165 TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA
= 0x0093,
166 TLS_RSA_PSK_WITH_AES_128_CBC_SHA
= 0x0094,
167 TLS_RSA_PSK_WITH_AES_256_CBC_SHA
= 0x0095,
168 TLS_PSK_WITH_NULL_SHA
= 0x002C,
169 TLS_DHE_PSK_WITH_NULL_SHA
= 0x002D,
170 TLS_RSA_PSK_WITH_NULL_SHA
= 0x002E,
171 TLS_PSK_WITH_AES_128_GCM_SHA256
= 0x00A8,
172 TLS_PSK_WITH_AES_256_GCM_SHA384
= 0x00A9,
173 TLS_DHE_PSK_WITH_AES_128_GCM_SHA256
= 0x00AA,
174 TLS_DHE_PSK_WITH_AES_256_GCM_SHA384
= 0x00AB,
175 TLS_RSA_PSK_WITH_AES_128_GCM_SHA256
= 0x00AC,
176 TLS_RSA_PSK_WITH_AES_256_GCM_SHA384
= 0x00AD,
177 TLS_PSK_WITH_AES_128_CBC_SHA256
= 0x00AE,
178 TLS_PSK_WITH_AES_256_CBC_SHA384
= 0x00AF,
179 TLS_PSK_WITH_NULL_SHA256
= 0x00B0,
180 TLS_PSK_WITH_NULL_SHA384
= 0x00B1,
181 TLS_DHE_PSK_WITH_AES_128_CBC_SHA256
= 0x00B2,
182 TLS_DHE_PSK_WITH_AES_256_CBC_SHA384
= 0x00B3,
183 TLS_DHE_PSK_WITH_NULL_SHA256
= 0x00B4,
184 TLS_DHE_PSK_WITH_NULL_SHA384
= 0x00B5,
185 TLS_RSA_PSK_WITH_AES_128_CBC_SHA256
= 0x00B6,
186 TLS_RSA_PSK_WITH_AES_256_CBC_SHA384
= 0x00B7,
187 TLS_RSA_PSK_WITH_NULL_SHA256
= 0x00B8,
188 TLS_RSA_PSK_WITH_NULL_SHA384
= 0x00B9,
196 schan_mode_HANDSHAKE
,
200 SSLContextRef context
;
201 struct schan_transport
*transport
;
202 enum schan_mode mode
;
203 pthread_mutex_t mutex
;
212 schan_kx_DH_anon_EXPORT
,
214 schan_kx_DH_DSS_EXPORT
,
216 schan_kx_DH_RSA_EXPORT
,
218 schan_kx_DHE_DSS_EXPORT
,
221 schan_kx_DHE_RSA_EXPORT
,
226 schan_kx_ECDHE_ECDSA
,
228 schan_kx_FORTEZZA_DMS
,
237 schan_enc_3DES_EDE_CBC
,
238 schan_enc_AES_128_CBC
,
239 schan_enc_AES_128_GCM
,
240 schan_enc_AES_256_CBC
,
241 schan_enc_AES_256_GCM
,
244 schan_enc_FORTEZZA_CBC
,
248 schan_enc_RC2_CBC_40
,
262 struct cipher_suite
{
263 SSLCipherSuite suite
;
270 /* This table corresponds to the enum in <Security/CipherSuite.h>. */
271 static const struct cipher_suite cipher_suites
[] = {
272 #define CIPHER_SUITE(p, kx, enc, mac) { p##_##kx##_WITH_##enc##_##mac, schan_proto_##p, \
273 schan_kx_##kx, schan_enc_##enc, schan_mac_##mac }
274 CIPHER_SUITE(SSL
, RSA
, NULL
, MD5
),
275 CIPHER_SUITE(SSL
, RSA
, NULL
, MD5
),
276 CIPHER_SUITE(SSL
, RSA
, NULL
, SHA
),
277 CIPHER_SUITE(SSL
, RSA_EXPORT
, RC4_40
, MD5
),
278 CIPHER_SUITE(SSL
, RSA
, RC4_128
, MD5
),
279 CIPHER_SUITE(SSL
, RSA
, RC4_128
, SHA
),
280 CIPHER_SUITE(SSL
, RSA_EXPORT
, RC2_CBC_40
, MD5
),
281 CIPHER_SUITE(SSL
, RSA
, IDEA_CBC
, SHA
),
282 CIPHER_SUITE(SSL
, RSA_EXPORT
, DES40_CBC
, SHA
),
283 CIPHER_SUITE(SSL
, RSA
, DES_CBC
, SHA
),
284 CIPHER_SUITE(SSL
, RSA
, 3DES_EDE_CBC
, SHA
),
285 CIPHER_SUITE(SSL
, DH_DSS_EXPORT
, DES40_CBC
, SHA
),
286 CIPHER_SUITE(SSL
, DH_DSS
, DES_CBC
, SHA
),
287 CIPHER_SUITE(SSL
, DH_DSS
, 3DES_EDE_CBC
, SHA
),
288 CIPHER_SUITE(SSL
, DH_RSA_EXPORT
, DES40_CBC
, SHA
),
289 CIPHER_SUITE(SSL
, DH_RSA
, DES_CBC
, SHA
),
290 CIPHER_SUITE(SSL
, DH_RSA
, 3DES_EDE_CBC
, SHA
),
291 CIPHER_SUITE(SSL
, DHE_DSS_EXPORT
, DES40_CBC
, SHA
),
292 CIPHER_SUITE(SSL
, DHE_DSS
, DES_CBC
, SHA
),
293 CIPHER_SUITE(SSL
, DHE_DSS
, 3DES_EDE_CBC
, SHA
),
294 CIPHER_SUITE(SSL
, DHE_RSA_EXPORT
, DES40_CBC
, SHA
),
295 CIPHER_SUITE(SSL
, DHE_RSA
, DES_CBC
, SHA
),
296 CIPHER_SUITE(SSL
, DHE_RSA
, 3DES_EDE_CBC
, SHA
),
297 CIPHER_SUITE(SSL
, DH_anon_EXPORT
, RC4_40
, MD5
),
298 CIPHER_SUITE(SSL
, DH_anon
, RC4_128
, MD5
),
299 CIPHER_SUITE(SSL
, DH_anon_EXPORT
, DES40_CBC
, SHA
),
300 CIPHER_SUITE(SSL
, DH_anon
, DES_CBC
, SHA
),
301 CIPHER_SUITE(SSL
, DH_anon
, 3DES_EDE_CBC
, SHA
),
302 CIPHER_SUITE(SSL
, FORTEZZA_DMS
, NULL
, SHA
),
303 CIPHER_SUITE(SSL
, FORTEZZA_DMS
, FORTEZZA_CBC
, SHA
),
305 CIPHER_SUITE(TLS
, RSA
, AES_128_CBC
, SHA
),
306 CIPHER_SUITE(TLS
, DH_DSS
, AES_128_CBC
, SHA
),
307 CIPHER_SUITE(TLS
, DH_RSA
, AES_128_CBC
, SHA
),
308 CIPHER_SUITE(TLS
, DHE_DSS
, AES_128_CBC
, SHA
),
309 CIPHER_SUITE(TLS
, DHE_RSA
, AES_128_CBC
, SHA
),
310 CIPHER_SUITE(TLS
, DH_anon
, AES_128_CBC
, SHA
),
311 CIPHER_SUITE(TLS
, RSA
, AES_256_CBC
, SHA
),
312 CIPHER_SUITE(TLS
, DH_DSS
, AES_256_CBC
, SHA
),
313 CIPHER_SUITE(TLS
, DH_RSA
, AES_256_CBC
, SHA
),
314 CIPHER_SUITE(TLS
, DHE_DSS
, AES_256_CBC
, SHA
),
315 CIPHER_SUITE(TLS
, DHE_RSA
, AES_256_CBC
, SHA
),
316 CIPHER_SUITE(TLS
, DH_anon
, AES_256_CBC
, SHA
),
318 CIPHER_SUITE(TLS
, ECDH_ECDSA
, NULL
, SHA
),
319 CIPHER_SUITE(TLS
, ECDH_ECDSA
, RC4_128
, SHA
),
320 CIPHER_SUITE(TLS
, ECDH_ECDSA
, 3DES_EDE_CBC
, SHA
),
321 CIPHER_SUITE(TLS
, ECDH_ECDSA
, AES_128_CBC
, SHA
),
322 CIPHER_SUITE(TLS
, ECDH_ECDSA
, AES_256_CBC
, SHA
),
323 CIPHER_SUITE(TLS
, ECDHE_ECDSA
, NULL
, SHA
),
324 CIPHER_SUITE(TLS
, ECDHE_ECDSA
, RC4_128
, SHA
),
325 CIPHER_SUITE(TLS
, ECDHE_ECDSA
, 3DES_EDE_CBC
, SHA
),
326 CIPHER_SUITE(TLS
, ECDHE_ECDSA
, AES_128_CBC
, SHA
),
327 CIPHER_SUITE(TLS
, ECDHE_ECDSA
, AES_256_CBC
, SHA
),
328 CIPHER_SUITE(TLS
, ECDH_RSA
, NULL
, SHA
),
329 CIPHER_SUITE(TLS
, ECDH_RSA
, RC4_128
, SHA
),
330 CIPHER_SUITE(TLS
, ECDH_RSA
, 3DES_EDE_CBC
, SHA
),
331 CIPHER_SUITE(TLS
, ECDH_RSA
, AES_128_CBC
, SHA
),
332 CIPHER_SUITE(TLS
, ECDH_RSA
, AES_256_CBC
, SHA
),
333 CIPHER_SUITE(TLS
, ECDHE_RSA
, NULL
, SHA
),
334 CIPHER_SUITE(TLS
, ECDHE_RSA
, RC4_128
, SHA
),
335 CIPHER_SUITE(TLS
, ECDHE_RSA
, 3DES_EDE_CBC
, SHA
),
336 CIPHER_SUITE(TLS
, ECDHE_RSA
, AES_128_CBC
, SHA
),
337 CIPHER_SUITE(TLS
, ECDHE_RSA
, AES_256_CBC
, SHA
),
338 CIPHER_SUITE(TLS
, ECDH_anon
, NULL
, SHA
),
339 CIPHER_SUITE(TLS
, ECDH_anon
, RC4_128
, SHA
),
340 CIPHER_SUITE(TLS
, ECDH_anon
, 3DES_EDE_CBC
, SHA
),
341 CIPHER_SUITE(TLS
, ECDH_anon
, AES_128_CBC
, SHA
),
342 CIPHER_SUITE(TLS
, ECDH_anon
, AES_256_CBC
, SHA
),
344 CIPHER_SUITE(TLS
, NULL
, NULL
, NULL
),
345 CIPHER_SUITE(TLS
, RSA
, NULL
, MD5
),
346 CIPHER_SUITE(TLS
, RSA
, NULL
, SHA
),
347 CIPHER_SUITE(TLS
, RSA
, RC4_128
, MD5
),
348 CIPHER_SUITE(TLS
, RSA
, RC4_128
, SHA
),
349 CIPHER_SUITE(TLS
, RSA
, 3DES_EDE_CBC
, SHA
),
350 CIPHER_SUITE(TLS
, RSA
, NULL
, SHA256
),
351 CIPHER_SUITE(TLS
, RSA
, AES_128_CBC
, SHA256
),
352 CIPHER_SUITE(TLS
, RSA
, AES_256_CBC
, SHA256
),
353 CIPHER_SUITE(TLS
, DH_DSS
, 3DES_EDE_CBC
, SHA
),
354 CIPHER_SUITE(TLS
, DH_RSA
, 3DES_EDE_CBC
, SHA
),
355 CIPHER_SUITE(TLS
, DHE_DSS
, 3DES_EDE_CBC
, SHA
),
356 CIPHER_SUITE(TLS
, DHE_RSA
, 3DES_EDE_CBC
, SHA
),
357 CIPHER_SUITE(TLS
, DH_DSS
, AES_128_CBC
, SHA256
),
358 CIPHER_SUITE(TLS
, DH_RSA
, AES_128_CBC
, SHA256
),
359 CIPHER_SUITE(TLS
, DHE_DSS
, AES_128_CBC
, SHA256
),
360 CIPHER_SUITE(TLS
, DHE_RSA
, AES_128_CBC
, SHA256
),
361 CIPHER_SUITE(TLS
, DH_DSS
, AES_256_CBC
, SHA256
),
362 CIPHER_SUITE(TLS
, DH_RSA
, AES_256_CBC
, SHA256
),
363 CIPHER_SUITE(TLS
, DHE_DSS
, AES_256_CBC
, SHA256
),
364 CIPHER_SUITE(TLS
, DHE_RSA
, AES_256_CBC
, SHA256
),
365 CIPHER_SUITE(TLS
, DH_anon
, RC4_128
, MD5
),
366 CIPHER_SUITE(TLS
, DH_anon
, 3DES_EDE_CBC
, SHA
),
367 CIPHER_SUITE(TLS
, DH_anon
, AES_128_CBC
, SHA256
),
368 CIPHER_SUITE(TLS
, DH_anon
, AES_256_CBC
, SHA256
),
370 CIPHER_SUITE(TLS
, PSK
, RC4_128
, SHA
),
371 CIPHER_SUITE(TLS
, PSK
, 3DES_EDE_CBC
, SHA
),
372 CIPHER_SUITE(TLS
, PSK
, AES_128_CBC
, SHA
),
373 CIPHER_SUITE(TLS
, PSK
, AES_256_CBC
, SHA
),
374 CIPHER_SUITE(TLS
, DHE_PSK
, RC4_128
, SHA
),
375 CIPHER_SUITE(TLS
, DHE_PSK
, 3DES_EDE_CBC
, SHA
),
376 CIPHER_SUITE(TLS
, DHE_PSK
, AES_128_CBC
, SHA
),
377 CIPHER_SUITE(TLS
, DHE_PSK
, AES_256_CBC
, SHA
),
378 CIPHER_SUITE(TLS
, RSA_PSK
, RC4_128
, SHA
),
379 CIPHER_SUITE(TLS
, RSA_PSK
, 3DES_EDE_CBC
, SHA
),
380 CIPHER_SUITE(TLS
, RSA_PSK
, AES_128_CBC
, SHA
),
381 CIPHER_SUITE(TLS
, RSA_PSK
, AES_256_CBC
, SHA
),
382 CIPHER_SUITE(TLS
, PSK
, NULL
, SHA
),
383 CIPHER_SUITE(TLS
, DHE_PSK
, NULL
, SHA
),
384 CIPHER_SUITE(TLS
, RSA_PSK
, NULL
, SHA
),
386 CIPHER_SUITE(TLS
, RSA
, AES_128_GCM
, SHA256
),
387 CIPHER_SUITE(TLS
, RSA
, AES_256_GCM
, SHA384
),
388 CIPHER_SUITE(TLS
, DHE_RSA
, AES_128_GCM
, SHA256
),
389 CIPHER_SUITE(TLS
, DHE_RSA
, AES_256_GCM
, SHA384
),
390 CIPHER_SUITE(TLS
, DH_RSA
, AES_128_GCM
, SHA256
),
391 CIPHER_SUITE(TLS
, DH_RSA
, AES_256_GCM
, SHA384
),
392 CIPHER_SUITE(TLS
, DHE_DSS
, AES_128_GCM
, SHA256
),
393 CIPHER_SUITE(TLS
, DHE_DSS
, AES_256_GCM
, SHA384
),
394 CIPHER_SUITE(TLS
, DH_DSS
, AES_128_GCM
, SHA256
),
395 CIPHER_SUITE(TLS
, DH_DSS
, AES_256_GCM
, SHA384
),
396 CIPHER_SUITE(TLS
, DH_anon
, AES_128_GCM
, SHA256
),
397 CIPHER_SUITE(TLS
, DH_anon
, AES_256_GCM
, SHA384
),
399 CIPHER_SUITE(TLS
, PSK
, AES_128_GCM
, SHA256
),
400 CIPHER_SUITE(TLS
, PSK
, AES_256_GCM
, SHA384
),
401 CIPHER_SUITE(TLS
, DHE_PSK
, AES_128_GCM
, SHA256
),
402 CIPHER_SUITE(TLS
, DHE_PSK
, AES_256_GCM
, SHA384
),
403 CIPHER_SUITE(TLS
, RSA_PSK
, AES_128_GCM
, SHA256
),
404 CIPHER_SUITE(TLS
, RSA_PSK
, AES_256_GCM
, SHA384
),
405 CIPHER_SUITE(TLS
, PSK
, AES_128_CBC
, SHA256
),
406 CIPHER_SUITE(TLS
, PSK
, AES_256_CBC
, SHA384
),
407 CIPHER_SUITE(TLS
, PSK
, NULL
, SHA256
),
408 CIPHER_SUITE(TLS
, PSK
, NULL
, SHA384
),
409 CIPHER_SUITE(TLS
, DHE_PSK
, AES_128_CBC
, SHA256
),
410 CIPHER_SUITE(TLS
, DHE_PSK
, AES_256_CBC
, SHA384
),
411 CIPHER_SUITE(TLS
, DHE_PSK
, NULL
, SHA256
),
412 CIPHER_SUITE(TLS
, DHE_PSK
, NULL
, SHA384
),
413 CIPHER_SUITE(TLS
, RSA_PSK
, AES_128_CBC
, SHA256
),
414 CIPHER_SUITE(TLS
, RSA_PSK
, AES_256_CBC
, SHA384
),
415 CIPHER_SUITE(TLS
, RSA_PSK
, NULL
, SHA256
),
416 CIPHER_SUITE(TLS
, RSA_PSK
, NULL
, SHA384
),
418 CIPHER_SUITE(TLS
, ECDHE_ECDSA
, AES_128_CBC
, SHA256
),
419 CIPHER_SUITE(TLS
, ECDHE_ECDSA
, AES_256_CBC
, SHA384
),
420 CIPHER_SUITE(TLS
, ECDH_ECDSA
, AES_128_CBC
, SHA256
),
421 CIPHER_SUITE(TLS
, ECDH_ECDSA
, AES_256_CBC
, SHA384
),
422 CIPHER_SUITE(TLS
, ECDHE_RSA
, AES_128_CBC
, SHA256
),
423 CIPHER_SUITE(TLS
, ECDHE_RSA
, AES_256_CBC
, SHA384
),
424 CIPHER_SUITE(TLS
, ECDH_RSA
, AES_128_CBC
, SHA256
),
425 CIPHER_SUITE(TLS
, ECDH_RSA
, AES_256_CBC
, SHA384
),
426 CIPHER_SUITE(TLS
, ECDHE_ECDSA
, AES_128_GCM
, SHA256
),
427 CIPHER_SUITE(TLS
, ECDHE_ECDSA
, AES_256_GCM
, SHA384
),
428 CIPHER_SUITE(TLS
, ECDH_ECDSA
, AES_128_GCM
, SHA256
),
429 CIPHER_SUITE(TLS
, ECDH_ECDSA
, AES_256_GCM
, SHA384
),
430 CIPHER_SUITE(TLS
, ECDHE_RSA
, AES_128_GCM
, SHA256
),
431 CIPHER_SUITE(TLS
, ECDHE_RSA
, AES_256_GCM
, SHA384
),
432 CIPHER_SUITE(TLS
, ECDH_RSA
, AES_128_GCM
, SHA256
),
433 CIPHER_SUITE(TLS
, ECDH_RSA
, AES_256_GCM
, SHA384
),
435 CIPHER_SUITE(SSL
, RSA
, RC2_CBC
, MD5
),
436 CIPHER_SUITE(SSL
, RSA
, IDEA_CBC
, MD5
),
437 CIPHER_SUITE(SSL
, RSA
, DES_CBC
, MD5
),
438 CIPHER_SUITE(SSL
, RSA
, 3DES_EDE_CBC
, MD5
),
443 static const struct cipher_suite
* get_cipher_suite(SSLCipherSuite cipher_suite
)
446 for (i
= 0; i
< ARRAY_SIZE(cipher_suites
); i
++)
448 if (cipher_suites
[i
].suite
== cipher_suite
)
449 return &cipher_suites
[i
];
456 static DWORD
get_session_protocol(struct mac_session
* s
)
458 SSLProtocol protocol
;
461 TRACE("(%p/%p)\n", s
, s
->context
);
463 status
= SSLGetNegotiatedProtocolVersion(s
->context
, &protocol
);
466 ERR("Failed to get session protocol: %d\n", status
);
470 TRACE("protocol %d\n", protocol
);
474 case kSSLProtocol2
: return SP_PROT_SSL2_CLIENT
;
475 case kSSLProtocol3
: return SP_PROT_SSL3_CLIENT
;
476 case kTLSProtocol1
: return SP_PROT_TLS1_CLIENT
;
477 case kTLSProtocol11
: return SP_PROT_TLS1_1_CLIENT
;
478 case kTLSProtocol12
: return SP_PROT_TLS1_2_CLIENT
;
480 FIXME("unknown protocol %d\n", protocol
);
485 static ALG_ID
get_cipher_algid(const struct cipher_suite
* c
)
487 TRACE("(%#x)\n", (unsigned int)c
->suite
);
491 case schan_enc_3DES_EDE_CBC
: return CALG_3DES
;
492 case schan_enc_AES_128_CBC
: return CALG_AES_128
;
493 case schan_enc_AES_256_CBC
: return CALG_AES_256
;
494 case schan_enc_DES_CBC
: return CALG_DES
;
495 case schan_enc_DES40_CBC
: return CALG_DES
;
496 case schan_enc_NULL
: return 0;
497 case schan_enc_RC2_CBC_40
: return CALG_RC2
;
498 case schan_enc_RC2_CBC
: return CALG_RC2
;
499 case schan_enc_RC4_128
: return CALG_RC4
;
500 case schan_enc_RC4_40
: return CALG_RC4
;
502 case schan_enc_AES_128_GCM
:
503 case schan_enc_AES_256_GCM
:
504 case schan_enc_FORTEZZA_CBC
:
505 case schan_enc_IDEA_CBC
:
506 FIXME("Don't know CALG for encryption algorithm %d, returning 0\n", c
->enc_alg
);
510 FIXME("Unknown encryption algorithm %d for cipher suite %#x, returning 0\n", c
->enc_alg
, (unsigned int)c
->suite
);
515 static unsigned int get_cipher_key_size(const struct cipher_suite
* c
)
517 TRACE("(%#x)\n", (unsigned int)c
->suite
);
521 case schan_enc_3DES_EDE_CBC
: return 168;
522 case schan_enc_AES_128_CBC
: return 128;
523 case schan_enc_AES_128_GCM
: return 128;
524 case schan_enc_AES_256_CBC
: return 256;
525 case schan_enc_AES_256_GCM
: return 256;
526 case schan_enc_DES_CBC
: return 56;
527 case schan_enc_DES40_CBC
: return 40;
528 case schan_enc_NULL
: return 0;
529 case schan_enc_RC2_CBC_40
: return 40;
530 case schan_enc_RC2_CBC
: return 128;
531 case schan_enc_RC4_128
: return 128;
532 case schan_enc_RC4_40
: return 40;
534 case schan_enc_FORTEZZA_CBC
:
535 case schan_enc_IDEA_CBC
:
536 FIXME("Don't know key size for encryption algorithm %d, returning 0\n", c
->enc_alg
);
540 FIXME("Unknown encryption algorithm %d for cipher suite %#x, returning 0\n", c
->enc_alg
, (unsigned int)c
->suite
);
545 static ALG_ID
get_mac_algid(const struct cipher_suite
* c
)
547 TRACE("(%#x)\n", (unsigned int)c
->suite
);
551 case schan_mac_MD5
: return CALG_MD5
;
552 case schan_mac_NULL
: return 0;
553 case schan_mac_SHA
: return CALG_SHA
;
554 case schan_mac_SHA256
: return CALG_SHA_256
;
555 case schan_mac_SHA384
: return CALG_SHA_384
;
558 FIXME("Unknown hashing algorithm %d for cipher suite %#x, returning 0\n", c
->mac_alg
, (unsigned)c
->suite
);
563 static unsigned int get_mac_key_size(const struct cipher_suite
* c
)
565 TRACE("(%#x)\n", (unsigned int)c
->suite
);
569 case schan_mac_MD5
: return 128;
570 case schan_mac_NULL
: return 0;
571 case schan_mac_SHA
: return 160;
572 case schan_mac_SHA256
: return 256;
573 case schan_mac_SHA384
: return 384;
576 FIXME("Unknown hashing algorithm %d for cipher suite %#x, returning 0\n", c
->mac_alg
, (unsigned)c
->suite
);
581 static ALG_ID
get_kx_algid(const struct cipher_suite
* c
)
583 TRACE("(%#x)\n", (unsigned int)c
->suite
);
587 case schan_kx_DHE_DSS_EXPORT
:
588 case schan_kx_DHE_DSS
:
589 case schan_kx_DHE_PSK
:
590 case schan_kx_DHE_RSA_EXPORT
:
591 case schan_kx_DHE_RSA
: return CALG_DH_EPHEM
;
592 case schan_kx_ECDH_anon
:
593 case schan_kx_ECDH_ECDSA
:
594 case schan_kx_ECDH_RSA
: return CALG_ECDH
;
595 case schan_kx_ECDHE_ECDSA
:
596 case schan_kx_ECDHE_RSA
: return CALG_ECDH_EPHEM
;
597 case schan_kx_NULL
: return 0;
599 case schan_kx_RSA_EXPORT
:
600 case schan_kx_RSA_PSK
: return CALG_RSA_KEYX
;
602 case schan_kx_DH_anon_EXPORT
:
603 case schan_kx_DH_anon
:
604 case schan_kx_DH_DSS_EXPORT
:
605 case schan_kx_DH_DSS
:
606 case schan_kx_DH_RSA_EXPORT
:
607 case schan_kx_DH_RSA
:
608 case schan_kx_FORTEZZA_DMS
:
610 FIXME("Don't know CALG for key exchange algorithm %d for cipher suite %#x, returning 0\n", c
->kx_alg
, (unsigned)c
->suite
);
614 FIXME("Unknown key exchange algorithm %d for cipher suite %#x, returning 0\n", c
->kx_alg
, (unsigned)c
->suite
);
621 * Callback registered with SSLSetIOFuncs as the read function for a
622 * session. Reads data from the session connection. Conforms to the
625 * transport - The session connection
626 * buff - The buffer into which to store the read data. Must be at least
627 * *buff_len bytes in length.
628 * *buff_len - On input, the desired length to read. On successful return,
629 * the number of bytes actually read.
632 * noErr on complete success meaning the requested length was successfully
634 * errSSLWouldBlock when the requested length could not be read without
635 * blocking. *buff_len indicates how much was actually read. The
636 * caller should try again if/when they want to read more.
637 * errSSLClosedGraceful when the connection has closed and there's no
638 * more data to be read.
639 * other error code for failure.
641 static OSStatus
pull_adapter(SSLConnectionRef transport
, void *buff
, SIZE_T
*buff_len
)
643 struct mac_session
*s
= (struct mac_session
*)transport
;
644 size_t requested
= *buff_len
;
648 TRACE("(%p/%p, %p, %p/%lu)\n", s
, s
->transport
, buff
, buff_len
, *buff_len
);
650 if (s
->mode
!= schan_mode_READ
&& s
->mode
!= schan_mode_HANDSHAKE
)
652 WARN("called in mode %u\n", s
->mode
);
656 status
= callbacks
->pull(s
->transport
, buff
, buff_len
);
661 TRACE("Connection closed\n");
662 ret
= errSSLClosedGraceful
;
664 else if (*buff_len
< requested
)
666 TRACE("Pulled %lu bytes before would block\n", *buff_len
);
667 ret
= errSSLWouldBlock
;
671 TRACE("Pulled %lu bytes\n", *buff_len
);
675 else if (status
== -1)
677 TRACE("Would block before being able to pull anything\n");
678 ret
= errSSLWouldBlock
;
682 FIXME("Unknown status code from schan_pull: %d\n", status
);
690 * Callback registered with SSLSetIOFuncs as the write function for a
691 * session. Writes data to the session connection. Conforms to the
694 * transport - The session connection
695 * buff - The buffer of data to write. Must be at least *buff_len bytes in length.
696 * *buff_len - On input, the desired length to write. On successful return,
697 * the number of bytes actually written.
700 * noErr on complete or partial success; *buff_len indicates how much data
701 * was actually written, which may be less than requested.
702 * errSSLWouldBlock when no data could be written without blocking. The
703 * caller should try again.
704 * other error code for failure.
706 static OSStatus
push_adapter(SSLConnectionRef transport
, const void *buff
, SIZE_T
*buff_len
)
708 struct mac_session
*s
= (struct mac_session
*)transport
;
712 TRACE("(%p/%p, %p, %p/%lu)\n", s
, s
->transport
, buff
, buff_len
, *buff_len
);
714 if (s
->mode
!= schan_mode_WRITE
&& s
->mode
!= schan_mode_HANDSHAKE
)
716 WARN("called in mode %u\n", s
->mode
);
720 status
= callbacks
->push(s
->transport
, buff
, buff_len
);
723 TRACE("Pushed %lu bytes\n", *buff_len
);
726 else if (status
== -1)
728 TRACE("Would block before being able to push anything\n");
729 ret
= errSSLWouldBlock
;
733 FIXME("Unknown status code from schan_push: %d\n", status
);
740 static const struct {
742 SSLProtocol mac_version
;
743 } protocol_priority_flags
[] = {
744 {SP_PROT_TLS1_2_CLIENT
, kTLSProtocol12
},
745 {SP_PROT_TLS1_1_CLIENT
, kTLSProtocol11
},
746 {SP_PROT_TLS1_0_CLIENT
, kTLSProtocol1
},
747 {SP_PROT_SSL3_CLIENT
, kSSLProtocol3
},
748 {SP_PROT_SSL2_CLIENT
, kSSLProtocol2
}
751 static DWORD supported_protocols
;
753 static DWORD CDECL
schan_get_enabled_protocols(void)
755 return supported_protocols
;
758 static BOOL CDECL
schan_create_session(schan_session
*session
, schan_credentials
*cred
)
760 struct mac_session
*s
;
764 TRACE("(%p)\n", session
);
766 if (!(s
= RtlAllocateHeap(GetProcessHeap(), 0, sizeof(*s
)))) return FALSE
;
768 pthread_mutex_init(&s
->mutex
, NULL
);
770 status
= SSLNewContext(cred
->credential_use
== SECPKG_CRED_INBOUND
, &s
->context
);
773 ERR("Failed to create session context: %d\n", status
);
777 status
= SSLSetConnection(s
->context
, s
);
780 ERR("Failed to set session connection: %d\n", status
);
784 status
= SSLSetEnableCertVerify(s
->context
, FALSE
);
787 ERR("Failed to disable certificate verification: %d\n", status
);
791 for(i
= 0; i
< ARRAY_SIZE(protocol_priority_flags
); i
++) {
792 if(!(protocol_priority_flags
[i
].enable_flag
& supported_protocols
))
795 status
= SSLSetProtocolVersionEnabled(s
->context
, protocol_priority_flags
[i
].mac_version
,
796 (cred
->enabled_protocols
& protocol_priority_flags
[i
].enable_flag
) != 0);
799 ERR("Failed to set SSL version %d: %d\n", protocol_priority_flags
[i
].mac_version
, status
);
804 status
= SSLSetIOFuncs(s
->context
, pull_adapter
, push_adapter
);
807 ERR("Failed to set session I/O funcs: %d\n", status
);
811 s
->mode
= schan_mode_NONE
;
813 TRACE(" -> %p/%p\n", s
, s
->context
);
815 *session
= (schan_session
)s
;
819 RtlFreeHeap(GetProcessHeap(), 0, s
);
823 static void CDECL
schan_dispose_session(schan_session session
)
825 struct mac_session
*s
= (struct mac_session
*)session
;
828 TRACE("(%p/%p)\n", s
, s
->context
);
830 status
= SSLDisposeContext(s
->context
);
832 ERR("Failed to dispose of session context: %d\n", status
);
833 pthread_mutex_destroy(&s
->mutex
);
834 RtlFreeHeap(GetProcessHeap(), 0, s
);
837 static void CDECL
schan_set_session_transport(schan_session session
, struct schan_transport
*t
)
839 struct mac_session
*s
= (struct mac_session
*)session
;
841 TRACE("(%p/%p, %p)\n", s
, s
->context
, t
);
846 static void CDECL
schan_set_session_target(schan_session session
, const char *target
)
848 struct mac_session
*s
= (struct mac_session
*)session
;
850 TRACE("(%p/%p, %s)\n", s
, s
->context
, debugstr_a(target
));
852 SSLSetPeerDomainName( s
->context
, target
, strlen(target
) );
855 static SECURITY_STATUS CDECL
schan_handshake(schan_session session
)
857 struct mac_session
*s
= (struct mac_session
*)session
;
860 TRACE("(%p/%p)\n", s
, s
->context
);
862 s
->mode
= schan_mode_HANDSHAKE
;
863 status
= SSLHandshake(s
->context
);
864 s
->mode
= schan_mode_NONE
;
868 TRACE("Handshake completed\n");
871 else if (status
== errSSLWouldBlock
)
873 TRACE("Continue...\n");
874 return SEC_I_CONTINUE_NEEDED
;
876 else if (errSecErrnoBase
<= status
&& status
<= errSecErrnoLimit
)
878 ERR("Handshake failed: %s\n", strerror(status
));
879 return SEC_E_INTERNAL_ERROR
;
883 ERR("Handshake failed: %d\n", status
);
884 cssmPerror("SSLHandshake", status
);
885 return SEC_E_INTERNAL_ERROR
;
892 static unsigned int CDECL
schan_get_session_cipher_block_size(schan_session session
)
894 struct mac_session
* s
= (struct mac_session
*)session
;
895 SSLCipherSuite cipherSuite
;
896 const struct cipher_suite
* c
;
899 TRACE("(%p/%p)\n", s
, s
->context
);
901 status
= SSLGetNegotiatedCipher(s
->context
, &cipherSuite
);
904 ERR("Failed to get session cipher suite: %d\n", status
);
908 c
= get_cipher_suite(cipherSuite
);
911 ERR("Unknown session cipher suite: %#x\n", (unsigned int)cipherSuite
);
917 case schan_enc_3DES_EDE_CBC
: return 64;
918 case schan_enc_AES_128_CBC
: return 128;
919 case schan_enc_AES_128_GCM
: return 128;
920 case schan_enc_AES_256_CBC
: return 128;
921 case schan_enc_AES_256_GCM
: return 128;
922 case schan_enc_DES_CBC
: return 64;
923 case schan_enc_DES40_CBC
: return 64;
924 case schan_enc_NULL
: return 0;
925 case schan_enc_RC2_CBC_40
: return 64;
926 case schan_enc_RC2_CBC
: return 64;
927 case schan_enc_RC4_128
: return 0;
928 case schan_enc_RC4_40
: return 0;
930 case schan_enc_FORTEZZA_CBC
:
931 case schan_enc_IDEA_CBC
:
932 FIXME("Don't know block size for encryption algorithm %d, returning 0\n", c
->enc_alg
);
936 FIXME("Unknown encryption algorithm %d for cipher suite %#x, returning 0\n", c
->enc_alg
, (unsigned int)c
->suite
);
941 static unsigned int CDECL
schan_get_max_message_size(schan_session session
)
943 FIXME("Returning 1 << 14.\n");
947 static ALG_ID CDECL
schan_get_key_signature_algorithm(schan_session session
)
949 struct mac_session
* s
= (struct mac_session
*)session
;
950 SSLCipherSuite cipherSuite
;
951 const struct cipher_suite
* c
;
954 TRACE("(%p/%p)\n", s
, s
->context
);
956 status
= SSLGetNegotiatedCipher(s
->context
, &cipherSuite
);
959 ERR("Failed to get session cipher suite: %d\n", status
);
963 c
= get_cipher_suite(cipherSuite
);
966 ERR("Unknown session cipher suite: %#x\n", (unsigned int)cipherSuite
);
972 case schan_kx_DH_DSS_EXPORT
:
973 case schan_kx_DH_DSS
:
974 case schan_kx_DHE_DSS_EXPORT
:
975 case schan_kx_DHE_DSS
:
976 return CALG_DSS_SIGN
;
978 case schan_kx_DH_RSA_EXPORT
:
979 case schan_kx_DH_RSA
:
980 case schan_kx_DHE_RSA_EXPORT
:
981 case schan_kx_DHE_RSA
:
982 case schan_kx_ECDH_RSA
:
983 case schan_kx_ECDHE_RSA
:
984 case schan_kx_RSA_EXPORT
:
986 return CALG_RSA_SIGN
;
988 case schan_kx_ECDH_ECDSA
:
989 case schan_kx_ECDHE_ECDSA
:
992 case schan_kx_DH_anon_EXPORT
:
993 case schan_kx_DH_anon
:
994 case schan_kx_DHE_PSK
:
995 case schan_kx_ECDH_anon
:
996 case schan_kx_FORTEZZA_DMS
:
999 case schan_kx_RSA_PSK
:
1000 FIXME("Don't know key signature algorithm for key exchange algorithm %d, returning 0\n", c
->kx_alg
);
1004 FIXME("Unknown key exchange algorithm %d for cipher suite %#x, returning 0\n", c
->kx_alg
, (unsigned int)c
->suite
);
1009 static SECURITY_STATUS CDECL
schan_get_connection_info(schan_session session
, SecPkgContext_ConnectionInfo
*info
)
1011 struct mac_session
* s
= (struct mac_session
*)session
;
1012 SSLCipherSuite cipherSuite
;
1013 const struct cipher_suite
* c
;
1016 TRACE("(%p/%p, %p)\n", s
, s
->context
, info
);
1018 status
= SSLGetNegotiatedCipher(s
->context
, &cipherSuite
);
1019 if (status
!= noErr
)
1021 ERR("Failed to get session cipher suite: %d\n", status
);
1022 return SEC_E_INTERNAL_ERROR
;
1025 c
= get_cipher_suite(cipherSuite
);
1028 ERR("Unknown session cipher suite: %#x\n", (unsigned int)cipherSuite
);
1029 return SEC_E_INTERNAL_ERROR
;
1032 info
->dwProtocol
= get_session_protocol(s
);
1033 info
->aiCipher
= get_cipher_algid(c
);
1034 info
->dwCipherStrength
= get_cipher_key_size(c
);
1035 info
->aiHash
= get_mac_algid(c
);
1036 info
->dwHashStrength
= get_mac_key_size(c
);
1037 info
->aiExch
= get_kx_algid(c
);
1038 /* FIXME: info->dwExchStrength? */
1039 info
->dwExchStrength
= 0;
1044 static SECURITY_STATUS CDECL
schan_get_unique_channel_binding(schan_session session
, SecPkgContext_Bindings
*bindings
)
1046 FIXME("SECPKG_ATTR_UNIQUE_BINDINGS is unsupported on MacOS\n");
1047 return SEC_E_UNSUPPORTED_FUNCTION
;
1050 #ifndef HAVE_SSLCOPYPEERCERTIFICATES
1051 static void cf_release(const void *arg
, void *ctx
)
1057 static SECURITY_STATUS CDECL
schan_get_session_peer_certificate(schan_session session
, struct schan_cert_list
*list
)
1059 struct mac_session
*s
= (struct mac_session
*)session
;
1060 SECURITY_STATUS ret
= SEC_E_OK
;
1061 SecCertificateRef cert
;
1062 CFArrayRef cert_array
;
1069 TRACE("(%p/%p, %p)\n", s
, s
->context
, list
);
1071 #ifdef HAVE_SSLCOPYPEERCERTIFICATES
1072 status
= SSLCopyPeerCertificates(s
->context
, &cert_array
);
1074 status
= SSLGetPeerCertificates(s
->context
, &cert_array
);
1076 if (status
!= noErr
|| !cert_array
)
1078 WARN("SSLCopyPeerCertificates failed: %d\n", status
);
1079 return SEC_E_INTERNAL_ERROR
;
1082 list
->count
= CFArrayGetCount(cert_array
);
1083 size
= list
->count
* sizeof(list
->certs
[0]);
1085 for (i
= 0; i
< list
->count
; i
++)
1087 if (!(cert
= (SecCertificateRef
)CFArrayGetValueAtIndex(cert_array
, i
)) ||
1088 (SecKeychainItemExport(cert
, kSecFormatX509Cert
, 0, NULL
, &data
) != noErr
))
1090 WARN("Couldn't extract certificate data\n");
1091 ret
= SEC_E_INTERNAL_ERROR
;
1094 size
+= CFDataGetLength(data
);
1098 if (!(list
->certs
= RtlAllocateHeap(GetProcessHeap(), 0, size
)))
1100 ret
= SEC_E_INSUFFICIENT_MEMORY
;
1104 ptr
= (BYTE
*)&list
->certs
[list
->count
];
1105 for (i
= 0; i
< list
->count
; i
++)
1107 if (!(cert
= (SecCertificateRef
)CFArrayGetValueAtIndex(cert_array
, i
)) ||
1108 (SecKeychainItemExport(cert
, kSecFormatX509Cert
, 0, NULL
, &data
) != noErr
))
1110 WARN("Couldn't extract certificate data\n");
1111 ret
= SEC_E_INTERNAL_ERROR
;
1114 list
->certs
[i
].cbData
= CFDataGetLength(data
);
1115 list
->certs
[i
].pbData
= ptr
;
1116 memcpy(list
->certs
[i
].pbData
, CFDataGetBytePtr(data
), CFDataGetLength(data
));
1117 ptr
+= CFDataGetLength(data
);
1122 #ifndef HAVE_SSLCOPYPEERCERTIFICATES
1123 /* This is why SSLGetPeerCertificates was deprecated */
1124 CFArrayApplyFunction(cert_array
, CFRangeMake(0, CFArrayGetCount(cert_array
)), cf_release
, NULL
);
1126 CFRelease(cert_array
);
1130 static SECURITY_STATUS CDECL
schan_send(schan_session session
, const void *buffer
, SIZE_T
*length
)
1132 struct mac_session
* s
= (struct mac_session
*)session
;
1135 TRACE("(%p/%p, %p, %p/%lu)\n", s
, s
->context
, buffer
, length
, *length
);
1137 pthread_mutex_lock(&s
->mutex
);
1138 s
->mode
= schan_mode_WRITE
;
1140 status
= SSLWrite(s
->context
, buffer
, *length
, length
);
1142 s
->mode
= schan_mode_NONE
;
1143 pthread_mutex_unlock(&s
->mutex
);
1145 if (status
== noErr
)
1146 TRACE("Wrote %lu bytes\n", *length
);
1147 else if (status
== errSSLWouldBlock
)
1151 TRACE("Would block before being able to write anything\n");
1152 return SEC_I_CONTINUE_NEEDED
;
1155 TRACE("Wrote %lu bytes before would block\n", *length
);
1159 WARN("SSLWrite failed: %d\n", status
);
1160 return SEC_E_INTERNAL_ERROR
;
1166 static SECURITY_STATUS CDECL
schan_recv(schan_session session
, void *buffer
, SIZE_T
*length
)
1168 struct mac_session
* s
= (struct mac_session
*)session
;
1171 TRACE("(%p/%p, %p, %p/%lu)\n", s
, s
->context
, buffer
, length
, *length
);
1173 pthread_mutex_lock(&s
->mutex
);
1174 s
->mode
= schan_mode_READ
;
1176 status
= SSLRead(s
->context
, buffer
, *length
, length
);
1178 s
->mode
= schan_mode_NONE
;
1179 pthread_mutex_unlock(&s
->mutex
);
1181 if (status
== noErr
|| status
== errSSLClosedGraceful
)
1182 TRACE("Read %lu bytes\n", *length
);
1183 else if (status
== errSSLWouldBlock
)
1187 TRACE("Would block before being able to read anything\n");
1188 return SEC_I_CONTINUE_NEEDED
;
1191 TRACE("Read %lu bytes before would block\n", *length
);
1195 WARN("SSLRead failed: %d\n", status
);
1196 return SEC_E_INTERNAL_ERROR
;
1202 static BOOL CDECL
schan_allocate_certificate_credentials(schan_credentials
*c
, const CERT_CONTEXT
*cert
,
1203 const DATA_BLOB
*key_blob
)
1205 if (cert
) FIXME("no support for certificate credentials on this platform\n");
1206 c
->credentials
= NULL
;
1210 static void CDECL
schan_free_certificate_credentials(schan_credentials
*c
)
1214 static void CDECL
schan_set_application_protocols(schan_session session
, unsigned char *buffer
, unsigned int buflen
)
1216 FIXME("no support for application protocols on this platform\n");
1219 static SECURITY_STATUS CDECL
schan_get_application_protocol(schan_session session
,
1220 SecPkgContext_ApplicationProtocol
*protocol
)
1222 FIXME("no support for application protocols on this platform\n");
1223 return SEC_E_UNSUPPORTED_FUNCTION
;
1226 static SECURITY_STATUS CDECL
schan_set_dtls_mtu(schan_session session
, unsigned int mtu
)
1228 FIXME("no support for setting dtls mtu on this platform\n");
1229 return SEC_E_UNSUPPORTED_FUNCTION
;
1232 static void ssl_init(void)
1236 supported_protocols
= SP_PROT_SSL2_CLIENT
| SP_PROT_SSL3_CLIENT
| SP_PROT_TLS1_0_CLIENT
;
1238 #if MAC_OS_X_VERSION_MAX_ALLOWED >= 1080
1239 if(&SSLGetProtocolVersionMax
!= NULL
) {
1240 SSLProtocol max_protocol
;
1244 status
= SSLNewContext(FALSE
, &ctx
);
1245 if(status
== noErr
) {
1246 status
= SSLGetProtocolVersionMax(ctx
, &max_protocol
);
1247 if(status
== noErr
) {
1248 if(max_protocol
>= kTLSProtocol11
)
1249 supported_protocols
|= SP_PROT_TLS1_1_CLIENT
;
1250 if(max_protocol
>= kTLSProtocol12
)
1251 supported_protocols
|= SP_PROT_TLS1_2_CLIENT
;
1253 SSLDisposeContext(ctx
);
1255 WARN("SSLNewContext failed\n");
1261 static const struct schan_funcs funcs
=
1263 schan_allocate_certificate_credentials
,
1264 schan_create_session
,
1265 schan_dispose_session
,
1266 schan_free_certificate_credentials
,
1267 schan_get_application_protocol
,
1268 schan_get_connection_info
,
1269 schan_get_enabled_protocols
,
1270 schan_get_key_signature_algorithm
,
1271 schan_get_max_message_size
,
1272 schan_get_session_cipher_block_size
,
1273 schan_get_session_peer_certificate
,
1274 schan_get_unique_channel_binding
,
1278 schan_set_application_protocols
,
1280 schan_set_session_target
,
1281 schan_set_session_transport
,
1284 NTSTATUS CDECL
__wine_init_unix_lib( HMODULE module
, DWORD reason
, const void *ptr_in
, void *ptr_out
)
1286 if (reason
!= DLL_PROCESS_ATTACH
) return STATUS_SUCCESS
;
1289 *(const struct schan_funcs
**)ptr_out
= &funcs
;
1290 return STATUS_SUCCESS
;
1293 #endif /* HAVE_SECURITY_SECURITY_H && !SONAME_LIBGNUTLS */