VirtualBox

source: vbox/trunk/src/libs/curl-8.0.1/lib/vtls/sectransp.c@ 99344

Last change on this file since 99344 was 99344, checked in by vboxsync, 22 months ago

curl-8.0.1: Applied and adjusted our curl changes to 7.87.0 bugref:10417

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

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