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