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