1 /***************************************************************************
2 * _ _ ____ _
3 * Project ___| | | | _ \| |
4 * / __| | | | |_) | |
5 * | (__| |_| | _ <| |___
6 * \___|\___/|_| \_\_____|
7 *
8 * Copyright (C) 2012 - 2021, Daniel Stenberg, <daniel@haxx.se>, et al.
9 * Copyright (C) 2012 - 2017, Nick Zitzmann, <nickzman@gmail.com>.
10 *
11 * This software is licensed as described in the file COPYING, which
12 * you should have received as part of this distribution. The terms
13 * are also available at https://curl.se/docs/copyright.html.
14 *
15 * You may opt to use, copy, modify, merge, publish, distribute and/or sell
16 * copies of the Software, and permit persons to whom the Software is
17 * furnished to do so, under the terms of the COPYING file.
18 *
19 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
20 * KIND, either express or implied.
21 *
22 ***************************************************************************/
23
24 /*
25 * Source file for all iOS and macOS SecureTransport-specific code for the
26 * TLS/SSL layer. No code but vtls.c should ever call or use these functions.
27 */
28
29 #include "curl_setup.h"
30
31 #include "urldata.h" /* for the Curl_easy definition */
32 #include "curl_base64.h"
33 #include "strtok.h"
34 #include "multiif.h"
35 #include "strcase.h"
36
37 #ifdef USE_SECTRANSP
38
39 #ifdef __clang__
40 #pragma clang diagnostic push
41 #pragma clang diagnostic ignored "-Wtautological-pointer-compare"
42 #endif /* __clang__ */
43
44 #include <limits.h>
45
46 #include <Security/Security.h>
47 /* For some reason, when building for iOS, the omnibus header above does
48 * not include SecureTransport.h as of iOS SDK 5.1. */
49 #include <Security/SecureTransport.h>
50 #include <CoreFoundation/CoreFoundation.h>
51 #include <CommonCrypto/CommonDigest.h>
52
53 /* The Security framework has changed greatly between iOS and different macOS
54 versions, and we will try to support as many of them as we can (back to
55 Leopard and iOS 5) by using macros and weak-linking.
56
57 In general, you want to build this using the most recent OS SDK, since some
58 features require curl to be built against the latest SDK. TLS 1.1 and 1.2
59 support, for instance, require the macOS 10.8 SDK or later. TLS 1.3
60 requires the macOS 10.13 or iOS 11 SDK or later. */
61 #if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE))
62
63 #if MAC_OS_X_VERSION_MAX_ALLOWED < 1050
64 #error "The Secure Transport back-end requires Leopard or later."
65 #endif /* MAC_OS_X_VERSION_MAX_ALLOWED < 1050 */
66
67 #define CURL_BUILD_IOS 0
68 #define CURL_BUILD_IOS_7 0
69 #define CURL_BUILD_IOS_9 0
70 #define CURL_BUILD_IOS_11 0
71 #define CURL_BUILD_IOS_13 0
72 #define CURL_BUILD_MAC 1
73 /* This is the maximum API level we are allowed to use when building: */
74 #define CURL_BUILD_MAC_10_5 MAC_OS_X_VERSION_MAX_ALLOWED >= 1050
75 #define CURL_BUILD_MAC_10_6 MAC_OS_X_VERSION_MAX_ALLOWED >= 1060
76 #define CURL_BUILD_MAC_10_7 MAC_OS_X_VERSION_MAX_ALLOWED >= 1070
77 #define CURL_BUILD_MAC_10_8 MAC_OS_X_VERSION_MAX_ALLOWED >= 1080
78 #define CURL_BUILD_MAC_10_9 MAC_OS_X_VERSION_MAX_ALLOWED >= 1090
79 #define CURL_BUILD_MAC_10_11 MAC_OS_X_VERSION_MAX_ALLOWED >= 101100
80 #define CURL_BUILD_MAC_10_13 MAC_OS_X_VERSION_MAX_ALLOWED >= 101300
81 #define CURL_BUILD_MAC_10_15 MAC_OS_X_VERSION_MAX_ALLOWED >= 101500
82 /* These macros mean "the following code is present to allow runtime backward
83 compatibility with at least this cat or earlier":
84 (You set this at build-time using the compiler command line option
85 "-mmacosx-version-min.") */
86 #define CURL_SUPPORT_MAC_10_5 MAC_OS_X_VERSION_MIN_REQUIRED <= 1050
87 #define CURL_SUPPORT_MAC_10_6 MAC_OS_X_VERSION_MIN_REQUIRED <= 1060
88 #define CURL_SUPPORT_MAC_10_7 MAC_OS_X_VERSION_MIN_REQUIRED <= 1070
89 #define CURL_SUPPORT_MAC_10_8 MAC_OS_X_VERSION_MIN_REQUIRED <= 1080
90 #define CURL_SUPPORT_MAC_10_9 MAC_OS_X_VERSION_MIN_REQUIRED <= 1090
91
92 #elif TARGET_OS_EMBEDDED || TARGET_OS_IPHONE
93 #define CURL_BUILD_IOS 1
94 #define CURL_BUILD_IOS_7 __IPHONE_OS_VERSION_MAX_ALLOWED >= 70000
95 #define CURL_BUILD_IOS_9 __IPHONE_OS_VERSION_MAX_ALLOWED >= 90000
96 #define CURL_BUILD_IOS_11 __IPHONE_OS_VERSION_MAX_ALLOWED >= 110000
97 #define CURL_BUILD_IOS_13 __IPHONE_OS_VERSION_MAX_ALLOWED >= 130000
98 #define CURL_BUILD_MAC 0
99 #define CURL_BUILD_MAC_10_5 0
100 #define CURL_BUILD_MAC_10_6 0
101 #define CURL_BUILD_MAC_10_7 0
102 #define CURL_BUILD_MAC_10_8 0
103 #define CURL_BUILD_MAC_10_9 0
104 #define CURL_BUILD_MAC_10_11 0
105 #define CURL_BUILD_MAC_10_13 0
106 #define CURL_BUILD_MAC_10_15 0
107 #define CURL_SUPPORT_MAC_10_5 0
108 #define CURL_SUPPORT_MAC_10_6 0
109 #define CURL_SUPPORT_MAC_10_7 0
110 #define CURL_SUPPORT_MAC_10_8 0
111 #define CURL_SUPPORT_MAC_10_9 0
112
113 #else
114 #error "The Secure Transport back-end requires iOS or macOS."
115 #endif /* (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE)) */
116
117 #if CURL_BUILD_MAC
118 #include <sys/sysctl.h>
119 #endif /* CURL_BUILD_MAC */
120
121 #include "urldata.h"
122 #include "sendf.h"
123 #include "inet_pton.h"
124 #include "connect.h"
125 #include "select.h"
126 #include "vtls.h"
127 #include "sectransp.h"
128 #include "curl_printf.h"
129 #include "strdup.h"
130
131 #include "curl_memory.h"
132 /* The last #include file should be: */
133 #include "memdebug.h"
134
135 /* From MacTypes.h (which we can't include because it isn't present in iOS: */
136 #define ioErr -36
137 #define paramErr -50
138
139 struct ssl_backend_data {
140 SSLContextRef ssl_ctx;
141 curl_socket_t ssl_sockfd;
142 bool ssl_direction; /* true if writing, false if reading */
143 size_t ssl_write_buffered_length;
144 };
145
146 struct st_cipher {
147 const char *name; /* Cipher suite IANA name. It starts with "TLS_" prefix */
148 const char *alias_name; /* Alias name is the same as OpenSSL cipher name */
149 SSLCipherSuite num; /* Cipher suite code/number defined in IANA registry */
150 bool weak; /* Flag to mark cipher as weak based on previous implementation
151 of Secure Transport back-end by CURL */
152 };
153
154 /* Macro to initialize st_cipher data structure: stringify id to name, cipher
155 number/id, 'weak' suite flag
156 */
157 #define CIPHER_DEF(num, alias, weak) \
158 { #num, alias, num, weak }
159
160 /*
161 Macro to initialize st_cipher data structure with name, code (IANA cipher
162 number/id value), and 'weak' suite flag. The first 28 cipher suite numbers
163 have the same IANA code for both SSL and TLS standards: numbers 0x0000 to
164 0x001B. They have different names though. The first 4 letters of the cipher
165 suite name are the protocol name: "SSL_" or "TLS_", rest of the IANA name is
166 the same for both SSL and TLS cipher suite name.
167 The second part of the problem is that macOS/iOS SDKs don't define all TLS
168 codes but only 12 of them. The SDK defines all SSL codes though, i.e. SSL_NUM
169 constant is always defined for those 28 ciphers while TLS_NUM is defined only
170 for 12 of the first 28 ciphers. Those 12 TLS cipher codes match to
171 corresponding SSL enum value and represent the same cipher suite. Therefore
172 we'll use the SSL enum value for those cipher suites because it is defined
173 for all 28 of them.
174 We make internal data consistent and based on TLS names, i.e. all st_cipher
175 item names start with the "TLS_" prefix.
176 Summarizing all the above, those 28 first ciphers are presented in our table
177 with both TLS and SSL names. Their cipher numbers are assigned based on the
178 SDK enum value for the SSL cipher, which matches to IANA TLS number.
179 */
180 #define CIPHER_DEF_SSLTLS(num_wo_prefix, alias, weak) \
181 { "TLS_" #num_wo_prefix, alias, SSL_##num_wo_prefix, weak }
182
183 /*
184 Cipher suites were marked as weak based on the following:
185 RC4 encryption - rfc7465, the document contains a list of deprecated ciphers.
186 Marked in the code below as weak.
187 RC2 encryption - many mentions, was found vulnerable to a relatively easy
188 attack https://link.springer.com/chapter/10.1007%2F3-540-69710-1_14
189 Marked in the code below as weak.
190 DES and IDEA encryption - rfc5469, has a list of deprecated ciphers.
191 Marked in the code below as weak.
192 Anonymous Diffie-Hellman authentication and anonymous elliptic curve
193 Diffie-Hellman - vulnerable to a man-in-the-middle attack. Deprecated by
194 RFC 4346 aka TLS 1.1 (section A.5, page 60)
195 Null bulk encryption suites - not encrypted communication
196 Export ciphers, i.e. ciphers with restrictions to be used outside the US for
197 software exported to some countries, they were excluded from TLS 1.1
198 version. More precisely, they were noted as ciphers which MUST NOT be
199 negotiated in RFC 4346 aka TLS 1.1 (section A.5, pages 60 and 61).
200 All of those filters were considered weak because they contain a weak
201 algorithm like DES, RC2 or RC4, and already considered weak by other
202 criteria.
203 3DES - NIST deprecated it and is going to retire it by 2023
204 https://csrc.nist.gov/News/2017/Update-to-Current-Use-and-Deprecation-of-TDEA
205 OpenSSL https://www.openssl.org/blog/blog/2016/08/24/sweet32/ also
206 deprecated those ciphers. Some other libraries also consider it
207 vulnerable or at least not strong enough.
208
209 CBC ciphers are vulnerable with SSL3.0 and TLS1.0:
210 https://www.cisco.com/c/en/us/support/docs/security/email-security-appliance
211 /118518-technote-esa-00.html
212 We don't take care of this issue because it is resolved by later TLS
213 versions and for us, it requires more complicated checks, we need to
214 check a protocol version also. Vulnerability doesn't look very critical
215 and we do not filter out those cipher suites.
216 */
217
218 #define CIPHER_WEAK_NOT_ENCRYPTED TRUE
219 #define CIPHER_WEAK_RC_ENCRYPTION TRUE
220 #define CIPHER_WEAK_DES_ENCRYPTION TRUE
221 #define CIPHER_WEAK_IDEA_ENCRYPTION TRUE
222 #define CIPHER_WEAK_ANON_AUTH TRUE
223 #define CIPHER_WEAK_3DES_ENCRYPTION TRUE
224 #define CIPHER_STRONG_ENOUGH FALSE
225
226 /* Please do not change the order of the first ciphers available for SSL.
227 Do not insert and do not delete any of them. Code below
228 depends on their order and continuity.
229 If you add a new cipher, please maintain order by number, i.e.
230 insert in between existing items to appropriate place based on
231 cipher suite IANA number
232 */
233 const static struct st_cipher ciphertable[] = {
234 /* SSL version 3.0 and initial TLS 1.0 cipher suites.
235 Defined since SDK 10.2.8 */
236 CIPHER_DEF_SSLTLS(NULL_WITH_NULL_NULL, /* 0x0000 */
237 NULL,
238 CIPHER_WEAK_NOT_ENCRYPTED),
239 CIPHER_DEF_SSLTLS(RSA_WITH_NULL_MD5, /* 0x0001 */
240 "NULL-MD5",
241 CIPHER_WEAK_NOT_ENCRYPTED),
242 CIPHER_DEF_SSLTLS(RSA_WITH_NULL_SHA, /* 0x0002 */
243 "NULL-SHA",
244 CIPHER_WEAK_NOT_ENCRYPTED),
245 CIPHER_DEF_SSLTLS(RSA_EXPORT_WITH_RC4_40_MD5, /* 0x0003 */
246 "EXP-RC4-MD5",
247 CIPHER_WEAK_RC_ENCRYPTION),
248 CIPHER_DEF_SSLTLS(RSA_WITH_RC4_128_MD5, /* 0x0004 */
249 "RC4-MD5",
250 CIPHER_WEAK_RC_ENCRYPTION),
251 CIPHER_DEF_SSLTLS(RSA_WITH_RC4_128_SHA, /* 0x0005 */
252 "RC4-SHA",
253 CIPHER_WEAK_RC_ENCRYPTION),
254 CIPHER_DEF_SSLTLS(RSA_EXPORT_WITH_RC2_CBC_40_MD5, /* 0x0006 */
255 "EXP-RC2-CBC-MD5",
256 CIPHER_WEAK_RC_ENCRYPTION),
257 CIPHER_DEF_SSLTLS(RSA_WITH_IDEA_CBC_SHA, /* 0x0007 */
258 "IDEA-CBC-SHA",
259 CIPHER_WEAK_IDEA_ENCRYPTION),
260 CIPHER_DEF_SSLTLS(RSA_EXPORT_WITH_DES40_CBC_SHA, /* 0x0008 */
261 "EXP-DES-CBC-SHA",
262 CIPHER_WEAK_DES_ENCRYPTION),
263 CIPHER_DEF_SSLTLS(RSA_WITH_DES_CBC_SHA, /* 0x0009 */
264 "DES-CBC-SHA",
265 CIPHER_WEAK_DES_ENCRYPTION),
266 CIPHER_DEF_SSLTLS(RSA_WITH_3DES_EDE_CBC_SHA, /* 0x000A */
267 "DES-CBC3-SHA",
268 CIPHER_WEAK_3DES_ENCRYPTION),
269 CIPHER_DEF_SSLTLS(DH_DSS_EXPORT_WITH_DES40_CBC_SHA, /* 0x000B */
270 "EXP-DH-DSS-DES-CBC-SHA",
271 CIPHER_WEAK_DES_ENCRYPTION),
272 CIPHER_DEF_SSLTLS(DH_DSS_WITH_DES_CBC_SHA, /* 0x000C */
273 "DH-DSS-DES-CBC-SHA",
274 CIPHER_WEAK_DES_ENCRYPTION),
275 CIPHER_DEF_SSLTLS(DH_DSS_WITH_3DES_EDE_CBC_SHA, /* 0x000D */
276 "DH-DSS-DES-CBC3-SHA",
277 CIPHER_WEAK_3DES_ENCRYPTION),
278 CIPHER_DEF_SSLTLS(DH_RSA_EXPORT_WITH_DES40_CBC_SHA, /* 0x000E */
279 "EXP-DH-RSA-DES-CBC-SHA",
280 CIPHER_WEAK_DES_ENCRYPTION),
281 CIPHER_DEF_SSLTLS(DH_RSA_WITH_DES_CBC_SHA, /* 0x000F */
282 "DH-RSA-DES-CBC-SHA",
283 CIPHER_WEAK_DES_ENCRYPTION),
284 CIPHER_DEF_SSLTLS(DH_RSA_WITH_3DES_EDE_CBC_SHA, /* 0x0010 */
285 "DH-RSA-DES-CBC3-SHA",
286 CIPHER_WEAK_3DES_ENCRYPTION),
287 CIPHER_DEF_SSLTLS(DHE_DSS_EXPORT_WITH_DES40_CBC_SHA, /* 0x0011 */
288 "EXP-EDH-DSS-DES-CBC-SHA",
289 CIPHER_WEAK_DES_ENCRYPTION),
290 CIPHER_DEF_SSLTLS(DHE_DSS_WITH_DES_CBC_SHA, /* 0x0012 */
291 "EDH-DSS-CBC-SHA",
292 CIPHER_WEAK_DES_ENCRYPTION),
293 CIPHER_DEF_SSLTLS(DHE_DSS_WITH_3DES_EDE_CBC_SHA, /* 0x0013 */
294 "DHE-DSS-DES-CBC3-SHA",
295 CIPHER_WEAK_3DES_ENCRYPTION),
296 CIPHER_DEF_SSLTLS(DHE_RSA_EXPORT_WITH_DES40_CBC_SHA, /* 0x0014 */
297 "EXP-EDH-RSA-DES-CBC-SHA",
298 CIPHER_WEAK_DES_ENCRYPTION),
299 CIPHER_DEF_SSLTLS(DHE_RSA_WITH_DES_CBC_SHA, /* 0x0015 */
300 "EDH-RSA-DES-CBC-SHA",
301 CIPHER_WEAK_DES_ENCRYPTION),
302 CIPHER_DEF_SSLTLS(DHE_RSA_WITH_3DES_EDE_CBC_SHA, /* 0x0016 */
303 "DHE-RSA-DES-CBC3-SHA",
304 CIPHER_WEAK_3DES_ENCRYPTION),
305 CIPHER_DEF_SSLTLS(DH_anon_EXPORT_WITH_RC4_40_MD5, /* 0x0017 */
306 "EXP-ADH-RC4-MD5",
307 CIPHER_WEAK_ANON_AUTH),
308 CIPHER_DEF_SSLTLS(DH_anon_WITH_RC4_128_MD5, /* 0x0018 */
309 "ADH-RC4-MD5",
310 CIPHER_WEAK_ANON_AUTH),
311 CIPHER_DEF_SSLTLS(DH_anon_EXPORT_WITH_DES40_CBC_SHA, /* 0x0019 */
312 "EXP-ADH-DES-CBC-SHA",
313 CIPHER_WEAK_ANON_AUTH),
314 CIPHER_DEF_SSLTLS(DH_anon_WITH_DES_CBC_SHA, /* 0x001A */
315 "ADH-DES-CBC-SHA",
316 CIPHER_WEAK_ANON_AUTH),
317 CIPHER_DEF_SSLTLS(DH_anon_WITH_3DES_EDE_CBC_SHA, /* 0x001B */
318 "ADH-DES-CBC3-SHA",
319 CIPHER_WEAK_3DES_ENCRYPTION),
320 CIPHER_DEF(SSL_FORTEZZA_DMS_WITH_NULL_SHA, /* 0x001C */
321 NULL,
322 CIPHER_WEAK_NOT_ENCRYPTED),
323 CIPHER_DEF(SSL_FORTEZZA_DMS_WITH_FORTEZZA_CBC_SHA, /* 0x001D */
324 NULL,
325 CIPHER_STRONG_ENOUGH),
326
327 #if CURL_BUILD_MAC_10_9 || CURL_BUILD_IOS_7
328 /* RFC 4785 - Pre-Shared Key (PSK) Ciphersuites with NULL Encryption */
329 CIPHER_DEF(TLS_PSK_WITH_NULL_SHA, /* 0x002C */
330 "PSK-NULL-SHA",
331 CIPHER_WEAK_NOT_ENCRYPTED),
332 CIPHER_DEF(TLS_DHE_PSK_WITH_NULL_SHA, /* 0x002D */
333 "DHE-PSK-NULL-SHA",
334 CIPHER_WEAK_NOT_ENCRYPTED),
335 CIPHER_DEF(TLS_RSA_PSK_WITH_NULL_SHA, /* 0x002E */
336 "RSA-PSK-NULL-SHA",
337 CIPHER_WEAK_NOT_ENCRYPTED),
338 #endif /* CURL_BUILD_MAC_10_9 || CURL_BUILD_IOS_7 */
339
340 /* TLS addenda using AES, per RFC 3268. Defined since SDK 10.4u */
341 CIPHER_DEF(TLS_RSA_WITH_AES_128_CBC_SHA, /* 0x002F */
342 "AES128-SHA",
343 CIPHER_STRONG_ENOUGH),
344 CIPHER_DEF(TLS_DH_DSS_WITH_AES_128_CBC_SHA, /* 0x0030 */
345 "DH-DSS-AES128-SHA",
346 CIPHER_STRONG_ENOUGH),
347 CIPHER_DEF(TLS_DH_RSA_WITH_AES_128_CBC_SHA, /* 0x0031 */
348 "DH-RSA-AES128-SHA",
349 CIPHER_STRONG_ENOUGH),
350 CIPHER_DEF(TLS_DHE_DSS_WITH_AES_128_CBC_SHA, /* 0x0032 */
351 "DHE-DSS-AES128-SHA",
352 CIPHER_STRONG_ENOUGH),
353 CIPHER_DEF(TLS_DHE_RSA_WITH_AES_128_CBC_SHA, /* 0x0033 */
354 "DHE-RSA-AES128-SHA",
355 CIPHER_STRONG_ENOUGH),
356 CIPHER_DEF(TLS_DH_anon_WITH_AES_128_CBC_SHA, /* 0x0034 */
357 "ADH-AES128-SHA",
358 CIPHER_WEAK_ANON_AUTH),
359 CIPHER_DEF(TLS_RSA_WITH_AES_256_CBC_SHA, /* 0x0035 */
360 "AES256-SHA",
361 CIPHER_STRONG_ENOUGH),
362 CIPHER_DEF(TLS_DH_DSS_WITH_AES_256_CBC_SHA, /* 0x0036 */
363 "DH-DSS-AES256-SHA",
364 CIPHER_STRONG_ENOUGH),
365 CIPHER_DEF(TLS_DH_RSA_WITH_AES_256_CBC_SHA, /* 0x0037 */
366 "DH-RSA-AES256-SHA",
367 CIPHER_STRONG_ENOUGH),
368 CIPHER_DEF(TLS_DHE_DSS_WITH_AES_256_CBC_SHA, /* 0x0038 */
369 "DHE-DSS-AES256-SHA",
370 CIPHER_STRONG_ENOUGH),
371 CIPHER_DEF(TLS_DHE_RSA_WITH_AES_256_CBC_SHA, /* 0x0039 */
372 "DHE-RSA-AES256-SHA",
373 CIPHER_STRONG_ENOUGH),
374 CIPHER_DEF(TLS_DH_anon_WITH_AES_256_CBC_SHA, /* 0x003A */
375 "ADH-AES256-SHA",
376 CIPHER_WEAK_ANON_AUTH),
377
378 #if CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS
379 /* TLS 1.2 addenda, RFC 5246 */
380 /* Server provided RSA certificate for key exchange. */
381 CIPHER_DEF(TLS_RSA_WITH_NULL_SHA256, /* 0x003B */
382 "NULL-SHA256",
383 CIPHER_WEAK_NOT_ENCRYPTED),
384 CIPHER_DEF(TLS_RSA_WITH_AES_128_CBC_SHA256, /* 0x003C */
385 "AES128-SHA256",
386 CIPHER_STRONG_ENOUGH),
387 CIPHER_DEF(TLS_RSA_WITH_AES_256_CBC_SHA256, /* 0x003D */
388 "AES256-SHA256",
389 CIPHER_STRONG_ENOUGH),
390 /* Server-authenticated (and optionally client-authenticated)
391 Diffie-Hellman. */
392 CIPHER_DEF(TLS_DH_DSS_WITH_AES_128_CBC_SHA256, /* 0x003E */
393 "DH-DSS-AES128-SHA256",
394 CIPHER_STRONG_ENOUGH),
395 CIPHER_DEF(TLS_DH_RSA_WITH_AES_128_CBC_SHA256, /* 0x003F */
396 "DH-RSA-AES128-SHA256",
397 CIPHER_STRONG_ENOUGH),
398 CIPHER_DEF(TLS_DHE_DSS_WITH_AES_128_CBC_SHA256, /* 0x0040 */
399 "DHE-DSS-AES128-SHA256",
400 CIPHER_STRONG_ENOUGH),
401
402 /* TLS 1.2 addenda, RFC 5246 */
403 CIPHER_DEF(TLS_DHE_RSA_WITH_AES_128_CBC_SHA256, /* 0x0067 */
404 "DHE-RSA-AES128-SHA256",
405 CIPHER_STRONG_ENOUGH),
406 CIPHER_DEF(TLS_DH_DSS_WITH_AES_256_CBC_SHA256, /* 0x0068 */
407 "DH-DSS-AES256-SHA256",
408 CIPHER_STRONG_ENOUGH),
409 CIPHER_DEF(TLS_DH_RSA_WITH_AES_256_CBC_SHA256, /* 0x0069 */
410 "DH-RSA-AES256-SHA256",
411 CIPHER_STRONG_ENOUGH),
412 CIPHER_DEF(TLS_DHE_DSS_WITH_AES_256_CBC_SHA256, /* 0x006A */
413 "DHE-DSS-AES256-SHA256",
414 CIPHER_STRONG_ENOUGH),
415 CIPHER_DEF(TLS_DHE_RSA_WITH_AES_256_CBC_SHA256, /* 0x006B */
416 "DHE-RSA-AES256-SHA256",
417 CIPHER_STRONG_ENOUGH),
418 CIPHER_DEF(TLS_DH_anon_WITH_AES_128_CBC_SHA256, /* 0x006C */
419 "ADH-AES128-SHA256",
420 CIPHER_WEAK_ANON_AUTH),
421 CIPHER_DEF(TLS_DH_anon_WITH_AES_256_CBC_SHA256, /* 0x006D */
422 "ADH-AES256-SHA256",
423 CIPHER_WEAK_ANON_AUTH),
424 #endif /* CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS */
425
426 #if CURL_BUILD_MAC_10_9 || CURL_BUILD_IOS_7
427 /* Addendum from RFC 4279, TLS PSK */
428 CIPHER_DEF(TLS_PSK_WITH_RC4_128_SHA, /* 0x008A */
429 "PSK-RC4-SHA",
430 CIPHER_WEAK_RC_ENCRYPTION),
431 CIPHER_DEF(TLS_PSK_WITH_3DES_EDE_CBC_SHA, /* 0x008B */
432 "PSK-3DES-EDE-CBC-SHA",
433 CIPHER_WEAK_3DES_ENCRYPTION),
434 CIPHER_DEF(TLS_PSK_WITH_AES_128_CBC_SHA, /* 0x008C */
435 "PSK-AES128-CBC-SHA",
436 CIPHER_STRONG_ENOUGH),
437 CIPHER_DEF(TLS_PSK_WITH_AES_256_CBC_SHA, /* 0x008D */
438 "PSK-AES256-CBC-SHA",
439 CIPHER_STRONG_ENOUGH),
440 CIPHER_DEF(TLS_DHE_PSK_WITH_RC4_128_SHA, /* 0x008E */
441 "DHE-PSK-RC4-SHA",
442 CIPHER_WEAK_RC_ENCRYPTION),
443 CIPHER_DEF(TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA, /* 0x008F */
444 "DHE-PSK-3DES-EDE-CBC-SHA",
445 CIPHER_WEAK_3DES_ENCRYPTION),
446 CIPHER_DEF(TLS_DHE_PSK_WITH_AES_128_CBC_SHA, /* 0x0090 */
447 "DHE-PSK-AES128-CBC-SHA",
448 CIPHER_STRONG_ENOUGH),
449 CIPHER_DEF(TLS_DHE_PSK_WITH_AES_256_CBC_SHA, /* 0x0091 */
450 "DHE-PSK-AES256-CBC-SHA",
451 CIPHER_STRONG_ENOUGH),
452 CIPHER_DEF(TLS_RSA_PSK_WITH_RC4_128_SHA, /* 0x0092 */
453 "RSA-PSK-RC4-SHA",
454 CIPHER_WEAK_RC_ENCRYPTION),
455 CIPHER_DEF(TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA, /* 0x0093 */
456 "RSA-PSK-3DES-EDE-CBC-SHA",
457 CIPHER_WEAK_3DES_ENCRYPTION),
458 CIPHER_DEF(TLS_RSA_PSK_WITH_AES_128_CBC_SHA, /* 0x0094 */
459 "RSA-PSK-AES128-CBC-SHA",
460 CIPHER_STRONG_ENOUGH),
461 CIPHER_DEF(TLS_RSA_PSK_WITH_AES_256_CBC_SHA, /* 0x0095 */
462 "RSA-PSK-AES256-CBC-SHA",
463 CIPHER_STRONG_ENOUGH),
464 #endif /* CURL_BUILD_MAC_10_9 || CURL_BUILD_IOS_7 */
465
466 #if CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS
467 /* Addenda from rfc 5288 AES Galois Counter Mode (GCM) Cipher Suites
468 for TLS. */
469 CIPHER_DEF(TLS_RSA_WITH_AES_128_GCM_SHA256, /* 0x009C */
470 "AES128-GCM-SHA256",
471 CIPHER_STRONG_ENOUGH),
472 CIPHER_DEF(TLS_RSA_WITH_AES_256_GCM_SHA384, /* 0x009D */
473 "AES256-GCM-SHA384",
474 CIPHER_STRONG_ENOUGH),
475 CIPHER_DEF(TLS_DHE_RSA_WITH_AES_128_GCM_SHA256, /* 0x009E */
476 "DHE-RSA-AES128-GCM-SHA256",
477 CIPHER_STRONG_ENOUGH),
478 CIPHER_DEF(TLS_DHE_RSA_WITH_AES_256_GCM_SHA384, /* 0x009F */
479 "DHE-RSA-AES256-GCM-SHA384",
480 CIPHER_STRONG_ENOUGH),
481 CIPHER_DEF(TLS_DH_RSA_WITH_AES_128_GCM_SHA256, /* 0x00A0 */
482 "DH-RSA-AES128-GCM-SHA256",
483 CIPHER_STRONG_ENOUGH),
484 CIPHER_DEF(TLS_DH_RSA_WITH_AES_256_GCM_SHA384, /* 0x00A1 */
485 "DH-RSA-AES256-GCM-SHA384",
486 CIPHER_STRONG_ENOUGH),
487 CIPHER_DEF(TLS_DHE_DSS_WITH_AES_128_GCM_SHA256, /* 0x00A2 */
488 "DHE-DSS-AES128-GCM-SHA256",
489 CIPHER_STRONG_ENOUGH),
490 CIPHER_DEF(TLS_DHE_DSS_WITH_AES_256_GCM_SHA384, /* 0x00A3 */
491 "DHE-DSS-AES256-GCM-SHA384",
492 CIPHER_STRONG_ENOUGH),
493 CIPHER_DEF(TLS_DH_DSS_WITH_AES_128_GCM_SHA256, /* 0x00A4 */
494 "DH-DSS-AES128-GCM-SHA256",
495 CIPHER_STRONG_ENOUGH),
496 CIPHER_DEF(TLS_DH_DSS_WITH_AES_256_GCM_SHA384, /* 0x00A5 */
497 "DH-DSS-AES256-GCM-SHA384",
498 CIPHER_STRONG_ENOUGH),
499 CIPHER_DEF(TLS_DH_anon_WITH_AES_128_GCM_SHA256, /* 0x00A6 */
500 "ADH-AES128-GCM-SHA256",
501 CIPHER_WEAK_ANON_AUTH),
502 CIPHER_DEF(TLS_DH_anon_WITH_AES_256_GCM_SHA384, /* 0x00A7 */
503 "ADH-AES256-GCM-SHA384",
504 CIPHER_WEAK_ANON_AUTH),
505 #endif /* CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS */
506
507 #if CURL_BUILD_MAC_10_9 || CURL_BUILD_IOS_7
508 /* RFC 5487 - PSK with SHA-256/384 and AES GCM */
509 CIPHER_DEF(TLS_PSK_WITH_AES_128_GCM_SHA256, /* 0x00A8 */
510 "PSK-AES128-GCM-SHA256",
511 CIPHER_STRONG_ENOUGH),
512 CIPHER_DEF(TLS_PSK_WITH_AES_256_GCM_SHA384, /* 0x00A9 */
513 "PSK-AES256-GCM-SHA384",
514 CIPHER_STRONG_ENOUGH),
515 CIPHER_DEF(TLS_DHE_PSK_WITH_AES_128_GCM_SHA256, /* 0x00AA */
516 "DHE-PSK-AES128-GCM-SHA256",
517 CIPHER_STRONG_ENOUGH),
518 CIPHER_DEF(TLS_DHE_PSK_WITH_AES_256_GCM_SHA384, /* 0x00AB */
519 "DHE-PSK-AES256-GCM-SHA384",
520 CIPHER_STRONG_ENOUGH),
521 CIPHER_DEF(TLS_RSA_PSK_WITH_AES_128_GCM_SHA256, /* 0x00AC */
522 "RSA-PSK-AES128-GCM-SHA256",
523 CIPHER_STRONG_ENOUGH),
524 CIPHER_DEF(TLS_RSA_PSK_WITH_AES_256_GCM_SHA384, /* 0x00AD */
525 "RSA-PSK-AES256-GCM-SHA384",
526 CIPHER_STRONG_ENOUGH),
527 CIPHER_DEF(TLS_PSK_WITH_AES_128_CBC_SHA256, /* 0x00AE */
528 "PSK-AES128-CBC-SHA256",
529 CIPHER_STRONG_ENOUGH),
530 CIPHER_DEF(TLS_PSK_WITH_AES_256_CBC_SHA384, /* 0x00AF */
531 "PSK-AES256-CBC-SHA384",
532 CIPHER_STRONG_ENOUGH),
533 CIPHER_DEF(TLS_PSK_WITH_NULL_SHA256, /* 0x00B0 */
534 "PSK-NULL-SHA256",
535 CIPHER_WEAK_NOT_ENCRYPTED),
536 CIPHER_DEF(TLS_PSK_WITH_NULL_SHA384, /* 0x00B1 */
537 "PSK-NULL-SHA384",
538 CIPHER_WEAK_NOT_ENCRYPTED),
539 CIPHER_DEF(TLS_DHE_PSK_WITH_AES_128_CBC_SHA256, /* 0x00B2 */
540 "DHE-PSK-AES128-CBC-SHA256",
541 CIPHER_STRONG_ENOUGH),
542 CIPHER_DEF(TLS_DHE_PSK_WITH_AES_256_CBC_SHA384, /* 0x00B3 */
543 "DHE-PSK-AES256-CBC-SHA384",
544 CIPHER_STRONG_ENOUGH),
545 CIPHER_DEF(TLS_DHE_PSK_WITH_NULL_SHA256, /* 0x00B4 */
546 "DHE-PSK-NULL-SHA256",
547 CIPHER_WEAK_NOT_ENCRYPTED),
548 CIPHER_DEF(TLS_DHE_PSK_WITH_NULL_SHA384, /* 0x00B5 */
549 "DHE-PSK-NULL-SHA384",
550 CIPHER_WEAK_NOT_ENCRYPTED),
551 CIPHER_DEF(TLS_RSA_PSK_WITH_AES_128_CBC_SHA256, /* 0x00B6 */
552 "RSA-PSK-AES128-CBC-SHA256",
553 CIPHER_STRONG_ENOUGH),
554 CIPHER_DEF(TLS_RSA_PSK_WITH_AES_256_CBC_SHA384, /* 0x00B7 */
555 "RSA-PSK-AES256-CBC-SHA384",
556 CIPHER_STRONG_ENOUGH),
557 CIPHER_DEF(TLS_RSA_PSK_WITH_NULL_SHA256, /* 0x00B8 */
558 "RSA-PSK-NULL-SHA256",
559 CIPHER_WEAK_NOT_ENCRYPTED),
560 CIPHER_DEF(TLS_RSA_PSK_WITH_NULL_SHA384, /* 0x00B9 */
561 "RSA-PSK-NULL-SHA384",
562 CIPHER_WEAK_NOT_ENCRYPTED),
563 #endif /* CURL_BUILD_MAC_10_9 || CURL_BUILD_IOS_7 */
564
565 /* RFC 5746 - Secure Renegotiation. This is not a real suite,
566 it is a response to initiate negotiation again */
567 CIPHER_DEF(TLS_EMPTY_RENEGOTIATION_INFO_SCSV, /* 0x00FF */
568 NULL,
569 CIPHER_STRONG_ENOUGH),
570
571 #if CURL_BUILD_MAC_10_13 || CURL_BUILD_IOS_11
572 /* TLS 1.3 standard cipher suites for ChaCha20+Poly1305.
573 Note: TLS 1.3 ciphersuites do not specify the key exchange
574 algorithm -- they only specify the symmetric ciphers.
575 Cipher alias name matches to OpenSSL cipher name, and for
576 TLS 1.3 ciphers */
577 CIPHER_DEF(TLS_AES_128_GCM_SHA256, /* 0x1301 */
578 NULL, /* The OpenSSL cipher name matches to the IANA name */
579 CIPHER_STRONG_ENOUGH),
580 CIPHER_DEF(TLS_AES_256_GCM_SHA384, /* 0x1302 */
581 NULL, /* The OpenSSL cipher name matches to the IANA name */
582 CIPHER_STRONG_ENOUGH),
583 CIPHER_DEF(TLS_CHACHA20_POLY1305_SHA256, /* 0x1303 */
584 NULL, /* The OpenSSL cipher name matches to the IANA name */
585 CIPHER_STRONG_ENOUGH),
586 CIPHER_DEF(TLS_AES_128_CCM_SHA256, /* 0x1304 */
587 NULL, /* The OpenSSL cipher name matches to the IANA name */
588 CIPHER_STRONG_ENOUGH),
589 CIPHER_DEF(TLS_AES_128_CCM_8_SHA256, /* 0x1305 */
590 NULL, /* The OpenSSL cipher name matches to the IANA name */
591 CIPHER_STRONG_ENOUGH),
592 #endif /* CURL_BUILD_MAC_10_13 || CURL_BUILD_IOS_11 */
593
594 #if CURL_BUILD_MAC_10_6 || CURL_BUILD_IOS
595 /* ECDSA addenda, RFC 4492 */
596 CIPHER_DEF(TLS_ECDH_ECDSA_WITH_NULL_SHA, /* 0xC001 */
597 "ECDH-ECDSA-NULL-SHA",
598 CIPHER_WEAK_NOT_ENCRYPTED),
599 CIPHER_DEF(TLS_ECDH_ECDSA_WITH_RC4_128_SHA, /* 0xC002 */
600 "ECDH-ECDSA-RC4-SHA",
601 CIPHER_WEAK_RC_ENCRYPTION),
602 CIPHER_DEF(TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA, /* 0xC003 */
603 "ECDH-ECDSA-DES-CBC3-SHA",
604 CIPHER_STRONG_ENOUGH),
605 CIPHER_DEF(TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA, /* 0xC004 */
606 "ECDH-ECDSA-AES128-SHA",
607 CIPHER_STRONG_ENOUGH),
608 CIPHER_DEF(TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA, /* 0xC005 */
609 "ECDH-ECDSA-AES256-SHA",
610 CIPHER_STRONG_ENOUGH),
611 CIPHER_DEF(TLS_ECDHE_ECDSA_WITH_NULL_SHA, /* 0xC006 */
612 "ECDHE-ECDSA-NULL-SHA",
613 CIPHER_WEAK_NOT_ENCRYPTED),
614 CIPHER_DEF(TLS_ECDHE_ECDSA_WITH_RC4_128_SHA, /* 0xC007 */
615 "ECDHE-ECDSA-RC4-SHA",
616 CIPHER_WEAK_RC_ENCRYPTION),
617 CIPHER_DEF(TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA, /* 0xC008 */
618 "ECDHE-ECDSA-DES-CBC3-SHA",
619 CIPHER_WEAK_3DES_ENCRYPTION),
620 CIPHER_DEF(TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, /* 0xC009 */
621 "ECDHE-ECDSA-AES128-SHA",
622 CIPHER_STRONG_ENOUGH),
623 CIPHER_DEF(TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, /* 0xC00A */
624 "ECDHE-ECDSA-AES256-SHA",
625 CIPHER_STRONG_ENOUGH),
626 CIPHER_DEF(TLS_ECDH_RSA_WITH_NULL_SHA, /* 0xC00B */
627 "ECDH-RSA-NULL-SHA",
628 CIPHER_WEAK_NOT_ENCRYPTED),
629 CIPHER_DEF(TLS_ECDH_RSA_WITH_RC4_128_SHA, /* 0xC00C */
630 "ECDH-RSA-RC4-SHA",
631 CIPHER_WEAK_RC_ENCRYPTION),
632 CIPHER_DEF(TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA, /* 0xC00D */
633 "ECDH-RSA-DES-CBC3-SHA",
634 CIPHER_WEAK_3DES_ENCRYPTION),
635 CIPHER_DEF(TLS_ECDH_RSA_WITH_AES_128_CBC_SHA, /* 0xC00E */
636 "ECDH-RSA-AES128-SHA",
637 CIPHER_STRONG_ENOUGH),
638 CIPHER_DEF(TLS_ECDH_RSA_WITH_AES_256_CBC_SHA, /* 0xC00F */
639 "ECDH-RSA-AES256-SHA",
640 CIPHER_STRONG_ENOUGH),
641 CIPHER_DEF(TLS_ECDHE_RSA_WITH_NULL_SHA, /* 0xC010 */
642 "ECDHE-RSA-NULL-SHA",
643 CIPHER_WEAK_NOT_ENCRYPTED),
644 CIPHER_DEF(TLS_ECDHE_RSA_WITH_RC4_128_SHA, /* 0xC011 */
645 "ECDHE-RSA-RC4-SHA",
646 CIPHER_WEAK_RC_ENCRYPTION),
647 CIPHER_DEF(TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, /* 0xC012 */
648 "ECDHE-RSA-DES-CBC3-SHA",
649 CIPHER_WEAK_3DES_ENCRYPTION),
650 CIPHER_DEF(TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, /* 0xC013 */
651 "ECDHE-RSA-AES128-SHA",
652 CIPHER_STRONG_ENOUGH),
653 CIPHER_DEF(TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, /* 0xC014 */
654 "ECDHE-RSA-AES256-SHA",
655 CIPHER_STRONG_ENOUGH),
656 CIPHER_DEF(TLS_ECDH_anon_WITH_NULL_SHA, /* 0xC015 */
657 "AECDH-NULL-SHA",
658 CIPHER_WEAK_ANON_AUTH),
659 CIPHER_DEF(TLS_ECDH_anon_WITH_RC4_128_SHA, /* 0xC016 */
660 "AECDH-RC4-SHA",
661 CIPHER_WEAK_ANON_AUTH),
662 CIPHER_DEF(TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA, /* 0xC017 */
663 "AECDH-DES-CBC3-SHA",
664 CIPHER_WEAK_3DES_ENCRYPTION),
665 CIPHER_DEF(TLS_ECDH_anon_WITH_AES_128_CBC_SHA, /* 0xC018 */
666 "AECDH-AES128-SHA",
667 CIPHER_WEAK_ANON_AUTH),
668 CIPHER_DEF(TLS_ECDH_anon_WITH_AES_256_CBC_SHA, /* 0xC019 */
669 "AECDH-AES256-SHA",
670 CIPHER_WEAK_ANON_AUTH),
671 #endif /* CURL_BUILD_MAC_10_6 || CURL_BUILD_IOS */
672
673 #if CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS
674 /* Addenda from rfc 5289 Elliptic Curve Cipher Suites with
675 HMAC SHA-256/384. */
676 CIPHER_DEF(TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, /* 0xC023 */
677 "ECDHE-ECDSA-AES128-SHA256",
678 CIPHER_STRONG_ENOUGH),
679 CIPHER_DEF(TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384, /* 0xC024 */
680 "ECDHE-ECDSA-AES256-SHA384",
681 CIPHER_STRONG_ENOUGH),
682 CIPHER_DEF(TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256, /* 0xC025 */
683 "ECDH-ECDSA-AES128-SHA256",
684 CIPHER_STRONG_ENOUGH),
685 CIPHER_DEF(TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384, /* 0xC026 */
686 "ECDH-ECDSA-AES256-SHA384",
687 CIPHER_STRONG_ENOUGH),
688 CIPHER_DEF(TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, /* 0xC027 */
689 "ECDHE-RSA-AES128-SHA256",
690 CIPHER_STRONG_ENOUGH),
691 CIPHER_DEF(TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384, /* 0xC028 */
692 "ECDHE-RSA-AES256-SHA384",
693 CIPHER_STRONG_ENOUGH),
694 CIPHER_DEF(TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256, /* 0xC029 */
695 "ECDH-RSA-AES128-SHA256",
696 CIPHER_STRONG_ENOUGH),
697 CIPHER_DEF(TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384, /* 0xC02A */
698 "ECDH-RSA-AES256-SHA384",
699 CIPHER_STRONG_ENOUGH),
700 /* Addenda from rfc 5289 Elliptic Curve Cipher Suites with
701 SHA-256/384 and AES Galois Counter Mode (GCM) */
702 CIPHER_DEF(TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, /* 0xC02B */
703 "ECDHE-ECDSA-AES128-GCM-SHA256",
704 CIPHER_STRONG_ENOUGH),
705 CIPHER_DEF(TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, /* 0xC02C */
706 "ECDHE-ECDSA-AES256-GCM-SHA384",
707 CIPHER_STRONG_ENOUGH),
708 CIPHER_DEF(TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256, /* 0xC02D */
709 "ECDH-ECDSA-AES128-GCM-SHA256",
710 CIPHER_STRONG_ENOUGH),
711 CIPHER_DEF(TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384, /* 0xC02E */
712 "ECDH-ECDSA-AES256-GCM-SHA384",
713 CIPHER_STRONG_ENOUGH),
714 CIPHER_DEF(TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, /* 0xC02F */
715 "ECDHE-RSA-AES128-GCM-SHA256",
716 CIPHER_STRONG_ENOUGH),
717 CIPHER_DEF(TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, /* 0xC030 */
718 "ECDHE-RSA-AES256-GCM-SHA384",
719 CIPHER_STRONG_ENOUGH),
720 CIPHER_DEF(TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256, /* 0xC031 */
721 "ECDH-RSA-AES128-GCM-SHA256",
722 CIPHER_STRONG_ENOUGH),
723 CIPHER_DEF(TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384, /* 0xC032 */
724 "ECDH-RSA-AES256-GCM-SHA384",
725 CIPHER_STRONG_ENOUGH),
726 #endif /* CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS */
727
728 #if CURL_BUILD_MAC_10_15 || CURL_BUILD_IOS_13
729 /* ECDHE_PSK Cipher Suites for Transport Layer Security (TLS), RFC 5489 */
730 CIPHER_DEF(TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA, /* 0xC035 */
731 "ECDHE-PSK-AES128-CBC-SHA",
732 CIPHER_STRONG_ENOUGH),
733 CIPHER_DEF(TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA, /* 0xC036 */
734 "ECDHE-PSK-AES256-CBC-SHA",
735 CIPHER_STRONG_ENOUGH),
736 #endif /* CURL_BUILD_MAC_10_15 || CURL_BUILD_IOS_13 */
737
738 #if CURL_BUILD_MAC_10_13 || CURL_BUILD_IOS_11
739 /* Addenda from rfc 7905 ChaCha20-Poly1305 Cipher Suites for
740 Transport Layer Security (TLS). */
741 CIPHER_DEF(TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, /* 0xCCA8 */
742 "ECDHE-RSA-CHACHA20-POLY1305",
743 CIPHER_STRONG_ENOUGH),
744 CIPHER_DEF(TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, /* 0xCCA9 */
745 "ECDHE-ECDSA-CHACHA20-POLY1305",
746 CIPHER_STRONG_ENOUGH),
747 #endif /* CURL_BUILD_MAC_10_13 || CURL_BUILD_IOS_11 */
748
749 #if CURL_BUILD_MAC_10_15 || CURL_BUILD_IOS_13
750 /* ChaCha20-Poly1305 Cipher Suites for Transport Layer Security (TLS),
751 RFC 7905 */
752 CIPHER_DEF(TLS_PSK_WITH_CHACHA20_POLY1305_SHA256, /* 0xCCAB */
753 "PSK-CHACHA20-POLY1305",
754 CIPHER_STRONG_ENOUGH),
755 #endif /* CURL_BUILD_MAC_10_15 || CURL_BUILD_IOS_13 */
756
757 /* Tags for SSL 2 cipher kinds which are not specified for SSL 3.
758 Defined since SDK 10.2.8 */
759 CIPHER_DEF(SSL_RSA_WITH_RC2_CBC_MD5, /* 0xFF80 */
760 NULL,
761 CIPHER_WEAK_RC_ENCRYPTION),
762 CIPHER_DEF(SSL_RSA_WITH_IDEA_CBC_MD5, /* 0xFF81 */
763 NULL,
764 CIPHER_WEAK_IDEA_ENCRYPTION),
765 CIPHER_DEF(SSL_RSA_WITH_DES_CBC_MD5, /* 0xFF82 */
766 NULL,
767 CIPHER_WEAK_DES_ENCRYPTION),
768 CIPHER_DEF(SSL_RSA_WITH_3DES_EDE_CBC_MD5, /* 0xFF83 */
769 NULL,
770 CIPHER_WEAK_3DES_ENCRYPTION),
771 };
772
773 #define NUM_OF_CIPHERS sizeof(ciphertable)/sizeof(ciphertable[0])
774
775
776 /* pinned public key support tests */
777
778 /* version 1 supports macOS 10.12+ and iOS 10+ */
779 #if ((TARGET_OS_IPHONE && __IPHONE_OS_VERSION_MIN_REQUIRED >= 100000) || \
780 (!TARGET_OS_IPHONE && __MAC_OS_X_VERSION_MIN_REQUIRED >= 101200))
781 #define SECTRANSP_PINNEDPUBKEY_V1 1
782 #endif
783
784 /* version 2 supports MacOSX 10.7+ */
785 #if (!TARGET_OS_IPHONE && __MAC_OS_X_VERSION_MIN_REQUIRED >= 1070)
786 #define SECTRANSP_PINNEDPUBKEY_V2 1
787 #endif
788
789 #if defined(SECTRANSP_PINNEDPUBKEY_V1) || defined(SECTRANSP_PINNEDPUBKEY_V2)
790 /* this backend supports CURLOPT_PINNEDPUBLICKEY */
791 #define SECTRANSP_PINNEDPUBKEY 1
792 #endif /* SECTRANSP_PINNEDPUBKEY */
793
794 #ifdef SECTRANSP_PINNEDPUBKEY
795 /* both new and old APIs return rsa keys missing the spki header (not DER) */
796 static const unsigned char rsa4096SpkiHeader[] = {
797 0x30, 0x82, 0x02, 0x22, 0x30, 0x0d,
798 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
799 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05,
800 0x00, 0x03, 0x82, 0x02, 0x0f, 0x00};
801
802 static const unsigned char rsa2048SpkiHeader[] = {
803 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d,
804 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
805 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05,
806 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00};
807 #ifdef SECTRANSP_PINNEDPUBKEY_V1
808 /* the *new* version doesn't return DER encoded ecdsa certs like the old... */
809 static const unsigned char ecDsaSecp256r1SpkiHeader[] = {
810 0x30, 0x59, 0x30, 0x13, 0x06, 0x07,
811 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x02,
812 0x01, 0x06, 0x08, 0x2a, 0x86, 0x48,
813 0xce, 0x3d, 0x03, 0x01, 0x07, 0x03,
814 0x42, 0x00};
815
816 static const unsigned char ecDsaSecp384r1SpkiHeader[] = {
817 0x30, 0x76, 0x30, 0x10, 0x06, 0x07,
818 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x02,
819 0x01, 0x06, 0x05, 0x2b, 0x81, 0x04,
820 0x00, 0x22, 0x03, 0x62, 0x00};
821 #endif /* SECTRANSP_PINNEDPUBKEY_V1 */
822 #endif /* SECTRANSP_PINNEDPUBKEY */
823
824 /* The following two functions were ripped from Apple sample code,
825 * with some modifications: */
SocketRead(SSLConnectionRef connection,void * data,size_t * dataLength)826 static OSStatus SocketRead(SSLConnectionRef connection,
827 void *data, /* owned by
828 * caller, data
829 * RETURNED */
830 size_t *dataLength) /* IN/OUT */
831 {
832 size_t bytesToGo = *dataLength;
833 size_t initLen = bytesToGo;
834 UInt8 *currData = (UInt8 *)data;
835 /*int sock = *(int *)connection;*/
836 struct ssl_connect_data *connssl = (struct ssl_connect_data *)connection;
837 struct ssl_backend_data *backend = connssl->backend;
838 int sock = backend->ssl_sockfd;
839 OSStatus rtn = noErr;
840 size_t bytesRead;
841 ssize_t rrtn;
842 int theErr;
843
844 *dataLength = 0;
845
846 for(;;) {
847 bytesRead = 0;
848 rrtn = read(sock, currData, bytesToGo);
849 if(rrtn <= 0) {
850 /* this is guesswork... */
851 theErr = errno;
852 if(rrtn == 0) { /* EOF = server hung up */
853 /* the framework will turn this into errSSLClosedNoNotify */
854 rtn = errSSLClosedGraceful;
855 }
856 else /* do the switch */
857 switch(theErr) {
858 case ENOENT:
859 /* connection closed */
860 rtn = errSSLClosedGraceful;
861 break;
862 case ECONNRESET:
863 rtn = errSSLClosedAbort;
864 break;
865 case EAGAIN:
866 rtn = errSSLWouldBlock;
867 backend->ssl_direction = false;
868 break;
869 default:
870 rtn = ioErr;
871 break;
872 }
873 break;
874 }
875 else {
876 bytesRead = rrtn;
877 }
878 bytesToGo -= bytesRead;
879 currData += bytesRead;
880
881 if(bytesToGo == 0) {
882 /* filled buffer with incoming data, done */
883 break;
884 }
885 }
886 *dataLength = initLen - bytesToGo;
887
888 return rtn;
889 }
890
SocketWrite(SSLConnectionRef connection,const void * data,size_t * dataLength)891 static OSStatus SocketWrite(SSLConnectionRef connection,
892 const void *data,
893 size_t *dataLength) /* IN/OUT */
894 {
895 size_t bytesSent = 0;
896 /*int sock = *(int *)connection;*/
897 struct ssl_connect_data *connssl = (struct ssl_connect_data *)connection;
898 struct ssl_backend_data *backend = connssl->backend;
899 int sock = backend->ssl_sockfd;
900 ssize_t length;
901 size_t dataLen = *dataLength;
902 const UInt8 *dataPtr = (UInt8 *)data;
903 OSStatus ortn;
904 int theErr;
905
906 *dataLength = 0;
907
908 do {
909 length = write(sock,
910 (char *)dataPtr + bytesSent,
911 dataLen - bytesSent);
912 } while((length > 0) &&
913 ( (bytesSent += length) < dataLen) );
914
915 if(length <= 0) {
916 theErr = errno;
917 if(theErr == EAGAIN) {
918 ortn = errSSLWouldBlock;
919 backend->ssl_direction = true;
920 }
921 else {
922 ortn = ioErr;
923 }
924 }
925 else {
926 ortn = noErr;
927 }
928 *dataLength = bytesSent;
929 return ortn;
930 }
931
932 #ifndef CURL_DISABLE_VERBOSE_STRINGS
TLSCipherNameForNumber(SSLCipherSuite cipher)933 CF_INLINE const char *TLSCipherNameForNumber(SSLCipherSuite cipher)
934 {
935 /* The first ciphers in the ciphertable are continuos. Here we do small
936 optimization and instead of loop directly get SSL name by cipher number.
937 */
938 if(cipher <= SSL_FORTEZZA_DMS_WITH_FORTEZZA_CBC_SHA) {
939 return ciphertable[cipher].name;
940 }
941 /* Iterate through the rest of the ciphers */
942 for(size_t i = SSL_FORTEZZA_DMS_WITH_FORTEZZA_CBC_SHA + 1;
943 i < NUM_OF_CIPHERS;
944 ++i) {
945 if(ciphertable[i].num == cipher) {
946 return ciphertable[i].name;
947 }
948 }
949 return ciphertable[SSL_NULL_WITH_NULL_NULL].name;
950 }
951 #endif /* !CURL_DISABLE_VERBOSE_STRINGS */
952
953 #if CURL_BUILD_MAC
GetDarwinVersionNumber(int * major,int * minor)954 CF_INLINE void GetDarwinVersionNumber(int *major, int *minor)
955 {
956 int mib[2];
957 char *os_version;
958 size_t os_version_len;
959 char *os_version_major, *os_version_minor;
960 char *tok_buf;
961
962 /* Get the Darwin kernel version from the kernel using sysctl(): */
963 mib[0] = CTL_KERN;
964 mib[1] = KERN_OSRELEASE;
965 if(sysctl(mib, 2, NULL, &os_version_len, NULL, 0) == -1)
966 return;
967 os_version = malloc(os_version_len*sizeof(char));
968 if(!os_version)
969 return;
970 if(sysctl(mib, 2, os_version, &os_version_len, NULL, 0) == -1) {
971 free(os_version);
972 return;
973 }
974
975 /* Parse the version: */
976 os_version_major = strtok_r(os_version, ".", &tok_buf);
977 os_version_minor = strtok_r(NULL, ".", &tok_buf);
978 *major = atoi(os_version_major);
979 *minor = atoi(os_version_minor);
980 free(os_version);
981 }
982 #endif /* CURL_BUILD_MAC */
983
984 /* Apple provides a myriad of ways of getting information about a certificate
985 into a string. Some aren't available under iOS or newer cats. So here's
986 a unified function for getting a string describing the certificate that
987 ought to work in all cats starting with Leopard. */
getsubject(SecCertificateRef cert)988 CF_INLINE CFStringRef getsubject(SecCertificateRef cert)
989 {
990 CFStringRef server_cert_summary = CFSTR("(null)");
991
992 #if CURL_BUILD_IOS
993 /* iOS: There's only one way to do this. */
994 server_cert_summary = SecCertificateCopySubjectSummary(cert);
995 #else
996 #if CURL_BUILD_MAC_10_7
997 /* Lion & later: Get the long description if we can. */
998 if(SecCertificateCopyLongDescription != NULL)
999 server_cert_summary =
1000 SecCertificateCopyLongDescription(NULL, cert, NULL);
1001 else
1002 #endif /* CURL_BUILD_MAC_10_7 */
1003 #if CURL_BUILD_MAC_10_6
1004 /* Snow Leopard: Get the certificate summary. */
1005 if(SecCertificateCopySubjectSummary != NULL)
1006 server_cert_summary = SecCertificateCopySubjectSummary(cert);
1007 else
1008 #endif /* CURL_BUILD_MAC_10_6 */
1009 /* Leopard is as far back as we go... */
1010 (void)SecCertificateCopyCommonName(cert, &server_cert_summary);
1011 #endif /* CURL_BUILD_IOS */
1012 return server_cert_summary;
1013 }
1014
CopyCertSubject(struct Curl_easy * data,SecCertificateRef cert,char ** certp)1015 static CURLcode CopyCertSubject(struct Curl_easy *data,
1016 SecCertificateRef cert, char **certp)
1017 {
1018 CFStringRef c = getsubject(cert);
1019 CURLcode result = CURLE_OK;
1020 const char *direct;
1021 char *cbuf = NULL;
1022 *certp = NULL;
1023
1024 if(!c) {
1025 failf(data, "SSL: invalid CA certificate subject");
1026 return CURLE_PEER_FAILED_VERIFICATION;
1027 }
1028
1029 /* If the subject is already available as UTF-8 encoded (ie 'direct') then
1030 use that, else convert it. */
1031 direct = CFStringGetCStringPtr(c, kCFStringEncodingUTF8);
1032 if(direct) {
1033 *certp = strdup(direct);
1034 if(!*certp) {
1035 failf(data, "SSL: out of memory");
1036 result = CURLE_OUT_OF_MEMORY;
1037 }
1038 }
1039 else {
1040 size_t cbuf_size = ((size_t)CFStringGetLength(c) * 4) + 1;
1041 cbuf = calloc(cbuf_size, 1);
1042 if(cbuf) {
1043 if(!CFStringGetCString(c, cbuf, cbuf_size,
1044 kCFStringEncodingUTF8)) {
1045 failf(data, "SSL: invalid CA certificate subject");
1046 result = CURLE_PEER_FAILED_VERIFICATION;
1047 }
1048 else
1049 /* pass back the buffer */
1050 *certp = cbuf;
1051 }
1052 else {
1053 failf(data, "SSL: couldn't allocate %zu bytes of memory", cbuf_size);
1054 result = CURLE_OUT_OF_MEMORY;
1055 }
1056 }
1057 if(result)
1058 free(cbuf);
1059 CFRelease(c);
1060 return result;
1061 }
1062
1063 #if CURL_SUPPORT_MAC_10_6
1064 /* The SecKeychainSearch API was deprecated in Lion, and using it will raise
1065 deprecation warnings, so let's not compile this unless it's necessary: */
CopyIdentityWithLabelOldSchool(char * label,SecIdentityRef * out_c_a_k)1066 static OSStatus CopyIdentityWithLabelOldSchool(char *label,
1067 SecIdentityRef *out_c_a_k)
1068 {
1069 OSStatus status = errSecItemNotFound;
1070 SecKeychainAttributeList attr_list;
1071 SecKeychainAttribute attr;
1072 SecKeychainSearchRef search = NULL;
1073 SecCertificateRef cert = NULL;
1074
1075 /* Set up the attribute list: */
1076 attr_list.count = 1L;
1077 attr_list.attr = &attr;
1078
1079 /* Set up our lone search criterion: */
1080 attr.tag = kSecLabelItemAttr;
1081 attr.data = label;
1082 attr.length = (UInt32)strlen(label);
1083
1084 /* Start searching: */
1085 status = SecKeychainSearchCreateFromAttributes(NULL,
1086 kSecCertificateItemClass,
1087 &attr_list,
1088 &search);
1089 if(status == noErr) {
1090 status = SecKeychainSearchCopyNext(search,
1091 (SecKeychainItemRef *)&cert);
1092 if(status == noErr && cert) {
1093 /* If we found a certificate, does it have a private key? */
1094 status = SecIdentityCreateWithCertificate(NULL, cert, out_c_a_k);
1095 CFRelease(cert);
1096 }
1097 }
1098
1099 if(search)
1100 CFRelease(search);
1101 return status;
1102 }
1103 #endif /* CURL_SUPPORT_MAC_10_6 */
1104
CopyIdentityWithLabel(char * label,SecIdentityRef * out_cert_and_key)1105 static OSStatus CopyIdentityWithLabel(char *label,
1106 SecIdentityRef *out_cert_and_key)
1107 {
1108 OSStatus status = errSecItemNotFound;
1109
1110 #if CURL_BUILD_MAC_10_7 || CURL_BUILD_IOS
1111 CFArrayRef keys_list;
1112 CFIndex keys_list_count;
1113 CFIndex i;
1114 CFStringRef common_name;
1115
1116 /* SecItemCopyMatching() was introduced in iOS and Snow Leopard.
1117 kSecClassIdentity was introduced in Lion. If both exist, let's use them
1118 to find the certificate. */
1119 if(SecItemCopyMatching != NULL && kSecClassIdentity != NULL) {
1120 CFTypeRef keys[5];
1121 CFTypeRef values[5];
1122 CFDictionaryRef query_dict;
1123 CFStringRef label_cf = CFStringCreateWithCString(NULL, label,
1124 kCFStringEncodingUTF8);
1125
1126 /* Set up our search criteria and expected results: */
1127 values[0] = kSecClassIdentity; /* we want a certificate and a key */
1128 keys[0] = kSecClass;
1129 values[1] = kCFBooleanTrue; /* we want a reference */
1130 keys[1] = kSecReturnRef;
1131 values[2] = kSecMatchLimitAll; /* kSecMatchLimitOne would be better if the
1132 * label matching below worked correctly */
1133 keys[2] = kSecMatchLimit;
1134 /* identity searches need a SecPolicyRef in order to work */
1135 values[3] = SecPolicyCreateSSL(false, NULL);
1136 keys[3] = kSecMatchPolicy;
1137 /* match the name of the certificate (doesn't work in macOS 10.12.1) */
1138 values[4] = label_cf;
1139 keys[4] = kSecAttrLabel;
1140 query_dict = CFDictionaryCreate(NULL, (const void **)keys,
1141 (const void **)values, 5L,
1142 &kCFCopyStringDictionaryKeyCallBacks,
1143 &kCFTypeDictionaryValueCallBacks);
1144 CFRelease(values[3]);
1145
1146 /* Do we have a match? */
1147 status = SecItemCopyMatching(query_dict, (CFTypeRef *) &keys_list);
1148
1149 /* Because kSecAttrLabel matching doesn't work with kSecClassIdentity,
1150 * we need to find the correct identity ourselves */
1151 if(status == noErr) {
1152 keys_list_count = CFArrayGetCount(keys_list);
1153 *out_cert_and_key = NULL;
1154 status = 1;
1155 for(i = 0; i<keys_list_count; i++) {
1156 OSStatus err = noErr;
1157 SecCertificateRef cert = NULL;
1158 SecIdentityRef identity =
1159 (SecIdentityRef) CFArrayGetValueAtIndex(keys_list, i);
1160 err = SecIdentityCopyCertificate(identity, &cert);
1161 if(err == noErr) {
1162 OSStatus copy_status = noErr;
1163 #if CURL_BUILD_IOS
1164 common_name = SecCertificateCopySubjectSummary(cert);
1165 #elif CURL_BUILD_MAC_10_7
1166 copy_status = SecCertificateCopyCommonName(cert, &common_name);
1167 #endif
1168 if(copy_status == noErr &&
1169 CFStringCompare(common_name, label_cf, 0) == kCFCompareEqualTo) {
1170 CFRelease(cert);
1171 CFRelease(common_name);
1172 CFRetain(identity);
1173 *out_cert_and_key = identity;
1174 status = noErr;
1175 break;
1176 }
1177 CFRelease(common_name);
1178 }
1179 CFRelease(cert);
1180 }
1181 }
1182
1183 if(keys_list)
1184 CFRelease(keys_list);
1185 CFRelease(query_dict);
1186 CFRelease(label_cf);
1187 }
1188 else {
1189 #if CURL_SUPPORT_MAC_10_6
1190 /* On Leopard and Snow Leopard, fall back to SecKeychainSearch. */
1191 status = CopyIdentityWithLabelOldSchool(label, out_cert_and_key);
1192 #endif /* CURL_SUPPORT_MAC_10_6 */
1193 }
1194 #elif CURL_SUPPORT_MAC_10_6
1195 /* For developers building on older cats, we have no choice but to fall back
1196 to SecKeychainSearch. */
1197 status = CopyIdentityWithLabelOldSchool(label, out_cert_and_key);
1198 #endif /* CURL_BUILD_MAC_10_7 || CURL_BUILD_IOS */
1199 return status;
1200 }
1201
CopyIdentityFromPKCS12File(const char * cPath,const struct curl_blob * blob,const char * cPassword,SecIdentityRef * out_cert_and_key)1202 static OSStatus CopyIdentityFromPKCS12File(const char *cPath,
1203 const struct curl_blob *blob,
1204 const char *cPassword,
1205 SecIdentityRef *out_cert_and_key)
1206 {
1207 OSStatus status = errSecItemNotFound;
1208 CFURLRef pkcs_url = NULL;
1209 CFStringRef password = cPassword ? CFStringCreateWithCString(NULL,
1210 cPassword, kCFStringEncodingUTF8) : NULL;
1211 CFDataRef pkcs_data = NULL;
1212
1213 /* We can import P12 files on iOS or OS X 10.7 or later: */
1214 /* These constants are documented as having first appeared in 10.6 but they
1215 raise linker errors when used on that cat for some reason. */
1216 #if CURL_BUILD_MAC_10_7 || CURL_BUILD_IOS
1217 bool resource_imported;
1218
1219 if(blob) {
1220 pkcs_data = CFDataCreate(kCFAllocatorDefault,
1221 (const unsigned char *)blob->data, blob->len);
1222 status = (pkcs_data != NULL) ? errSecSuccess : errSecAllocate;
1223 resource_imported = (pkcs_data != NULL);
1224 }
1225 else {
1226 pkcs_url =
1227 CFURLCreateFromFileSystemRepresentation(NULL,
1228 (const UInt8 *)cPath,
1229 strlen(cPath), false);
1230 resource_imported =
1231 CFURLCreateDataAndPropertiesFromResource(NULL,
1232 pkcs_url, &pkcs_data,
1233 NULL, NULL, &status);
1234 }
1235
1236 if(resource_imported) {
1237 CFArrayRef items = NULL;
1238
1239 /* On iOS SecPKCS12Import will never add the client certificate to the
1240 * Keychain.
1241 *
1242 * It gives us back a SecIdentityRef that we can use directly. */
1243 #if CURL_BUILD_IOS
1244 const void *cKeys[] = {kSecImportExportPassphrase};
1245 const void *cValues[] = {password};
1246 CFDictionaryRef options = CFDictionaryCreate(NULL, cKeys, cValues,
1247 password ? 1L : 0L, NULL, NULL);
1248
1249 if(options != NULL) {
1250 status = SecPKCS12Import(pkcs_data, options, &items);
1251 CFRelease(options);
1252 }
1253
1254
1255 /* On macOS SecPKCS12Import will always add the client certificate to
1256 * the Keychain.
1257 *
1258 * As this doesn't match iOS, and apps may not want to see their client
1259 * certificate saved in the user's keychain, we use SecItemImport
1260 * with a NULL keychain to avoid importing it.
1261 *
1262 * This returns a SecCertificateRef from which we can construct a
1263 * SecIdentityRef.
1264 */
1265 #elif CURL_BUILD_MAC_10_7
1266 SecItemImportExportKeyParameters keyParams;
1267 SecExternalFormat inputFormat = kSecFormatPKCS12;
1268 SecExternalItemType inputType = kSecItemTypeCertificate;
1269
1270 memset(&keyParams, 0x00, sizeof(keyParams));
1271 keyParams.version = SEC_KEY_IMPORT_EXPORT_PARAMS_VERSION;
1272 keyParams.passphrase = password;
1273
1274 status = SecItemImport(pkcs_data, NULL, &inputFormat, &inputType,
1275 0, &keyParams, NULL, &items);
1276 #endif
1277
1278
1279 /* Extract the SecIdentityRef */
1280 if(status == errSecSuccess && items && CFArrayGetCount(items)) {
1281 CFIndex i, count;
1282 count = CFArrayGetCount(items);
1283
1284 for(i = 0; i < count; i++) {
1285 CFTypeRef item = (CFTypeRef) CFArrayGetValueAtIndex(items, i);
1286 CFTypeID itemID = CFGetTypeID(item);
1287
1288 if(itemID == CFDictionaryGetTypeID()) {
1289 CFTypeRef identity = (CFTypeRef) CFDictionaryGetValue(
1290 (CFDictionaryRef) item,
1291 kSecImportItemIdentity);
1292 CFRetain(identity);
1293 *out_cert_and_key = (SecIdentityRef) identity;
1294 break;
1295 }
1296 #if CURL_BUILD_MAC_10_7
1297 else if(itemID == SecCertificateGetTypeID()) {
1298 status = SecIdentityCreateWithCertificate(NULL,
1299 (SecCertificateRef) item,
1300 out_cert_and_key);
1301 break;
1302 }
1303 #endif
1304 }
1305 }
1306
1307 if(items)
1308 CFRelease(items);
1309 CFRelease(pkcs_data);
1310 }
1311 #endif /* CURL_BUILD_MAC_10_7 || CURL_BUILD_IOS */
1312 if(password)
1313 CFRelease(password);
1314 if(pkcs_url)
1315 CFRelease(pkcs_url);
1316 return status;
1317 }
1318
1319 /* This code was borrowed from nss.c, with some modifications:
1320 * Determine whether the nickname passed in is a filename that needs to
1321 * be loaded as a PEM or a regular NSS nickname.
1322 *
1323 * returns 1 for a file
1324 * returns 0 for not a file
1325 */
is_file(const char * filename)1326 CF_INLINE bool is_file(const char *filename)
1327 {
1328 struct_stat st;
1329
1330 if(!filename)
1331 return false;
1332
1333 if(stat(filename, &st) == 0)
1334 return S_ISREG(st.st_mode);
1335 return false;
1336 }
1337
1338 #if CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS
sectransp_version_from_curl(SSLProtocol * darwinver,long ssl_version)1339 static CURLcode sectransp_version_from_curl(SSLProtocol *darwinver,
1340 long ssl_version)
1341 {
1342 switch(ssl_version) {
1343 case CURL_SSLVERSION_TLSv1_0:
1344 *darwinver = kTLSProtocol1;
1345 return CURLE_OK;
1346 case CURL_SSLVERSION_TLSv1_1:
1347 *darwinver = kTLSProtocol11;
1348 return CURLE_OK;
1349 case CURL_SSLVERSION_TLSv1_2:
1350 *darwinver = kTLSProtocol12;
1351 return CURLE_OK;
1352 case CURL_SSLVERSION_TLSv1_3:
1353 /* TLS 1.3 support first appeared in iOS 11 and macOS 10.13 */
1354 #if (CURL_BUILD_MAC_10_13 || CURL_BUILD_IOS_11) && HAVE_BUILTIN_AVAILABLE == 1
1355 if(__builtin_available(macOS 10.13, iOS 11.0, *)) {
1356 *darwinver = kTLSProtocol13;
1357 return CURLE_OK;
1358 }
1359 #endif /* (CURL_BUILD_MAC_10_13 || CURL_BUILD_IOS_11) &&
1360 HAVE_BUILTIN_AVAILABLE == 1 */
1361 break;
1362 }
1363 return CURLE_SSL_CONNECT_ERROR;
1364 }
1365 #endif
1366
1367 static CURLcode
set_ssl_version_min_max(struct Curl_easy * data,struct connectdata * conn,int sockindex)1368 set_ssl_version_min_max(struct Curl_easy *data, struct connectdata *conn,
1369 int sockindex)
1370 {
1371 struct ssl_connect_data *connssl = &conn->ssl[sockindex];
1372 struct ssl_backend_data *backend = connssl->backend;
1373 long ssl_version = SSL_CONN_CONFIG(version);
1374 long ssl_version_max = SSL_CONN_CONFIG(version_max);
1375 long max_supported_version_by_os;
1376
1377 /* macOS 10.5-10.7 supported TLS 1.0 only.
1378 macOS 10.8 and later, and iOS 5 and later, added TLS 1.1 and 1.2.
1379 macOS 10.13 and later, and iOS 11 and later, added TLS 1.3. */
1380 #if (CURL_BUILD_MAC_10_13 || CURL_BUILD_IOS_11) && HAVE_BUILTIN_AVAILABLE == 1
1381 if(__builtin_available(macOS 10.13, iOS 11.0, *)) {
1382 max_supported_version_by_os = CURL_SSLVERSION_MAX_TLSv1_3;
1383 }
1384 else {
1385 max_supported_version_by_os = CURL_SSLVERSION_MAX_TLSv1_2;
1386 }
1387 #else
1388 max_supported_version_by_os = CURL_SSLVERSION_MAX_TLSv1_2;
1389 #endif /* (CURL_BUILD_MAC_10_13 || CURL_BUILD_IOS_11) &&
1390 HAVE_BUILTIN_AVAILABLE == 1 */
1391
1392 switch(ssl_version) {
1393 case CURL_SSLVERSION_DEFAULT:
1394 case CURL_SSLVERSION_TLSv1:
1395 ssl_version = CURL_SSLVERSION_TLSv1_0;
1396 break;
1397 }
1398
1399 switch(ssl_version_max) {
1400 case CURL_SSLVERSION_MAX_NONE:
1401 case CURL_SSLVERSION_MAX_DEFAULT:
1402 ssl_version_max = max_supported_version_by_os;
1403 break;
1404 }
1405
1406 #if CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS
1407 if(SSLSetProtocolVersionMax != NULL) {
1408 SSLProtocol darwin_ver_min = kTLSProtocol1;
1409 SSLProtocol darwin_ver_max = kTLSProtocol1;
1410 CURLcode result = sectransp_version_from_curl(&darwin_ver_min,
1411 ssl_version);
1412 if(result) {
1413 failf(data, "unsupported min version passed via CURLOPT_SSLVERSION");
1414 return result;
1415 }
1416 result = sectransp_version_from_curl(&darwin_ver_max,
1417 ssl_version_max >> 16);
1418 if(result) {
1419 failf(data, "unsupported max version passed via CURLOPT_SSLVERSION");
1420 return result;
1421 }
1422
1423 (void)SSLSetProtocolVersionMin(backend->ssl_ctx, darwin_ver_min);
1424 (void)SSLSetProtocolVersionMax(backend->ssl_ctx, darwin_ver_max);
1425 return result;
1426 }
1427 else {
1428 #if CURL_SUPPORT_MAC_10_8
1429 long i = ssl_version;
1430 (void)SSLSetProtocolVersionEnabled(backend->ssl_ctx,
1431 kSSLProtocolAll,
1432 false);
1433 for(; i <= (ssl_version_max >> 16); i++) {
1434 switch(i) {
1435 case CURL_SSLVERSION_TLSv1_0:
1436 (void)SSLSetProtocolVersionEnabled(backend->ssl_ctx,
1437 kTLSProtocol1,
1438 true);
1439 break;
1440 case CURL_SSLVERSION_TLSv1_1:
1441 (void)SSLSetProtocolVersionEnabled(backend->ssl_ctx,
1442 kTLSProtocol11,
1443 true);
1444 break;
1445 case CURL_SSLVERSION_TLSv1_2:
1446 (void)SSLSetProtocolVersionEnabled(backend->ssl_ctx,
1447 kTLSProtocol12,
1448 true);
1449 break;
1450 case CURL_SSLVERSION_TLSv1_3:
1451 failf(data, "Your version of the OS does not support TLSv1.3");
1452 return CURLE_SSL_CONNECT_ERROR;
1453 }
1454 }
1455 return CURLE_OK;
1456 #endif /* CURL_SUPPORT_MAC_10_8 */
1457 }
1458 #endif /* CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS */
1459 failf(data, "Secure Transport: cannot set SSL protocol");
1460 return CURLE_SSL_CONNECT_ERROR;
1461 }
1462
is_cipher_suite_strong(SSLCipherSuite suite_num)1463 static bool is_cipher_suite_strong(SSLCipherSuite suite_num)
1464 {
1465 for(size_t i = 0; i < NUM_OF_CIPHERS; ++i) {
1466 if(ciphertable[i].num == suite_num) {
1467 return !ciphertable[i].weak;
1468 }
1469 }
1470 /* If the cipher is not in our list, assume it is a new one
1471 and therefore strong. Previous implementation was the same,
1472 if cipher suite is not in the list, it was considered strong enough */
1473 return true;
1474 }
1475
is_separator(char c)1476 static bool is_separator(char c)
1477 {
1478 /* Return whether character is a cipher list separator. */
1479 switch(c) {
1480 case ' ':
1481 case '\t':
1482 case ':':
1483 case ',':
1484 case ';':
1485 return true;
1486 }
1487 return false;
1488 }
1489
sectransp_set_default_ciphers(struct Curl_easy * data,SSLContextRef ssl_ctx)1490 static CURLcode sectransp_set_default_ciphers(struct Curl_easy *data,
1491 SSLContextRef ssl_ctx)
1492 {
1493 size_t all_ciphers_count = 0UL, allowed_ciphers_count = 0UL, i;
1494 SSLCipherSuite *all_ciphers = NULL, *allowed_ciphers = NULL;
1495 OSStatus err = noErr;
1496
1497 #if CURL_BUILD_MAC
1498 int darwinver_maj = 0, darwinver_min = 0;
1499
1500 GetDarwinVersionNumber(&darwinver_maj, &darwinver_min);
1501 #endif /* CURL_BUILD_MAC */
1502
1503 /* Disable cipher suites that ST supports but are not safe. These ciphers
1504 are unlikely to be used in any case since ST gives other ciphers a much
1505 higher priority, but it's probably better that we not connect at all than
1506 to give the user a false sense of security if the server only supports
1507 insecure ciphers. (Note: We don't care about SSLv2-only ciphers.) */
1508 err = SSLGetNumberSupportedCiphers(ssl_ctx, &all_ciphers_count);
1509 if(err != noErr) {
1510 failf(data, "SSL: SSLGetNumberSupportedCiphers() failed: OSStatus %d",
1511 err);
1512 return CURLE_SSL_CIPHER;
1513 }
1514 all_ciphers = malloc(all_ciphers_count*sizeof(SSLCipherSuite));
1515 if(!all_ciphers) {
1516 failf(data, "SSL: Failed to allocate memory for all ciphers");
1517 return CURLE_OUT_OF_MEMORY;
1518 }
1519 allowed_ciphers = malloc(all_ciphers_count*sizeof(SSLCipherSuite));
1520 if(!allowed_ciphers) {
1521 Curl_safefree(all_ciphers);
1522 failf(data, "SSL: Failed to allocate memory for allowed ciphers");
1523 return CURLE_OUT_OF_MEMORY;
1524 }
1525 err = SSLGetSupportedCiphers(ssl_ctx, all_ciphers,
1526 &all_ciphers_count);
1527 if(err != noErr) {
1528 Curl_safefree(all_ciphers);
1529 Curl_safefree(allowed_ciphers);
1530 return CURLE_SSL_CIPHER;
1531 }
1532 for(i = 0UL ; i < all_ciphers_count ; i++) {
1533 #if CURL_BUILD_MAC
1534 /* There's a known bug in early versions of Mountain Lion where ST's ECC
1535 ciphers (cipher suite 0xC001 through 0xC032) simply do not work.
1536 Work around the problem here by disabling those ciphers if we are
1537 running in an affected version of OS X. */
1538 if(darwinver_maj == 12 && darwinver_min <= 3 &&
1539 all_ciphers[i] >= 0xC001 && all_ciphers[i] <= 0xC032) {
1540 continue;
1541 }
1542 #endif /* CURL_BUILD_MAC */
1543 if(is_cipher_suite_strong(all_ciphers[i])) {
1544 allowed_ciphers[allowed_ciphers_count++] = all_ciphers[i];
1545 }
1546 }
1547 err = SSLSetEnabledCiphers(ssl_ctx, allowed_ciphers,
1548 allowed_ciphers_count);
1549 Curl_safefree(all_ciphers);
1550 Curl_safefree(allowed_ciphers);
1551 if(err != noErr) {
1552 failf(data, "SSL: SSLSetEnabledCiphers() failed: OSStatus %d", err);
1553 return CURLE_SSL_CIPHER;
1554 }
1555 return CURLE_OK;
1556 }
1557
sectransp_set_selected_ciphers(struct Curl_easy * data,SSLContextRef ssl_ctx,const char * ciphers)1558 static CURLcode sectransp_set_selected_ciphers(struct Curl_easy *data,
1559 SSLContextRef ssl_ctx,
1560 const char *ciphers)
1561 {
1562 size_t ciphers_count = 0;
1563 const char *cipher_start = ciphers;
1564 OSStatus err = noErr;
1565 SSLCipherSuite selected_ciphers[NUM_OF_CIPHERS];
1566
1567 if(!ciphers)
1568 return CURLE_OK;
1569
1570 while(is_separator(*ciphers)) /* Skip initial separators. */
1571 ciphers++;
1572 if(!*ciphers)
1573 return CURLE_OK;
1574
1575 cipher_start = ciphers;
1576 while(*cipher_start && ciphers_count < NUM_OF_CIPHERS) {
1577 bool cipher_found = FALSE;
1578 size_t cipher_len = 0;
1579 const char *cipher_end = NULL;
1580 bool tls_name = FALSE;
1581
1582 /* Skip separators */
1583 while(is_separator(*cipher_start))
1584 cipher_start++;
1585 if(*cipher_start == '\0') {
1586 break;
1587 }
1588 /* Find last position of a cipher in the ciphers string */
1589 cipher_end = cipher_start;
1590 while (*cipher_end != '\0' && !is_separator(*cipher_end)) {
1591 ++cipher_end;
1592 }
1593
1594 /* IANA cipher names start with the TLS_ or SSL_ prefix.
1595 If the 4th symbol of the cipher is '_' we look for a cipher in the
1596 table by its (TLS) name.
1597 Otherwise, we try to match cipher by an alias. */
1598 if(cipher_start[3] == '_') {
1599 tls_name = TRUE;
1600 }
1601 /* Iterate through the cipher table and look for the cipher, starting
1602 the cipher number 0x01 because the 0x00 is not the real cipher */
1603 cipher_len = cipher_end - cipher_start;
1604 for(size_t i = 1; i < NUM_OF_CIPHERS; ++i) {
1605 const char *table_cipher_name = NULL;
1606 if(tls_name) {
1607 table_cipher_name = ciphertable[i].name;
1608 }
1609 else if(ciphertable[i].alias_name != NULL) {
1610 table_cipher_name = ciphertable[i].alias_name;
1611 }
1612 else {
1613 continue;
1614 }
1615 /* Compare a part of the string between separators with a cipher name
1616 in the table and make sure we matched the whole cipher name */
1617 if(strncmp(cipher_start, table_cipher_name, cipher_len) == 0
1618 && table_cipher_name[cipher_len] == '\0') {
1619 selected_ciphers[ciphers_count] = ciphertable[i].num;
1620 ++ciphers_count;
1621 cipher_found = TRUE;
1622 break;
1623 }
1624 }
1625 if(!cipher_found) {
1626 /* It would be more human-readable if we print the wrong cipher name
1627 but we don't want to allocate any additional memory and copy the name
1628 into it, then add it into logs.
1629 Also, we do not modify an original cipher list string. We just point
1630 to positions where cipher starts and ends in the cipher list string.
1631 The message is a bit cryptic and longer than necessary but can be
1632 understood by humans. */
1633 failf(data, "SSL: cipher string \"%s\" contains unsupported cipher name"
1634 " starting position %d and ending position %d",
1635 ciphers,
1636 cipher_start - ciphers,
1637 cipher_end - ciphers);
1638 return CURLE_SSL_CIPHER;
1639 }
1640 if(*cipher_end) {
1641 cipher_start = cipher_end + 1;
1642 }
1643 else {
1644 break;
1645 }
1646 }
1647 /* All cipher suites in the list are found. Report to logs as-is */
1648 infof(data, "SSL: Setting cipher suites list \"%s\"", ciphers);
1649
1650 err = SSLSetEnabledCiphers(ssl_ctx, selected_ciphers, ciphers_count);
1651 if(err != noErr) {
1652 failf(data, "SSL: SSLSetEnabledCiphers() failed: OSStatus %d", err);
1653 return CURLE_SSL_CIPHER;
1654 }
1655 return CURLE_OK;
1656 }
1657
sectransp_connect_step1(struct Curl_easy * data,struct connectdata * conn,int sockindex)1658 static CURLcode sectransp_connect_step1(struct Curl_easy *data,
1659 struct connectdata *conn,
1660 int sockindex)
1661 {
1662 curl_socket_t sockfd = conn->sock[sockindex];
1663 struct ssl_connect_data *connssl = &conn->ssl[sockindex];
1664 struct ssl_backend_data *backend = connssl->backend;
1665 const struct curl_blob *ssl_cablob = SSL_CONN_CONFIG(ca_info_blob);
1666 const char * const ssl_cafile =
1667 /* CURLOPT_CAINFO_BLOB overrides CURLOPT_CAINFO */
1668 (ssl_cablob ? NULL : SSL_CONN_CONFIG(CAfile));
1669 const bool verifypeer = SSL_CONN_CONFIG(verifypeer);
1670 char * const ssl_cert = SSL_SET_OPTION(primary.clientcert);
1671 const struct curl_blob *ssl_cert_blob = SSL_SET_OPTION(primary.cert_blob);
1672 bool isproxy = SSL_IS_PROXY();
1673 const char * const hostname = SSL_HOST_NAME();
1674 const long int port = SSL_HOST_PORT();
1675 #ifdef ENABLE_IPV6
1676 struct in6_addr addr;
1677 #else
1678 struct in_addr addr;
1679 #endif /* ENABLE_IPV6 */
1680 char *ciphers;
1681 OSStatus err = noErr;
1682 #if CURL_BUILD_MAC
1683 int darwinver_maj = 0, darwinver_min = 0;
1684
1685 GetDarwinVersionNumber(&darwinver_maj, &darwinver_min);
1686 #endif /* CURL_BUILD_MAC */
1687
1688 #if CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS
1689 if(SSLCreateContext != NULL) { /* use the newer API if available */
1690 if(backend->ssl_ctx)
1691 CFRelease(backend->ssl_ctx);
1692 backend->ssl_ctx = SSLCreateContext(NULL, kSSLClientSide, kSSLStreamType);
1693 if(!backend->ssl_ctx) {
1694 failf(data, "SSL: couldn't create a context!");
1695 return CURLE_OUT_OF_MEMORY;
1696 }
1697 }
1698 else {
1699 /* The old ST API does not exist under iOS, so don't compile it: */
1700 #if CURL_SUPPORT_MAC_10_8
1701 if(backend->ssl_ctx)
1702 (void)SSLDisposeContext(backend->ssl_ctx);
1703 err = SSLNewContext(false, &(backend->ssl_ctx));
1704 if(err != noErr) {
1705 failf(data, "SSL: couldn't create a context: OSStatus %d", err);
1706 return CURLE_OUT_OF_MEMORY;
1707 }
1708 #endif /* CURL_SUPPORT_MAC_10_8 */
1709 }
1710 #else
1711 if(backend->ssl_ctx)
1712 (void)SSLDisposeContext(backend->ssl_ctx);
1713 err = SSLNewContext(false, &(backend->ssl_ctx));
1714 if(err != noErr) {
1715 failf(data, "SSL: couldn't create a context: OSStatus %d", err);
1716 return CURLE_OUT_OF_MEMORY;
1717 }
1718 #endif /* CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS */
1719 backend->ssl_write_buffered_length = 0UL; /* reset buffered write length */
1720
1721 /* check to see if we've been told to use an explicit SSL/TLS version */
1722 #if CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS
1723 if(SSLSetProtocolVersionMax != NULL) {
1724 switch(conn->ssl_config.version) {
1725 case CURL_SSLVERSION_TLSv1:
1726 (void)SSLSetProtocolVersionMin(backend->ssl_ctx, kTLSProtocol1);
1727 #if (CURL_BUILD_MAC_10_13 || CURL_BUILD_IOS_11) && HAVE_BUILTIN_AVAILABLE == 1
1728 if(__builtin_available(macOS 10.13, iOS 11.0, *)) {
1729 (void)SSLSetProtocolVersionMax(backend->ssl_ctx, kTLSProtocol13);
1730 }
1731 else {
1732 (void)SSLSetProtocolVersionMax(backend->ssl_ctx, kTLSProtocol12);
1733 }
1734 #else
1735 (void)SSLSetProtocolVersionMax(backend->ssl_ctx, kTLSProtocol12);
1736 #endif /* (CURL_BUILD_MAC_10_13 || CURL_BUILD_IOS_11) &&
1737 HAVE_BUILTIN_AVAILABLE == 1 */
1738 break;
1739 case CURL_SSLVERSION_DEFAULT:
1740 case CURL_SSLVERSION_TLSv1_0:
1741 case CURL_SSLVERSION_TLSv1_1:
1742 case CURL_SSLVERSION_TLSv1_2:
1743 case CURL_SSLVERSION_TLSv1_3:
1744 {
1745 CURLcode result = set_ssl_version_min_max(data, conn, sockindex);
1746 if(result != CURLE_OK)
1747 return result;
1748 break;
1749 }
1750 case CURL_SSLVERSION_SSLv3:
1751 case CURL_SSLVERSION_SSLv2:
1752 failf(data, "SSL versions not supported");
1753 return CURLE_NOT_BUILT_IN;
1754 default:
1755 failf(data, "Unrecognized parameter passed via CURLOPT_SSLVERSION");
1756 return CURLE_SSL_CONNECT_ERROR;
1757 }
1758 }
1759 else {
1760 #if CURL_SUPPORT_MAC_10_8
1761 (void)SSLSetProtocolVersionEnabled(backend->ssl_ctx,
1762 kSSLProtocolAll,
1763 false);
1764 switch(conn->ssl_config.version) {
1765 case CURL_SSLVERSION_DEFAULT:
1766 case CURL_SSLVERSION_TLSv1:
1767 (void)SSLSetProtocolVersionEnabled(backend->ssl_ctx,
1768 kTLSProtocol1,
1769 true);
1770 (void)SSLSetProtocolVersionEnabled(backend->ssl_ctx,
1771 kTLSProtocol11,
1772 true);
1773 (void)SSLSetProtocolVersionEnabled(backend->ssl_ctx,
1774 kTLSProtocol12,
1775 true);
1776 break;
1777 case CURL_SSLVERSION_TLSv1_0:
1778 case CURL_SSLVERSION_TLSv1_1:
1779 case CURL_SSLVERSION_TLSv1_2:
1780 case CURL_SSLVERSION_TLSv1_3:
1781 {
1782 CURLcode result = set_ssl_version_min_max(data, conn, sockindex);
1783 if(result != CURLE_OK)
1784 return result;
1785 break;
1786 }
1787 case CURL_SSLVERSION_SSLv3:
1788 case CURL_SSLVERSION_SSLv2:
1789 failf(data, "SSL versions not supported");
1790 return CURLE_NOT_BUILT_IN;
1791 default:
1792 failf(data, "Unrecognized parameter passed via CURLOPT_SSLVERSION");
1793 return CURLE_SSL_CONNECT_ERROR;
1794 }
1795 #endif /* CURL_SUPPORT_MAC_10_8 */
1796 }
1797 #else
1798 if(conn->ssl_config.version_max != CURL_SSLVERSION_MAX_NONE) {
1799 failf(data, "Your version of the OS does not support to set maximum"
1800 " SSL/TLS version");
1801 return CURLE_SSL_CONNECT_ERROR;
1802 }
1803 (void)SSLSetProtocolVersionEnabled(backend->ssl_ctx, kSSLProtocolAll, false);
1804 switch(conn->ssl_config.version) {
1805 case CURL_SSLVERSION_DEFAULT:
1806 case CURL_SSLVERSION_TLSv1:
1807 case CURL_SSLVERSION_TLSv1_0:
1808 (void)SSLSetProtocolVersionEnabled(backend->ssl_ctx,
1809 kTLSProtocol1,
1810 true);
1811 break;
1812 case CURL_SSLVERSION_TLSv1_1:
1813 failf(data, "Your version of the OS does not support TLSv1.1");
1814 return CURLE_SSL_CONNECT_ERROR;
1815 case CURL_SSLVERSION_TLSv1_2:
1816 failf(data, "Your version of the OS does not support TLSv1.2");
1817 return CURLE_SSL_CONNECT_ERROR;
1818 case CURL_SSLVERSION_TLSv1_3:
1819 failf(data, "Your version of the OS does not support TLSv1.3");
1820 return CURLE_SSL_CONNECT_ERROR;
1821 case CURL_SSLVERSION_SSLv2:
1822 case CURL_SSLVERSION_SSLv3:
1823 failf(data, "SSL versions not supported");
1824 return CURLE_NOT_BUILT_IN;
1825 default:
1826 failf(data, "Unrecognized parameter passed via CURLOPT_SSLVERSION");
1827 return CURLE_SSL_CONNECT_ERROR;
1828 }
1829 #endif /* CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS */
1830
1831 #if (CURL_BUILD_MAC_10_13 || CURL_BUILD_IOS_11) && HAVE_BUILTIN_AVAILABLE == 1
1832 if(conn->bits.tls_enable_alpn) {
1833 if(__builtin_available(macOS 10.13.4, iOS 11, tvOS 11, *)) {
1834 CFMutableArrayRef alpnArr = CFArrayCreateMutable(NULL, 0,
1835 &kCFTypeArrayCallBacks);
1836
1837 #ifdef USE_HTTP2
1838 if(data->state.httpwant >= CURL_HTTP_VERSION_2
1839 #ifndef CURL_DISABLE_PROXY
1840 && (!isproxy || !conn->bits.tunnel_proxy)
1841 #endif
1842 ) {
1843 CFArrayAppendValue(alpnArr, CFSTR(ALPN_H2));
1844 infof(data, "ALPN, offering %s", ALPN_H2);
1845 }
1846 #endif
1847
1848 CFArrayAppendValue(alpnArr, CFSTR(ALPN_HTTP_1_1));
1849 infof(data, "ALPN, offering %s", ALPN_HTTP_1_1);
1850
1851 /* expects length prefixed preference ordered list of protocols in wire
1852 * format
1853 */
1854 err = SSLSetALPNProtocols(backend->ssl_ctx, alpnArr);
1855 if(err != noErr)
1856 infof(data, "WARNING: failed to set ALPN protocols; OSStatus %d",
1857 err);
1858 CFRelease(alpnArr);
1859 }
1860 }
1861 #endif
1862
1863 if(SSL_SET_OPTION(key)) {
1864 infof(data, "WARNING: SSL: CURLOPT_SSLKEY is ignored by Secure "
1865 "Transport. The private key must be in the Keychain.");
1866 }
1867
1868 if(ssl_cert || ssl_cert_blob) {
1869 bool is_cert_data = ssl_cert_blob != NULL;
1870 bool is_cert_file = (!is_cert_data) && is_file(ssl_cert);
1871 SecIdentityRef cert_and_key = NULL;
1872
1873 /* User wants to authenticate with a client cert. Look for it. Assume that
1874 the user wants to use an identity loaded from the Keychain. If not, try
1875 it as a file on disk */
1876
1877 if(!is_cert_data)
1878 err = CopyIdentityWithLabel(ssl_cert, &cert_and_key);
1879 else
1880 err = !noErr;
1881 if((err != noErr) && (is_cert_file || is_cert_data)) {
1882 if(!SSL_SET_OPTION(cert_type))
1883 infof(data, "SSL: Certificate type not set, assuming "
1884 "PKCS#12 format.");
1885 else if(!strcasecompare(SSL_SET_OPTION(cert_type), "P12")) {
1886 failf(data, "SSL: The Security framework only supports "
1887 "loading identities that are in PKCS#12 format.");
1888 return CURLE_SSL_CERTPROBLEM;
1889 }
1890
1891 err = CopyIdentityFromPKCS12File(ssl_cert, ssl_cert_blob,
1892 SSL_SET_OPTION(key_passwd),
1893 &cert_and_key);
1894 }
1895
1896 if(err == noErr && cert_and_key) {
1897 SecCertificateRef cert = NULL;
1898 CFTypeRef certs_c[1];
1899 CFArrayRef certs;
1900
1901 /* If we found one, print it out: */
1902 err = SecIdentityCopyCertificate(cert_and_key, &cert);
1903 if(err == noErr) {
1904 char *certp;
1905 CURLcode result = CopyCertSubject(data, cert, &certp);
1906 if(!result) {
1907 infof(data, "Client certificate: %s", certp);
1908 free(certp);
1909 }
1910
1911 CFRelease(cert);
1912 if(result == CURLE_PEER_FAILED_VERIFICATION)
1913 return CURLE_SSL_CERTPROBLEM;
1914 if(result)
1915 return result;
1916 }
1917 certs_c[0] = cert_and_key;
1918 certs = CFArrayCreate(NULL, (const void **)certs_c, 1L,
1919 &kCFTypeArrayCallBacks);
1920 err = SSLSetCertificate(backend->ssl_ctx, certs);
1921 if(certs)
1922 CFRelease(certs);
1923 if(err != noErr) {
1924 failf(data, "SSL: SSLSetCertificate() failed: OSStatus %d", err);
1925 return CURLE_SSL_CERTPROBLEM;
1926 }
1927 CFRelease(cert_and_key);
1928 }
1929 else {
1930 const char *cert_showfilename_error =
1931 is_cert_data ? "(memory blob)" : ssl_cert;
1932
1933 switch(err) {
1934 case errSecAuthFailed: case -25264: /* errSecPkcs12VerifyFailure */
1935 failf(data, "SSL: Incorrect password for the certificate \"%s\" "
1936 "and its private key.", cert_showfilename_error);
1937 break;
1938 case -26275: /* errSecDecode */ case -25257: /* errSecUnknownFormat */
1939 failf(data, "SSL: Couldn't make sense of the data in the "
1940 "certificate \"%s\" and its private key.",
1941 cert_showfilename_error);
1942 break;
1943 case -25260: /* errSecPassphraseRequired */
1944 failf(data, "SSL The certificate \"%s\" requires a password.",
1945 cert_showfilename_error);
1946 break;
1947 case errSecItemNotFound:
1948 failf(data, "SSL: Can't find the certificate \"%s\" and its private "
1949 "key in the Keychain.", cert_showfilename_error);
1950 break;
1951 default:
1952 failf(data, "SSL: Can't load the certificate \"%s\" and its private "
1953 "key: OSStatus %d", cert_showfilename_error, err);
1954 break;
1955 }
1956 return CURLE_SSL_CERTPROBLEM;
1957 }
1958 }
1959
1960 /* SSL always tries to verify the peer, this only says whether it should
1961 * fail to connect if the verification fails, or if it should continue
1962 * anyway. In the latter case the result of the verification is checked with
1963 * SSL_get_verify_result() below. */
1964 #if CURL_BUILD_MAC_10_6 || CURL_BUILD_IOS
1965 /* Snow Leopard introduced the SSLSetSessionOption() function, but due to
1966 a library bug with the way the kSSLSessionOptionBreakOnServerAuth flag
1967 works, it doesn't work as expected under Snow Leopard, Lion or
1968 Mountain Lion.
1969 So we need to call SSLSetEnableCertVerify() on those older cats in order
1970 to disable certificate validation if the user turned that off.
1971 (SecureTransport will always validate the certificate chain by
1972 default.)
1973 Note:
1974 Darwin 11.x.x is Lion (10.7)
1975 Darwin 12.x.x is Mountain Lion (10.8)
1976 Darwin 13.x.x is Mavericks (10.9)
1977 Darwin 14.x.x is Yosemite (10.10)
1978 Darwin 15.x.x is El Capitan (10.11)
1979 */
1980 #if CURL_BUILD_MAC
1981 if(SSLSetSessionOption != NULL && darwinver_maj >= 13) {
1982 #else
1983 if(SSLSetSessionOption != NULL) {
1984 #endif /* CURL_BUILD_MAC */
1985 bool break_on_auth = !conn->ssl_config.verifypeer ||
1986 ssl_cafile || ssl_cablob;
1987 err = SSLSetSessionOption(backend->ssl_ctx,
1988 kSSLSessionOptionBreakOnServerAuth,
1989 break_on_auth);
1990 if(err != noErr) {
1991 failf(data, "SSL: SSLSetSessionOption() failed: OSStatus %d", err);
1992 return CURLE_SSL_CONNECT_ERROR;
1993 }
1994 }
1995 else {
1996 #if CURL_SUPPORT_MAC_10_8
1997 err = SSLSetEnableCertVerify(backend->ssl_ctx,
1998 conn->ssl_config.verifypeer?true:false);
1999 if(err != noErr) {
2000 failf(data, "SSL: SSLSetEnableCertVerify() failed: OSStatus %d", err);
2001 return CURLE_SSL_CONNECT_ERROR;
2002 }
2003 #endif /* CURL_SUPPORT_MAC_10_8 */
2004 }
2005 #else
2006 err = SSLSetEnableCertVerify(backend->ssl_ctx,
2007 conn->ssl_config.verifypeer?true:false);
2008 if(err != noErr) {
2009 failf(data, "SSL: SSLSetEnableCertVerify() failed: OSStatus %d", err);
2010 return CURLE_SSL_CONNECT_ERROR;
2011 }
2012 #endif /* CURL_BUILD_MAC_10_6 || CURL_BUILD_IOS */
2013
2014 if((ssl_cafile || ssl_cablob) && verifypeer) {
2015 bool is_cert_data = ssl_cablob != NULL;
2016 bool is_cert_file = (!is_cert_data) && is_file(ssl_cafile);
2017
2018 if(!(is_cert_file || is_cert_data)) {
2019 failf(data, "SSL: can't load CA certificate file %s",
2020 ssl_cafile ? ssl_cafile : "(blob memory)");
2021 return CURLE_SSL_CACERT_BADFILE;
2022 }
2023 }
2024
2025 /* Configure hostname check. SNI is used if available.
2026 * Both hostname check and SNI require SSLSetPeerDomainName().
2027 * Also: the verifyhost setting influences SNI usage */
2028 if(conn->ssl_config.verifyhost) {
2029 err = SSLSetPeerDomainName(backend->ssl_ctx, hostname,
2030 strlen(hostname));
2031
2032 if(err != noErr) {
2033 infof(data, "WARNING: SSL: SSLSetPeerDomainName() failed: OSStatus %d",
2034 err);
2035 }
2036
2037 if((Curl_inet_pton(AF_INET, hostname, &addr))
2038 #ifdef ENABLE_IPV6
2039 || (Curl_inet_pton(AF_INET6, hostname, &addr))
2040 #endif
2041 ) {
2042 infof(data, "WARNING: using IP address, SNI is being disabled by "
2043 "the OS.");
2044 }
2045 }
2046 else {
2047 infof(data, "WARNING: disabling hostname validation also disables SNI.");
2048 }
2049
2050 ciphers = SSL_CONN_CONFIG(cipher_list);
2051 if(ciphers) {
2052 err = sectransp_set_selected_ciphers(data, backend->ssl_ctx, ciphers);
2053 }
2054 else {
2055 err = sectransp_set_default_ciphers(data, backend->ssl_ctx);
2056 }
2057 if(err != noErr) {
2058 failf(data, "SSL: Unable to set ciphers for SSL/TLS handshake. "
2059 "Error code: %d", err);
2060 return CURLE_SSL_CIPHER;
2061 }
2062
2063 #if CURL_BUILD_MAC_10_9 || CURL_BUILD_IOS_7
2064 /* We want to enable 1/n-1 when using a CBC cipher unless the user
2065 specifically doesn't want us doing that: */
2066 if(SSLSetSessionOption != NULL) {
2067 SSLSetSessionOption(backend->ssl_ctx, kSSLSessionOptionSendOneByteRecord,
2068 !SSL_SET_OPTION(enable_beast));
2069 SSLSetSessionOption(backend->ssl_ctx, kSSLSessionOptionFalseStart,
2070 data->set.ssl.falsestart); /* false start support */
2071 }
2072 #endif /* CURL_BUILD_MAC_10_9 || CURL_BUILD_IOS_7 */
2073
2074 /* Check if there's a cached ID we can/should use here! */
2075 if(SSL_SET_OPTION(primary.sessionid)) {
2076 char *ssl_sessionid;
2077 size_t ssl_sessionid_len;
2078
2079 Curl_ssl_sessionid_lock(data);
2080 if(!Curl_ssl_getsessionid(data, conn, isproxy, (void **)&ssl_sessionid,
2081 &ssl_sessionid_len, sockindex)) {
2082 /* we got a session id, use it! */
2083 err = SSLSetPeerID(backend->ssl_ctx, ssl_sessionid, ssl_sessionid_len);
2084 Curl_ssl_sessionid_unlock(data);
2085 if(err != noErr) {
2086 failf(data, "SSL: SSLSetPeerID() failed: OSStatus %d", err);
2087 return CURLE_SSL_CONNECT_ERROR;
2088 }
2089 /* Informational message */
2090 infof(data, "SSL re-using session ID");
2091 }
2092 /* If there isn't one, then let's make one up! This has to be done prior
2093 to starting the handshake. */
2094 else {
2095 CURLcode result;
2096 ssl_sessionid =
2097 aprintf("%s:%d:%d:%s:%ld",
2098 ssl_cafile ? ssl_cafile : "(blob memory)",
2099 verifypeer, SSL_CONN_CONFIG(verifyhost), hostname, port);
2100 ssl_sessionid_len = strlen(ssl_sessionid);
2101
2102 err = SSLSetPeerID(backend->ssl_ctx, ssl_sessionid, ssl_sessionid_len);
2103 if(err != noErr) {
2104 Curl_ssl_sessionid_unlock(data);
2105 failf(data, "SSL: SSLSetPeerID() failed: OSStatus %d", err);
2106 return CURLE_SSL_CONNECT_ERROR;
2107 }
2108
2109 result = Curl_ssl_addsessionid(data, conn, isproxy, ssl_sessionid,
2110 ssl_sessionid_len, sockindex);
2111 Curl_ssl_sessionid_unlock(data);
2112 if(result) {
2113 failf(data, "failed to store ssl session");
2114 return result;
2115 }
2116 }
2117 }
2118
2119 err = SSLSetIOFuncs(backend->ssl_ctx, SocketRead, SocketWrite);
2120 if(err != noErr) {
2121 failf(data, "SSL: SSLSetIOFuncs() failed: OSStatus %d", err);
2122 return CURLE_SSL_CONNECT_ERROR;
2123 }
2124
2125 /* pass the raw socket into the SSL layers */
2126 /* We need to store the FD in a constant memory address, because
2127 * SSLSetConnection() will not copy that address. I've found that
2128 * conn->sock[sockindex] may change on its own. */
2129 backend->ssl_sockfd = sockfd;
2130 err = SSLSetConnection(backend->ssl_ctx, connssl);
2131 if(err != noErr) {
2132 failf(data, "SSL: SSLSetConnection() failed: %d", err);
2133 return CURLE_SSL_CONNECT_ERROR;
2134 }
2135
2136 connssl->connecting_state = ssl_connect_2;
2137 return CURLE_OK;
2138 }
2139
2140 static long pem_to_der(const char *in, unsigned char **out, size_t *outlen)
2141 {
2142 char *sep_start, *sep_end, *cert_start, *cert_end;
2143 size_t i, j, err;
2144 size_t len;
2145 unsigned char *b64;
2146
2147 /* Jump through the separators at the beginning of the certificate. */
2148 sep_start = strstr(in, "-----");
2149 if(!sep_start)
2150 return 0;
2151 cert_start = strstr(sep_start + 1, "-----");
2152 if(!cert_start)
2153 return -1;
2154
2155 cert_start += 5;
2156
2157 /* Find separator after the end of the certificate. */
2158 cert_end = strstr(cert_start, "-----");
2159 if(!cert_end)
2160 return -1;
2161
2162 sep_end = strstr(cert_end + 1, "-----");
2163 if(!sep_end)
2164 return -1;
2165 sep_end += 5;
2166
2167 len = cert_end - cert_start;
2168 b64 = malloc(len + 1);
2169 if(!b64)
2170 return -1;
2171
2172 /* Create base64 string without linefeeds. */
2173 for(i = 0, j = 0; i < len; i++) {
2174 if(cert_start[i] != '\r' && cert_start[i] != '\n')
2175 b64[j++] = cert_start[i];
2176 }
2177 b64[j] = '\0';
2178
2179 err = Curl_base64_decode((const char *)b64, out, outlen);
2180 free(b64);
2181 if(err) {
2182 free(*out);
2183 return -1;
2184 }
2185
2186 return sep_end - in;
2187 }
2188
2189 static int read_cert(const char *file, unsigned char **out, size_t *outlen)
2190 {
2191 int fd;
2192 ssize_t n, len = 0, cap = 512;
2193 unsigned char buf[512], *data;
2194
2195 fd = open(file, 0);
2196 if(fd < 0)
2197 return -1;
2198
2199 data = malloc(cap);
2200 if(!data) {
2201 close(fd);
2202 return -1;
2203 }
2204
2205 for(;;) {
2206 n = read(fd, buf, sizeof(buf));
2207 if(n < 0) {
2208 close(fd);
2209 free(data);
2210 return -1;
2211 }
2212 else if(n == 0) {
2213 close(fd);
2214 break;
2215 }
2216
2217 if(len + n >= cap) {
2218 cap *= 2;
2219 data = Curl_saferealloc(data, cap);
2220 if(!data) {
2221 close(fd);
2222 return -1;
2223 }
2224 }
2225
2226 memcpy(data + len, buf, n);
2227 len += n;
2228 }
2229 data[len] = '\0';
2230
2231 *out = data;
2232 *outlen = len;
2233
2234 return 0;
2235 }
2236
2237 static int append_cert_to_array(struct Curl_easy *data,
2238 const unsigned char *buf, size_t buflen,
2239 CFMutableArrayRef array)
2240 {
2241 CFDataRef certdata = CFDataCreate(kCFAllocatorDefault, buf, buflen);
2242 char *certp;
2243 CURLcode result;
2244 if(!certdata) {
2245 failf(data, "SSL: failed to allocate array for CA certificate");
2246 return CURLE_OUT_OF_MEMORY;
2247 }
2248
2249 SecCertificateRef cacert =
2250 SecCertificateCreateWithData(kCFAllocatorDefault, certdata);
2251 CFRelease(certdata);
2252 if(!cacert) {
2253 failf(data, "SSL: failed to create SecCertificate from CA certificate");
2254 return CURLE_SSL_CACERT_BADFILE;
2255 }
2256
2257 /* Check if cacert is valid. */
2258 result = CopyCertSubject(data, cacert, &certp);
2259 switch(result) {
2260 case CURLE_OK:
2261 break;
2262 case CURLE_PEER_FAILED_VERIFICATION:
2263 return CURLE_SSL_CACERT_BADFILE;
2264 case CURLE_OUT_OF_MEMORY:
2265 default:
2266 return result;
2267 }
2268 free(certp);
2269
2270 CFArrayAppendValue(array, cacert);
2271 CFRelease(cacert);
2272
2273 return CURLE_OK;
2274 }
2275
2276 static CURLcode verify_cert_buf(struct Curl_easy *data,
2277 const unsigned char *certbuf, size_t buflen,
2278 SSLContextRef ctx)
2279 {
2280 int n = 0, rc;
2281 long res;
2282 unsigned char *der;
2283 size_t derlen, offset = 0;
2284
2285 /*
2286 * Certbuf now contains the contents of the certificate file, which can be
2287 * - a single DER certificate,
2288 * - a single PEM certificate or
2289 * - a bunch of PEM certificates (certificate bundle).
2290 *
2291 * Go through certbuf, and convert any PEM certificate in it into DER
2292 * format.
2293 */
2294 CFMutableArrayRef array = CFArrayCreateMutable(kCFAllocatorDefault, 0,
2295 &kCFTypeArrayCallBacks);
2296 if(!array) {
2297 failf(data, "SSL: out of memory creating CA certificate array");
2298 return CURLE_OUT_OF_MEMORY;
2299 }
2300
2301 while(offset < buflen) {
2302 n++;
2303
2304 /*
2305 * Check if the certificate is in PEM format, and convert it to DER. If
2306 * this fails, we assume the certificate is in DER format.
2307 */
2308 res = pem_to_der((const char *)certbuf + offset, &der, &derlen);
2309 if(res < 0) {
2310 CFRelease(array);
2311 failf(data, "SSL: invalid CA certificate #%d (offset %zu) in bundle",
2312 n, offset);
2313 return CURLE_SSL_CACERT_BADFILE;
2314 }
2315 offset += res;
2316
2317 if(res == 0 && offset == 0) {
2318 /* This is not a PEM file, probably a certificate in DER format. */
2319 rc = append_cert_to_array(data, certbuf, buflen, array);
2320 if(rc != CURLE_OK) {
2321 CFRelease(array);
2322 return rc;
2323 }
2324 break;
2325 }
2326 else if(res == 0) {
2327 /* No more certificates in the bundle. */
2328 break;
2329 }
2330
2331 rc = append_cert_to_array(data, der, derlen, array);
2332 free(der);
2333 if(rc != CURLE_OK) {
2334 CFRelease(array);
2335 return rc;
2336 }
2337 }
2338
2339 SecTrustRef trust;
2340 OSStatus ret = SSLCopyPeerTrust(ctx, &trust);
2341 if(!trust) {
2342 failf(data, "SSL: error getting certificate chain");
2343 CFRelease(array);
2344 return CURLE_PEER_FAILED_VERIFICATION;
2345 }
2346 else if(ret != noErr) {
2347 CFRelease(array);
2348 failf(data, "SSLCopyPeerTrust() returned error %d", ret);
2349 return CURLE_PEER_FAILED_VERIFICATION;
2350 }
2351
2352 ret = SecTrustSetAnchorCertificates(trust, array);
2353 if(ret != noErr) {
2354 CFRelease(array);
2355 CFRelease(trust);
2356 failf(data, "SecTrustSetAnchorCertificates() returned error %d", ret);
2357 return CURLE_PEER_FAILED_VERIFICATION;
2358 }
2359 ret = SecTrustSetAnchorCertificatesOnly(trust, true);
2360 if(ret != noErr) {
2361 CFRelease(array);
2362 CFRelease(trust);
2363 failf(data, "SecTrustSetAnchorCertificatesOnly() returned error %d", ret);
2364 return CURLE_PEER_FAILED_VERIFICATION;
2365 }
2366
2367 SecTrustResultType trust_eval = 0;
2368 ret = SecTrustEvaluate(trust, &trust_eval);
2369 CFRelease(array);
2370 CFRelease(trust);
2371 if(ret != noErr) {
2372 failf(data, "SecTrustEvaluate() returned error %d", ret);
2373 return CURLE_PEER_FAILED_VERIFICATION;
2374 }
2375
2376 switch(trust_eval) {
2377 case kSecTrustResultUnspecified:
2378 case kSecTrustResultProceed:
2379 return CURLE_OK;
2380
2381 case kSecTrustResultRecoverableTrustFailure:
2382 case kSecTrustResultDeny:
2383 default:
2384 failf(data, "SSL: certificate verification failed (result: %d)",
2385 trust_eval);
2386 return CURLE_PEER_FAILED_VERIFICATION;
2387 }
2388 }
2389
2390 static CURLcode verify_cert(struct Curl_easy *data, const char *cafile,
2391 const struct curl_blob *ca_info_blob,
2392 SSLContextRef ctx)
2393 {
2394 int result;
2395 unsigned char *certbuf;
2396 size_t buflen;
2397
2398 if(ca_info_blob) {
2399 certbuf = (unsigned char *)malloc(ca_info_blob->len + 1);
2400 if(!certbuf) {
2401 return CURLE_OUT_OF_MEMORY;
2402 }
2403 buflen = ca_info_blob->len;
2404 memcpy(certbuf, ca_info_blob->data, ca_info_blob->len);
2405 certbuf[ca_info_blob->len]='\0';
2406 }
2407 else if(cafile) {
2408 if(read_cert(cafile, &certbuf, &buflen) < 0) {
2409 failf(data, "SSL: failed to read or invalid CA certificate");
2410 return CURLE_SSL_CACERT_BADFILE;
2411 }
2412 }
2413 else
2414 return CURLE_SSL_CACERT_BADFILE;
2415
2416 result = verify_cert_buf(data, certbuf, buflen, ctx);
2417 free(certbuf);
2418 return result;
2419 }
2420
2421
2422 #ifdef SECTRANSP_PINNEDPUBKEY
2423 static CURLcode pkp_pin_peer_pubkey(struct Curl_easy *data,
2424 SSLContextRef ctx,
2425 const char *pinnedpubkey)
2426 { /* Scratch */
2427 size_t pubkeylen, realpubkeylen, spkiHeaderLength = 24;
2428 unsigned char *pubkey = NULL, *realpubkey = NULL;
2429 const unsigned char *spkiHeader = NULL;
2430 CFDataRef publicKeyBits = NULL;
2431
2432 /* Result is returned to caller */
2433 CURLcode result = CURLE_SSL_PINNEDPUBKEYNOTMATCH;
2434
2435 /* if a path wasn't specified, don't pin */
2436 if(!pinnedpubkey)
2437 return CURLE_OK;
2438
2439
2440 if(!ctx)
2441 return result;
2442
2443 do {
2444 SecTrustRef trust;
2445 OSStatus ret = SSLCopyPeerTrust(ctx, &trust);
2446 if(ret != noErr || !trust)
2447 break;
2448
2449 SecKeyRef keyRef = SecTrustCopyPublicKey(trust);
2450 CFRelease(trust);
2451 if(!keyRef)
2452 break;
2453
2454 #ifdef SECTRANSP_PINNEDPUBKEY_V1
2455
2456 publicKeyBits = SecKeyCopyExternalRepresentation(keyRef, NULL);
2457 CFRelease(keyRef);
2458 if(!publicKeyBits)
2459 break;
2460
2461 #elif SECTRANSP_PINNEDPUBKEY_V2
2462
2463 OSStatus success = SecItemExport(keyRef, kSecFormatOpenSSL, 0, NULL,
2464 &publicKeyBits);
2465 CFRelease(keyRef);
2466 if(success != errSecSuccess || !publicKeyBits)
2467 break;
2468
2469 #endif /* SECTRANSP_PINNEDPUBKEY_V2 */
2470
2471 pubkeylen = CFDataGetLength(publicKeyBits);
2472 pubkey = (unsigned char *)CFDataGetBytePtr(publicKeyBits);
2473
2474 switch(pubkeylen) {
2475 case 526:
2476 /* 4096 bit RSA pubkeylen == 526 */
2477 spkiHeader = rsa4096SpkiHeader;
2478 break;
2479 case 270:
2480 /* 2048 bit RSA pubkeylen == 270 */
2481 spkiHeader = rsa2048SpkiHeader;
2482 break;
2483 #ifdef SECTRANSP_PINNEDPUBKEY_V1
2484 case 65:
2485 /* ecDSA secp256r1 pubkeylen == 65 */
2486 spkiHeader = ecDsaSecp256r1SpkiHeader;
2487 spkiHeaderLength = 26;
2488 break;
2489 case 97:
2490 /* ecDSA secp384r1 pubkeylen == 97 */
2491 spkiHeader = ecDsaSecp384r1SpkiHeader;
2492 spkiHeaderLength = 23;
2493 break;
2494 default:
2495 infof(data, "SSL: unhandled public key length: %d", pubkeylen);
2496 #elif SECTRANSP_PINNEDPUBKEY_V2
2497 default:
2498 /* ecDSA secp256r1 pubkeylen == 91 header already included?
2499 * ecDSA secp384r1 header already included too
2500 * we assume rest of algorithms do same, so do nothing
2501 */
2502 result = Curl_pin_peer_pubkey(data, pinnedpubkey, pubkey,
2503 pubkeylen);
2504 #endif /* SECTRANSP_PINNEDPUBKEY_V2 */
2505 continue; /* break from loop */
2506 }
2507
2508 realpubkeylen = pubkeylen + spkiHeaderLength;
2509 realpubkey = malloc(realpubkeylen);
2510 if(!realpubkey)
2511 break;
2512
2513 memcpy(realpubkey, spkiHeader, spkiHeaderLength);
2514 memcpy(realpubkey + spkiHeaderLength, pubkey, pubkeylen);
2515
2516 result = Curl_pin_peer_pubkey(data, pinnedpubkey, realpubkey,
2517 realpubkeylen);
2518
2519 } while(0);
2520
2521 Curl_safefree(realpubkey);
2522 if(publicKeyBits != NULL)
2523 CFRelease(publicKeyBits);
2524
2525 return result;
2526 }
2527 #endif /* SECTRANSP_PINNEDPUBKEY */
2528
2529 static CURLcode
2530 sectransp_connect_step2(struct Curl_easy *data, struct connectdata *conn,
2531 int sockindex)
2532 {
2533 struct ssl_connect_data *connssl = &conn->ssl[sockindex];
2534 struct ssl_backend_data *backend = connssl->backend;
2535 OSStatus err;
2536 SSLCipherSuite cipher;
2537 SSLProtocol protocol = 0;
2538 const char * const hostname = SSL_HOST_NAME();
2539
2540 DEBUGASSERT(ssl_connect_2 == connssl->connecting_state
2541 || ssl_connect_2_reading == connssl->connecting_state
2542 || ssl_connect_2_writing == connssl->connecting_state);
2543
2544 /* Here goes nothing: */
2545 err = SSLHandshake(backend->ssl_ctx);
2546
2547 if(err != noErr) {
2548 switch(err) {
2549 case errSSLWouldBlock: /* they're not done with us yet */
2550 connssl->connecting_state = backend->ssl_direction ?
2551 ssl_connect_2_writing : ssl_connect_2_reading;
2552 return CURLE_OK;
2553
2554 /* The below is errSSLServerAuthCompleted; it's not defined in
2555 Leopard's headers */
2556 case -9841:
2557 if((SSL_CONN_CONFIG(CAfile) || SSL_CONN_CONFIG(ca_info_blob)) &&
2558 SSL_CONN_CONFIG(verifypeer)) {
2559 CURLcode result = verify_cert(data, SSL_CONN_CONFIG(CAfile),
2560 SSL_CONN_CONFIG(ca_info_blob),
2561 backend->ssl_ctx);
2562 if(result)
2563 return result;
2564 }
2565 /* the documentation says we need to call SSLHandshake() again */
2566 return sectransp_connect_step2(data, conn, sockindex);
2567
2568 /* Problem with encrypt / decrypt */
2569 case errSSLPeerDecodeError:
2570 failf(data, "Decode failed");
2571 break;
2572 case errSSLDecryptionFail:
2573 case errSSLPeerDecryptionFail:
2574 failf(data, "Decryption failed");
2575 break;
2576 case errSSLPeerDecryptError:
2577 failf(data, "A decryption error occurred");
2578 break;
2579 case errSSLBadCipherSuite:
2580 failf(data, "A bad SSL cipher suite was encountered");
2581 break;
2582 case errSSLCrypto:
2583 failf(data, "An underlying cryptographic error was encountered");
2584 break;
2585 #if CURL_BUILD_MAC_10_11 || CURL_BUILD_IOS_9
2586 case errSSLWeakPeerEphemeralDHKey:
2587 failf(data, "Indicates a weak ephemeral Diffie-Hellman key");
2588 break;
2589 #endif
2590
2591 /* Problem with the message record validation */
2592 case errSSLBadRecordMac:
2593 case errSSLPeerBadRecordMac:
2594 failf(data, "A record with a bad message authentication code (MAC) "
2595 "was encountered");
2596 break;
2597 case errSSLRecordOverflow:
2598 case errSSLPeerRecordOverflow:
2599 failf(data, "A record overflow occurred");
2600 break;
2601
2602 /* Problem with zlib decompression */
2603 case errSSLPeerDecompressFail:
2604 failf(data, "Decompression failed");
2605 break;
2606
2607 /* Problem with access */
2608 case errSSLPeerAccessDenied:
2609 failf(data, "Access was denied");
2610 break;
2611 case errSSLPeerInsufficientSecurity:
2612 failf(data, "There is insufficient security for this operation");
2613 break;
2614
2615 /* These are all certificate problems with the server: */
2616 case errSSLXCertChainInvalid:
2617 failf(data, "SSL certificate problem: Invalid certificate chain");
2618 return CURLE_PEER_FAILED_VERIFICATION;
2619 case errSSLUnknownRootCert:
2620 failf(data, "SSL certificate problem: Untrusted root certificate");
2621 return CURLE_PEER_FAILED_VERIFICATION;
2622 case errSSLNoRootCert:
2623 failf(data, "SSL certificate problem: No root certificate");
2624 return CURLE_PEER_FAILED_VERIFICATION;
2625 case errSSLCertNotYetValid:
2626 failf(data, "SSL certificate problem: The certificate chain had a "
2627 "certificate that is not yet valid");
2628 return CURLE_PEER_FAILED_VERIFICATION;
2629 case errSSLCertExpired:
2630 case errSSLPeerCertExpired:
2631 failf(data, "SSL certificate problem: Certificate chain had an "
2632 "expired certificate");
2633 return CURLE_PEER_FAILED_VERIFICATION;
2634 case errSSLBadCert:
2635 case errSSLPeerBadCert:
2636 failf(data, "SSL certificate problem: Couldn't understand the server "
2637 "certificate format");
2638 return CURLE_PEER_FAILED_VERIFICATION;
2639 case errSSLPeerUnsupportedCert:
2640 failf(data, "SSL certificate problem: An unsupported certificate "
2641 "format was encountered");
2642 return CURLE_PEER_FAILED_VERIFICATION;
2643 case errSSLPeerCertRevoked:
2644 failf(data, "SSL certificate problem: The certificate was revoked");
2645 return CURLE_PEER_FAILED_VERIFICATION;
2646 case errSSLPeerCertUnknown:
2647 failf(data, "SSL certificate problem: The certificate is unknown");
2648 return CURLE_PEER_FAILED_VERIFICATION;
2649
2650 /* These are all certificate problems with the client: */
2651 case errSecAuthFailed:
2652 failf(data, "SSL authentication failed");
2653 break;
2654 case errSSLPeerHandshakeFail:
2655 failf(data, "SSL peer handshake failed, the server most likely "
2656 "requires a client certificate to connect");
2657 break;
2658 case errSSLPeerUnknownCA:
2659 failf(data, "SSL server rejected the client certificate due to "
2660 "the certificate being signed by an unknown certificate "
2661 "authority");
2662 break;
2663
2664 /* This error is raised if the server's cert didn't match the server's
2665 host name: */
2666 case errSSLHostNameMismatch:
2667 failf(data, "SSL certificate peer verification failed, the "
2668 "certificate did not match \"%s\"\n", conn->host.dispname);
2669 return CURLE_PEER_FAILED_VERIFICATION;
2670
2671 /* Problem with SSL / TLS negotiation */
2672 case errSSLNegotiation:
2673 failf(data, "Could not negotiate an SSL cipher suite with the server");
2674 break;
2675 case errSSLBadConfiguration:
2676 failf(data, "A configuration error occurred");
2677 break;
2678 case errSSLProtocol:
2679 failf(data, "SSL protocol error");
2680 break;
2681 case errSSLPeerProtocolVersion:
2682 failf(data, "A bad protocol version was encountered");
2683 break;
2684 case errSSLPeerNoRenegotiation:
2685 failf(data, "No renegotiation is allowed");
2686 break;
2687
2688 /* Generic handshake errors: */
2689 case errSSLConnectionRefused:
2690 failf(data, "Server dropped the connection during the SSL handshake");
2691 break;
2692 case errSSLClosedAbort:
2693 failf(data, "Server aborted the SSL handshake");
2694 break;
2695 case errSSLClosedGraceful:
2696 failf(data, "The connection closed gracefully");
2697 break;
2698 case errSSLClosedNoNotify:
2699 failf(data, "The server closed the session with no notification");
2700 break;
2701 /* Sometimes paramErr happens with buggy ciphers: */
2702 case paramErr:
2703 case errSSLInternal:
2704 case errSSLPeerInternalError:
2705 failf(data, "Internal SSL engine error encountered during the "
2706 "SSL handshake");
2707 break;
2708 case errSSLFatalAlert:
2709 failf(data, "Fatal SSL engine error encountered during the SSL "
2710 "handshake");
2711 break;
2712 /* Unclassified error */
2713 case errSSLBufferOverflow:
2714 failf(data, "An insufficient buffer was provided");
2715 break;
2716 case errSSLIllegalParam:
2717 failf(data, "An illegal parameter was encountered");
2718 break;
2719 case errSSLModuleAttach:
2720 failf(data, "Module attach failure");
2721 break;
2722 case errSSLSessionNotFound:
2723 failf(data, "An attempt to restore an unknown session failed");
2724 break;
2725 case errSSLPeerExportRestriction:
2726 failf(data, "An export restriction occurred");
2727 break;
2728 case errSSLPeerUserCancelled:
2729 failf(data, "The user canceled the operation");
2730 break;
2731 case errSSLPeerUnexpectedMsg:
2732 failf(data, "Peer rejected unexpected message");
2733 break;
2734 #if CURL_BUILD_MAC_10_11 || CURL_BUILD_IOS_9
2735 /* Treaing non-fatal error as fatal like before */
2736 case errSSLClientHelloReceived:
2737 failf(data, "A non-fatal result for providing a server name "
2738 "indication");
2739 break;
2740 #endif
2741
2742 /* Error codes defined in the enum but should never be returned.
2743 We list them here just in case. */
2744 #if CURL_BUILD_MAC_10_6
2745 /* Only returned when kSSLSessionOptionBreakOnCertRequested is set */
2746 case errSSLClientCertRequested:
2747 failf(data, "Server requested a client certificate during the "
2748 "handshake");
2749 return CURLE_SSL_CLIENTCERT;
2750 #endif
2751 #if CURL_BUILD_MAC_10_9
2752 /* Alias for errSSLLast, end of error range */
2753 case errSSLUnexpectedRecord:
2754 failf(data, "Unexpected (skipped) record in DTLS");
2755 break;
2756 #endif
2757 default:
2758 /* May also return codes listed in Security Framework Result Codes */
2759 failf(data, "Unknown SSL protocol error in connection to %s:%d",
2760 hostname, err);
2761 break;
2762 }
2763 return CURLE_SSL_CONNECT_ERROR;
2764 }
2765 else {
2766 /* we have been connected fine, we're not waiting for anything else. */
2767 connssl->connecting_state = ssl_connect_3;
2768
2769 #ifdef SECTRANSP_PINNEDPUBKEY
2770 if(data->set.str[STRING_SSL_PINNEDPUBLICKEY]) {
2771 CURLcode result =
2772 pkp_pin_peer_pubkey(data, backend->ssl_ctx,
2773 data->set.str[STRING_SSL_PINNEDPUBLICKEY]);
2774 if(result) {
2775 failf(data, "SSL: public key does not match pinned public key!");
2776 return result;
2777 }
2778 }
2779 #endif /* SECTRANSP_PINNEDPUBKEY */
2780
2781 /* Informational message */
2782 (void)SSLGetNegotiatedCipher(backend->ssl_ctx, &cipher);
2783 (void)SSLGetNegotiatedProtocolVersion(backend->ssl_ctx, &protocol);
2784 switch(protocol) {
2785 case kSSLProtocol2:
2786 infof(data, "SSL 2.0 connection using %s",
2787 TLSCipherNameForNumber(cipher));
2788 break;
2789 case kSSLProtocol3:
2790 infof(data, "SSL 3.0 connection using %s",
2791 TLSCipherNameForNumber(cipher));
2792 break;
2793 case kTLSProtocol1:
2794 infof(data, "TLS 1.0 connection using %s",
2795 TLSCipherNameForNumber(cipher));
2796 break;
2797 #if CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS
2798 case kTLSProtocol11:
2799 infof(data, "TLS 1.1 connection using %s",
2800 TLSCipherNameForNumber(cipher));
2801 break;
2802 case kTLSProtocol12:
2803 infof(data, "TLS 1.2 connection using %s",
2804 TLSCipherNameForNumber(cipher));
2805 break;
2806 #endif /* CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS */
2807 #if CURL_BUILD_MAC_10_13 || CURL_BUILD_IOS_11
2808 case kTLSProtocol13:
2809 infof(data, "TLS 1.3 connection using %s",
2810 TLSCipherNameForNumber(cipher));
2811 break;
2812 #endif /* CURL_BUILD_MAC_10_13 || CURL_BUILD_IOS_11 */
2813 default:
2814 infof(data, "Unknown protocol connection");
2815 break;
2816 }
2817
2818 #if(CURL_BUILD_MAC_10_13 || CURL_BUILD_IOS_11) && HAVE_BUILTIN_AVAILABLE == 1
2819 if(conn->bits.tls_enable_alpn) {
2820 if(__builtin_available(macOS 10.13.4, iOS 11, tvOS 11, *)) {
2821 CFArrayRef alpnArr = NULL;
2822 CFStringRef chosenProtocol = NULL;
2823 err = SSLCopyALPNProtocols(backend->ssl_ctx, &alpnArr);
2824
2825 if(err == noErr && alpnArr && CFArrayGetCount(alpnArr) >= 1)
2826 chosenProtocol = CFArrayGetValueAtIndex(alpnArr, 0);
2827
2828 #ifdef USE_HTTP2
2829 if(chosenProtocol &&
2830 !CFStringCompare(chosenProtocol, CFSTR(ALPN_H2), 0)) {
2831 conn->negnpn = CURL_HTTP_VERSION_2;
2832 }
2833 else
2834 #endif
2835 if(chosenProtocol &&
2836 !CFStringCompare(chosenProtocol, CFSTR(ALPN_HTTP_1_1), 0)) {
2837 conn->negnpn = CURL_HTTP_VERSION_1_1;
2838 }
2839 else
2840 infof(data, "ALPN, server did not agree to a protocol");
2841
2842 Curl_multiuse_state(data, conn->negnpn == CURL_HTTP_VERSION_2 ?
2843 BUNDLE_MULTIPLEX : BUNDLE_NO_MULTIUSE);
2844
2845 /* chosenProtocol is a reference to the string within alpnArr
2846 and doesn't need to be freed separately */
2847 if(alpnArr)
2848 CFRelease(alpnArr);
2849 }
2850 }
2851 #endif
2852
2853 return CURLE_OK;
2854 }
2855 }
2856
2857 #ifndef CURL_DISABLE_VERBOSE_STRINGS
2858 /* This should be called during step3 of the connection at the earliest */
2859 static void
2860 show_verbose_server_cert(struct Curl_easy *data,
2861 struct connectdata *conn,
2862 int sockindex)
2863 {
2864 struct ssl_connect_data *connssl = &conn->ssl[sockindex];
2865 struct ssl_backend_data *backend = connssl->backend;
2866 CFArrayRef server_certs = NULL;
2867 SecCertificateRef server_cert;
2868 OSStatus err;
2869 CFIndex i, count;
2870 SecTrustRef trust = NULL;
2871
2872 if(!backend->ssl_ctx)
2873 return;
2874
2875 #if CURL_BUILD_MAC_10_7 || CURL_BUILD_IOS
2876 #if CURL_BUILD_IOS
2877 #pragma unused(server_certs)
2878 err = SSLCopyPeerTrust(backend->ssl_ctx, &trust);
2879 /* For some reason, SSLCopyPeerTrust() can return noErr and yet return
2880 a null trust, so be on guard for that: */
2881 if(err == noErr && trust) {
2882 count = SecTrustGetCertificateCount(trust);
2883 for(i = 0L ; i < count ; i++) {
2884 CURLcode result;
2885 char *certp;
2886 server_cert = SecTrustGetCertificateAtIndex(trust, i);
2887 result = CopyCertSubject(data, server_cert, &certp);
2888 if(!result) {
2889 infof(data, "Server certificate: %s", certp);
2890 free(certp);
2891 }
2892 }
2893 CFRelease(trust);
2894 }
2895 #else
2896 /* SSLCopyPeerCertificates() is deprecated as of Mountain Lion.
2897 The function SecTrustGetCertificateAtIndex() is officially present
2898 in Lion, but it is unfortunately also present in Snow Leopard as
2899 private API and doesn't work as expected. So we have to look for
2900 a different symbol to make sure this code is only executed under
2901 Lion or later. */
2902 if(SecTrustEvaluateAsync != NULL) {
2903 #pragma unused(server_certs)
2904 err = SSLCopyPeerTrust(backend->ssl_ctx, &trust);
2905 /* For some reason, SSLCopyPeerTrust() can return noErr and yet return
2906 a null trust, so be on guard for that: */
2907 if(err == noErr && trust) {
2908 count = SecTrustGetCertificateCount(trust);
2909 for(i = 0L ; i < count ; i++) {
2910 char *certp;
2911 CURLcode result;
2912 server_cert = SecTrustGetCertificateAtIndex(trust, i);
2913 result = CopyCertSubject(data, server_cert, &certp);
2914 if(!result) {
2915 infof(data, "Server certificate: %s", certp);
2916 free(certp);
2917 }
2918 }
2919 CFRelease(trust);
2920 }
2921 }
2922 else {
2923 #if CURL_SUPPORT_MAC_10_8
2924 err = SSLCopyPeerCertificates(backend->ssl_ctx, &server_certs);
2925 /* Just in case SSLCopyPeerCertificates() returns null too... */
2926 if(err == noErr && server_certs) {
2927 count = CFArrayGetCount(server_certs);
2928 for(i = 0L ; i < count ; i++) {
2929 char *certp;
2930 CURLcode result;
2931 server_cert = (SecCertificateRef)CFArrayGetValueAtIndex(server_certs,
2932 i);
2933 result = CopyCertSubject(data, server_cert, &certp);
2934 if(!result) {
2935 infof(data, "Server certificate: %s", certp);
2936 free(certp);
2937 }
2938 }
2939 CFRelease(server_certs);
2940 }
2941 #endif /* CURL_SUPPORT_MAC_10_8 */
2942 }
2943 #endif /* CURL_BUILD_IOS */
2944 #else
2945 #pragma unused(trust)
2946 err = SSLCopyPeerCertificates(backend->ssl_ctx, &server_certs);
2947 if(err == noErr) {
2948 count = CFArrayGetCount(server_certs);
2949 for(i = 0L ; i < count ; i++) {
2950 CURLcode result;
2951 char *certp;
2952 server_cert = (SecCertificateRef)CFArrayGetValueAtIndex(server_certs, i);
2953 result = CopyCertSubject(data, server_cert, &certp);
2954 if(!result) {
2955 infof(data, "Server certificate: %s", certp);
2956 free(certp);
2957 }
2958 }
2959 CFRelease(server_certs);
2960 }
2961 #endif /* CURL_BUILD_MAC_10_7 || CURL_BUILD_IOS */
2962 }
2963 #endif /* !CURL_DISABLE_VERBOSE_STRINGS */
2964
2965 static CURLcode
2966 sectransp_connect_step3(struct Curl_easy *data, struct connectdata *conn,
2967 int sockindex)
2968 {
2969 struct ssl_connect_data *connssl = &conn->ssl[sockindex];
2970
2971 /* There is no step 3!
2972 * Well, okay, if verbose mode is on, let's print the details of the
2973 * server certificates. */
2974 #ifndef CURL_DISABLE_VERBOSE_STRINGS
2975 if(data->set.verbose)
2976 show_verbose_server_cert(data, conn, sockindex);
2977 #endif
2978
2979 connssl->connecting_state = ssl_connect_done;
2980 return CURLE_OK;
2981 }
2982
2983 static Curl_recv sectransp_recv;
2984 static Curl_send sectransp_send;
2985
2986 static CURLcode
2987 sectransp_connect_common(struct Curl_easy *data,
2988 struct connectdata *conn,
2989 int sockindex,
2990 bool nonblocking,
2991 bool *done)
2992 {
2993 CURLcode result;
2994 struct ssl_connect_data *connssl = &conn->ssl[sockindex];
2995 curl_socket_t sockfd = conn->sock[sockindex];
2996 int what;
2997
2998 /* check if the connection has already been established */
2999 if(ssl_connection_complete == connssl->state) {
3000 *done = TRUE;
3001 return CURLE_OK;
3002 }
3003
3004 if(ssl_connect_1 == connssl->connecting_state) {
3005 /* Find out how much more time we're allowed */
3006 const timediff_t timeout_ms = Curl_timeleft(data, NULL, TRUE);
3007
3008 if(timeout_ms < 0) {
3009 /* no need to continue if time already is up */
3010 failf(data, "SSL connection timeout");
3011 return CURLE_OPERATION_TIMEDOUT;
3012 }
3013
3014 result = sectransp_connect_step1(data, conn, sockindex);
3015 if(result)
3016 return result;
3017 }
3018
3019 while(ssl_connect_2 == connssl->connecting_state ||
3020 ssl_connect_2_reading == connssl->connecting_state ||
3021 ssl_connect_2_writing == connssl->connecting_state) {
3022
3023 /* check allowed time left */
3024 const timediff_t timeout_ms = Curl_timeleft(data, NULL, TRUE);
3025
3026 if(timeout_ms < 0) {
3027 /* no need to continue if time already is up */
3028 failf(data, "SSL connection timeout");
3029 return CURLE_OPERATION_TIMEDOUT;
3030 }
3031
3032 /* if ssl is expecting something, check if it's available. */
3033 if(connssl->connecting_state == ssl_connect_2_reading ||
3034 connssl->connecting_state == ssl_connect_2_writing) {
3035
3036 curl_socket_t writefd = ssl_connect_2_writing ==
3037 connssl->connecting_state?sockfd:CURL_SOCKET_BAD;
3038 curl_socket_t readfd = ssl_connect_2_reading ==
3039 connssl->connecting_state?sockfd:CURL_SOCKET_BAD;
3040
3041 what = Curl_socket_check(readfd, CURL_SOCKET_BAD, writefd,
3042 nonblocking ? 0 : timeout_ms);
3043 if(what < 0) {
3044 /* fatal error */
3045 failf(data, "select/poll on SSL socket, errno: %d", SOCKERRNO);
3046 return CURLE_SSL_CONNECT_ERROR;
3047 }
3048 else if(0 == what) {
3049 if(nonblocking) {
3050 *done = FALSE;
3051 return CURLE_OK;
3052 }
3053 else {
3054 /* timeout */
3055 failf(data, "SSL connection timeout");
3056 return CURLE_OPERATION_TIMEDOUT;
3057 }
3058 }
3059 /* socket is readable or writable */
3060 }
3061
3062 /* Run transaction, and return to the caller if it failed or if this
3063 * connection is done nonblocking and this loop would execute again. This
3064 * permits the owner of a multi handle to abort a connection attempt
3065 * before step2 has completed while ensuring that a client using select()
3066 * or epoll() will always have a valid fdset to wait on.
3067 */
3068 result = sectransp_connect_step2(data, conn, sockindex);
3069 if(result || (nonblocking &&
3070 (ssl_connect_2 == connssl->connecting_state ||
3071 ssl_connect_2_reading == connssl->connecting_state ||
3072 ssl_connect_2_writing == connssl->connecting_state)))
3073 return result;
3074
3075 } /* repeat step2 until all transactions are done. */
3076
3077
3078 if(ssl_connect_3 == connssl->connecting_state) {
3079 result = sectransp_connect_step3(data, conn, sockindex);
3080 if(result)
3081 return result;
3082 }
3083
3084 if(ssl_connect_done == connssl->connecting_state) {
3085 connssl->state = ssl_connection_complete;
3086 conn->recv[sockindex] = sectransp_recv;
3087 conn->send[sockindex] = sectransp_send;
3088 *done = TRUE;
3089 }
3090 else
3091 *done = FALSE;
3092
3093 /* Reset our connect state machine */
3094 connssl->connecting_state = ssl_connect_1;
3095
3096 return CURLE_OK;
3097 }
3098
3099 static CURLcode sectransp_connect_nonblocking(struct Curl_easy *data,
3100 struct connectdata *conn,
3101 int sockindex, bool *done)
3102 {
3103 return sectransp_connect_common(data, conn, sockindex, TRUE, done);
3104 }
3105
3106 static CURLcode sectransp_connect(struct Curl_easy *data,
3107 struct connectdata *conn, int sockindex)
3108 {
3109 CURLcode result;
3110 bool done = FALSE;
3111
3112 result = sectransp_connect_common(data, conn, sockindex, FALSE, &done);
3113
3114 if(result)
3115 return result;
3116
3117 DEBUGASSERT(done);
3118
3119 return CURLE_OK;
3120 }
3121
3122 static void sectransp_close(struct Curl_easy *data, struct connectdata *conn,
3123 int sockindex)
3124 {
3125 struct ssl_connect_data *connssl = &conn->ssl[sockindex];
3126 struct ssl_backend_data *backend = connssl->backend;
3127
3128 (void) data;
3129
3130 if(backend->ssl_ctx) {
3131 (void)SSLClose(backend->ssl_ctx);
3132 #if CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS
3133 if(SSLCreateContext != NULL)
3134 CFRelease(backend->ssl_ctx);
3135 #if CURL_SUPPORT_MAC_10_8
3136 else
3137 (void)SSLDisposeContext(backend->ssl_ctx);
3138 #endif /* CURL_SUPPORT_MAC_10_8 */
3139 #else
3140 (void)SSLDisposeContext(backend->ssl_ctx);
3141 #endif /* CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS */
3142 backend->ssl_ctx = NULL;
3143 }
3144 backend->ssl_sockfd = 0;
3145 }
3146
3147 static int sectransp_shutdown(struct Curl_easy *data,
3148 struct connectdata *conn, int sockindex)
3149 {
3150 struct ssl_connect_data *connssl = &conn->ssl[sockindex];
3151 struct ssl_backend_data *backend = connssl->backend;
3152 ssize_t nread;
3153 int what;
3154 int rc;
3155 char buf[120];
3156 int loop = 10; /* avoid getting stuck */
3157
3158 if(!backend->ssl_ctx)
3159 return 0;
3160
3161 #ifndef CURL_DISABLE_FTP
3162 if(data->set.ftp_ccc != CURLFTPSSL_CCC_ACTIVE)
3163 return 0;
3164 #endif
3165
3166 sectransp_close(data, conn, sockindex);
3167
3168 rc = 0;
3169
3170 what = SOCKET_READABLE(conn->sock[sockindex], SSL_SHUTDOWN_TIMEOUT);
3171
3172 while(loop--) {
3173 if(what < 0) {
3174 /* anything that gets here is fatally bad */
3175 failf(data, "select/poll on SSL socket, errno: %d", SOCKERRNO);
3176 rc = -1;
3177 break;
3178 }
3179
3180 if(!what) { /* timeout */
3181 failf(data, "SSL shutdown timeout");
3182 break;
3183 }
3184
3185 /* Something to read, let's do it and hope that it is the close
3186 notify alert from the server. No way to SSL_Read now, so use read(). */
3187
3188 nread = read(conn->sock[sockindex], buf, sizeof(buf));
3189
3190 if(nread < 0) {
3191 failf(data, "read: %s", strerror(errno));
3192 rc = -1;
3193 }
3194
3195 if(nread <= 0)
3196 break;
3197
3198 what = SOCKET_READABLE(conn->sock[sockindex], 0);
3199 }
3200
3201 return rc;
3202 }
3203
3204 static void sectransp_session_free(void *ptr)
3205 {
3206 /* ST, as of iOS 5 and Mountain Lion, has no public method of deleting a
3207 cached session ID inside the Security framework. There is a private
3208 function that does this, but I don't want to have to explain to you why I
3209 got your application rejected from the App Store due to the use of a
3210 private API, so the best we can do is free up our own char array that we
3211 created way back in sectransp_connect_step1... */
3212 Curl_safefree(ptr);
3213 }
3214
3215 static size_t sectransp_version(char *buffer, size_t size)
3216 {
3217 return msnprintf(buffer, size, "SecureTransport");
3218 }
3219
3220 /*
3221 * This function uses SSLGetSessionState to determine connection status.
3222 *
3223 * Return codes:
3224 * 1 means the connection is still in place
3225 * 0 means the connection has been closed
3226 * -1 means the connection status is unknown
3227 */
3228 static int sectransp_check_cxn(struct connectdata *conn)
3229 {
3230 struct ssl_connect_data *connssl = &conn->ssl[FIRSTSOCKET];
3231 struct ssl_backend_data *backend = connssl->backend;
3232 OSStatus err;
3233 SSLSessionState state;
3234
3235 if(backend->ssl_ctx) {
3236 err = SSLGetSessionState(backend->ssl_ctx, &state);
3237 if(err == noErr)
3238 return state == kSSLConnected || state == kSSLHandshake;
3239 return -1;
3240 }
3241 return 0;
3242 }
3243
3244 static bool sectransp_data_pending(const struct connectdata *conn,
3245 int connindex)
3246 {
3247 const struct ssl_connect_data *connssl = &conn->ssl[connindex];
3248 struct ssl_backend_data *backend = connssl->backend;
3249 OSStatus err;
3250 size_t buffer;
3251
3252 if(backend->ssl_ctx) { /* SSL is in use */
3253 err = SSLGetBufferedReadSize(backend->ssl_ctx, &buffer);
3254 if(err == noErr)
3255 return buffer > 0UL;
3256 return false;
3257 }
3258 else
3259 return false;
3260 }
3261
3262 static CURLcode sectransp_random(struct Curl_easy *data UNUSED_PARAM,
3263 unsigned char *entropy, size_t length)
3264 {
3265 /* arc4random_buf() isn't available on cats older than Lion, so let's
3266 do this manually for the benefit of the older cats. */
3267 size_t i;
3268 u_int32_t random_number = 0;
3269
3270 (void)data;
3271
3272 for(i = 0 ; i < length ; i++) {
3273 if(i % sizeof(u_int32_t) == 0)
3274 random_number = arc4random();
3275 entropy[i] = random_number & 0xFF;
3276 random_number >>= 8;
3277 }
3278 i = random_number = 0;
3279 return CURLE_OK;
3280 }
3281
3282 static CURLcode sectransp_sha256sum(const unsigned char *tmp, /* input */
3283 size_t tmplen,
3284 unsigned char *sha256sum, /* output */
3285 size_t sha256len)
3286 {
3287 assert(sha256len >= CURL_SHA256_DIGEST_LENGTH);
3288 (void)CC_SHA256(tmp, (CC_LONG)tmplen, sha256sum);
3289 return CURLE_OK;
3290 }
3291
3292 static bool sectransp_false_start(void)
3293 {
3294 #if CURL_BUILD_MAC_10_9 || CURL_BUILD_IOS_7
3295 if(SSLSetSessionOption != NULL)
3296 return TRUE;
3297 #endif
3298 return FALSE;
3299 }
3300
3301 static ssize_t sectransp_send(struct Curl_easy *data,
3302 int sockindex,
3303 const void *mem,
3304 size_t len,
3305 CURLcode *curlcode)
3306 {
3307 struct connectdata *conn = data->conn;
3308 struct ssl_connect_data *connssl = &conn->ssl[sockindex];
3309 struct ssl_backend_data *backend = connssl->backend;
3310 size_t processed = 0UL;
3311 OSStatus err;
3312
3313 /* The SSLWrite() function works a little differently than expected. The
3314 fourth argument (processed) is currently documented in Apple's
3315 documentation as: "On return, the length, in bytes, of the data actually
3316 written."
3317
3318 Now, one could interpret that as "written to the socket," but actually,
3319 it returns the amount of data that was written to a buffer internal to
3320 the SSLContextRef instead. So it's possible for SSLWrite() to return
3321 errSSLWouldBlock and a number of bytes "written" because those bytes were
3322 encrypted and written to a buffer, not to the socket.
3323
3324 So if this happens, then we need to keep calling SSLWrite() over and
3325 over again with no new data until it quits returning errSSLWouldBlock. */
3326
3327 /* Do we have buffered data to write from the last time we were called? */
3328 if(backend->ssl_write_buffered_length) {
3329 /* Write the buffered data: */
3330 err = SSLWrite(backend->ssl_ctx, NULL, 0UL, &processed);
3331 switch(err) {
3332 case noErr:
3333 /* processed is always going to be 0 because we didn't write to
3334 the buffer, so return how much was written to the socket */
3335 processed = backend->ssl_write_buffered_length;
3336 backend->ssl_write_buffered_length = 0UL;
3337 break;
3338 case errSSLWouldBlock: /* argh, try again */
3339 *curlcode = CURLE_AGAIN;
3340 return -1L;
3341 default:
3342 failf(data, "SSLWrite() returned error %d", err);
3343 *curlcode = CURLE_SEND_ERROR;
3344 return -1L;
3345 }
3346 }
3347 else {
3348 /* We've got new data to write: */
3349 err = SSLWrite(backend->ssl_ctx, mem, len, &processed);
3350 if(err != noErr) {
3351 switch(err) {
3352 case errSSLWouldBlock:
3353 /* Data was buffered but not sent, we have to tell the caller
3354 to try sending again, and remember how much was buffered */
3355 backend->ssl_write_buffered_length = len;
3356 *curlcode = CURLE_AGAIN;
3357 return -1L;
3358 default:
3359 failf(data, "SSLWrite() returned error %d", err);
3360 *curlcode = CURLE_SEND_ERROR;
3361 return -1L;
3362 }
3363 }
3364 }
3365 return (ssize_t)processed;
3366 }
3367
3368 static ssize_t sectransp_recv(struct Curl_easy *data,
3369 int num,
3370 char *buf,
3371 size_t buffersize,
3372 CURLcode *curlcode)
3373 {
3374 struct connectdata *conn = data->conn;
3375 struct ssl_connect_data *connssl = &conn->ssl[num];
3376 struct ssl_backend_data *backend = connssl->backend;
3377 size_t processed = 0UL;
3378 OSStatus err;
3379
3380 again:
3381 err = SSLRead(backend->ssl_ctx, buf, buffersize, &processed);
3382
3383 if(err != noErr) {
3384 switch(err) {
3385 case errSSLWouldBlock: /* return how much we read (if anything) */
3386 if(processed)
3387 return (ssize_t)processed;
3388 *curlcode = CURLE_AGAIN;
3389 return -1L;
3390 break;
3391
3392 /* errSSLClosedGraceful - server gracefully shut down the SSL session
3393 errSSLClosedNoNotify - server hung up on us instead of sending a
3394 closure alert notice, read() is returning 0
3395 Either way, inform the caller that the server disconnected. */
3396 case errSSLClosedGraceful:
3397 case errSSLClosedNoNotify:
3398 *curlcode = CURLE_OK;
3399 return -1L;
3400 break;
3401
3402 /* The below is errSSLPeerAuthCompleted; it's not defined in
3403 Leopard's headers */
3404 case -9841:
3405 if((SSL_CONN_CONFIG(CAfile) || SSL_CONN_CONFIG(ca_info_blob)) &&
3406 SSL_CONN_CONFIG(verifypeer)) {
3407 CURLcode result = verify_cert(data, SSL_CONN_CONFIG(CAfile),
3408 SSL_CONN_CONFIG(ca_info_blob),
3409 backend->ssl_ctx);
3410 if(result)
3411 return result;
3412 }
3413 goto again;
3414 default:
3415 failf(data, "SSLRead() return error %d", err);
3416 *curlcode = CURLE_RECV_ERROR;
3417 return -1L;
3418 break;
3419 }
3420 }
3421 return (ssize_t)processed;
3422 }
3423
3424 static void *sectransp_get_internals(struct ssl_connect_data *connssl,
3425 CURLINFO info UNUSED_PARAM)
3426 {
3427 struct ssl_backend_data *backend = connssl->backend;
3428 (void)info;
3429 return backend->ssl_ctx;
3430 }
3431
3432 const struct Curl_ssl Curl_ssl_sectransp = {
3433 { CURLSSLBACKEND_SECURETRANSPORT, "secure-transport" }, /* info */
3434
3435 SSLSUPP_CAINFO_BLOB |
3436 #ifdef SECTRANSP_PINNEDPUBKEY
3437 SSLSUPP_PINNEDPUBKEY,
3438 #else
3439 0,
3440 #endif /* SECTRANSP_PINNEDPUBKEY */
3441
3442 sizeof(struct ssl_backend_data),
3443
3444 Curl_none_init, /* init */
3445 Curl_none_cleanup, /* cleanup */
3446 sectransp_version, /* version */
3447 sectransp_check_cxn, /* check_cxn */
3448 sectransp_shutdown, /* shutdown */
3449 sectransp_data_pending, /* data_pending */
3450 sectransp_random, /* random */
3451 Curl_none_cert_status_request, /* cert_status_request */
3452 sectransp_connect, /* connect */
3453 sectransp_connect_nonblocking, /* connect_nonblocking */
3454 Curl_ssl_getsock, /* getsock */
3455 sectransp_get_internals, /* get_internals */
3456 sectransp_close, /* close_one */
3457 Curl_none_close_all, /* close_all */
3458 sectransp_session_free, /* session_free */
3459 Curl_none_set_engine, /* set_engine */
3460 Curl_none_set_engine_default, /* set_engine_default */
3461 Curl_none_engines_list, /* engines_list */
3462 sectransp_false_start, /* false_start */
3463 sectransp_sha256sum, /* sha256sum */
3464 NULL, /* associate_connection */
3465 NULL /* disassociate_connection */
3466 };
3467
3468 #ifdef __clang__
3469 #pragma clang diagnostic pop
3470 #endif
3471
3472 #endif /* USE_SECTRANSP */
3473