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