VirtualBox

source: vbox/trunk/src/libs/curl-7.83.1/lib/vtls/sectransp.c@ 97623

Last change on this file since 97623 was 95312, checked in by vboxsync, 3 years ago

libs/{curl,libxml2}: OSE export fixes, bugref:8515

  • Property svn:eol-style set to native
File size: 125.8 KB
Line 
1/***************************************************************************
2 * _ _ ____ _
3 * Project ___| | | | _ \| |
4 * / __| | | | |_) | |
5 * | (__| |_| | _ <| |___
6 * \___|\___/|_| \_\_____|
7 *
8 * Copyright (C) 2012 - 2022, Daniel Stenberg, <[email protected]>, et al.
9 * Copyright (C) 2012 - 2017, Nick Zitzmann, <[email protected]>.
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_WEAK_3DES_ENCRYPTION),
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;
841 OSStatus rtn = noErr;
842 size_t bytesRead;
843 ssize_t rrtn;
844 int theErr;
845
846 DEBUGASSERT(backend);
847 sock = backend->ssl_sockfd;
848 *dataLength = 0;
849
850 for(;;) {
851 bytesRead = 0;
852 rrtn = read(sock, currData, bytesToGo);
853 if(rrtn <= 0) {
854 /* this is guesswork... */
855 theErr = errno;
856 if(rrtn == 0) { /* EOF = server hung up */
857 /* the framework will turn this into errSSLClosedNoNotify */
858 rtn = errSSLClosedGraceful;
859 }
860 else /* do the switch */
861 switch(theErr) {
862 case ENOENT:
863 /* connection closed */
864 rtn = errSSLClosedGraceful;
865 break;
866 case ECONNRESET:
867 rtn = errSSLClosedAbort;
868 break;
869 case EAGAIN:
870 rtn = errSSLWouldBlock;
871 backend->ssl_direction = false;
872 break;
873 default:
874 rtn = ioErr;
875 break;
876 }
877 break;
878 }
879 else {
880 bytesRead = rrtn;
881 }
882 bytesToGo -= bytesRead;
883 currData += bytesRead;
884
885 if(bytesToGo == 0) {
886 /* filled buffer with incoming data, done */
887 break;
888 }
889 }
890 *dataLength = initLen - bytesToGo;
891
892 return rtn;
893}
894
895static OSStatus SocketWrite(SSLConnectionRef connection,
896 const void *data,
897 size_t *dataLength) /* IN/OUT */
898{
899 size_t bytesSent = 0;
900 /*int sock = *(int *)connection;*/
901 struct ssl_connect_data *connssl = (struct ssl_connect_data *)connection;
902 struct ssl_backend_data *backend = connssl->backend;
903 int sock;
904 ssize_t length;
905 size_t dataLen = *dataLength;
906 const UInt8 *dataPtr = (UInt8 *)data;
907 OSStatus ortn;
908 int theErr;
909
910 DEBUGASSERT(backend);
911 sock = backend->ssl_sockfd;
912 *dataLength = 0;
913
914 do {
915 length = write(sock,
916 (char *)dataPtr + bytesSent,
917 dataLen - bytesSent);
918 } while((length > 0) &&
919 ( (bytesSent += length) < dataLen) );
920
921 if(length <= 0) {
922 theErr = errno;
923 if(theErr == EAGAIN) {
924 ortn = errSSLWouldBlock;
925 backend->ssl_direction = true;
926 }
927 else {
928 ortn = ioErr;
929 }
930 }
931 else {
932 ortn = noErr;
933 }
934 *dataLength = bytesSent;
935 return ortn;
936}
937
938#ifndef CURL_DISABLE_VERBOSE_STRINGS
939CF_INLINE const char *TLSCipherNameForNumber(SSLCipherSuite cipher)
940{
941 /* The first ciphers in the ciphertable are continuous. Here we do small
942 optimization and instead of loop directly get SSL name by cipher number.
943 */
944 if(cipher <= SSL_FORTEZZA_DMS_WITH_FORTEZZA_CBC_SHA) {
945 return ciphertable[cipher].name;
946 }
947 /* Iterate through the rest of the ciphers */
948 for(size_t i = SSL_FORTEZZA_DMS_WITH_FORTEZZA_CBC_SHA + 1;
949 i < NUM_OF_CIPHERS;
950 ++i) {
951 if(ciphertable[i].num == cipher) {
952 return ciphertable[i].name;
953 }
954 }
955 return ciphertable[SSL_NULL_WITH_NULL_NULL].name;
956}
957#endif /* !CURL_DISABLE_VERBOSE_STRINGS */
958
959#if CURL_BUILD_MAC
960CF_INLINE void GetDarwinVersionNumber(int *major, int *minor)
961{
962 int mib[2];
963 char *os_version;
964 size_t os_version_len;
965 char *os_version_major, *os_version_minor;
966 char *tok_buf;
967
968 /* Get the Darwin kernel version from the kernel using sysctl(): */
969 mib[0] = CTL_KERN;
970 mib[1] = KERN_OSRELEASE;
971 if(sysctl(mib, 2, NULL, &os_version_len, NULL, 0) == -1)
972 return;
973 os_version = malloc(os_version_len*sizeof(char));
974 if(!os_version)
975 return;
976 if(sysctl(mib, 2, os_version, &os_version_len, NULL, 0) == -1) {
977 free(os_version);
978 return;
979 }
980
981 /* Parse the version: */
982 os_version_major = strtok_r(os_version, ".", &tok_buf);
983 os_version_minor = strtok_r(NULL, ".", &tok_buf);
984 *major = atoi(os_version_major);
985 *minor = atoi(os_version_minor);
986 free(os_version);
987}
988#endif /* CURL_BUILD_MAC */
989
990/* Apple provides a myriad of ways of getting information about a certificate
991 into a string. Some aren't available under iOS or newer cats. So here's
992 a unified function for getting a string describing the certificate that
993 ought to work in all cats starting with Leopard. */
994CF_INLINE CFStringRef getsubject(SecCertificateRef cert)
995{
996 CFStringRef server_cert_summary = CFSTR("(null)");
997
998#if CURL_BUILD_IOS
999 /* iOS: There's only one way to do this. */
1000 server_cert_summary = SecCertificateCopySubjectSummary(cert);
1001#else
1002#if CURL_BUILD_MAC_10_7
1003 /* Lion & later: Get the long description if we can. */
1004 if(SecCertificateCopyLongDescription)
1005 server_cert_summary =
1006 SecCertificateCopyLongDescription(NULL, cert, NULL);
1007 else
1008#endif /* CURL_BUILD_MAC_10_7 */
1009#if CURL_BUILD_MAC_10_6
1010 /* Snow Leopard: Get the certificate summary. */
1011 if(SecCertificateCopySubjectSummary)
1012 server_cert_summary = SecCertificateCopySubjectSummary(cert);
1013 else
1014#endif /* CURL_BUILD_MAC_10_6 */
1015 /* Leopard is as far back as we go... */
1016 (void)SecCertificateCopyCommonName(cert, &server_cert_summary);
1017#endif /* CURL_BUILD_IOS */
1018 return server_cert_summary;
1019}
1020
1021static CURLcode CopyCertSubject(struct Curl_easy *data,
1022 SecCertificateRef cert, char **certp)
1023{
1024 CFStringRef c = getsubject(cert);
1025 CURLcode result = CURLE_OK;
1026 const char *direct;
1027 char *cbuf = NULL;
1028 *certp = NULL;
1029
1030 if(!c) {
1031 failf(data, "SSL: invalid CA certificate subject");
1032 return CURLE_PEER_FAILED_VERIFICATION;
1033 }
1034
1035 /* If the subject is already available as UTF-8 encoded (ie 'direct') then
1036 use that, else convert it. */
1037 direct = CFStringGetCStringPtr(c, kCFStringEncodingUTF8);
1038 if(direct) {
1039 *certp = strdup(direct);
1040 if(!*certp) {
1041 failf(data, "SSL: out of memory");
1042 result = CURLE_OUT_OF_MEMORY;
1043 }
1044 }
1045 else {
1046 size_t cbuf_size = ((size_t)CFStringGetLength(c) * 4) + 1;
1047 cbuf = calloc(cbuf_size, 1);
1048 if(cbuf) {
1049 if(!CFStringGetCString(c, cbuf, cbuf_size,
1050 kCFStringEncodingUTF8)) {
1051 failf(data, "SSL: invalid CA certificate subject");
1052 result = CURLE_PEER_FAILED_VERIFICATION;
1053 }
1054 else
1055 /* pass back the buffer */
1056 *certp = cbuf;
1057 }
1058 else {
1059 failf(data, "SSL: couldn't allocate %zu bytes of memory", cbuf_size);
1060 result = CURLE_OUT_OF_MEMORY;
1061 }
1062 }
1063 if(result)
1064 free(cbuf);
1065 CFRelease(c);
1066 return result;
1067}
1068
1069#if CURL_SUPPORT_MAC_10_6
1070/* The SecKeychainSearch API was deprecated in Lion, and using it will raise
1071 deprecation warnings, so let's not compile this unless it's necessary: */
1072static OSStatus CopyIdentityWithLabelOldSchool(char *label,
1073 SecIdentityRef *out_c_a_k)
1074{
1075 OSStatus status = errSecItemNotFound;
1076 SecKeychainAttributeList attr_list;
1077 SecKeychainAttribute attr;
1078 SecKeychainSearchRef search = NULL;
1079 SecCertificateRef cert = NULL;
1080
1081 /* Set up the attribute list: */
1082 attr_list.count = 1L;
1083 attr_list.attr = &attr;
1084
1085 /* Set up our lone search criterion: */
1086 attr.tag = kSecLabelItemAttr;
1087 attr.data = label;
1088 attr.length = (UInt32)strlen(label);
1089
1090 /* Start searching: */
1091 status = SecKeychainSearchCreateFromAttributes(NULL,
1092 kSecCertificateItemClass,
1093 &attr_list,
1094 &search);
1095 if(status == noErr) {
1096 status = SecKeychainSearchCopyNext(search,
1097 (SecKeychainItemRef *)&cert);
1098 if(status == noErr && cert) {
1099 /* If we found a certificate, does it have a private key? */
1100 status = SecIdentityCreateWithCertificate(NULL, cert, out_c_a_k);
1101 CFRelease(cert);
1102 }
1103 }
1104
1105 if(search)
1106 CFRelease(search);
1107 return status;
1108}
1109#endif /* CURL_SUPPORT_MAC_10_6 */
1110
1111static OSStatus CopyIdentityWithLabel(char *label,
1112 SecIdentityRef *out_cert_and_key)
1113{
1114 OSStatus status = errSecItemNotFound;
1115
1116#if CURL_BUILD_MAC_10_7 || CURL_BUILD_IOS
1117 CFArrayRef keys_list;
1118 CFIndex keys_list_count;
1119 CFIndex i;
1120 CFStringRef common_name;
1121
1122 /* SecItemCopyMatching() was introduced in iOS and Snow Leopard.
1123 kSecClassIdentity was introduced in Lion. If both exist, let's use them
1124 to find the certificate. */
1125 if(SecItemCopyMatching && kSecClassIdentity) {
1126 CFTypeRef keys[5];
1127 CFTypeRef values[5];
1128 CFDictionaryRef query_dict;
1129 CFStringRef label_cf = CFStringCreateWithCString(NULL, label,
1130 kCFStringEncodingUTF8);
1131
1132 /* Set up our search criteria and expected results: */
1133 values[0] = kSecClassIdentity; /* we want a certificate and a key */
1134 keys[0] = kSecClass;
1135 values[1] = kCFBooleanTrue; /* we want a reference */
1136 keys[1] = kSecReturnRef;
1137 values[2] = kSecMatchLimitAll; /* kSecMatchLimitOne would be better if the
1138 * label matching below worked correctly */
1139 keys[2] = kSecMatchLimit;
1140 /* identity searches need a SecPolicyRef in order to work */
1141 values[3] = SecPolicyCreateSSL(false, NULL);
1142 keys[3] = kSecMatchPolicy;
1143 /* match the name of the certificate (doesn't work in macOS 10.12.1) */
1144 values[4] = label_cf;
1145 keys[4] = kSecAttrLabel;
1146 query_dict = CFDictionaryCreate(NULL, (const void **)keys,
1147 (const void **)values, 5L,
1148 &kCFCopyStringDictionaryKeyCallBacks,
1149 &kCFTypeDictionaryValueCallBacks);
1150 CFRelease(values[3]);
1151
1152 /* Do we have a match? */
1153 status = SecItemCopyMatching(query_dict, (CFTypeRef *) &keys_list);
1154
1155 /* Because kSecAttrLabel matching doesn't work with kSecClassIdentity,
1156 * we need to find the correct identity ourselves */
1157 if(status == noErr) {
1158 keys_list_count = CFArrayGetCount(keys_list);
1159 *out_cert_and_key = NULL;
1160 status = 1;
1161 for(i = 0; i<keys_list_count; i++) {
1162 OSStatus err = noErr;
1163 SecCertificateRef cert = NULL;
1164 SecIdentityRef identity =
1165 (SecIdentityRef) CFArrayGetValueAtIndex(keys_list, i);
1166 err = SecIdentityCopyCertificate(identity, &cert);
1167 if(err == noErr) {
1168 OSStatus copy_status = noErr;
1169#if CURL_BUILD_IOS
1170 common_name = SecCertificateCopySubjectSummary(cert);
1171#elif CURL_BUILD_MAC_10_7
1172 copy_status = SecCertificateCopyCommonName(cert, &common_name);
1173#endif
1174 if(copy_status == noErr &&
1175 CFStringCompare(common_name, label_cf, 0) == kCFCompareEqualTo) {
1176 CFRelease(cert);
1177 CFRelease(common_name);
1178 CFRetain(identity);
1179 *out_cert_and_key = identity;
1180 status = noErr;
1181 break;
1182 }
1183 CFRelease(common_name);
1184 }
1185 CFRelease(cert);
1186 }
1187 }
1188
1189 if(keys_list)
1190 CFRelease(keys_list);
1191 CFRelease(query_dict);
1192 CFRelease(label_cf);
1193 }
1194 else {
1195#if CURL_SUPPORT_MAC_10_6
1196 /* On Leopard and Snow Leopard, fall back to SecKeychainSearch. */
1197 status = CopyIdentityWithLabelOldSchool(label, out_cert_and_key);
1198#endif /* CURL_SUPPORT_MAC_10_6 */
1199 }
1200#elif CURL_SUPPORT_MAC_10_6
1201 /* For developers building on older cats, we have no choice but to fall back
1202 to SecKeychainSearch. */
1203 status = CopyIdentityWithLabelOldSchool(label, out_cert_and_key);
1204#endif /* CURL_BUILD_MAC_10_7 || CURL_BUILD_IOS */
1205 return status;
1206}
1207
1208static OSStatus CopyIdentityFromPKCS12File(const char *cPath,
1209 const struct curl_blob *blob,
1210 const char *cPassword,
1211 SecIdentityRef *out_cert_and_key)
1212{
1213 OSStatus status = errSecItemNotFound;
1214 CFURLRef pkcs_url = NULL;
1215 CFStringRef password = cPassword ? CFStringCreateWithCString(NULL,
1216 cPassword, kCFStringEncodingUTF8) : NULL;
1217 CFDataRef pkcs_data = NULL;
1218
1219 /* We can import P12 files on iOS or OS X 10.7 or later: */
1220 /* These constants are documented as having first appeared in 10.6 but they
1221 raise linker errors when used on that cat for some reason. */
1222#if CURL_BUILD_MAC_10_7 || CURL_BUILD_IOS
1223 bool resource_imported;
1224
1225 if(blob) {
1226 pkcs_data = CFDataCreate(kCFAllocatorDefault,
1227 (const unsigned char *)blob->data, blob->len);
1228 status = (pkcs_data != NULL) ? errSecSuccess : errSecAllocate;
1229 resource_imported = (pkcs_data != NULL);
1230 }
1231 else {
1232 pkcs_url =
1233 CFURLCreateFromFileSystemRepresentation(NULL,
1234 (const UInt8 *)cPath,
1235 strlen(cPath), false);
1236 resource_imported =
1237 CFURLCreateDataAndPropertiesFromResource(NULL,
1238 pkcs_url, &pkcs_data,
1239 NULL, NULL, &status);
1240 }
1241
1242 if(resource_imported) {
1243 CFArrayRef items = NULL;
1244
1245 /* On iOS SecPKCS12Import will never add the client certificate to the
1246 * Keychain.
1247 *
1248 * It gives us back a SecIdentityRef that we can use directly. */
1249#if CURL_BUILD_IOS
1250 const void *cKeys[] = {kSecImportExportPassphrase};
1251 const void *cValues[] = {password};
1252 CFDictionaryRef options = CFDictionaryCreate(NULL, cKeys, cValues,
1253 password ? 1L : 0L, NULL, NULL);
1254
1255 if(options) {
1256 status = SecPKCS12Import(pkcs_data, options, &items);
1257 CFRelease(options);
1258 }
1259
1260
1261 /* On macOS SecPKCS12Import will always add the client certificate to
1262 * the Keychain.
1263 *
1264 * As this doesn't match iOS, and apps may not want to see their client
1265 * certificate saved in the user's keychain, we use SecItemImport
1266 * with a NULL keychain to avoid importing it.
1267 *
1268 * This returns a SecCertificateRef from which we can construct a
1269 * SecIdentityRef.
1270 */
1271#elif CURL_BUILD_MAC_10_7
1272 SecItemImportExportKeyParameters keyParams;
1273 SecExternalFormat inputFormat = kSecFormatPKCS12;
1274 SecExternalItemType inputType = kSecItemTypeCertificate;
1275
1276 memset(&keyParams, 0x00, sizeof(keyParams));
1277 keyParams.version = SEC_KEY_IMPORT_EXPORT_PARAMS_VERSION;
1278 keyParams.passphrase = password;
1279
1280 status = SecItemImport(pkcs_data, NULL, &inputFormat, &inputType,
1281 0, &keyParams, NULL, &items);
1282#endif
1283
1284
1285 /* Extract the SecIdentityRef */
1286 if(status == errSecSuccess && items && CFArrayGetCount(items)) {
1287 CFIndex i, count;
1288 count = CFArrayGetCount(items);
1289
1290 for(i = 0; i < count; i++) {
1291 CFTypeRef item = (CFTypeRef) CFArrayGetValueAtIndex(items, i);
1292 CFTypeID itemID = CFGetTypeID(item);
1293
1294 if(itemID == CFDictionaryGetTypeID()) {
1295 CFTypeRef identity = (CFTypeRef) CFDictionaryGetValue(
1296 (CFDictionaryRef) item,
1297 kSecImportItemIdentity);
1298 CFRetain(identity);
1299 *out_cert_and_key = (SecIdentityRef) identity;
1300 break;
1301 }
1302#if CURL_BUILD_MAC_10_7
1303 else if(itemID == SecCertificateGetTypeID()) {
1304 status = SecIdentityCreateWithCertificate(NULL,
1305 (SecCertificateRef) item,
1306 out_cert_and_key);
1307 break;
1308 }
1309#endif
1310 }
1311 }
1312
1313 if(items)
1314 CFRelease(items);
1315 CFRelease(pkcs_data);
1316 }
1317#endif /* CURL_BUILD_MAC_10_7 || CURL_BUILD_IOS */
1318 if(password)
1319 CFRelease(password);
1320 if(pkcs_url)
1321 CFRelease(pkcs_url);
1322 return status;
1323}
1324
1325/* This code was borrowed from nss.c, with some modifications:
1326 * Determine whether the nickname passed in is a filename that needs to
1327 * be loaded as a PEM or a regular NSS nickname.
1328 *
1329 * returns 1 for a file
1330 * returns 0 for not a file
1331 */
1332CF_INLINE bool is_file(const char *filename)
1333{
1334 struct_stat st;
1335
1336 if(!filename)
1337 return false;
1338
1339 if(stat(filename, &st) == 0)
1340 return S_ISREG(st.st_mode);
1341 return false;
1342}
1343
1344#if CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS
1345static CURLcode sectransp_version_from_curl(SSLProtocol *darwinver,
1346 long ssl_version)
1347{
1348 switch(ssl_version) {
1349 case CURL_SSLVERSION_TLSv1_0:
1350 *darwinver = kTLSProtocol1;
1351 return CURLE_OK;
1352 case CURL_SSLVERSION_TLSv1_1:
1353 *darwinver = kTLSProtocol11;
1354 return CURLE_OK;
1355 case CURL_SSLVERSION_TLSv1_2:
1356 *darwinver = kTLSProtocol12;
1357 return CURLE_OK;
1358 case CURL_SSLVERSION_TLSv1_3:
1359 /* TLS 1.3 support first appeared in iOS 11 and macOS 10.13 */
1360#if (CURL_BUILD_MAC_10_13 || CURL_BUILD_IOS_11) && HAVE_BUILTIN_AVAILABLE == 1
1361 if(__builtin_available(macOS 10.13, iOS 11.0, *)) {
1362 *darwinver = kTLSProtocol13;
1363 return CURLE_OK;
1364 }
1365#endif /* (CURL_BUILD_MAC_10_13 || CURL_BUILD_IOS_11) &&
1366 HAVE_BUILTIN_AVAILABLE == 1 */
1367 break;
1368 }
1369 return CURLE_SSL_CONNECT_ERROR;
1370}
1371#endif
1372
1373static CURLcode
1374set_ssl_version_min_max(struct Curl_easy *data, struct connectdata *conn,
1375 int sockindex)
1376{
1377 struct ssl_connect_data *connssl = &conn->ssl[sockindex];
1378 struct ssl_backend_data *backend = connssl->backend;
1379 long ssl_version = SSL_CONN_CONFIG(version);
1380 long ssl_version_max = SSL_CONN_CONFIG(version_max);
1381 long max_supported_version_by_os;
1382
1383 DEBUGASSERT(backend);
1384
1385 /* macOS 10.5-10.7 supported TLS 1.0 only.
1386 macOS 10.8 and later, and iOS 5 and later, added TLS 1.1 and 1.2.
1387 macOS 10.13 and later, and iOS 11 and later, added TLS 1.3. */
1388#if (CURL_BUILD_MAC_10_13 || CURL_BUILD_IOS_11) && HAVE_BUILTIN_AVAILABLE == 1
1389 if(__builtin_available(macOS 10.13, iOS 11.0, *)) {
1390 max_supported_version_by_os = CURL_SSLVERSION_MAX_TLSv1_3;
1391 }
1392 else {
1393 max_supported_version_by_os = CURL_SSLVERSION_MAX_TLSv1_2;
1394 }
1395#else
1396 max_supported_version_by_os = CURL_SSLVERSION_MAX_TLSv1_2;
1397#endif /* (CURL_BUILD_MAC_10_13 || CURL_BUILD_IOS_11) &&
1398 HAVE_BUILTIN_AVAILABLE == 1 */
1399
1400 switch(ssl_version) {
1401 case CURL_SSLVERSION_DEFAULT:
1402 case CURL_SSLVERSION_TLSv1:
1403 ssl_version = CURL_SSLVERSION_TLSv1_0;
1404 break;
1405 }
1406
1407 switch(ssl_version_max) {
1408 case CURL_SSLVERSION_MAX_NONE:
1409 case CURL_SSLVERSION_MAX_DEFAULT:
1410 ssl_version_max = max_supported_version_by_os;
1411 break;
1412 }
1413
1414#if CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS
1415 if(SSLSetProtocolVersionMax) {
1416 SSLProtocol darwin_ver_min = kTLSProtocol1;
1417 SSLProtocol darwin_ver_max = kTLSProtocol1;
1418 CURLcode result = sectransp_version_from_curl(&darwin_ver_min,
1419 ssl_version);
1420 if(result) {
1421 failf(data, "unsupported min version passed via CURLOPT_SSLVERSION");
1422 return result;
1423 }
1424 result = sectransp_version_from_curl(&darwin_ver_max,
1425 ssl_version_max >> 16);
1426 if(result) {
1427 failf(data, "unsupported max version passed via CURLOPT_SSLVERSION");
1428 return result;
1429 }
1430
1431 (void)SSLSetProtocolVersionMin(backend->ssl_ctx, darwin_ver_min);
1432 (void)SSLSetProtocolVersionMax(backend->ssl_ctx, darwin_ver_max);
1433 return result;
1434 }
1435 else {
1436#if CURL_SUPPORT_MAC_10_8
1437 long i = ssl_version;
1438 (void)SSLSetProtocolVersionEnabled(backend->ssl_ctx,
1439 kSSLProtocolAll,
1440 false);
1441 for(; i <= (ssl_version_max >> 16); i++) {
1442 switch(i) {
1443 case CURL_SSLVERSION_TLSv1_0:
1444 (void)SSLSetProtocolVersionEnabled(backend->ssl_ctx,
1445 kTLSProtocol1,
1446 true);
1447 break;
1448 case CURL_SSLVERSION_TLSv1_1:
1449 (void)SSLSetProtocolVersionEnabled(backend->ssl_ctx,
1450 kTLSProtocol11,
1451 true);
1452 break;
1453 case CURL_SSLVERSION_TLSv1_2:
1454 (void)SSLSetProtocolVersionEnabled(backend->ssl_ctx,
1455 kTLSProtocol12,
1456 true);
1457 break;
1458 case CURL_SSLVERSION_TLSv1_3:
1459 failf(data, "Your version of the OS does not support TLSv1.3");
1460 return CURLE_SSL_CONNECT_ERROR;
1461 }
1462 }
1463 return CURLE_OK;
1464#endif /* CURL_SUPPORT_MAC_10_8 */
1465 }
1466#endif /* CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS */
1467 failf(data, "Secure Transport: cannot set SSL protocol");
1468 return CURLE_SSL_CONNECT_ERROR;
1469}
1470
1471static bool is_cipher_suite_strong(SSLCipherSuite suite_num)
1472{
1473 for(size_t i = 0; i < NUM_OF_CIPHERS; ++i) {
1474 if(ciphertable[i].num == suite_num) {
1475 return !ciphertable[i].weak;
1476 }
1477 }
1478 /* If the cipher is not in our list, assume it is a new one
1479 and therefore strong. Previous implementation was the same,
1480 if cipher suite is not in the list, it was considered strong enough */
1481 return true;
1482}
1483
1484static bool is_separator(char c)
1485{
1486 /* Return whether character is a cipher list separator. */
1487 switch(c) {
1488 case ' ':
1489 case '\t':
1490 case ':':
1491 case ',':
1492 case ';':
1493 return true;
1494 }
1495 return false;
1496}
1497
1498static CURLcode sectransp_set_default_ciphers(struct Curl_easy *data,
1499 SSLContextRef ssl_ctx)
1500{
1501 size_t all_ciphers_count = 0UL, allowed_ciphers_count = 0UL, i;
1502 SSLCipherSuite *all_ciphers = NULL, *allowed_ciphers = NULL;
1503 OSStatus err = noErr;
1504
1505#if CURL_BUILD_MAC
1506 int darwinver_maj = 0, darwinver_min = 0;
1507
1508 GetDarwinVersionNumber(&darwinver_maj, &darwinver_min);
1509#endif /* CURL_BUILD_MAC */
1510
1511 /* Disable cipher suites that ST supports but are not safe. These ciphers
1512 are unlikely to be used in any case since ST gives other ciphers a much
1513 higher priority, but it's probably better that we not connect at all than
1514 to give the user a false sense of security if the server only supports
1515 insecure ciphers. (Note: We don't care about SSLv2-only ciphers.) */
1516 err = SSLGetNumberSupportedCiphers(ssl_ctx, &all_ciphers_count);
1517 if(err != noErr) {
1518 failf(data, "SSL: SSLGetNumberSupportedCiphers() failed: OSStatus %d",
1519 err);
1520 return CURLE_SSL_CIPHER;
1521 }
1522 all_ciphers = malloc(all_ciphers_count*sizeof(SSLCipherSuite));
1523 if(!all_ciphers) {
1524 failf(data, "SSL: Failed to allocate memory for all ciphers");
1525 return CURLE_OUT_OF_MEMORY;
1526 }
1527 allowed_ciphers = malloc(all_ciphers_count*sizeof(SSLCipherSuite));
1528 if(!allowed_ciphers) {
1529 Curl_safefree(all_ciphers);
1530 failf(data, "SSL: Failed to allocate memory for allowed ciphers");
1531 return CURLE_OUT_OF_MEMORY;
1532 }
1533 err = SSLGetSupportedCiphers(ssl_ctx, all_ciphers,
1534 &all_ciphers_count);
1535 if(err != noErr) {
1536 Curl_safefree(all_ciphers);
1537 Curl_safefree(allowed_ciphers);
1538 return CURLE_SSL_CIPHER;
1539 }
1540 for(i = 0UL ; i < all_ciphers_count ; i++) {
1541#if CURL_BUILD_MAC
1542 /* There's a known bug in early versions of Mountain Lion where ST's ECC
1543 ciphers (cipher suite 0xC001 through 0xC032) simply do not work.
1544 Work around the problem here by disabling those ciphers if we are
1545 running in an affected version of OS X. */
1546 if(darwinver_maj == 12 && darwinver_min <= 3 &&
1547 all_ciphers[i] >= 0xC001 && all_ciphers[i] <= 0xC032) {
1548 continue;
1549 }
1550#endif /* CURL_BUILD_MAC */
1551 if(is_cipher_suite_strong(all_ciphers[i])) {
1552 allowed_ciphers[allowed_ciphers_count++] = all_ciphers[i];
1553 }
1554 }
1555 err = SSLSetEnabledCiphers(ssl_ctx, allowed_ciphers,
1556 allowed_ciphers_count);
1557 Curl_safefree(all_ciphers);
1558 Curl_safefree(allowed_ciphers);
1559 if(err != noErr) {
1560 failf(data, "SSL: SSLSetEnabledCiphers() failed: OSStatus %d", err);
1561 return CURLE_SSL_CIPHER;
1562 }
1563 return CURLE_OK;
1564}
1565
1566static CURLcode sectransp_set_selected_ciphers(struct Curl_easy *data,
1567 SSLContextRef ssl_ctx,
1568 const char *ciphers)
1569{
1570 size_t ciphers_count = 0;
1571 const char *cipher_start = ciphers;
1572 OSStatus err = noErr;
1573 SSLCipherSuite selected_ciphers[NUM_OF_CIPHERS];
1574
1575 if(!ciphers)
1576 return CURLE_OK;
1577
1578 while(is_separator(*ciphers)) /* Skip initial separators. */
1579 ciphers++;
1580 if(!*ciphers)
1581 return CURLE_OK;
1582
1583 cipher_start = ciphers;
1584 while(*cipher_start && ciphers_count < NUM_OF_CIPHERS) {
1585 bool cipher_found = FALSE;
1586 size_t cipher_len = 0;
1587 const char *cipher_end = NULL;
1588 bool tls_name = FALSE;
1589
1590 /* Skip separators */
1591 while(is_separator(*cipher_start))
1592 cipher_start++;
1593 if(*cipher_start == '\0') {
1594 break;
1595 }
1596 /* Find last position of a cipher in the ciphers string */
1597 cipher_end = cipher_start;
1598 while (*cipher_end != '\0' && !is_separator(*cipher_end)) {
1599 ++cipher_end;
1600 }
1601
1602 /* IANA cipher names start with the TLS_ or SSL_ prefix.
1603 If the 4th symbol of the cipher is '_' we look for a cipher in the
1604 table by its (TLS) name.
1605 Otherwise, we try to match cipher by an alias. */
1606 if(cipher_start[3] == '_') {
1607 tls_name = TRUE;
1608 }
1609 /* Iterate through the cipher table and look for the cipher, starting
1610 the cipher number 0x01 because the 0x00 is not the real cipher */
1611 cipher_len = cipher_end - cipher_start;
1612 for(size_t i = 1; i < NUM_OF_CIPHERS; ++i) {
1613 const char *table_cipher_name = NULL;
1614 if(tls_name) {
1615 table_cipher_name = ciphertable[i].name;
1616 }
1617 else if(ciphertable[i].alias_name) {
1618 table_cipher_name = ciphertable[i].alias_name;
1619 }
1620 else {
1621 continue;
1622 }
1623 /* Compare a part of the string between separators with a cipher name
1624 in the table and make sure we matched the whole cipher name */
1625 if(strncmp(cipher_start, table_cipher_name, cipher_len) == 0
1626 && table_cipher_name[cipher_len] == '\0') {
1627 selected_ciphers[ciphers_count] = ciphertable[i].num;
1628 ++ciphers_count;
1629 cipher_found = TRUE;
1630 break;
1631 }
1632 }
1633 if(!cipher_found) {
1634 /* It would be more human-readable if we print the wrong cipher name
1635 but we don't want to allocate any additional memory and copy the name
1636 into it, then add it into logs.
1637 Also, we do not modify an original cipher list string. We just point
1638 to positions where cipher starts and ends in the cipher list string.
1639 The message is a bit cryptic and longer than necessary but can be
1640 understood by humans. */
1641 failf(data, "SSL: cipher string \"%s\" contains unsupported cipher name"
1642 " starting position %d and ending position %d",
1643 ciphers,
1644 cipher_start - ciphers,
1645 cipher_end - ciphers);
1646 return CURLE_SSL_CIPHER;
1647 }
1648 if(*cipher_end) {
1649 cipher_start = cipher_end + 1;
1650 }
1651 else {
1652 break;
1653 }
1654 }
1655 /* All cipher suites in the list are found. Report to logs as-is */
1656 infof(data, "SSL: Setting cipher suites list \"%s\"", ciphers);
1657
1658 err = SSLSetEnabledCiphers(ssl_ctx, selected_ciphers, ciphers_count);
1659 if(err != noErr) {
1660 failf(data, "SSL: SSLSetEnabledCiphers() failed: OSStatus %d", err);
1661 return CURLE_SSL_CIPHER;
1662 }
1663 return CURLE_OK;
1664}
1665
1666static CURLcode sectransp_connect_step1(struct Curl_easy *data,
1667 struct connectdata *conn,
1668 int sockindex)
1669{
1670 curl_socket_t sockfd = conn->sock[sockindex];
1671 struct ssl_connect_data *connssl = &conn->ssl[sockindex];
1672 struct ssl_backend_data *backend = connssl->backend;
1673 const struct curl_blob *ssl_cablob = SSL_CONN_CONFIG(ca_info_blob);
1674 const char * const ssl_cafile =
1675 /* CURLOPT_CAINFO_BLOB overrides CURLOPT_CAINFO */
1676 (ssl_cablob ? NULL : SSL_CONN_CONFIG(CAfile));
1677 const bool verifypeer = SSL_CONN_CONFIG(verifypeer);
1678 char * const ssl_cert = SSL_SET_OPTION(primary.clientcert);
1679 const struct curl_blob *ssl_cert_blob = SSL_SET_OPTION(primary.cert_blob);
1680 bool isproxy = SSL_IS_PROXY();
1681 const char * const hostname = SSL_HOST_NAME();
1682 const long int port = SSL_HOST_PORT();
1683#ifdef ENABLE_IPV6
1684 struct in6_addr addr;
1685#else
1686 struct in_addr addr;
1687#endif /* ENABLE_IPV6 */
1688 char *ciphers;
1689 OSStatus err = noErr;
1690#if CURL_BUILD_MAC
1691 int darwinver_maj = 0, darwinver_min = 0;
1692
1693 DEBUGASSERT(backend);
1694
1695 GetDarwinVersionNumber(&darwinver_maj, &darwinver_min);
1696#endif /* CURL_BUILD_MAC */
1697
1698#if CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS
1699 if(SSLCreateContext) { /* use the newer API if available */
1700 if(backend->ssl_ctx)
1701 CFRelease(backend->ssl_ctx);
1702 backend->ssl_ctx = SSLCreateContext(NULL, kSSLClientSide, kSSLStreamType);
1703 if(!backend->ssl_ctx) {
1704 failf(data, "SSL: couldn't create a context");
1705 return CURLE_OUT_OF_MEMORY;
1706 }
1707 }
1708 else {
1709 /* The old ST API does not exist under iOS, so don't compile it: */
1710#if CURL_SUPPORT_MAC_10_8
1711 if(backend->ssl_ctx)
1712 (void)SSLDisposeContext(backend->ssl_ctx);
1713 err = SSLNewContext(false, &(backend->ssl_ctx));
1714 if(err != noErr) {
1715 failf(data, "SSL: couldn't create a context: OSStatus %d", err);
1716 return CURLE_OUT_OF_MEMORY;
1717 }
1718#endif /* CURL_SUPPORT_MAC_10_8 */
1719 }
1720#else
1721 if(backend->ssl_ctx)
1722 (void)SSLDisposeContext(backend->ssl_ctx);
1723 err = SSLNewContext(false, &(backend->ssl_ctx));
1724 if(err != noErr) {
1725 failf(data, "SSL: couldn't create a context: OSStatus %d", err);
1726 return CURLE_OUT_OF_MEMORY;
1727 }
1728#endif /* CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS */
1729 backend->ssl_write_buffered_length = 0UL; /* reset buffered write length */
1730
1731 /* check to see if we've been told to use an explicit SSL/TLS version */
1732#if CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS
1733 if(SSLSetProtocolVersionMax) {
1734 switch(conn->ssl_config.version) {
1735 case CURL_SSLVERSION_TLSv1:
1736 (void)SSLSetProtocolVersionMin(backend->ssl_ctx, kTLSProtocol1);
1737#if (CURL_BUILD_MAC_10_13 || CURL_BUILD_IOS_11) && HAVE_BUILTIN_AVAILABLE == 1
1738 if(__builtin_available(macOS 10.13, iOS 11.0, *)) {
1739 (void)SSLSetProtocolVersionMax(backend->ssl_ctx, kTLSProtocol13);
1740 }
1741 else {
1742 (void)SSLSetProtocolVersionMax(backend->ssl_ctx, kTLSProtocol12);
1743 }
1744#else
1745 (void)SSLSetProtocolVersionMax(backend->ssl_ctx, kTLSProtocol12);
1746#endif /* (CURL_BUILD_MAC_10_13 || CURL_BUILD_IOS_11) &&
1747 HAVE_BUILTIN_AVAILABLE == 1 */
1748 break;
1749 case CURL_SSLVERSION_DEFAULT:
1750 case CURL_SSLVERSION_TLSv1_0:
1751 case CURL_SSLVERSION_TLSv1_1:
1752 case CURL_SSLVERSION_TLSv1_2:
1753 case CURL_SSLVERSION_TLSv1_3:
1754 {
1755 CURLcode result = set_ssl_version_min_max(data, conn, sockindex);
1756 if(result != CURLE_OK)
1757 return result;
1758 break;
1759 }
1760 case CURL_SSLVERSION_SSLv3:
1761 case CURL_SSLVERSION_SSLv2:
1762 failf(data, "SSL versions not supported");
1763 return CURLE_NOT_BUILT_IN;
1764 default:
1765 failf(data, "Unrecognized parameter passed via CURLOPT_SSLVERSION");
1766 return CURLE_SSL_CONNECT_ERROR;
1767 }
1768 }
1769 else {
1770#if CURL_SUPPORT_MAC_10_8
1771 (void)SSLSetProtocolVersionEnabled(backend->ssl_ctx,
1772 kSSLProtocolAll,
1773 false);
1774 switch(conn->ssl_config.version) {
1775 case CURL_SSLVERSION_DEFAULT:
1776 case CURL_SSLVERSION_TLSv1:
1777 (void)SSLSetProtocolVersionEnabled(backend->ssl_ctx,
1778 kTLSProtocol1,
1779 true);
1780 (void)SSLSetProtocolVersionEnabled(backend->ssl_ctx,
1781 kTLSProtocol11,
1782 true);
1783 (void)SSLSetProtocolVersionEnabled(backend->ssl_ctx,
1784 kTLSProtocol12,
1785 true);
1786 break;
1787 case CURL_SSLVERSION_TLSv1_0:
1788 case CURL_SSLVERSION_TLSv1_1:
1789 case CURL_SSLVERSION_TLSv1_2:
1790 case CURL_SSLVERSION_TLSv1_3:
1791 {
1792 CURLcode result = set_ssl_version_min_max(data, conn, sockindex);
1793 if(result != CURLE_OK)
1794 return result;
1795 break;
1796 }
1797 case CURL_SSLVERSION_SSLv3:
1798 case CURL_SSLVERSION_SSLv2:
1799 failf(data, "SSL versions not supported");
1800 return CURLE_NOT_BUILT_IN;
1801 default:
1802 failf(data, "Unrecognized parameter passed via CURLOPT_SSLVERSION");
1803 return CURLE_SSL_CONNECT_ERROR;
1804 }
1805#endif /* CURL_SUPPORT_MAC_10_8 */
1806 }
1807#else
1808 if(conn->ssl_config.version_max != CURL_SSLVERSION_MAX_NONE) {
1809 failf(data, "Your version of the OS does not support to set maximum"
1810 " SSL/TLS version");
1811 return CURLE_SSL_CONNECT_ERROR;
1812 }
1813 (void)SSLSetProtocolVersionEnabled(backend->ssl_ctx, kSSLProtocolAll, false);
1814 switch(conn->ssl_config.version) {
1815 case CURL_SSLVERSION_DEFAULT:
1816 case CURL_SSLVERSION_TLSv1:
1817 case CURL_SSLVERSION_TLSv1_0:
1818 (void)SSLSetProtocolVersionEnabled(backend->ssl_ctx,
1819 kTLSProtocol1,
1820 true);
1821 break;
1822 case CURL_SSLVERSION_TLSv1_1:
1823 failf(data, "Your version of the OS does not support TLSv1.1");
1824 return CURLE_SSL_CONNECT_ERROR;
1825 case CURL_SSLVERSION_TLSv1_2:
1826 failf(data, "Your version of the OS does not support TLSv1.2");
1827 return CURLE_SSL_CONNECT_ERROR;
1828 case CURL_SSLVERSION_TLSv1_3:
1829 failf(data, "Your version of the OS does not support TLSv1.3");
1830 return CURLE_SSL_CONNECT_ERROR;
1831 case CURL_SSLVERSION_SSLv2:
1832 case CURL_SSLVERSION_SSLv3:
1833 failf(data, "SSL versions not supported");
1834 return CURLE_NOT_BUILT_IN;
1835 default:
1836 failf(data, "Unrecognized parameter passed via CURLOPT_SSLVERSION");
1837 return CURLE_SSL_CONNECT_ERROR;
1838 }
1839#endif /* CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS */
1840
1841#if (CURL_BUILD_MAC_10_13 || CURL_BUILD_IOS_11) && HAVE_BUILTIN_AVAILABLE == 1
1842 if(conn->bits.tls_enable_alpn) {
1843 if(__builtin_available(macOS 10.13.4, iOS 11, tvOS 11, *)) {
1844 CFMutableArrayRef alpnArr = CFArrayCreateMutable(NULL, 0,
1845 &kCFTypeArrayCallBacks);
1846
1847#ifdef USE_HTTP2
1848 if(data->state.httpwant >= CURL_HTTP_VERSION_2
1849#ifndef CURL_DISABLE_PROXY
1850 && (!isproxy || !conn->bits.tunnel_proxy)
1851#endif
1852 ) {
1853 CFArrayAppendValue(alpnArr, CFSTR(ALPN_H2));
1854 infof(data, VTLS_INFOF_ALPN_OFFER_1STR, ALPN_H2);
1855 }
1856#endif
1857
1858 CFArrayAppendValue(alpnArr, CFSTR(ALPN_HTTP_1_1));
1859 infof(data, VTLS_INFOF_ALPN_OFFER_1STR, ALPN_HTTP_1_1);
1860
1861 /* expects length prefixed preference ordered list of protocols in wire
1862 * format
1863 */
1864 err = SSLSetALPNProtocols(backend->ssl_ctx, alpnArr);
1865 if(err != noErr)
1866 infof(data, "WARNING: failed to set ALPN protocols; OSStatus %d",
1867 err);
1868 CFRelease(alpnArr);
1869 }
1870 }
1871#endif
1872
1873 if(SSL_SET_OPTION(key)) {
1874 infof(data, "WARNING: SSL: CURLOPT_SSLKEY is ignored by Secure "
1875 "Transport. The private key must be in the Keychain.");
1876 }
1877
1878 if(ssl_cert || ssl_cert_blob) {
1879 bool is_cert_data = ssl_cert_blob != NULL;
1880 bool is_cert_file = (!is_cert_data) && is_file(ssl_cert);
1881 SecIdentityRef cert_and_key = NULL;
1882
1883 /* User wants to authenticate with a client cert. Look for it. Assume that
1884 the user wants to use an identity loaded from the Keychain. If not, try
1885 it as a file on disk */
1886
1887 if(!is_cert_data)
1888 err = CopyIdentityWithLabel(ssl_cert, &cert_and_key);
1889 else
1890 err = !noErr;
1891 if((err != noErr) && (is_cert_file || is_cert_data)) {
1892 if(!SSL_SET_OPTION(cert_type))
1893 infof(data, "SSL: Certificate type not set, assuming "
1894 "PKCS#12 format.");
1895 else if(!strcasecompare(SSL_SET_OPTION(cert_type), "P12")) {
1896 failf(data, "SSL: The Security framework only supports "
1897 "loading identities that are in PKCS#12 format.");
1898 return CURLE_SSL_CERTPROBLEM;
1899 }
1900
1901 err = CopyIdentityFromPKCS12File(ssl_cert, ssl_cert_blob,
1902 SSL_SET_OPTION(key_passwd),
1903 &cert_and_key);
1904 }
1905
1906 if(err == noErr && cert_and_key) {
1907 SecCertificateRef cert = NULL;
1908 CFTypeRef certs_c[1];
1909 CFArrayRef certs;
1910
1911 /* If we found one, print it out: */
1912 err = SecIdentityCopyCertificate(cert_and_key, &cert);
1913 if(err == noErr) {
1914 char *certp;
1915 CURLcode result = CopyCertSubject(data, cert, &certp);
1916 if(!result) {
1917 infof(data, "Client certificate: %s", certp);
1918 free(certp);
1919 }
1920
1921 CFRelease(cert);
1922 if(result == CURLE_PEER_FAILED_VERIFICATION)
1923 return CURLE_SSL_CERTPROBLEM;
1924 if(result)
1925 return result;
1926 }
1927 certs_c[0] = cert_and_key;
1928 certs = CFArrayCreate(NULL, (const void **)certs_c, 1L,
1929 &kCFTypeArrayCallBacks);
1930 err = SSLSetCertificate(backend->ssl_ctx, certs);
1931 if(certs)
1932 CFRelease(certs);
1933 if(err != noErr) {
1934 failf(data, "SSL: SSLSetCertificate() failed: OSStatus %d", err);
1935 return CURLE_SSL_CERTPROBLEM;
1936 }
1937 CFRelease(cert_and_key);
1938 }
1939 else {
1940 const char *cert_showfilename_error =
1941 is_cert_data ? "(memory blob)" : ssl_cert;
1942
1943 switch(err) {
1944 case errSecAuthFailed: case -25264: /* errSecPkcs12VerifyFailure */
1945 failf(data, "SSL: Incorrect password for the certificate \"%s\" "
1946 "and its private key.", cert_showfilename_error);
1947 break;
1948 case -26275: /* errSecDecode */ case -25257: /* errSecUnknownFormat */
1949 failf(data, "SSL: Couldn't make sense of the data in the "
1950 "certificate \"%s\" and its private key.",
1951 cert_showfilename_error);
1952 break;
1953 case -25260: /* errSecPassphraseRequired */
1954 failf(data, "SSL The certificate \"%s\" requires a password.",
1955 cert_showfilename_error);
1956 break;
1957 case errSecItemNotFound:
1958 failf(data, "SSL: Can't find the certificate \"%s\" and its private "
1959 "key in the Keychain.", cert_showfilename_error);
1960 break;
1961 default:
1962 failf(data, "SSL: Can't load the certificate \"%s\" and its private "
1963 "key: OSStatus %d", cert_showfilename_error, err);
1964 break;
1965 }
1966 return CURLE_SSL_CERTPROBLEM;
1967 }
1968 }
1969
1970 /* SSL always tries to verify the peer, this only says whether it should
1971 * fail to connect if the verification fails, or if it should continue
1972 * anyway. In the latter case the result of the verification is checked with
1973 * SSL_get_verify_result() below. */
1974#if CURL_BUILD_MAC_10_6 || CURL_BUILD_IOS
1975 /* Snow Leopard introduced the SSLSetSessionOption() function, but due to
1976 a library bug with the way the kSSLSessionOptionBreakOnServerAuth flag
1977 works, it doesn't work as expected under Snow Leopard, Lion or
1978 Mountain Lion.
1979 So we need to call SSLSetEnableCertVerify() on those older cats in order
1980 to disable certificate validation if the user turned that off.
1981 (SecureTransport will always validate the certificate chain by
1982 default.)
1983 Note:
1984 Darwin 11.x.x is Lion (10.7)
1985 Darwin 12.x.x is Mountain Lion (10.8)
1986 Darwin 13.x.x is Mavericks (10.9)
1987 Darwin 14.x.x is Yosemite (10.10)
1988 Darwin 15.x.x is El Capitan (10.11)
1989 */
1990#if CURL_BUILD_MAC
1991 if(SSLSetSessionOption && darwinver_maj >= 13) {
1992#else
1993 if(SSLSetSessionOption) {
1994#endif /* CURL_BUILD_MAC */
1995 bool break_on_auth = !conn->ssl_config.verifypeer ||
1996 ssl_cafile || ssl_cablob;
1997 err = SSLSetSessionOption(backend->ssl_ctx,
1998 kSSLSessionOptionBreakOnServerAuth,
1999 break_on_auth);
2000 if(err != noErr) {
2001 failf(data, "SSL: SSLSetSessionOption() failed: OSStatus %d", err);
2002 return CURLE_SSL_CONNECT_ERROR;
2003 }
2004 }
2005 else {
2006#if CURL_SUPPORT_MAC_10_8
2007 err = SSLSetEnableCertVerify(backend->ssl_ctx,
2008 conn->ssl_config.verifypeer?true:false);
2009 if(err != noErr) {
2010 failf(data, "SSL: SSLSetEnableCertVerify() failed: OSStatus %d", err);
2011 return CURLE_SSL_CONNECT_ERROR;
2012 }
2013#endif /* CURL_SUPPORT_MAC_10_8 */
2014 }
2015#else
2016 err = SSLSetEnableCertVerify(backend->ssl_ctx,
2017 conn->ssl_config.verifypeer?true:false);
2018 if(err != noErr) {
2019 failf(data, "SSL: SSLSetEnableCertVerify() failed: OSStatus %d", err);
2020 return CURLE_SSL_CONNECT_ERROR;
2021 }
2022#endif /* CURL_BUILD_MAC_10_6 || CURL_BUILD_IOS */
2023
2024 if((ssl_cafile || ssl_cablob) && verifypeer) {
2025 bool is_cert_data = ssl_cablob != NULL;
2026 bool is_cert_file = (!is_cert_data) && is_file(ssl_cafile);
2027
2028 if(!(is_cert_file || is_cert_data)) {
2029 failf(data, "SSL: can't load CA certificate file %s",
2030 ssl_cafile ? ssl_cafile : "(blob memory)");
2031 return CURLE_SSL_CACERT_BADFILE;
2032 }
2033 }
2034
2035 /* Configure hostname check. SNI is used if available.
2036 * Both hostname check and SNI require SSLSetPeerDomainName().
2037 * Also: the verifyhost setting influences SNI usage */
2038 if(conn->ssl_config.verifyhost) {
2039 size_t snilen;
2040 char *snihost = Curl_ssl_snihost(data, hostname, &snilen);
2041 if(!snihost) {
2042 failf(data, "Failed to set SNI");
2043 return CURLE_SSL_CONNECT_ERROR;
2044 }
2045 err = SSLSetPeerDomainName(backend->ssl_ctx, snihost, snilen);
2046
2047 if(err != noErr) {
2048 failf(data, "SSL: SSLSetPeerDomainName() failed: OSStatus %d",
2049 err);
2050 return CURLE_SSL_CONNECT_ERROR;
2051 }
2052
2053 if((Curl_inet_pton(AF_INET, hostname, &addr))
2054 #ifdef ENABLE_IPV6
2055 || (Curl_inet_pton(AF_INET6, hostname, &addr))
2056 #endif
2057 ) {
2058 infof(data, "WARNING: using IP address, SNI is being disabled by "
2059 "the OS.");
2060 }
2061 }
2062 else {
2063 infof(data, "WARNING: disabling hostname validation also disables SNI.");
2064 }
2065
2066 ciphers = SSL_CONN_CONFIG(cipher_list);
2067 if(ciphers) {
2068 err = sectransp_set_selected_ciphers(data, backend->ssl_ctx, ciphers);
2069 }
2070 else {
2071 err = sectransp_set_default_ciphers(data, backend->ssl_ctx);
2072 }
2073 if(err != noErr) {
2074 failf(data, "SSL: Unable to set ciphers for SSL/TLS handshake. "
2075 "Error code: %d", err);
2076 return CURLE_SSL_CIPHER;
2077 }
2078
2079#if CURL_BUILD_MAC_10_9 || CURL_BUILD_IOS_7
2080 /* We want to enable 1/n-1 when using a CBC cipher unless the user
2081 specifically doesn't want us doing that: */
2082 if(SSLSetSessionOption) {
2083 SSLSetSessionOption(backend->ssl_ctx, kSSLSessionOptionSendOneByteRecord,
2084 !SSL_SET_OPTION(enable_beast));
2085 SSLSetSessionOption(backend->ssl_ctx, kSSLSessionOptionFalseStart,
2086 data->set.ssl.falsestart); /* false start support */
2087 }
2088#endif /* CURL_BUILD_MAC_10_9 || CURL_BUILD_IOS_7 */
2089
2090 /* Check if there's a cached ID we can/should use here! */
2091 if(SSL_SET_OPTION(primary.sessionid)) {
2092 char *ssl_sessionid;
2093 size_t ssl_sessionid_len;
2094
2095 Curl_ssl_sessionid_lock(data);
2096 if(!Curl_ssl_getsessionid(data, conn, isproxy, (void **)&ssl_sessionid,
2097 &ssl_sessionid_len, sockindex)) {
2098 /* we got a session id, use it! */
2099 err = SSLSetPeerID(backend->ssl_ctx, ssl_sessionid, ssl_sessionid_len);
2100 Curl_ssl_sessionid_unlock(data);
2101 if(err != noErr) {
2102 failf(data, "SSL: SSLSetPeerID() failed: OSStatus %d", err);
2103 return CURLE_SSL_CONNECT_ERROR;
2104 }
2105 /* Informational message */
2106 infof(data, "SSL re-using session ID");
2107 }
2108 /* If there isn't one, then let's make one up! This has to be done prior
2109 to starting the handshake. */
2110 else {
2111 CURLcode result;
2112 ssl_sessionid =
2113 aprintf("%s:%d:%d:%s:%ld",
2114 ssl_cafile ? ssl_cafile : "(blob memory)",
2115 verifypeer, SSL_CONN_CONFIG(verifyhost), hostname, port);
2116 ssl_sessionid_len = strlen(ssl_sessionid);
2117
2118 err = SSLSetPeerID(backend->ssl_ctx, ssl_sessionid, ssl_sessionid_len);
2119 if(err != noErr) {
2120 Curl_ssl_sessionid_unlock(data);
2121 failf(data, "SSL: SSLSetPeerID() failed: OSStatus %d", err);
2122 return CURLE_SSL_CONNECT_ERROR;
2123 }
2124
2125 result = Curl_ssl_addsessionid(data, conn, isproxy, ssl_sessionid,
2126 ssl_sessionid_len, sockindex, NULL);
2127 Curl_ssl_sessionid_unlock(data);
2128 if(result) {
2129 failf(data, "failed to store ssl session");
2130 return result;
2131 }
2132 }
2133 }
2134
2135 err = SSLSetIOFuncs(backend->ssl_ctx, SocketRead, SocketWrite);
2136 if(err != noErr) {
2137 failf(data, "SSL: SSLSetIOFuncs() failed: OSStatus %d", err);
2138 return CURLE_SSL_CONNECT_ERROR;
2139 }
2140
2141 /* pass the raw socket into the SSL layers */
2142 /* We need to store the FD in a constant memory address, because
2143 * SSLSetConnection() will not copy that address. I've found that
2144 * conn->sock[sockindex] may change on its own. */
2145 backend->ssl_sockfd = sockfd;
2146 err = SSLSetConnection(backend->ssl_ctx, connssl);
2147 if(err != noErr) {
2148 failf(data, "SSL: SSLSetConnection() failed: %d", err);
2149 return CURLE_SSL_CONNECT_ERROR;
2150 }
2151
2152 connssl->connecting_state = ssl_connect_2;
2153 return CURLE_OK;
2154}
2155
2156static long pem_to_der(const char *in, unsigned char **out, size_t *outlen)
2157{
2158 char *sep_start, *sep_end, *cert_start, *cert_end;
2159 size_t i, j, err;
2160 size_t len;
2161 unsigned char *b64;
2162
2163 /* Jump through the separators at the beginning of the certificate. */
2164 sep_start = strstr(in, "-----");
2165 if(!sep_start)
2166 return 0;
2167 cert_start = strstr(sep_start + 1, "-----");
2168 if(!cert_start)
2169 return -1;
2170
2171 cert_start += 5;
2172
2173 /* Find separator after the end of the certificate. */
2174 cert_end = strstr(cert_start, "-----");
2175 if(!cert_end)
2176 return -1;
2177
2178 sep_end = strstr(cert_end + 1, "-----");
2179 if(!sep_end)
2180 return -1;
2181 sep_end += 5;
2182
2183 len = cert_end - cert_start;
2184 b64 = malloc(len + 1);
2185 if(!b64)
2186 return -1;
2187
2188 /* Create base64 string without linefeeds. */
2189 for(i = 0, j = 0; i < len; i++) {
2190 if(cert_start[i] != '\r' && cert_start[i] != '\n')
2191 b64[j++] = cert_start[i];
2192 }
2193 b64[j] = '\0';
2194
2195 err = Curl_base64_decode((const char *)b64, out, outlen);
2196 free(b64);
2197 if(err) {
2198 free(*out);
2199 return -1;
2200 }
2201
2202 return sep_end - in;
2203}
2204
2205static int read_cert(const char *file, unsigned char **out, size_t *outlen)
2206{
2207 int fd;
2208 ssize_t n, len = 0, cap = 512;
2209 unsigned char buf[512], *data;
2210
2211 fd = open(file, 0);
2212 if(fd < 0)
2213 return -1;
2214
2215 data = malloc(cap);
2216 if(!data) {
2217 close(fd);
2218 return -1;
2219 }
2220
2221 for(;;) {
2222 n = read(fd, buf, sizeof(buf));
2223 if(n < 0) {
2224 close(fd);
2225 free(data);
2226 return -1;
2227 }
2228 else if(n == 0) {
2229 close(fd);
2230 break;
2231 }
2232
2233 if(len + n >= cap) {
2234 cap *= 2;
2235 data = Curl_saferealloc(data, cap);
2236 if(!data) {
2237 close(fd);
2238 return -1;
2239 }
2240 }
2241
2242 memcpy(data + len, buf, n);
2243 len += n;
2244 }
2245 data[len] = '\0';
2246
2247 *out = data;
2248 *outlen = len;
2249
2250 return 0;
2251}
2252
2253static int append_cert_to_array(struct Curl_easy *data,
2254 const unsigned char *buf, size_t buflen,
2255 CFMutableArrayRef array)
2256{
2257 CFDataRef certdata = CFDataCreate(kCFAllocatorDefault, buf, buflen);
2258 char *certp;
2259 CURLcode result;
2260 if(!certdata) {
2261 failf(data, "SSL: failed to allocate array for CA certificate");
2262 return CURLE_OUT_OF_MEMORY;
2263 }
2264
2265 SecCertificateRef cacert =
2266 SecCertificateCreateWithData(kCFAllocatorDefault, certdata);
2267 CFRelease(certdata);
2268 if(!cacert) {
2269 failf(data, "SSL: failed to create SecCertificate from CA certificate");
2270 return CURLE_SSL_CACERT_BADFILE;
2271 }
2272
2273 /* Check if cacert is valid. */
2274 result = CopyCertSubject(data, cacert, &certp);
2275 switch(result) {
2276 case CURLE_OK:
2277 break;
2278 case CURLE_PEER_FAILED_VERIFICATION:
2279 return CURLE_SSL_CACERT_BADFILE;
2280 case CURLE_OUT_OF_MEMORY:
2281 default:
2282 return result;
2283 }
2284 free(certp);
2285
2286 CFArrayAppendValue(array, cacert);
2287 CFRelease(cacert);
2288
2289 return CURLE_OK;
2290}
2291
2292static CURLcode verify_cert_buf(struct Curl_easy *data,
2293 const unsigned char *certbuf, size_t buflen,
2294 SSLContextRef ctx)
2295{
2296 int n = 0, rc;
2297 long res;
2298 unsigned char *der;
2299 size_t derlen, offset = 0;
2300
2301 /*
2302 * Certbuf now contains the contents of the certificate file, which can be
2303 * - a single DER certificate,
2304 * - a single PEM certificate or
2305 * - a bunch of PEM certificates (certificate bundle).
2306 *
2307 * Go through certbuf, and convert any PEM certificate in it into DER
2308 * format.
2309 */
2310 CFMutableArrayRef array = CFArrayCreateMutable(kCFAllocatorDefault, 0,
2311 &kCFTypeArrayCallBacks);
2312 if(!array) {
2313 failf(data, "SSL: out of memory creating CA certificate array");
2314 return CURLE_OUT_OF_MEMORY;
2315 }
2316
2317 while(offset < buflen) {
2318 n++;
2319
2320 /*
2321 * Check if the certificate is in PEM format, and convert it to DER. If
2322 * this fails, we assume the certificate is in DER format.
2323 */
2324 res = pem_to_der((const char *)certbuf + offset, &der, &derlen);
2325 if(res < 0) {
2326 CFRelease(array);
2327 failf(data, "SSL: invalid CA certificate #%d (offset %zu) in bundle",
2328 n, offset);
2329 return CURLE_SSL_CACERT_BADFILE;
2330 }
2331 offset += res;
2332
2333 if(res == 0 && offset == 0) {
2334 /* This is not a PEM file, probably a certificate in DER format. */
2335 rc = append_cert_to_array(data, certbuf, buflen, array);
2336 if(rc != CURLE_OK) {
2337 CFRelease(array);
2338 return rc;
2339 }
2340 break;
2341 }
2342 else if(res == 0) {
2343 /* No more certificates in the bundle. */
2344 break;
2345 }
2346
2347 rc = append_cert_to_array(data, der, derlen, array);
2348 free(der);
2349 if(rc != CURLE_OK) {
2350 CFRelease(array);
2351 return rc;
2352 }
2353 }
2354
2355 SecTrustRef trust;
2356 OSStatus ret = SSLCopyPeerTrust(ctx, &trust);
2357 if(!trust) {
2358 failf(data, "SSL: error getting certificate chain");
2359 CFRelease(array);
2360 return CURLE_PEER_FAILED_VERIFICATION;
2361 }
2362 else if(ret != noErr) {
2363 CFRelease(array);
2364 failf(data, "SSLCopyPeerTrust() returned error %d", ret);
2365 return CURLE_PEER_FAILED_VERIFICATION;
2366 }
2367
2368 ret = SecTrustSetAnchorCertificates(trust, array);
2369 if(ret != noErr) {
2370 CFRelease(array);
2371 CFRelease(trust);
2372 failf(data, "SecTrustSetAnchorCertificates() returned error %d", ret);
2373 return CURLE_PEER_FAILED_VERIFICATION;
2374 }
2375 ret = SecTrustSetAnchorCertificatesOnly(trust, true);
2376 if(ret != noErr) {
2377 CFRelease(array);
2378 CFRelease(trust);
2379 failf(data, "SecTrustSetAnchorCertificatesOnly() returned error %d", ret);
2380 return CURLE_PEER_FAILED_VERIFICATION;
2381 }
2382
2383 SecTrustResultType trust_eval = 0;
2384 ret = SecTrustEvaluate(trust, &trust_eval);
2385 CFRelease(array);
2386 CFRelease(trust);
2387 if(ret != noErr) {
2388 failf(data, "SecTrustEvaluate() returned error %d", ret);
2389 return CURLE_PEER_FAILED_VERIFICATION;
2390 }
2391
2392 switch(trust_eval) {
2393 case kSecTrustResultUnspecified:
2394 case kSecTrustResultProceed:
2395 return CURLE_OK;
2396
2397 case kSecTrustResultRecoverableTrustFailure:
2398 case kSecTrustResultDeny:
2399 default:
2400 failf(data, "SSL: certificate verification failed (result: %d)",
2401 trust_eval);
2402 return CURLE_PEER_FAILED_VERIFICATION;
2403 }
2404}
2405
2406static CURLcode verify_cert(struct Curl_easy *data, const char *cafile,
2407 const struct curl_blob *ca_info_blob,
2408 SSLContextRef ctx)
2409{
2410 int result;
2411 unsigned char *certbuf;
2412 size_t buflen;
2413
2414 if(ca_info_blob) {
2415 certbuf = (unsigned char *)malloc(ca_info_blob->len + 1);
2416 if(!certbuf) {
2417 return CURLE_OUT_OF_MEMORY;
2418 }
2419 buflen = ca_info_blob->len;
2420 memcpy(certbuf, ca_info_blob->data, ca_info_blob->len);
2421 certbuf[ca_info_blob->len]='\0';
2422 }
2423 else if(cafile) {
2424 if(read_cert(cafile, &certbuf, &buflen) < 0) {
2425 failf(data, "SSL: failed to read or invalid CA certificate");
2426 return CURLE_SSL_CACERT_BADFILE;
2427 }
2428 }
2429 else
2430 return CURLE_SSL_CACERT_BADFILE;
2431
2432 result = verify_cert_buf(data, certbuf, buflen, ctx);
2433 free(certbuf);
2434 return result;
2435}
2436
2437
2438#ifdef SECTRANSP_PINNEDPUBKEY
2439static CURLcode pkp_pin_peer_pubkey(struct Curl_easy *data,
2440 SSLContextRef ctx,
2441 const char *pinnedpubkey)
2442{ /* Scratch */
2443 size_t pubkeylen, realpubkeylen, spkiHeaderLength = 24;
2444 unsigned char *pubkey = NULL, *realpubkey = NULL;
2445 const unsigned char *spkiHeader = NULL;
2446 CFDataRef publicKeyBits = NULL;
2447
2448 /* Result is returned to caller */
2449 CURLcode result = CURLE_SSL_PINNEDPUBKEYNOTMATCH;
2450
2451 /* if a path wasn't specified, don't pin */
2452 if(!pinnedpubkey)
2453 return CURLE_OK;
2454
2455
2456 if(!ctx)
2457 return result;
2458
2459 do {
2460 SecTrustRef trust;
2461 OSStatus ret = SSLCopyPeerTrust(ctx, &trust);
2462 if(ret != noErr || !trust)
2463 break;
2464
2465 SecKeyRef keyRef = SecTrustCopyPublicKey(trust);
2466 CFRelease(trust);
2467 if(!keyRef)
2468 break;
2469
2470#ifdef SECTRANSP_PINNEDPUBKEY_V1
2471
2472 publicKeyBits = SecKeyCopyExternalRepresentation(keyRef, NULL);
2473 CFRelease(keyRef);
2474 if(!publicKeyBits)
2475 break;
2476
2477#elif SECTRANSP_PINNEDPUBKEY_V2
2478
2479 OSStatus success = SecItemExport(keyRef, kSecFormatOpenSSL, 0, NULL,
2480 &publicKeyBits);
2481 CFRelease(keyRef);
2482 if(success != errSecSuccess || !publicKeyBits)
2483 break;
2484
2485#endif /* SECTRANSP_PINNEDPUBKEY_V2 */
2486
2487 pubkeylen = CFDataGetLength(publicKeyBits);
2488 pubkey = (unsigned char *)CFDataGetBytePtr(publicKeyBits);
2489
2490 switch(pubkeylen) {
2491 case 526:
2492 /* 4096 bit RSA pubkeylen == 526 */
2493 spkiHeader = rsa4096SpkiHeader;
2494 break;
2495 case 270:
2496 /* 2048 bit RSA pubkeylen == 270 */
2497 spkiHeader = rsa2048SpkiHeader;
2498 break;
2499#ifdef SECTRANSP_PINNEDPUBKEY_V1
2500 case 65:
2501 /* ecDSA secp256r1 pubkeylen == 65 */
2502 spkiHeader = ecDsaSecp256r1SpkiHeader;
2503 spkiHeaderLength = 26;
2504 break;
2505 case 97:
2506 /* ecDSA secp384r1 pubkeylen == 97 */
2507 spkiHeader = ecDsaSecp384r1SpkiHeader;
2508 spkiHeaderLength = 23;
2509 break;
2510 default:
2511 infof(data, "SSL: unhandled public key length: %d", pubkeylen);
2512#elif SECTRANSP_PINNEDPUBKEY_V2
2513 default:
2514 /* ecDSA secp256r1 pubkeylen == 91 header already included?
2515 * ecDSA secp384r1 header already included too
2516 * we assume rest of algorithms do same, so do nothing
2517 */
2518 result = Curl_pin_peer_pubkey(data, pinnedpubkey, pubkey,
2519 pubkeylen);
2520#endif /* SECTRANSP_PINNEDPUBKEY_V2 */
2521 continue; /* break from loop */
2522 }
2523
2524 realpubkeylen = pubkeylen + spkiHeaderLength;
2525 realpubkey = malloc(realpubkeylen);
2526 if(!realpubkey)
2527 break;
2528
2529 memcpy(realpubkey, spkiHeader, spkiHeaderLength);
2530 memcpy(realpubkey + spkiHeaderLength, pubkey, pubkeylen);
2531
2532 result = Curl_pin_peer_pubkey(data, pinnedpubkey, realpubkey,
2533 realpubkeylen);
2534
2535 } while(0);
2536
2537 Curl_safefree(realpubkey);
2538 if(publicKeyBits)
2539 CFRelease(publicKeyBits);
2540
2541 return result;
2542}
2543#endif /* SECTRANSP_PINNEDPUBKEY */
2544
2545static CURLcode
2546sectransp_connect_step2(struct Curl_easy *data, struct connectdata *conn,
2547 int sockindex)
2548{
2549 struct ssl_connect_data *connssl = &conn->ssl[sockindex];
2550 struct ssl_backend_data *backend = connssl->backend;
2551 OSStatus err;
2552 SSLCipherSuite cipher;
2553 SSLProtocol protocol = 0;
2554 const char * const hostname = SSL_HOST_NAME();
2555
2556 DEBUGASSERT(ssl_connect_2 == connssl->connecting_state
2557 || ssl_connect_2_reading == connssl->connecting_state
2558 || ssl_connect_2_writing == connssl->connecting_state);
2559 DEBUGASSERT(backend);
2560
2561 /* Here goes nothing: */
2562 err = SSLHandshake(backend->ssl_ctx);
2563
2564 if(err != noErr) {
2565 switch(err) {
2566 case errSSLWouldBlock: /* they're not done with us yet */
2567 connssl->connecting_state = backend->ssl_direction ?
2568 ssl_connect_2_writing : ssl_connect_2_reading;
2569 return CURLE_OK;
2570
2571 /* The below is errSSLServerAuthCompleted; it's not defined in
2572 Leopard's headers */
2573 case -9841:
2574 if((SSL_CONN_CONFIG(CAfile) || SSL_CONN_CONFIG(ca_info_blob)) &&
2575 SSL_CONN_CONFIG(verifypeer)) {
2576 CURLcode result = verify_cert(data, SSL_CONN_CONFIG(CAfile),
2577 SSL_CONN_CONFIG(ca_info_blob),
2578 backend->ssl_ctx);
2579 if(result)
2580 return result;
2581 }
2582 /* the documentation says we need to call SSLHandshake() again */
2583 return sectransp_connect_step2(data, conn, sockindex);
2584
2585 /* Problem with encrypt / decrypt */
2586 case errSSLPeerDecodeError:
2587 failf(data, "Decode failed");
2588 break;
2589 case errSSLDecryptionFail:
2590 case errSSLPeerDecryptionFail:
2591 failf(data, "Decryption failed");
2592 break;
2593 case errSSLPeerDecryptError:
2594 failf(data, "A decryption error occurred");
2595 break;
2596 case errSSLBadCipherSuite:
2597 failf(data, "A bad SSL cipher suite was encountered");
2598 break;
2599 case errSSLCrypto:
2600 failf(data, "An underlying cryptographic error was encountered");
2601 break;
2602#if CURL_BUILD_MAC_10_11 || CURL_BUILD_IOS_9
2603 case errSSLWeakPeerEphemeralDHKey:
2604 failf(data, "Indicates a weak ephemeral Diffie-Hellman key");
2605 break;
2606#endif
2607
2608 /* Problem with the message record validation */
2609 case errSSLBadRecordMac:
2610 case errSSLPeerBadRecordMac:
2611 failf(data, "A record with a bad message authentication code (MAC) "
2612 "was encountered");
2613 break;
2614 case errSSLRecordOverflow:
2615 case errSSLPeerRecordOverflow:
2616 failf(data, "A record overflow occurred");
2617 break;
2618
2619 /* Problem with zlib decompression */
2620 case errSSLPeerDecompressFail:
2621 failf(data, "Decompression failed");
2622 break;
2623
2624 /* Problem with access */
2625 case errSSLPeerAccessDenied:
2626 failf(data, "Access was denied");
2627 break;
2628 case errSSLPeerInsufficientSecurity:
2629 failf(data, "There is insufficient security for this operation");
2630 break;
2631
2632 /* These are all certificate problems with the server: */
2633 case errSSLXCertChainInvalid:
2634 failf(data, "SSL certificate problem: Invalid certificate chain");
2635 return CURLE_PEER_FAILED_VERIFICATION;
2636 case errSSLUnknownRootCert:
2637 failf(data, "SSL certificate problem: Untrusted root certificate");
2638 return CURLE_PEER_FAILED_VERIFICATION;
2639 case errSSLNoRootCert:
2640 failf(data, "SSL certificate problem: No root certificate");
2641 return CURLE_PEER_FAILED_VERIFICATION;
2642 case errSSLCertNotYetValid:
2643 failf(data, "SSL certificate problem: The certificate chain had a "
2644 "certificate that is not yet valid");
2645 return CURLE_PEER_FAILED_VERIFICATION;
2646 case errSSLCertExpired:
2647 case errSSLPeerCertExpired:
2648 failf(data, "SSL certificate problem: Certificate chain had an "
2649 "expired certificate");
2650 return CURLE_PEER_FAILED_VERIFICATION;
2651 case errSSLBadCert:
2652 case errSSLPeerBadCert:
2653 failf(data, "SSL certificate problem: Couldn't understand the server "
2654 "certificate format");
2655 return CURLE_PEER_FAILED_VERIFICATION;
2656 case errSSLPeerUnsupportedCert:
2657 failf(data, "SSL certificate problem: An unsupported certificate "
2658 "format was encountered");
2659 return CURLE_PEER_FAILED_VERIFICATION;
2660 case errSSLPeerCertRevoked:
2661 failf(data, "SSL certificate problem: The certificate was revoked");
2662 return CURLE_PEER_FAILED_VERIFICATION;
2663 case errSSLPeerCertUnknown:
2664 failf(data, "SSL certificate problem: The certificate is unknown");
2665 return CURLE_PEER_FAILED_VERIFICATION;
2666
2667 /* These are all certificate problems with the client: */
2668 case errSecAuthFailed:
2669 failf(data, "SSL authentication failed");
2670 break;
2671 case errSSLPeerHandshakeFail:
2672 failf(data, "SSL peer handshake failed, the server most likely "
2673 "requires a client certificate to connect");
2674 break;
2675 case errSSLPeerUnknownCA:
2676 failf(data, "SSL server rejected the client certificate due to "
2677 "the certificate being signed by an unknown certificate "
2678 "authority");
2679 break;
2680
2681 /* This error is raised if the server's cert didn't match the server's
2682 host name: */
2683 case errSSLHostNameMismatch:
2684 failf(data, "SSL certificate peer verification failed, the "
2685 "certificate did not match \"%s\"\n", conn->host.dispname);
2686 return CURLE_PEER_FAILED_VERIFICATION;
2687
2688 /* Problem with SSL / TLS negotiation */
2689 case errSSLNegotiation:
2690 failf(data, "Could not negotiate an SSL cipher suite with the server");
2691 break;
2692 case errSSLBadConfiguration:
2693 failf(data, "A configuration error occurred");
2694 break;
2695 case errSSLProtocol:
2696 failf(data, "SSL protocol error");
2697 break;
2698 case errSSLPeerProtocolVersion:
2699 failf(data, "A bad protocol version was encountered");
2700 break;
2701 case errSSLPeerNoRenegotiation:
2702 failf(data, "No renegotiation is allowed");
2703 break;
2704
2705 /* Generic handshake errors: */
2706 case errSSLConnectionRefused:
2707 failf(data, "Server dropped the connection during the SSL handshake");
2708 break;
2709 case errSSLClosedAbort:
2710 failf(data, "Server aborted the SSL handshake");
2711 break;
2712 case errSSLClosedGraceful:
2713 failf(data, "The connection closed gracefully");
2714 break;
2715 case errSSLClosedNoNotify:
2716 failf(data, "The server closed the session with no notification");
2717 break;
2718 /* Sometimes paramErr happens with buggy ciphers: */
2719 case paramErr:
2720 case errSSLInternal:
2721 case errSSLPeerInternalError:
2722 failf(data, "Internal SSL engine error encountered during the "
2723 "SSL handshake");
2724 break;
2725 case errSSLFatalAlert:
2726 failf(data, "Fatal SSL engine error encountered during the SSL "
2727 "handshake");
2728 break;
2729 /* Unclassified error */
2730 case errSSLBufferOverflow:
2731 failf(data, "An insufficient buffer was provided");
2732 break;
2733 case errSSLIllegalParam:
2734 failf(data, "An illegal parameter was encountered");
2735 break;
2736 case errSSLModuleAttach:
2737 failf(data, "Module attach failure");
2738 break;
2739 case errSSLSessionNotFound:
2740 failf(data, "An attempt to restore an unknown session failed");
2741 break;
2742 case errSSLPeerExportRestriction:
2743 failf(data, "An export restriction occurred");
2744 break;
2745 case errSSLPeerUserCancelled:
2746 failf(data, "The user canceled the operation");
2747 break;
2748 case errSSLPeerUnexpectedMsg:
2749 failf(data, "Peer rejected unexpected message");
2750 break;
2751#if CURL_BUILD_MAC_10_11 || CURL_BUILD_IOS_9
2752 /* Treaing non-fatal error as fatal like before */
2753 case errSSLClientHelloReceived:
2754 failf(data, "A non-fatal result for providing a server name "
2755 "indication");
2756 break;
2757#endif
2758
2759 /* Error codes defined in the enum but should never be returned.
2760 We list them here just in case. */
2761#if CURL_BUILD_MAC_10_6
2762 /* Only returned when kSSLSessionOptionBreakOnCertRequested is set */
2763 case errSSLClientCertRequested:
2764 failf(data, "Server requested a client certificate during the "
2765 "handshake");
2766 return CURLE_SSL_CLIENTCERT;
2767#endif
2768#if CURL_BUILD_MAC_10_9
2769 /* Alias for errSSLLast, end of error range */
2770 case errSSLUnexpectedRecord:
2771 failf(data, "Unexpected (skipped) record in DTLS");
2772 break;
2773#endif
2774 default:
2775 /* May also return codes listed in Security Framework Result Codes */
2776 failf(data, "Unknown SSL protocol error in connection to %s:%d",
2777 hostname, err);
2778 break;
2779 }
2780 return CURLE_SSL_CONNECT_ERROR;
2781 }
2782 else {
2783 /* we have been connected fine, we're not waiting for anything else. */
2784 connssl->connecting_state = ssl_connect_3;
2785
2786#ifdef SECTRANSP_PINNEDPUBKEY
2787 if(data->set.str[STRING_SSL_PINNEDPUBLICKEY]) {
2788 CURLcode result =
2789 pkp_pin_peer_pubkey(data, backend->ssl_ctx,
2790 data->set.str[STRING_SSL_PINNEDPUBLICKEY]);
2791 if(result) {
2792 failf(data, "SSL: public key does not match pinned public key");
2793 return result;
2794 }
2795 }
2796#endif /* SECTRANSP_PINNEDPUBKEY */
2797
2798 /* Informational message */
2799 (void)SSLGetNegotiatedCipher(backend->ssl_ctx, &cipher);
2800 (void)SSLGetNegotiatedProtocolVersion(backend->ssl_ctx, &protocol);
2801 switch(protocol) {
2802 case kSSLProtocol2:
2803 infof(data, "SSL 2.0 connection using %s",
2804 TLSCipherNameForNumber(cipher));
2805 break;
2806 case kSSLProtocol3:
2807 infof(data, "SSL 3.0 connection using %s",
2808 TLSCipherNameForNumber(cipher));
2809 break;
2810 case kTLSProtocol1:
2811 infof(data, "TLS 1.0 connection using %s",
2812 TLSCipherNameForNumber(cipher));
2813 break;
2814#if CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS
2815 case kTLSProtocol11:
2816 infof(data, "TLS 1.1 connection using %s",
2817 TLSCipherNameForNumber(cipher));
2818 break;
2819 case kTLSProtocol12:
2820 infof(data, "TLS 1.2 connection using %s",
2821 TLSCipherNameForNumber(cipher));
2822 break;
2823#endif /* CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS */
2824#if CURL_BUILD_MAC_10_13 || CURL_BUILD_IOS_11
2825 case kTLSProtocol13:
2826 infof(data, "TLS 1.3 connection using %s",
2827 TLSCipherNameForNumber(cipher));
2828 break;
2829#endif /* CURL_BUILD_MAC_10_13 || CURL_BUILD_IOS_11 */
2830 default:
2831 infof(data, "Unknown protocol connection");
2832 break;
2833 }
2834
2835#if(CURL_BUILD_MAC_10_13 || CURL_BUILD_IOS_11) && HAVE_BUILTIN_AVAILABLE == 1
2836 if(conn->bits.tls_enable_alpn) {
2837 if(__builtin_available(macOS 10.13.4, iOS 11, tvOS 11, *)) {
2838 CFArrayRef alpnArr = NULL;
2839 CFStringRef chosenProtocol = NULL;
2840 err = SSLCopyALPNProtocols(backend->ssl_ctx, &alpnArr);
2841
2842 if(err == noErr && alpnArr && CFArrayGetCount(alpnArr) >= 1)
2843 chosenProtocol = CFArrayGetValueAtIndex(alpnArr, 0);
2844
2845#ifdef USE_HTTP2
2846 if(chosenProtocol &&
2847 !CFStringCompare(chosenProtocol, CFSTR(ALPN_H2), 0)) {
2848 conn->negnpn = CURL_HTTP_VERSION_2;
2849 }
2850 else
2851#endif
2852 if(chosenProtocol &&
2853 !CFStringCompare(chosenProtocol, CFSTR(ALPN_HTTP_1_1), 0)) {
2854 conn->negnpn = CURL_HTTP_VERSION_1_1;
2855 }
2856 else
2857 infof(data, VTLS_INFOF_NO_ALPN);
2858
2859 Curl_multiuse_state(data, conn->negnpn == CURL_HTTP_VERSION_2 ?
2860 BUNDLE_MULTIPLEX : BUNDLE_NO_MULTIUSE);
2861
2862 /* chosenProtocol is a reference to the string within alpnArr
2863 and doesn't need to be freed separately */
2864 if(alpnArr)
2865 CFRelease(alpnArr);
2866 }
2867 }
2868#endif
2869
2870 return CURLE_OK;
2871 }
2872}
2873
2874static CURLcode
2875add_cert_to_certinfo(struct Curl_easy *data,
2876 SecCertificateRef server_cert,
2877 int idx)
2878{
2879 CURLcode result = CURLE_OK;
2880 const char *beg;
2881 const char *end;
2882 CFDataRef cert_data = SecCertificateCopyData(server_cert);
2883
2884 if(!cert_data)
2885 return CURLE_PEER_FAILED_VERIFICATION;
2886
2887 beg = (const char *)CFDataGetBytePtr(cert_data);
2888 end = beg + CFDataGetLength(cert_data);
2889 result = Curl_extract_certinfo(data, idx, beg, end);
2890 CFRelease(cert_data);
2891 return result;
2892}
2893
2894static CURLcode
2895collect_server_cert_single(struct Curl_easy *data,
2896 SecCertificateRef server_cert,
2897 CFIndex idx)
2898{
2899 CURLcode result = CURLE_OK;
2900#ifndef CURL_DISABLE_VERBOSE_STRINGS
2901 if(data->set.verbose) {
2902 char *certp;
2903 result = CopyCertSubject(data, server_cert, &certp);
2904 if(!result) {
2905 infof(data, "Server certificate: %s", certp);
2906 free(certp);
2907 }
2908 }
2909#endif
2910 if(data->set.ssl.certinfo)
2911 result = add_cert_to_certinfo(data, server_cert, (int)idx);
2912 return result;
2913}
2914
2915/* This should be called during step3 of the connection at the earliest */
2916static CURLcode
2917collect_server_cert(struct Curl_easy *data,
2918 struct connectdata *conn,
2919 int sockindex)
2920{
2921#ifndef CURL_DISABLE_VERBOSE_STRINGS
2922 const bool show_verbose_server_cert = data->set.verbose;
2923#else
2924 const bool show_verbose_server_cert = false;
2925#endif
2926 CURLcode result = data->set.ssl.certinfo ?
2927 CURLE_PEER_FAILED_VERIFICATION : CURLE_OK;
2928 struct ssl_connect_data *connssl = &conn->ssl[sockindex];
2929 struct ssl_backend_data *backend = connssl->backend;
2930 CFArrayRef server_certs = NULL;
2931 SecCertificateRef server_cert;
2932 OSStatus err;
2933 CFIndex i, count;
2934 SecTrustRef trust = NULL;
2935
2936 DEBUGASSERT(backend);
2937
2938 if(!show_verbose_server_cert && !data->set.ssl.certinfo)
2939 return CURLE_OK;
2940
2941 if(!backend->ssl_ctx)
2942 return result;
2943
2944#if CURL_BUILD_MAC_10_7 || CURL_BUILD_IOS
2945#if CURL_BUILD_IOS
2946#pragma unused(server_certs)
2947 err = SSLCopyPeerTrust(backend->ssl_ctx, &trust);
2948 /* For some reason, SSLCopyPeerTrust() can return noErr and yet return
2949 a null trust, so be on guard for that: */
2950 if(err == noErr && trust) {
2951 count = SecTrustGetCertificateCount(trust);
2952 if(data->set.ssl.certinfo)
2953 result = Curl_ssl_init_certinfo(data, (int)count);
2954 for(i = 0L ; !result && (i < count) ; i++) {
2955 server_cert = SecTrustGetCertificateAtIndex(trust, i);
2956 result = collect_server_cert_single(data, server_cert, i);
2957 }
2958 CFRelease(trust);
2959 }
2960#else
2961 /* SSLCopyPeerCertificates() is deprecated as of Mountain Lion.
2962 The function SecTrustGetCertificateAtIndex() is officially present
2963 in Lion, but it is unfortunately also present in Snow Leopard as
2964 private API and doesn't work as expected. So we have to look for
2965 a different symbol to make sure this code is only executed under
2966 Lion or later. */
2967 if(SecTrustEvaluateAsync) {
2968#pragma unused(server_certs)
2969 err = SSLCopyPeerTrust(backend->ssl_ctx, &trust);
2970 /* For some reason, SSLCopyPeerTrust() can return noErr and yet return
2971 a null trust, so be on guard for that: */
2972 if(err == noErr && trust) {
2973 count = SecTrustGetCertificateCount(trust);
2974 if(data->set.ssl.certinfo)
2975 result = Curl_ssl_init_certinfo(data, (int)count);
2976 for(i = 0L ; !result && (i < count) ; i++) {
2977 server_cert = SecTrustGetCertificateAtIndex(trust, i);
2978 result = collect_server_cert_single(data, server_cert, i);
2979 }
2980 CFRelease(trust);
2981 }
2982 }
2983 else {
2984#if CURL_SUPPORT_MAC_10_8
2985 err = SSLCopyPeerCertificates(backend->ssl_ctx, &server_certs);
2986 /* Just in case SSLCopyPeerCertificates() returns null too... */
2987 if(err == noErr && server_certs) {
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,
2993 i);
2994 result = collect_server_cert_single(data, server_cert, i);
2995 }
2996 CFRelease(server_certs);
2997 }
2998#endif /* CURL_SUPPORT_MAC_10_8 */
2999 }
3000#endif /* CURL_BUILD_IOS */
3001#else
3002#pragma unused(trust)
3003 err = SSLCopyPeerCertificates(backend->ssl_ctx, &server_certs);
3004 if(err == noErr) {
3005 count = CFArrayGetCount(server_certs);
3006 if(data->set.ssl.certinfo)
3007 result = Curl_ssl_init_certinfo(data, (int)count);
3008 for(i = 0L ; !result && (i < count) ; i++) {
3009 server_cert = (SecCertificateRef)CFArrayGetValueAtIndex(server_certs, i);
3010 result = collect_server_cert_single(data, server_cert, i);
3011 }
3012 CFRelease(server_certs);
3013 }
3014#endif /* CURL_BUILD_MAC_10_7 || CURL_BUILD_IOS */
3015 return result;
3016}
3017
3018static CURLcode
3019sectransp_connect_step3(struct Curl_easy *data, struct connectdata *conn,
3020 int sockindex)
3021{
3022 struct ssl_connect_data *connssl = &conn->ssl[sockindex];
3023
3024 /* There is no step 3!
3025 * Well, okay, let's collect server certificates, and if verbose mode is on,
3026 * let's print the details of the server certificates. */
3027 const CURLcode result = collect_server_cert(data, conn, sockindex);
3028 if(result)
3029 return result;
3030
3031 connssl->connecting_state = ssl_connect_done;
3032 return CURLE_OK;
3033}
3034
3035static Curl_recv sectransp_recv;
3036static Curl_send sectransp_send;
3037
3038static CURLcode
3039sectransp_connect_common(struct Curl_easy *data,
3040 struct connectdata *conn,
3041 int sockindex,
3042 bool nonblocking,
3043 bool *done)
3044{
3045 CURLcode result;
3046 struct ssl_connect_data *connssl = &conn->ssl[sockindex];
3047 curl_socket_t sockfd = conn->sock[sockindex];
3048 int what;
3049
3050 /* check if the connection has already been established */
3051 if(ssl_connection_complete == connssl->state) {
3052 *done = TRUE;
3053 return CURLE_OK;
3054 }
3055
3056 if(ssl_connect_1 == connssl->connecting_state) {
3057 /* Find out how much more time we're allowed */
3058 const timediff_t timeout_ms = Curl_timeleft(data, NULL, TRUE);
3059
3060 if(timeout_ms < 0) {
3061 /* no need to continue if time already is up */
3062 failf(data, "SSL connection timeout");
3063 return CURLE_OPERATION_TIMEDOUT;
3064 }
3065
3066 result = sectransp_connect_step1(data, conn, sockindex);
3067 if(result)
3068 return result;
3069 }
3070
3071 while(ssl_connect_2 == connssl->connecting_state ||
3072 ssl_connect_2_reading == connssl->connecting_state ||
3073 ssl_connect_2_writing == connssl->connecting_state) {
3074
3075 /* check allowed time left */
3076 const timediff_t timeout_ms = Curl_timeleft(data, NULL, TRUE);
3077
3078 if(timeout_ms < 0) {
3079 /* no need to continue if time already is up */
3080 failf(data, "SSL connection timeout");
3081 return CURLE_OPERATION_TIMEDOUT;
3082 }
3083
3084 /* if ssl is expecting something, check if it's available. */
3085 if(connssl->connecting_state == ssl_connect_2_reading ||
3086 connssl->connecting_state == ssl_connect_2_writing) {
3087
3088 curl_socket_t writefd = ssl_connect_2_writing ==
3089 connssl->connecting_state?sockfd:CURL_SOCKET_BAD;
3090 curl_socket_t readfd = ssl_connect_2_reading ==
3091 connssl->connecting_state?sockfd:CURL_SOCKET_BAD;
3092
3093 what = Curl_socket_check(readfd, CURL_SOCKET_BAD, writefd,
3094 nonblocking ? 0 : timeout_ms);
3095 if(what < 0) {
3096 /* fatal error */
3097 failf(data, "select/poll on SSL socket, errno: %d", SOCKERRNO);
3098 return CURLE_SSL_CONNECT_ERROR;
3099 }
3100 else if(0 == what) {
3101 if(nonblocking) {
3102 *done = FALSE;
3103 return CURLE_OK;
3104 }
3105 else {
3106 /* timeout */
3107 failf(data, "SSL connection timeout");
3108 return CURLE_OPERATION_TIMEDOUT;
3109 }
3110 }
3111 /* socket is readable or writable */
3112 }
3113
3114 /* Run transaction, and return to the caller if it failed or if this
3115 * connection is done nonblocking and this loop would execute again. This
3116 * permits the owner of a multi handle to abort a connection attempt
3117 * before step2 has completed while ensuring that a client using select()
3118 * or epoll() will always have a valid fdset to wait on.
3119 */
3120 result = sectransp_connect_step2(data, conn, sockindex);
3121 if(result || (nonblocking &&
3122 (ssl_connect_2 == connssl->connecting_state ||
3123 ssl_connect_2_reading == connssl->connecting_state ||
3124 ssl_connect_2_writing == connssl->connecting_state)))
3125 return result;
3126
3127 } /* repeat step2 until all transactions are done. */
3128
3129
3130 if(ssl_connect_3 == connssl->connecting_state) {
3131 result = sectransp_connect_step3(data, conn, sockindex);
3132 if(result)
3133 return result;
3134 }
3135
3136 if(ssl_connect_done == connssl->connecting_state) {
3137 connssl->state = ssl_connection_complete;
3138 conn->recv[sockindex] = sectransp_recv;
3139 conn->send[sockindex] = sectransp_send;
3140 *done = TRUE;
3141 }
3142 else
3143 *done = FALSE;
3144
3145 /* Reset our connect state machine */
3146 connssl->connecting_state = ssl_connect_1;
3147
3148 return CURLE_OK;
3149}
3150
3151static CURLcode sectransp_connect_nonblocking(struct Curl_easy *data,
3152 struct connectdata *conn,
3153 int sockindex, bool *done)
3154{
3155 return sectransp_connect_common(data, conn, sockindex, TRUE, done);
3156}
3157
3158static CURLcode sectransp_connect(struct Curl_easy *data,
3159 struct connectdata *conn, int sockindex)
3160{
3161 CURLcode result;
3162 bool done = FALSE;
3163
3164 result = sectransp_connect_common(data, conn, sockindex, FALSE, &done);
3165
3166 if(result)
3167 return result;
3168
3169 DEBUGASSERT(done);
3170
3171 return CURLE_OK;
3172}
3173
3174static void sectransp_close(struct Curl_easy *data, struct connectdata *conn,
3175 int sockindex)
3176{
3177 struct ssl_connect_data *connssl = &conn->ssl[sockindex];
3178 struct ssl_backend_data *backend = connssl->backend;
3179
3180 (void) data;
3181
3182 DEBUGASSERT(backend);
3183
3184 if(backend->ssl_ctx) {
3185 (void)SSLClose(backend->ssl_ctx);
3186#if CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS
3187 if(SSLCreateContext)
3188 CFRelease(backend->ssl_ctx);
3189#if CURL_SUPPORT_MAC_10_8
3190 else
3191 (void)SSLDisposeContext(backend->ssl_ctx);
3192#endif /* CURL_SUPPORT_MAC_10_8 */
3193#else
3194 (void)SSLDisposeContext(backend->ssl_ctx);
3195#endif /* CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS */
3196 backend->ssl_ctx = NULL;
3197 }
3198 backend->ssl_sockfd = 0;
3199}
3200
3201static int sectransp_shutdown(struct Curl_easy *data,
3202 struct connectdata *conn, int sockindex)
3203{
3204 struct ssl_connect_data *connssl = &conn->ssl[sockindex];
3205 struct ssl_backend_data *backend = connssl->backend;
3206 ssize_t nread;
3207 int what;
3208 int rc;
3209 char buf[120];
3210 int loop = 10; /* avoid getting stuck */
3211
3212 DEBUGASSERT(backend);
3213
3214 if(!backend->ssl_ctx)
3215 return 0;
3216
3217#ifndef CURL_DISABLE_FTP
3218 if(data->set.ftp_ccc != CURLFTPSSL_CCC_ACTIVE)
3219 return 0;
3220#endif
3221
3222 sectransp_close(data, conn, sockindex);
3223
3224 rc = 0;
3225
3226 what = SOCKET_READABLE(conn->sock[sockindex], SSL_SHUTDOWN_TIMEOUT);
3227
3228 while(loop--) {
3229 if(what < 0) {
3230 /* anything that gets here is fatally bad */
3231 failf(data, "select/poll on SSL socket, errno: %d", SOCKERRNO);
3232 rc = -1;
3233 break;
3234 }
3235
3236 if(!what) { /* timeout */
3237 failf(data, "SSL shutdown timeout");
3238 break;
3239 }
3240
3241 /* Something to read, let's do it and hope that it is the close
3242 notify alert from the server. No way to SSL_Read now, so use read(). */
3243
3244 nread = read(conn->sock[sockindex], buf, sizeof(buf));
3245
3246 if(nread < 0) {
3247 char buffer[STRERROR_LEN];
3248 failf(data, "read: %s",
3249 Curl_strerror(errno, buffer, sizeof(buffer)));
3250 rc = -1;
3251 }
3252
3253 if(nread <= 0)
3254 break;
3255
3256 what = SOCKET_READABLE(conn->sock[sockindex], 0);
3257 }
3258
3259 return rc;
3260}
3261
3262static void sectransp_session_free(void *ptr)
3263{
3264 /* ST, as of iOS 5 and Mountain Lion, has no public method of deleting a
3265 cached session ID inside the Security framework. There is a private
3266 function that does this, but I don't want to have to explain to you why I
3267 got your application rejected from the App Store due to the use of a
3268 private API, so the best we can do is free up our own char array that we
3269 created way back in sectransp_connect_step1... */
3270 Curl_safefree(ptr);
3271}
3272
3273static size_t sectransp_version(char *buffer, size_t size)
3274{
3275 return msnprintf(buffer, size, "SecureTransport");
3276}
3277
3278/*
3279 * This function uses SSLGetSessionState to determine connection status.
3280 *
3281 * Return codes:
3282 * 1 means the connection is still in place
3283 * 0 means the connection has been closed
3284 * -1 means the connection status is unknown
3285 */
3286static int sectransp_check_cxn(struct connectdata *conn)
3287{
3288 struct ssl_connect_data *connssl = &conn->ssl[FIRSTSOCKET];
3289 struct ssl_backend_data *backend = connssl->backend;
3290 OSStatus err;
3291 SSLSessionState state;
3292
3293 DEBUGASSERT(backend);
3294
3295 if(backend->ssl_ctx) {
3296 err = SSLGetSessionState(backend->ssl_ctx, &state);
3297 if(err == noErr)
3298 return state == kSSLConnected || state == kSSLHandshake;
3299 return -1;
3300 }
3301 return 0;
3302}
3303
3304static bool sectransp_data_pending(const struct connectdata *conn,
3305 int connindex)
3306{
3307 const struct ssl_connect_data *connssl = &conn->ssl[connindex];
3308 struct ssl_backend_data *backend = connssl->backend;
3309 OSStatus err;
3310 size_t buffer;
3311
3312 DEBUGASSERT(backend);
3313
3314 if(backend->ssl_ctx) { /* SSL is in use */
3315 err = SSLGetBufferedReadSize(backend->ssl_ctx, &buffer);
3316 if(err == noErr)
3317 return buffer > 0UL;
3318 return false;
3319 }
3320 else
3321 return false;
3322}
3323
3324static CURLcode sectransp_random(struct Curl_easy *data UNUSED_PARAM,
3325 unsigned char *entropy, size_t length)
3326{
3327 /* arc4random_buf() isn't available on cats older than Lion, so let's
3328 do this manually for the benefit of the older cats. */
3329 size_t i;
3330 u_int32_t random_number = 0;
3331
3332 (void)data;
3333
3334 for(i = 0 ; i < length ; i++) {
3335 if(i % sizeof(u_int32_t) == 0)
3336 random_number = arc4random();
3337 entropy[i] = random_number & 0xFF;
3338 random_number >>= 8;
3339 }
3340 i = random_number = 0;
3341 return CURLE_OK;
3342}
3343
3344static CURLcode sectransp_sha256sum(const unsigned char *tmp, /* input */
3345 size_t tmplen,
3346 unsigned char *sha256sum, /* output */
3347 size_t sha256len)
3348{
3349 assert(sha256len >= CURL_SHA256_DIGEST_LENGTH);
3350 (void)CC_SHA256(tmp, (CC_LONG)tmplen, sha256sum);
3351 return CURLE_OK;
3352}
3353
3354static bool sectransp_false_start(void)
3355{
3356#if CURL_BUILD_MAC_10_9 || CURL_BUILD_IOS_7
3357 if(SSLSetSessionOption)
3358 return TRUE;
3359#endif
3360 return FALSE;
3361}
3362
3363static ssize_t sectransp_send(struct Curl_easy *data,
3364 int sockindex,
3365 const void *mem,
3366 size_t len,
3367 CURLcode *curlcode)
3368{
3369 struct connectdata *conn = data->conn;
3370 struct ssl_connect_data *connssl = &conn->ssl[sockindex];
3371 struct ssl_backend_data *backend = connssl->backend;
3372 size_t processed = 0UL;
3373 OSStatus err;
3374
3375 DEBUGASSERT(backend);
3376
3377 /* The SSLWrite() function works a little differently than expected. The
3378 fourth argument (processed) is currently documented in Apple's
3379 documentation as: "On return, the length, in bytes, of the data actually
3380 written."
3381
3382 Now, one could interpret that as "written to the socket," but actually,
3383 it returns the amount of data that was written to a buffer internal to
3384 the SSLContextRef instead. So it's possible for SSLWrite() to return
3385 errSSLWouldBlock and a number of bytes "written" because those bytes were
3386 encrypted and written to a buffer, not to the socket.
3387
3388 So if this happens, then we need to keep calling SSLWrite() over and
3389 over again with no new data until it quits returning errSSLWouldBlock. */
3390
3391 /* Do we have buffered data to write from the last time we were called? */
3392 if(backend->ssl_write_buffered_length) {
3393 /* Write the buffered data: */
3394 err = SSLWrite(backend->ssl_ctx, NULL, 0UL, &processed);
3395 switch(err) {
3396 case noErr:
3397 /* processed is always going to be 0 because we didn't write to
3398 the buffer, so return how much was written to the socket */
3399 processed = backend->ssl_write_buffered_length;
3400 backend->ssl_write_buffered_length = 0UL;
3401 break;
3402 case errSSLWouldBlock: /* argh, try again */
3403 *curlcode = CURLE_AGAIN;
3404 return -1L;
3405 default:
3406 failf(data, "SSLWrite() returned error %d", err);
3407 *curlcode = CURLE_SEND_ERROR;
3408 return -1L;
3409 }
3410 }
3411 else {
3412 /* We've got new data to write: */
3413 err = SSLWrite(backend->ssl_ctx, mem, len, &processed);
3414 if(err != noErr) {
3415 switch(err) {
3416 case errSSLWouldBlock:
3417 /* Data was buffered but not sent, we have to tell the caller
3418 to try sending again, and remember how much was buffered */
3419 backend->ssl_write_buffered_length = len;
3420 *curlcode = CURLE_AGAIN;
3421 return -1L;
3422 default:
3423 failf(data, "SSLWrite() returned error %d", err);
3424 *curlcode = CURLE_SEND_ERROR;
3425 return -1L;
3426 }
3427 }
3428 }
3429 return (ssize_t)processed;
3430}
3431
3432static ssize_t sectransp_recv(struct Curl_easy *data,
3433 int num,
3434 char *buf,
3435 size_t buffersize,
3436 CURLcode *curlcode)
3437{
3438 struct connectdata *conn = data->conn;
3439 struct ssl_connect_data *connssl = &conn->ssl[num];
3440 struct ssl_backend_data *backend = connssl->backend;
3441 size_t processed = 0UL;
3442 OSStatus err;
3443
3444 DEBUGASSERT(backend);
3445
3446 again:
3447 err = SSLRead(backend->ssl_ctx, buf, buffersize, &processed);
3448
3449 if(err != noErr) {
3450 switch(err) {
3451 case errSSLWouldBlock: /* return how much we read (if anything) */
3452 if(processed)
3453 return (ssize_t)processed;
3454 *curlcode = CURLE_AGAIN;
3455 return -1L;
3456 break;
3457
3458 /* errSSLClosedGraceful - server gracefully shut down the SSL session
3459 errSSLClosedNoNotify - server hung up on us instead of sending a
3460 closure alert notice, read() is returning 0
3461 Either way, inform the caller that the server disconnected. */
3462 case errSSLClosedGraceful:
3463 case errSSLClosedNoNotify:
3464 *curlcode = CURLE_OK;
3465 return -1L;
3466 break;
3467
3468 /* The below is errSSLPeerAuthCompleted; it's not defined in
3469 Leopard's headers */
3470 case -9841:
3471 if((SSL_CONN_CONFIG(CAfile) || SSL_CONN_CONFIG(ca_info_blob)) &&
3472 SSL_CONN_CONFIG(verifypeer)) {
3473 CURLcode result = verify_cert(data, SSL_CONN_CONFIG(CAfile),
3474 SSL_CONN_CONFIG(ca_info_blob),
3475 backend->ssl_ctx);
3476 if(result)
3477 return result;
3478 }
3479 goto again;
3480 default:
3481 failf(data, "SSLRead() return error %d", err);
3482 *curlcode = CURLE_RECV_ERROR;
3483 return -1L;
3484 break;
3485 }
3486 }
3487 return (ssize_t)processed;
3488}
3489
3490static void *sectransp_get_internals(struct ssl_connect_data *connssl,
3491 CURLINFO info UNUSED_PARAM)
3492{
3493 struct ssl_backend_data *backend = connssl->backend;
3494 (void)info;
3495 DEBUGASSERT(backend);
3496 return backend->ssl_ctx;
3497}
3498
3499const struct Curl_ssl Curl_ssl_sectransp = {
3500 { CURLSSLBACKEND_SECURETRANSPORT, "secure-transport" }, /* info */
3501
3502 SSLSUPP_CAINFO_BLOB |
3503 SSLSUPP_CERTINFO |
3504#ifdef SECTRANSP_PINNEDPUBKEY
3505 SSLSUPP_PINNEDPUBKEY,
3506#else
3507 0,
3508#endif /* SECTRANSP_PINNEDPUBKEY */
3509
3510 sizeof(struct ssl_backend_data),
3511
3512 Curl_none_init, /* init */
3513 Curl_none_cleanup, /* cleanup */
3514 sectransp_version, /* version */
3515 sectransp_check_cxn, /* check_cxn */
3516 sectransp_shutdown, /* shutdown */
3517 sectransp_data_pending, /* data_pending */
3518 sectransp_random, /* random */
3519 Curl_none_cert_status_request, /* cert_status_request */
3520 sectransp_connect, /* connect */
3521 sectransp_connect_nonblocking, /* connect_nonblocking */
3522 Curl_ssl_getsock, /* getsock */
3523 sectransp_get_internals, /* get_internals */
3524 sectransp_close, /* close_one */
3525 Curl_none_close_all, /* close_all */
3526 sectransp_session_free, /* session_free */
3527 Curl_none_set_engine, /* set_engine */
3528 Curl_none_set_engine_default, /* set_engine_default */
3529 Curl_none_engines_list, /* engines_list */
3530 sectransp_false_start, /* false_start */
3531 sectransp_sha256sum, /* sha256sum */
3532 NULL, /* associate_connection */
3533 NULL /* disassociate_connection */
3534};
3535
3536#ifdef __clang__
3537#pragma clang diagnostic pop
3538#endif
3539
3540#endif /* USE_SECTRANSP */
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette