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