VirtualBox

source: vbox/trunk/src/libs/curl-7.87.0/lib/vtls/sectransp.c@ 98326

最後變更 在這個檔案從98326是 98326,由 vboxsync 提交於 2 年 前

curl-7.87.0: Applied and adjusted our curl changes to 7.83.1. bugref:10356

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

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