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