darwinssl.c
Go to the documentation of this file.
1 /***************************************************************************
2  * _ _ ____ _
3  * Project ___| | | | _ \| |
4  * / __| | | | |_) | |
5  * | (__| |_| | _ <| |___
6  * \___|\___/|_| \_\_____|
7  *
8  * Copyright (C) 2012 - 2014, Nick Zitzmann, <nickzman@gmail.com>.
9  * Copyright (C) 2012 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
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.haxx.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 Mac OS X 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 
35 #ifdef USE_DARWINSSL
36 
37 #ifdef __clang__
38 #pragma clang diagnostic push
39 #pragma clang diagnostic ignored "-Wtautological-pointer-compare"
40 #endif /* __clang__ */
41 
42 #ifdef HAVE_LIMITS_H
43 #include <limits.h>
44 #endif
45 
46 #include <Security/Security.h>
47 /* For some reason, when building for iOS, the omnibus header above does
48  * not include SecureTransport.h as of iOS SDK 5.1. */
49 #include <Security/SecureTransport.h>
50 #include <CoreFoundation/CoreFoundation.h>
51 #include <CommonCrypto/CommonDigest.h>
52 
53 /* The Security framework has changed greatly between iOS and different OS X
54  versions, and we will try to support as many of them as we can (back to
55  Leopard and iOS 5) by using macros and weak-linking.
56 
57  IMPORTANT: If TLS 1.1 and 1.2 support are important for you on OS X, then
58  you must build this project against the 10.8 SDK or later. */
59 #if (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE))
60 
61 #if MAC_OS_X_VERSION_MAX_ALLOWED < 1050
62 #error "The darwinssl back-end requires Leopard or later."
63 #endif /* MAC_OS_X_VERSION_MAX_ALLOWED < 1050 */
64 
65 #define CURL_BUILD_IOS 0
66 #define CURL_BUILD_IOS_7 0
67 #define CURL_BUILD_MAC 1
68 /* This is the maximum API level we are allowed to use when building: */
69 #define CURL_BUILD_MAC_10_5 MAC_OS_X_VERSION_MAX_ALLOWED >= 1050
70 #define CURL_BUILD_MAC_10_6 MAC_OS_X_VERSION_MAX_ALLOWED >= 1060
71 #define CURL_BUILD_MAC_10_7 MAC_OS_X_VERSION_MAX_ALLOWED >= 1070
72 #define CURL_BUILD_MAC_10_8 MAC_OS_X_VERSION_MAX_ALLOWED >= 1080
73 #define CURL_BUILD_MAC_10_9 MAC_OS_X_VERSION_MAX_ALLOWED >= 1090
74 /* These macros mean "the following code is present to allow runtime backward
75  compatibility with at least this cat or earlier":
76  (You set this at build-time by setting the MACOSX_DEPLOYMENT_TARGET
77  environmental variable.) */
78 #define CURL_SUPPORT_MAC_10_5 MAC_OS_X_VERSION_MIN_REQUIRED <= 1050
79 #define CURL_SUPPORT_MAC_10_6 MAC_OS_X_VERSION_MIN_REQUIRED <= 1060
80 #define CURL_SUPPORT_MAC_10_7 MAC_OS_X_VERSION_MIN_REQUIRED <= 1070
81 #define CURL_SUPPORT_MAC_10_8 MAC_OS_X_VERSION_MIN_REQUIRED <= 1080
82 #define CURL_SUPPORT_MAC_10_9 MAC_OS_X_VERSION_MIN_REQUIRED <= 1090
83 
84 #elif TARGET_OS_EMBEDDED || TARGET_OS_IPHONE
85 #define CURL_BUILD_IOS 1
86 #define CURL_BUILD_IOS_7 __IPHONE_OS_VERSION_MAX_ALLOWED >= 70000
87 #define CURL_BUILD_MAC 0
88 #define CURL_BUILD_MAC_10_5 0
89 #define CURL_BUILD_MAC_10_6 0
90 #define CURL_BUILD_MAC_10_7 0
91 #define CURL_BUILD_MAC_10_8 0
92 #define CURL_SUPPORT_MAC_10_5 0
93 #define CURL_SUPPORT_MAC_10_6 0
94 #define CURL_SUPPORT_MAC_10_7 0
95 #define CURL_SUPPORT_MAC_10_8 0
96 #define CURL_SUPPORT_MAC_10_9 0
97 
98 #else
99 #error "The darwinssl back-end requires iOS or OS X."
100 #endif /* (TARGET_OS_MAC && !(TARGET_OS_EMBEDDED || TARGET_OS_IPHONE)) */
101 
102 #if CURL_BUILD_MAC
103 #include <sys/sysctl.h>
104 #endif /* CURL_BUILD_MAC */
105 
106 #include "urldata.h"
107 #include "sendf.h"
108 #include "inet_pton.h"
109 #include "connect.h"
110 #include "select.h"
111 #include "vtls.h"
112 #include "darwinssl.h"
113 #include "curl_printf.h"
114 
115 #include "curl_memory.h"
116 /* The last #include file should be: */
117 #include "memdebug.h"
118 
119 /* From MacTypes.h (which we can't include because it isn't present in iOS: */
120 #define ioErr -36
121 #define paramErr -50
122 
123 struct ssl_backend_data {
124  SSLContextRef ssl_ctx;
125  curl_socket_t ssl_sockfd;
126  bool ssl_direction; /* true if writing, false if reading */
127  size_t ssl_write_buffered_length;
128 };
129 
130 #define BACKEND connssl->backend
131 
132 /* pinned public key support tests */
133 
134 /* version 1 supports macOS 10.12+ and iOS 10+ */
135 #if ((TARGET_OS_IPHONE && __IPHONE_OS_VERSION_MIN_REQUIRED >= 100000) || \
136  (!TARGET_OS_IPHONE && __MAC_OS_X_VERSION_MIN_REQUIRED >= 101200))
137 #define DARWIN_SSL_PINNEDPUBKEY_V1 1
138 #endif
139 
140 /* version 2 supports MacOSX 10.7+ */
141 #if (!TARGET_OS_IPHONE && __MAC_OS_X_VERSION_MIN_REQUIRED >= 1070)
142 #define DARWIN_SSL_PINNEDPUBKEY_V2 1
143 #endif
144 
145 #if defined(DARWIN_SSL_PINNEDPUBKEY_V1) || defined(DARWIN_SSL_PINNEDPUBKEY_V2)
146 /* this backend supports CURLOPT_PINNEDPUBLICKEY */
147 #define DARWIN_SSL_PINNEDPUBKEY 1
148 #endif /* DARWIN_SSL_PINNEDPUBKEY */
149 
150 #ifdef DARWIN_SSL_PINNEDPUBKEY
151 /* both new and old APIs return rsa keys missing the spki header (not DER) */
152 static const unsigned char rsa4096SpkiHeader[] = {
153  0x30, 0x82, 0x02, 0x22, 0x30, 0x0d,
154  0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
155  0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05,
156  0x00, 0x03, 0x82, 0x02, 0x0f, 0x00};
157 
158 static const unsigned char rsa2048SpkiHeader[] = {
159  0x30, 0x82, 0x01, 0x22, 0x30, 0x0d,
160  0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
161  0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05,
162  0x00, 0x03, 0x82, 0x01, 0x0f, 0x00};
163 #ifdef DARWIN_SSL_PINNEDPUBKEY_V1
164 /* the *new* version doesn't return DER encoded ecdsa certs like the old... */
165 static const unsigned char ecDsaSecp256r1SpkiHeader[] = {
166  0x30, 0x59, 0x30, 0x13, 0x06, 0x07,
167  0x2a, 0x86, 0x48, 0xce, 0x3d, 0x02,
168  0x01, 0x06, 0x08, 0x2a, 0x86, 0x48,
169  0xce, 0x3d, 0x03, 0x01, 0x07, 0x03,
170  0x42, 0x00};
171 
172 static const unsigned char ecDsaSecp384r1SpkiHeader[] = {
173  0x30, 0x76, 0x30, 0x10, 0x06, 0x07,
174  0x2a, 0x86, 0x48, 0xce, 0x3d, 0x02,
175  0x01, 0x06, 0x05, 0x2b, 0x81, 0x04,
176  0x00, 0x22, 0x03, 0x62, 0x00};
177 #endif /* DARWIN_SSL_PINNEDPUBKEY_V1 */
178 #endif /* DARWIN_SSL_PINNEDPUBKEY */
179 
180 /* The following two functions were ripped from Apple sample code,
181  * with some modifications: */
182 static OSStatus SocketRead(SSLConnectionRef connection,
183  void *data, /* owned by
184  * caller, data
185  * RETURNED */
186  size_t *dataLength) /* IN/OUT */
187 {
188  size_t bytesToGo = *dataLength;
189  size_t initLen = bytesToGo;
190  UInt8 *currData = (UInt8 *)data;
191  /*int sock = *(int *)connection;*/
192  struct ssl_connect_data *connssl = (struct ssl_connect_data *)connection;
193  int sock = BACKEND->ssl_sockfd;
194  OSStatus rtn = noErr;
195  size_t bytesRead;
196  ssize_t rrtn;
197  int theErr;
198 
199  *dataLength = 0;
200 
201  for(;;) {
202  bytesRead = 0;
203  rrtn = read(sock, currData, bytesToGo);
204  if(rrtn <= 0) {
205  /* this is guesswork... */
206  theErr = errno;
207  if(rrtn == 0) { /* EOF = server hung up */
208  /* the framework will turn this into errSSLClosedNoNotify */
209  rtn = errSSLClosedGraceful;
210  }
211  else /* do the switch */
212  switch(theErr) {
213  case ENOENT:
214  /* connection closed */
215  rtn = errSSLClosedGraceful;
216  break;
217  case ECONNRESET:
218  rtn = errSSLClosedAbort;
219  break;
220  case EAGAIN:
221  rtn = errSSLWouldBlock;
222  BACKEND->ssl_direction = false;
223  break;
224  default:
225  rtn = ioErr;
226  break;
227  }
228  break;
229  }
230  else {
231  bytesRead = rrtn;
232  }
233  bytesToGo -= bytesRead;
234  currData += bytesRead;
235 
236  if(bytesToGo == 0) {
237  /* filled buffer with incoming data, done */
238  break;
239  }
240  }
241  *dataLength = initLen - bytesToGo;
242 
243  return rtn;
244 }
245 
246 static OSStatus SocketWrite(SSLConnectionRef connection,
247  const void *data,
248  size_t *dataLength) /* IN/OUT */
249 {
250  size_t bytesSent = 0;
251  /*int sock = *(int *)connection;*/
252  struct ssl_connect_data *connssl = (struct ssl_connect_data *)connection;
253  int sock = BACKEND->ssl_sockfd;
254  ssize_t length;
255  size_t dataLen = *dataLength;
256  const UInt8 *dataPtr = (UInt8 *)data;
257  OSStatus ortn;
258  int theErr;
259 
260  *dataLength = 0;
261 
262  do {
263  length = write(sock,
264  (char *)dataPtr + bytesSent,
265  dataLen - bytesSent);
266  } while((length > 0) &&
267  ( (bytesSent += length) < dataLen) );
268 
269  if(length <= 0) {
270  theErr = errno;
271  if(theErr == EAGAIN) {
272  ortn = errSSLWouldBlock;
273  BACKEND->ssl_direction = true;
274  }
275  else {
276  ortn = ioErr;
277  }
278  }
279  else {
280  ortn = noErr;
281  }
282  *dataLength = bytesSent;
283  return ortn;
284 }
285 
286 #ifndef CURL_DISABLE_VERBOSE_STRINGS
287 CF_INLINE const char *SSLCipherNameForNumber(SSLCipherSuite cipher)
288 {
289  switch(cipher) {
290  /* SSL version 3.0 */
291  case SSL_RSA_WITH_NULL_MD5:
292  return "SSL_RSA_WITH_NULL_MD5";
293  break;
294  case SSL_RSA_WITH_NULL_SHA:
295  return "SSL_RSA_WITH_NULL_SHA";
296  break;
297  case SSL_RSA_EXPORT_WITH_RC4_40_MD5:
298  return "SSL_RSA_EXPORT_WITH_RC4_40_MD5";
299  break;
300  case SSL_RSA_WITH_RC4_128_MD5:
301  return "SSL_RSA_WITH_RC4_128_MD5";
302  break;
303  case SSL_RSA_WITH_RC4_128_SHA:
304  return "SSL_RSA_WITH_RC4_128_SHA";
305  break;
306  case SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5:
307  return "SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5";
308  break;
309  case SSL_RSA_WITH_IDEA_CBC_SHA:
310  return "SSL_RSA_WITH_IDEA_CBC_SHA";
311  break;
312  case SSL_RSA_EXPORT_WITH_DES40_CBC_SHA:
313  return "SSL_RSA_EXPORT_WITH_DES40_CBC_SHA";
314  break;
315  case SSL_RSA_WITH_DES_CBC_SHA:
316  return "SSL_RSA_WITH_DES_CBC_SHA";
317  break;
318  case SSL_RSA_WITH_3DES_EDE_CBC_SHA:
319  return "SSL_RSA_WITH_3DES_EDE_CBC_SHA";
320  break;
321  case SSL_DH_DSS_EXPORT_WITH_DES40_CBC_SHA:
322  return "SSL_DH_DSS_EXPORT_WITH_DES40_CBC_SHA";
323  break;
324  case SSL_DH_DSS_WITH_DES_CBC_SHA:
325  return "SSL_DH_DSS_WITH_DES_CBC_SHA";
326  break;
327  case SSL_DH_DSS_WITH_3DES_EDE_CBC_SHA:
328  return "SSL_DH_DSS_WITH_3DES_EDE_CBC_SHA";
329  break;
330  case SSL_DH_RSA_EXPORT_WITH_DES40_CBC_SHA:
331  return "SSL_DH_RSA_EXPORT_WITH_DES40_CBC_SHA";
332  break;
333  case SSL_DH_RSA_WITH_DES_CBC_SHA:
334  return "SSL_DH_RSA_WITH_DES_CBC_SHA";
335  break;
336  case SSL_DH_RSA_WITH_3DES_EDE_CBC_SHA:
337  return "SSL_DH_RSA_WITH_3DES_EDE_CBC_SHA";
338  break;
339  case SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA:
340  return "SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA";
341  break;
342  case SSL_DHE_DSS_WITH_DES_CBC_SHA:
343  return "SSL_DHE_DSS_WITH_DES_CBC_SHA";
344  break;
345  case SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA:
346  return "SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA";
347  break;
348  case SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA:
349  return "SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA";
350  break;
351  case SSL_DHE_RSA_WITH_DES_CBC_SHA:
352  return "SSL_DHE_RSA_WITH_DES_CBC_SHA";
353  break;
354  case SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA:
355  return "SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA";
356  break;
357  case SSL_DH_anon_EXPORT_WITH_RC4_40_MD5:
358  return "SSL_DH_anon_EXPORT_WITH_RC4_40_MD5";
359  break;
360  case SSL_DH_anon_WITH_RC4_128_MD5:
361  return "SSL_DH_anon_WITH_RC4_128_MD5";
362  break;
363  case SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA:
364  return "SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA";
365  break;
366  case SSL_DH_anon_WITH_DES_CBC_SHA:
367  return "SSL_DH_anon_WITH_DES_CBC_SHA";
368  break;
369  case SSL_DH_anon_WITH_3DES_EDE_CBC_SHA:
370  return "SSL_DH_anon_WITH_3DES_EDE_CBC_SHA";
371  break;
372  case SSL_FORTEZZA_DMS_WITH_NULL_SHA:
373  return "SSL_FORTEZZA_DMS_WITH_NULL_SHA";
374  break;
375  case SSL_FORTEZZA_DMS_WITH_FORTEZZA_CBC_SHA:
376  return "SSL_FORTEZZA_DMS_WITH_FORTEZZA_CBC_SHA";
377  break;
378  /* TLS 1.0 with AES (RFC 3268)
379  (Apparently these are used in SSLv3 implementations as well.) */
380  case TLS_RSA_WITH_AES_128_CBC_SHA:
381  return "TLS_RSA_WITH_AES_128_CBC_SHA";
382  break;
383  case TLS_DH_DSS_WITH_AES_128_CBC_SHA:
384  return "TLS_DH_DSS_WITH_AES_128_CBC_SHA";
385  break;
386  case TLS_DH_RSA_WITH_AES_128_CBC_SHA:
387  return "TLS_DH_RSA_WITH_AES_128_CBC_SHA";
388  break;
389  case TLS_DHE_DSS_WITH_AES_128_CBC_SHA:
390  return "TLS_DHE_DSS_WITH_AES_128_CBC_SHA";
391  break;
392  case TLS_DHE_RSA_WITH_AES_128_CBC_SHA:
393  return "TLS_DHE_RSA_WITH_AES_128_CBC_SHA";
394  break;
395  case TLS_DH_anon_WITH_AES_128_CBC_SHA:
396  return "TLS_DH_anon_WITH_AES_128_CBC_SHA";
397  break;
398  case TLS_RSA_WITH_AES_256_CBC_SHA:
399  return "TLS_RSA_WITH_AES_256_CBC_SHA";
400  break;
401  case TLS_DH_DSS_WITH_AES_256_CBC_SHA:
402  return "TLS_DH_DSS_WITH_AES_256_CBC_SHA";
403  break;
404  case TLS_DH_RSA_WITH_AES_256_CBC_SHA:
405  return "TLS_DH_RSA_WITH_AES_256_CBC_SHA";
406  break;
407  case TLS_DHE_DSS_WITH_AES_256_CBC_SHA:
408  return "TLS_DHE_DSS_WITH_AES_256_CBC_SHA";
409  break;
410  case TLS_DHE_RSA_WITH_AES_256_CBC_SHA:
411  return "TLS_DHE_RSA_WITH_AES_256_CBC_SHA";
412  break;
413  case TLS_DH_anon_WITH_AES_256_CBC_SHA:
414  return "TLS_DH_anon_WITH_AES_256_CBC_SHA";
415  break;
416  /* SSL version 2.0 */
417  case SSL_RSA_WITH_RC2_CBC_MD5:
418  return "SSL_RSA_WITH_RC2_CBC_MD5";
419  break;
420  case SSL_RSA_WITH_IDEA_CBC_MD5:
421  return "SSL_RSA_WITH_IDEA_CBC_MD5";
422  break;
423  case SSL_RSA_WITH_DES_CBC_MD5:
424  return "SSL_RSA_WITH_DES_CBC_MD5";
425  break;
426  case SSL_RSA_WITH_3DES_EDE_CBC_MD5:
427  return "SSL_RSA_WITH_3DES_EDE_CBC_MD5";
428  break;
429  }
430  return "SSL_NULL_WITH_NULL_NULL";
431 }
432 
433 CF_INLINE const char *TLSCipherNameForNumber(SSLCipherSuite cipher)
434 {
435  switch(cipher) {
436  /* TLS 1.0 with AES (RFC 3268) */
437  case TLS_RSA_WITH_AES_128_CBC_SHA:
438  return "TLS_RSA_WITH_AES_128_CBC_SHA";
439  break;
440  case TLS_DH_DSS_WITH_AES_128_CBC_SHA:
441  return "TLS_DH_DSS_WITH_AES_128_CBC_SHA";
442  break;
443  case TLS_DH_RSA_WITH_AES_128_CBC_SHA:
444  return "TLS_DH_RSA_WITH_AES_128_CBC_SHA";
445  break;
446  case TLS_DHE_DSS_WITH_AES_128_CBC_SHA:
447  return "TLS_DHE_DSS_WITH_AES_128_CBC_SHA";
448  break;
449  case TLS_DHE_RSA_WITH_AES_128_CBC_SHA:
450  return "TLS_DHE_RSA_WITH_AES_128_CBC_SHA";
451  break;
452  case TLS_DH_anon_WITH_AES_128_CBC_SHA:
453  return "TLS_DH_anon_WITH_AES_128_CBC_SHA";
454  break;
455  case TLS_RSA_WITH_AES_256_CBC_SHA:
456  return "TLS_RSA_WITH_AES_256_CBC_SHA";
457  break;
458  case TLS_DH_DSS_WITH_AES_256_CBC_SHA:
459  return "TLS_DH_DSS_WITH_AES_256_CBC_SHA";
460  break;
461  case TLS_DH_RSA_WITH_AES_256_CBC_SHA:
462  return "TLS_DH_RSA_WITH_AES_256_CBC_SHA";
463  break;
464  case TLS_DHE_DSS_WITH_AES_256_CBC_SHA:
465  return "TLS_DHE_DSS_WITH_AES_256_CBC_SHA";
466  break;
467  case TLS_DHE_RSA_WITH_AES_256_CBC_SHA:
468  return "TLS_DHE_RSA_WITH_AES_256_CBC_SHA";
469  break;
470  case TLS_DH_anon_WITH_AES_256_CBC_SHA:
471  return "TLS_DH_anon_WITH_AES_256_CBC_SHA";
472  break;
473 #if CURL_BUILD_MAC_10_6 || CURL_BUILD_IOS
474  /* TLS 1.0 with ECDSA (RFC 4492) */
475  case TLS_ECDH_ECDSA_WITH_NULL_SHA:
476  return "TLS_ECDH_ECDSA_WITH_NULL_SHA";
477  break;
478  case TLS_ECDH_ECDSA_WITH_RC4_128_SHA:
479  return "TLS_ECDH_ECDSA_WITH_RC4_128_SHA";
480  break;
481  case TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA:
482  return "TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA";
483  break;
484  case TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA:
485  return "TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA";
486  break;
487  case TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA:
488  return "TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA";
489  break;
490  case TLS_ECDHE_ECDSA_WITH_NULL_SHA:
491  return "TLS_ECDHE_ECDSA_WITH_NULL_SHA";
492  break;
493  case TLS_ECDHE_ECDSA_WITH_RC4_128_SHA:
494  return "TLS_ECDHE_ECDSA_WITH_RC4_128_SHA";
495  break;
496  case TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA:
497  return "TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA";
498  break;
499  case TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA:
500  return "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA";
501  break;
502  case TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA:
503  return "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA";
504  break;
505  case TLS_ECDH_RSA_WITH_NULL_SHA:
506  return "TLS_ECDH_RSA_WITH_NULL_SHA";
507  break;
508  case TLS_ECDH_RSA_WITH_RC4_128_SHA:
509  return "TLS_ECDH_RSA_WITH_RC4_128_SHA";
510  break;
511  case TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA:
512  return "TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA";
513  break;
514  case TLS_ECDH_RSA_WITH_AES_128_CBC_SHA:
515  return "TLS_ECDH_RSA_WITH_AES_128_CBC_SHA";
516  break;
517  case TLS_ECDH_RSA_WITH_AES_256_CBC_SHA:
518  return "TLS_ECDH_RSA_WITH_AES_256_CBC_SHA";
519  break;
520  case TLS_ECDHE_RSA_WITH_NULL_SHA:
521  return "TLS_ECDHE_RSA_WITH_NULL_SHA";
522  break;
523  case TLS_ECDHE_RSA_WITH_RC4_128_SHA:
524  return "TLS_ECDHE_RSA_WITH_RC4_128_SHA";
525  break;
526  case TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA:
527  return "TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA";
528  break;
529  case TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA:
530  return "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA";
531  break;
532  case TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA:
533  return "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA";
534  break;
535  case TLS_ECDH_anon_WITH_NULL_SHA:
536  return "TLS_ECDH_anon_WITH_NULL_SHA";
537  break;
538  case TLS_ECDH_anon_WITH_RC4_128_SHA:
539  return "TLS_ECDH_anon_WITH_RC4_128_SHA";
540  break;
541  case TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA:
542  return "TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA";
543  break;
544  case TLS_ECDH_anon_WITH_AES_128_CBC_SHA:
545  return "TLS_ECDH_anon_WITH_AES_128_CBC_SHA";
546  break;
547  case TLS_ECDH_anon_WITH_AES_256_CBC_SHA:
548  return "TLS_ECDH_anon_WITH_AES_256_CBC_SHA";
549  break;
550 #endif /* CURL_BUILD_MAC_10_6 || CURL_BUILD_IOS */
551 #if CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS
552  /* TLS 1.2 (RFC 5246) */
553  case TLS_RSA_WITH_NULL_MD5:
554  return "TLS_RSA_WITH_NULL_MD5";
555  break;
556  case TLS_RSA_WITH_NULL_SHA:
557  return "TLS_RSA_WITH_NULL_SHA";
558  break;
559  case TLS_RSA_WITH_RC4_128_MD5:
560  return "TLS_RSA_WITH_RC4_128_MD5";
561  break;
562  case TLS_RSA_WITH_RC4_128_SHA:
563  return "TLS_RSA_WITH_RC4_128_SHA";
564  break;
565  case TLS_RSA_WITH_3DES_EDE_CBC_SHA:
566  return "TLS_RSA_WITH_3DES_EDE_CBC_SHA";
567  break;
568  case TLS_RSA_WITH_NULL_SHA256:
569  return "TLS_RSA_WITH_NULL_SHA256";
570  break;
571  case TLS_RSA_WITH_AES_128_CBC_SHA256:
572  return "TLS_RSA_WITH_AES_128_CBC_SHA256";
573  break;
574  case TLS_RSA_WITH_AES_256_CBC_SHA256:
575  return "TLS_RSA_WITH_AES_256_CBC_SHA256";
576  break;
577  case TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA:
578  return "TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA";
579  break;
580  case TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA:
581  return "TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA";
582  break;
583  case TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA:
584  return "TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA";
585  break;
586  case TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA:
587  return "TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA";
588  break;
589  case TLS_DH_DSS_WITH_AES_128_CBC_SHA256:
590  return "TLS_DH_DSS_WITH_AES_128_CBC_SHA256";
591  break;
592  case TLS_DH_RSA_WITH_AES_128_CBC_SHA256:
593  return "TLS_DH_RSA_WITH_AES_128_CBC_SHA256";
594  break;
595  case TLS_DHE_DSS_WITH_AES_128_CBC_SHA256:
596  return "TLS_DHE_DSS_WITH_AES_128_CBC_SHA256";
597  break;
598  case TLS_DHE_RSA_WITH_AES_128_CBC_SHA256:
599  return "TLS_DHE_RSA_WITH_AES_128_CBC_SHA256";
600  break;
601  case TLS_DH_DSS_WITH_AES_256_CBC_SHA256:
602  return "TLS_DH_DSS_WITH_AES_256_CBC_SHA256";
603  break;
604  case TLS_DH_RSA_WITH_AES_256_CBC_SHA256:
605  return "TLS_DH_RSA_WITH_AES_256_CBC_SHA256";
606  break;
607  case TLS_DHE_DSS_WITH_AES_256_CBC_SHA256:
608  return "TLS_DHE_DSS_WITH_AES_256_CBC_SHA256";
609  break;
610  case TLS_DHE_RSA_WITH_AES_256_CBC_SHA256:
611  return "TLS_DHE_RSA_WITH_AES_256_CBC_SHA256";
612  break;
613  case TLS_DH_anon_WITH_RC4_128_MD5:
614  return "TLS_DH_anon_WITH_RC4_128_MD5";
615  break;
616  case TLS_DH_anon_WITH_3DES_EDE_CBC_SHA:
617  return "TLS_DH_anon_WITH_3DES_EDE_CBC_SHA";
618  break;
619  case TLS_DH_anon_WITH_AES_128_CBC_SHA256:
620  return "TLS_DH_anon_WITH_AES_128_CBC_SHA256";
621  break;
622  case TLS_DH_anon_WITH_AES_256_CBC_SHA256:
623  return "TLS_DH_anon_WITH_AES_256_CBC_SHA256";
624  break;
625  /* TLS 1.2 with AES GCM (RFC 5288) */
626  case TLS_RSA_WITH_AES_128_GCM_SHA256:
627  return "TLS_RSA_WITH_AES_128_GCM_SHA256";
628  break;
629  case TLS_RSA_WITH_AES_256_GCM_SHA384:
630  return "TLS_RSA_WITH_AES_256_GCM_SHA384";
631  break;
632  case TLS_DHE_RSA_WITH_AES_128_GCM_SHA256:
633  return "TLS_DHE_RSA_WITH_AES_128_GCM_SHA256";
634  break;
635  case TLS_DHE_RSA_WITH_AES_256_GCM_SHA384:
636  return "TLS_DHE_RSA_WITH_AES_256_GCM_SHA384";
637  break;
638  case TLS_DH_RSA_WITH_AES_128_GCM_SHA256:
639  return "TLS_DH_RSA_WITH_AES_128_GCM_SHA256";
640  break;
641  case TLS_DH_RSA_WITH_AES_256_GCM_SHA384:
642  return "TLS_DH_RSA_WITH_AES_256_GCM_SHA384";
643  break;
644  case TLS_DHE_DSS_WITH_AES_128_GCM_SHA256:
645  return "TLS_DHE_DSS_WITH_AES_128_GCM_SHA256";
646  break;
647  case TLS_DHE_DSS_WITH_AES_256_GCM_SHA384:
648  return "TLS_DHE_DSS_WITH_AES_256_GCM_SHA384";
649  break;
650  case TLS_DH_DSS_WITH_AES_128_GCM_SHA256:
651  return "TLS_DH_DSS_WITH_AES_128_GCM_SHA256";
652  break;
653  case TLS_DH_DSS_WITH_AES_256_GCM_SHA384:
654  return "TLS_DH_DSS_WITH_AES_256_GCM_SHA384";
655  break;
656  case TLS_DH_anon_WITH_AES_128_GCM_SHA256:
657  return "TLS_DH_anon_WITH_AES_128_GCM_SHA256";
658  break;
659  case TLS_DH_anon_WITH_AES_256_GCM_SHA384:
660  return "TLS_DH_anon_WITH_AES_256_GCM_SHA384";
661  break;
662  /* TLS 1.2 with elliptic curve ciphers (RFC 5289) */
663  case TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256:
664  return "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256";
665  break;
666  case TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384:
667  return "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384";
668  break;
669  case TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256:
670  return "TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256";
671  break;
672  case TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384:
673  return "TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384";
674  break;
675  case TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256:
676  return "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256";
677  break;
678  case TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384:
679  return "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384";
680  break;
681  case TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256:
682  return "TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256";
683  break;
684  case TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384:
685  return "TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384";
686  break;
687  case TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256:
688  return "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256";
689  break;
690  case TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384:
691  return "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384";
692  break;
693  case TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256:
694  return "TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256";
695  break;
696  case TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384:
697  return "TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384";
698  break;
699  case TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256:
700  return "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256";
701  break;
702  case TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384:
703  return "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384";
704  break;
705  case TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256:
706  return "TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256";
707  break;
708  case TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384:
709  return "TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384";
710  break;
711  case TLS_EMPTY_RENEGOTIATION_INFO_SCSV:
712  return "TLS_EMPTY_RENEGOTIATION_INFO_SCSV";
713  break;
714 #else
715  case SSL_RSA_WITH_NULL_MD5:
716  return "TLS_RSA_WITH_NULL_MD5";
717  break;
718  case SSL_RSA_WITH_NULL_SHA:
719  return "TLS_RSA_WITH_NULL_SHA";
720  break;
721  case SSL_RSA_WITH_RC4_128_MD5:
722  return "TLS_RSA_WITH_RC4_128_MD5";
723  break;
724  case SSL_RSA_WITH_RC4_128_SHA:
725  return "TLS_RSA_WITH_RC4_128_SHA";
726  break;
727  case SSL_RSA_WITH_3DES_EDE_CBC_SHA:
728  return "TLS_RSA_WITH_3DES_EDE_CBC_SHA";
729  break;
730  case SSL_DH_anon_WITH_RC4_128_MD5:
731  return "TLS_DH_anon_WITH_RC4_128_MD5";
732  break;
733  case SSL_DH_anon_WITH_3DES_EDE_CBC_SHA:
734  return "TLS_DH_anon_WITH_3DES_EDE_CBC_SHA";
735  break;
736 #endif /* CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS */
737 #if CURL_BUILD_MAC_10_9 || CURL_BUILD_IOS_7
738  /* TLS PSK (RFC 4279): */
739  case TLS_PSK_WITH_RC4_128_SHA:
740  return "TLS_PSK_WITH_RC4_128_SHA";
741  break;
742  case TLS_PSK_WITH_3DES_EDE_CBC_SHA:
743  return "TLS_PSK_WITH_3DES_EDE_CBC_SHA";
744  break;
745  case TLS_PSK_WITH_AES_128_CBC_SHA:
746  return "TLS_PSK_WITH_AES_128_CBC_SHA";
747  break;
748  case TLS_PSK_WITH_AES_256_CBC_SHA:
749  return "TLS_PSK_WITH_AES_256_CBC_SHA";
750  break;
751  case TLS_DHE_PSK_WITH_RC4_128_SHA:
752  return "TLS_DHE_PSK_WITH_RC4_128_SHA";
753  break;
754  case TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA:
755  return "TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA";
756  break;
757  case TLS_DHE_PSK_WITH_AES_128_CBC_SHA:
758  return "TLS_DHE_PSK_WITH_AES_128_CBC_SHA";
759  break;
760  case TLS_DHE_PSK_WITH_AES_256_CBC_SHA:
761  return "TLS_DHE_PSK_WITH_AES_256_CBC_SHA";
762  break;
763  case TLS_RSA_PSK_WITH_RC4_128_SHA:
764  return "TLS_RSA_PSK_WITH_RC4_128_SHA";
765  break;
766  case TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA:
767  return "TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA";
768  break;
769  case TLS_RSA_PSK_WITH_AES_128_CBC_SHA:
770  return "TLS_RSA_PSK_WITH_AES_128_CBC_SHA";
771  break;
772  case TLS_RSA_PSK_WITH_AES_256_CBC_SHA:
773  return "TLS_RSA_PSK_WITH_AES_256_CBC_SHA";
774  break;
775  /* More TLS PSK (RFC 4785): */
776  case TLS_PSK_WITH_NULL_SHA:
777  return "TLS_PSK_WITH_NULL_SHA";
778  break;
779  case TLS_DHE_PSK_WITH_NULL_SHA:
780  return "TLS_DHE_PSK_WITH_NULL_SHA";
781  break;
782  case TLS_RSA_PSK_WITH_NULL_SHA:
783  return "TLS_RSA_PSK_WITH_NULL_SHA";
784  break;
785  /* Even more TLS PSK (RFC 5487): */
786  case TLS_PSK_WITH_AES_128_GCM_SHA256:
787  return "TLS_PSK_WITH_AES_128_GCM_SHA256";
788  break;
789  case TLS_PSK_WITH_AES_256_GCM_SHA384:
790  return "TLS_PSK_WITH_AES_256_GCM_SHA384";
791  break;
792  case TLS_DHE_PSK_WITH_AES_128_GCM_SHA256:
793  return "TLS_DHE_PSK_WITH_AES_128_GCM_SHA256";
794  break;
795  case TLS_DHE_PSK_WITH_AES_256_GCM_SHA384:
796  return "TLS_DHE_PSK_WITH_AES_256_GCM_SHA384";
797  break;
798  case TLS_RSA_PSK_WITH_AES_128_GCM_SHA256:
799  return "TLS_RSA_PSK_WITH_AES_128_GCM_SHA256";
800  break;
801  case TLS_RSA_PSK_WITH_AES_256_GCM_SHA384:
802  return "TLS_PSK_WITH_AES_256_GCM_SHA384";
803  break;
804  case TLS_PSK_WITH_AES_128_CBC_SHA256:
805  return "TLS_PSK_WITH_AES_128_CBC_SHA256";
806  break;
807  case TLS_PSK_WITH_AES_256_CBC_SHA384:
808  return "TLS_PSK_WITH_AES_256_CBC_SHA384";
809  break;
810  case TLS_PSK_WITH_NULL_SHA256:
811  return "TLS_PSK_WITH_NULL_SHA256";
812  break;
813  case TLS_PSK_WITH_NULL_SHA384:
814  return "TLS_PSK_WITH_NULL_SHA384";
815  break;
816  case TLS_DHE_PSK_WITH_AES_128_CBC_SHA256:
817  return "TLS_DHE_PSK_WITH_AES_128_CBC_SHA256";
818  break;
819  case TLS_DHE_PSK_WITH_AES_256_CBC_SHA384:
820  return "TLS_DHE_PSK_WITH_AES_256_CBC_SHA384";
821  break;
822  case TLS_DHE_PSK_WITH_NULL_SHA256:
823  return "TLS_DHE_PSK_WITH_NULL_SHA256";
824  break;
825  case TLS_DHE_PSK_WITH_NULL_SHA384:
826  return "TLS_RSA_PSK_WITH_NULL_SHA384";
827  break;
828  case TLS_RSA_PSK_WITH_AES_128_CBC_SHA256:
829  return "TLS_RSA_PSK_WITH_AES_128_CBC_SHA256";
830  break;
831  case TLS_RSA_PSK_WITH_AES_256_CBC_SHA384:
832  return "TLS_RSA_PSK_WITH_AES_256_CBC_SHA384";
833  break;
834  case TLS_RSA_PSK_WITH_NULL_SHA256:
835  return "TLS_RSA_PSK_WITH_NULL_SHA256";
836  break;
837  case TLS_RSA_PSK_WITH_NULL_SHA384:
838  return "TLS_RSA_PSK_WITH_NULL_SHA384";
839  break;
840 #endif /* CURL_BUILD_MAC_10_9 || CURL_BUILD_IOS_7 */
841  }
842  return "TLS_NULL_WITH_NULL_NULL";
843 }
844 #endif /* !CURL_DISABLE_VERBOSE_STRINGS */
845 
846 #if CURL_BUILD_MAC
847 CF_INLINE void GetDarwinVersionNumber(int *major, int *minor)
848 {
849  int mib[2];
850  char *os_version;
851  size_t os_version_len;
852  char *os_version_major, *os_version_minor;
853  char *tok_buf;
854 
855  /* Get the Darwin kernel version from the kernel using sysctl(): */
856  mib[0] = CTL_KERN;
857  mib[1] = KERN_OSRELEASE;
858  if(sysctl(mib, 2, NULL, &os_version_len, NULL, 0) == -1)
859  return;
860  os_version = malloc(os_version_len*sizeof(char));
861  if(!os_version)
862  return;
863  if(sysctl(mib, 2, os_version, &os_version_len, NULL, 0) == -1) {
864  free(os_version);
865  return;
866  }
867 
868  /* Parse the version: */
869  os_version_major = strtok_r(os_version, ".", &tok_buf);
870  os_version_minor = strtok_r(NULL, ".", &tok_buf);
871  *major = atoi(os_version_major);
872  *minor = atoi(os_version_minor);
873  free(os_version);
874 }
875 #endif /* CURL_BUILD_MAC */
876 
877 /* Apple provides a myriad of ways of getting information about a certificate
878  into a string. Some aren't available under iOS or newer cats. So here's
879  a unified function for getting a string describing the certificate that
880  ought to work in all cats starting with Leopard. */
881 CF_INLINE CFStringRef getsubject(SecCertificateRef cert)
882 {
883  CFStringRef server_cert_summary = CFSTR("(null)");
884 
885 #if CURL_BUILD_IOS
886  /* iOS: There's only one way to do this. */
887  server_cert_summary = SecCertificateCopySubjectSummary(cert);
888 #else
889 #if CURL_BUILD_MAC_10_7
890  /* Lion & later: Get the long description if we can. */
891  if(SecCertificateCopyLongDescription != NULL)
892  server_cert_summary =
893  SecCertificateCopyLongDescription(NULL, cert, NULL);
894  else
895 #endif /* CURL_BUILD_MAC_10_7 */
896 #if CURL_BUILD_MAC_10_6
897  /* Snow Leopard: Get the certificate summary. */
898  if(SecCertificateCopySubjectSummary != NULL)
899  server_cert_summary = SecCertificateCopySubjectSummary(cert);
900  else
901 #endif /* CURL_BUILD_MAC_10_6 */
902  /* Leopard is as far back as we go... */
903  (void)SecCertificateCopyCommonName(cert, &server_cert_summary);
904 #endif /* CURL_BUILD_IOS */
905  return server_cert_summary;
906 }
907 
908 static CURLcode CopyCertSubject(struct Curl_easy *data,
909  SecCertificateRef cert, char **certp)
910 {
911  CFStringRef c = getsubject(cert);
913  const char *direct;
914  char *cbuf = NULL;
915  *certp = NULL;
916 
917  if(!c) {
918  failf(data, "SSL: invalid CA certificate subject");
919  return CURLE_OUT_OF_MEMORY;
920  }
921 
922  /* If the subject is already available as UTF-8 encoded (ie 'direct') then
923  use that, else convert it. */
924  direct = CFStringGetCStringPtr(c, kCFStringEncodingUTF8);
925  if(direct) {
926  *certp = strdup(direct);
927  if(!*certp) {
928  failf(data, "SSL: out of memory");
929  result = CURLE_OUT_OF_MEMORY;
930  }
931  }
932  else {
933  size_t cbuf_size = ((size_t)CFStringGetLength(c) * 4) + 1;
934  cbuf = calloc(cbuf_size, 1);
935  if(cbuf) {
936  if(!CFStringGetCString(c, cbuf, cbuf_size,
937  kCFStringEncodingUTF8)) {
938  failf(data, "SSL: invalid CA certificate subject");
939  result = CURLE_SSL_CACERT;
940  }
941  else
942  /* pass back the buffer */
943  *certp = cbuf;
944  }
945  else {
946  failf(data, "SSL: couldn't allocate %zu bytes of memory", cbuf_size);
947  result = CURLE_OUT_OF_MEMORY;
948  }
949  }
950  if(result)
951  free(cbuf);
952  CFRelease(c);
953  return result;
954 }
955 
956 #if CURL_SUPPORT_MAC_10_6
957 /* The SecKeychainSearch API was deprecated in Lion, and using it will raise
958  deprecation warnings, so let's not compile this unless it's necessary: */
959 static OSStatus CopyIdentityWithLabelOldSchool(char *label,
960  SecIdentityRef *out_c_a_k)
961 {
962  OSStatus status = errSecItemNotFound;
963  SecKeychainAttributeList attr_list;
964  SecKeychainAttribute attr;
965  SecKeychainSearchRef search = NULL;
966  SecCertificateRef cert = NULL;
967 
968  /* Set up the attribute list: */
969  attr_list.count = 1L;
970  attr_list.attr = &attr;
971 
972  /* Set up our lone search criterion: */
973  attr.tag = kSecLabelItemAttr;
974  attr.data = label;
975  attr.length = (UInt32)strlen(label);
976 
977  /* Start searching: */
978  status = SecKeychainSearchCreateFromAttributes(NULL,
979  kSecCertificateItemClass,
980  &attr_list,
981  &search);
982  if(status == noErr) {
983  status = SecKeychainSearchCopyNext(search,
984  (SecKeychainItemRef *)&cert);
985  if(status == noErr && cert) {
986  /* If we found a certificate, does it have a private key? */
987  status = SecIdentityCreateWithCertificate(NULL, cert, out_c_a_k);
988  CFRelease(cert);
989  }
990  }
991 
992  if(search)
993  CFRelease(search);
994  return status;
995 }
996 #endif /* CURL_SUPPORT_MAC_10_6 */
997 
998 static OSStatus CopyIdentityWithLabel(char *label,
999  SecIdentityRef *out_cert_and_key)
1000 {
1001  OSStatus status = errSecItemNotFound;
1002 
1003 #if CURL_BUILD_MAC_10_7 || CURL_BUILD_IOS
1004  CFArrayRef keys_list;
1005  CFIndex keys_list_count;
1006  CFIndex i;
1007  CFStringRef common_name;
1008 
1009  /* SecItemCopyMatching() was introduced in iOS and Snow Leopard.
1010  kSecClassIdentity was introduced in Lion. If both exist, let's use them
1011  to find the certificate. */
1012  if(SecItemCopyMatching != NULL && kSecClassIdentity != NULL) {
1013  CFTypeRef keys[5];
1014  CFTypeRef values[5];
1015  CFDictionaryRef query_dict;
1016  CFStringRef label_cf = CFStringCreateWithCString(NULL, label,
1017  kCFStringEncodingUTF8);
1018 
1019  /* Set up our search criteria and expected results: */
1020  values[0] = kSecClassIdentity; /* we want a certificate and a key */
1021  keys[0] = kSecClass;
1022  values[1] = kCFBooleanTrue; /* we want a reference */
1023  keys[1] = kSecReturnRef;
1024  values[2] = kSecMatchLimitAll; /* kSecMatchLimitOne would be better if the
1025  * label matching below worked correctly */
1026  keys[2] = kSecMatchLimit;
1027  /* identity searches need a SecPolicyRef in order to work */
1028  values[3] = SecPolicyCreateSSL(false, NULL);
1029  keys[3] = kSecMatchPolicy;
1030  /* match the name of the certificate (doesn't work in macOS 10.12.1) */
1031  values[4] = label_cf;
1032  keys[4] = kSecAttrLabel;
1033  query_dict = CFDictionaryCreate(NULL, (const void **)keys,
1034  (const void **)values, 5L,
1035  &kCFCopyStringDictionaryKeyCallBacks,
1036  &kCFTypeDictionaryValueCallBacks);
1037  CFRelease(values[3]);
1038 
1039  /* Do we have a match? */
1040  status = SecItemCopyMatching(query_dict, (CFTypeRef *) &keys_list);
1041 
1042  /* Because kSecAttrLabel matching doesn't work with kSecClassIdentity,
1043  * we need to find the correct identity ourselves */
1044  if(status == noErr) {
1045  keys_list_count = CFArrayGetCount(keys_list);
1046  *out_cert_and_key = NULL;
1047  status = 1;
1048  for(i = 0; i<keys_list_count; i++) {
1049  OSStatus err = noErr;
1050  SecCertificateRef cert = NULL;
1051  SecIdentityRef identity =
1052  (SecIdentityRef) CFArrayGetValueAtIndex(keys_list, i);
1053  err = SecIdentityCopyCertificate(identity, &cert);
1054  if(err == noErr) {
1055 #if CURL_BUILD_IOS
1056  common_name = SecCertificateCopySubjectSummary(cert);
1057 #elif CURL_BUILD_MAC_10_7
1058  SecCertificateCopyCommonName(cert, &common_name);
1059 #endif
1060  if(CFStringCompare(common_name, label_cf, 0) == kCFCompareEqualTo) {
1061  CFRelease(cert);
1062  CFRelease(common_name);
1063  CFRetain(identity);
1064  *out_cert_and_key = identity;
1065  status = noErr;
1066  break;
1067  }
1068  CFRelease(common_name);
1069  }
1070  CFRelease(cert);
1071  }
1072  }
1073 
1074  if(keys_list)
1075  CFRelease(keys_list);
1076  CFRelease(query_dict);
1077  CFRelease(label_cf);
1078  }
1079  else {
1080 #if CURL_SUPPORT_MAC_10_6
1081  /* On Leopard and Snow Leopard, fall back to SecKeychainSearch. */
1082  status = CopyIdentityWithLabelOldSchool(label, out_cert_and_key);
1083 #endif /* CURL_SUPPORT_MAC_10_6 */
1084  }
1085 #elif CURL_SUPPORT_MAC_10_6
1086  /* For developers building on older cats, we have no choice but to fall back
1087  to SecKeychainSearch. */
1088  status = CopyIdentityWithLabelOldSchool(label, out_cert_and_key);
1089 #endif /* CURL_BUILD_MAC_10_7 || CURL_BUILD_IOS */
1090  return status;
1091 }
1092 
1093 static OSStatus CopyIdentityFromPKCS12File(const char *cPath,
1094  const char *cPassword,
1095  SecIdentityRef *out_cert_and_key)
1096 {
1097  OSStatus status = errSecItemNotFound;
1098  CFURLRef pkcs_url = CFURLCreateFromFileSystemRepresentation(NULL,
1099  (const UInt8 *)cPath, strlen(cPath), false);
1100  CFStringRef password = cPassword ? CFStringCreateWithCString(NULL,
1101  cPassword, kCFStringEncodingUTF8) : NULL;
1102  CFDataRef pkcs_data = NULL;
1103 
1104  /* We can import P12 files on iOS or OS X 10.7 or later: */
1105  /* These constants are documented as having first appeared in 10.6 but they
1106  raise linker errors when used on that cat for some reason. */
1107 #if CURL_BUILD_MAC_10_7 || CURL_BUILD_IOS
1108  if(CFURLCreateDataAndPropertiesFromResource(NULL, pkcs_url, &pkcs_data,
1109  NULL, NULL, &status)) {
1110  const void *cKeys[] = {kSecImportExportPassphrase};
1111  const void *cValues[] = {password};
1112  CFDictionaryRef options = CFDictionaryCreate(NULL, cKeys, cValues,
1113  password ? 1L : 0L, NULL, NULL);
1114  CFArrayRef items = NULL;
1115 
1116  /* Here we go: */
1117  status = SecPKCS12Import(pkcs_data, options, &items);
1118  if(status == errSecSuccess && items && CFArrayGetCount(items)) {
1119  CFDictionaryRef identity_and_trust = CFArrayGetValueAtIndex(items, 0L);
1120  const void *temp_identity = CFDictionaryGetValue(identity_and_trust,
1121  kSecImportItemIdentity);
1122 
1123  /* Retain the identity; we don't care about any other data... */
1124  CFRetain(temp_identity);
1125  *out_cert_and_key = (SecIdentityRef)temp_identity;
1126  }
1127 
1128  if(items)
1129  CFRelease(items);
1130  CFRelease(options);
1131  CFRelease(pkcs_data);
1132  }
1133 #endif /* CURL_BUILD_MAC_10_7 || CURL_BUILD_IOS */
1134  if(password)
1135  CFRelease(password);
1136  CFRelease(pkcs_url);
1137  return status;
1138 }
1139 
1140 /* This code was borrowed from nss.c, with some modifications:
1141  * Determine whether the nickname passed in is a filename that needs to
1142  * be loaded as a PEM or a regular NSS nickname.
1143  *
1144  * returns 1 for a file
1145  * returns 0 for not a file
1146  */
1147 CF_INLINE bool is_file(const char *filename)
1148 {
1149  struct_stat st;
1150 
1151  if(filename == NULL)
1152  return false;
1153 
1154  if(stat(filename, &st) == 0)
1155  return S_ISREG(st.st_mode);
1156  return false;
1157 }
1158 
1159 #if CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS
1160 static CURLcode darwinssl_version_from_curl(SSLProtocol *darwinver,
1161  long ssl_version)
1162 {
1163  switch(ssl_version) {
1165  *darwinver = kTLSProtocol1;
1166  return CURLE_OK;
1168  *darwinver = kTLSProtocol11;
1169  return CURLE_OK;
1171  *darwinver = kTLSProtocol12;
1172  return CURLE_OK;
1174  break;
1175  }
1176  return CURLE_SSL_CONNECT_ERROR;
1177 }
1178 #endif
1179 
1180 static CURLcode
1181 set_ssl_version_min_max(struct connectdata *conn, int sockindex)
1182 {
1183  struct Curl_easy *data = conn->data;
1184  struct ssl_connect_data *connssl = &conn->ssl[sockindex];
1185  long ssl_version = SSL_CONN_CONFIG(version);
1186  long ssl_version_max = SSL_CONN_CONFIG(version_max);
1187 
1188  switch(ssl_version) {
1190  case CURL_SSLVERSION_TLSv1:
1191  ssl_version = CURL_SSLVERSION_TLSv1_0;
1192  ssl_version_max = CURL_SSLVERSION_MAX_TLSv1_2;
1193  break;
1194  }
1195 
1196  switch(ssl_version_max) {
1198  ssl_version_max = ssl_version << 16;
1199  break;
1201  ssl_version_max = CURL_SSLVERSION_MAX_TLSv1_2;
1202  break;
1203  }
1204 
1205 #if CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS
1206  if(SSLSetProtocolVersionMax != NULL) {
1207  SSLProtocol darwin_ver_min = kTLSProtocol1;
1208  SSLProtocol darwin_ver_max = kTLSProtocol1;
1209  CURLcode result = darwinssl_version_from_curl(&darwin_ver_min,
1210  ssl_version);
1211  if(result) {
1212  failf(data, "unsupported min version passed via CURLOPT_SSLVERSION");
1213  return result;
1214  }
1215  result = darwinssl_version_from_curl(&darwin_ver_max,
1216  ssl_version_max >> 16);
1217  if(result) {
1218  failf(data, "unsupported max version passed via CURLOPT_SSLVERSION");
1219  return result;
1220  }
1221 
1222  (void)SSLSetProtocolVersionMin(BACKEND->ssl_ctx, darwin_ver_min);
1223  (void)SSLSetProtocolVersionMax(BACKEND->ssl_ctx, darwin_ver_max);
1224  return result;
1225  }
1226  else {
1227 #if CURL_SUPPORT_MAC_10_8
1228  long i = ssl_version;
1229  (void)SSLSetProtocolVersionEnabled(BACKEND->ssl_ctx,
1230  kSSLProtocolAll,
1231  false);
1232  for(; i <= (ssl_version_max >> 16); i++) {
1233  switch(i) {
1235  (void)SSLSetProtocolVersionEnabled(BACKEND->ssl_ctx,
1236  kTLSProtocol1,
1237  true);
1238  break;
1240  (void)SSLSetProtocolVersionEnabled(BACKEND->ssl_ctx,
1241  kTLSProtocol11,
1242  true);
1243  break;
1245  (void)SSLSetProtocolVersionEnabled(BACKEND->ssl_ctx,
1246  kTLSProtocol12,
1247  true);
1248  break;
1250  failf(data, "DarwinSSL: TLS 1.3 is not yet supported");
1251  return CURLE_SSL_CONNECT_ERROR;
1252  }
1253  }
1254  return CURLE_OK;
1255 #endif /* CURL_SUPPORT_MAC_10_8 */
1256  }
1257 #endif /* CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS */
1258  failf(data, "DarwinSSL: cannot set SSL protocol");
1259  return CURLE_SSL_CONNECT_ERROR;
1260 }
1261 
1262 
1263 static CURLcode darwinssl_connect_step1(struct connectdata *conn,
1264  int sockindex)
1265 {
1266  struct Curl_easy *data = conn->data;
1267  curl_socket_t sockfd = conn->sock[sockindex];
1268  struct ssl_connect_data *connssl = &conn->ssl[sockindex];
1269  const char * const ssl_cafile = SSL_CONN_CONFIG(CAfile);
1270  const bool verifypeer = SSL_CONN_CONFIG(verifypeer);
1271  char * const ssl_cert = SSL_SET_OPTION(cert);
1272  const char * const hostname = SSL_IS_PROXY() ? conn->http_proxy.host.name :
1273  conn->host.name;
1274  const long int port = SSL_IS_PROXY() ? conn->port : conn->remote_port;
1275 #ifdef ENABLE_IPV6
1276  struct in6_addr addr;
1277 #else
1278  struct in_addr addr;
1279 #endif /* ENABLE_IPV6 */
1280  size_t all_ciphers_count = 0UL, allowed_ciphers_count = 0UL, i;
1281  SSLCipherSuite *all_ciphers = NULL, *allowed_ciphers = NULL;
1282  OSStatus err = noErr;
1283 #if CURL_BUILD_MAC
1284  int darwinver_maj = 0, darwinver_min = 0;
1285 
1286  GetDarwinVersionNumber(&darwinver_maj, &darwinver_min);
1287 #endif /* CURL_BUILD_MAC */
1288 
1289 #if CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS
1290  if(SSLCreateContext != NULL) { /* use the newer API if avaialble */
1291  if(BACKEND->ssl_ctx)
1292  CFRelease(BACKEND->ssl_ctx);
1293  BACKEND->ssl_ctx = SSLCreateContext(NULL, kSSLClientSide, kSSLStreamType);
1294  if(!BACKEND->ssl_ctx) {
1295  failf(data, "SSL: couldn't create a context!");
1296  return CURLE_OUT_OF_MEMORY;
1297  }
1298  }
1299  else {
1300  /* The old ST API does not exist under iOS, so don't compile it: */
1301 #if CURL_SUPPORT_MAC_10_8
1302  if(BACKEND->ssl_ctx)
1303  (void)SSLDisposeContext(BACKEND->ssl_ctx);
1304  err = SSLNewContext(false, &(BACKEND->ssl_ctx));
1305  if(err != noErr) {
1306  failf(data, "SSL: couldn't create a context: OSStatus %d", err);
1307  return CURLE_OUT_OF_MEMORY;
1308  }
1309 #endif /* CURL_SUPPORT_MAC_10_8 */
1310  }
1311 #else
1312  if(BACKEND->ssl_ctx)
1313  (void)SSLDisposeContext(BACKEND->ssl_ctx);
1314  err = SSLNewContext(false, &(BACKEND->ssl_ctx));
1315  if(err != noErr) {
1316  failf(data, "SSL: couldn't create a context: OSStatus %d", err);
1317  return CURLE_OUT_OF_MEMORY;
1318  }
1319 #endif /* CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS */
1320  BACKEND->ssl_write_buffered_length = 0UL; /* reset buffered write length */
1321 
1322  /* check to see if we've been told to use an explicit SSL/TLS version */
1323 #if CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS
1324  if(SSLSetProtocolVersionMax != NULL) {
1325  switch(conn->ssl_config.version) {
1327  case CURL_SSLVERSION_TLSv1:
1328  (void)SSLSetProtocolVersionMin(BACKEND->ssl_ctx, kTLSProtocol1);
1329  (void)SSLSetProtocolVersionMax(BACKEND->ssl_ctx, kTLSProtocol12);
1330  break;
1335  {
1336  CURLcode result = set_ssl_version_min_max(conn, sockindex);
1337  if(result != CURLE_OK)
1338  return result;
1339  break;
1340  }
1341  case CURL_SSLVERSION_SSLv3:
1342  err = SSLSetProtocolVersionMin(BACKEND->ssl_ctx, kSSLProtocol3);
1343  if(err != noErr) {
1344  failf(data, "Your version of the OS does not support SSLv3");
1345  return CURLE_SSL_CONNECT_ERROR;
1346  }
1347  (void)SSLSetProtocolVersionMax(BACKEND->ssl_ctx, kSSLProtocol3);
1348  break;
1349  case CURL_SSLVERSION_SSLv2:
1350  err = SSLSetProtocolVersionMin(BACKEND->ssl_ctx, kSSLProtocol2);
1351  if(err != noErr) {
1352  failf(data, "Your version of the OS does not support SSLv2");
1353  return CURLE_SSL_CONNECT_ERROR;
1354  }
1355  (void)SSLSetProtocolVersionMax(BACKEND->ssl_ctx, kSSLProtocol2);
1356  break;
1357  default:
1358  failf(data, "Unrecognized parameter passed via CURLOPT_SSLVERSION");
1359  return CURLE_SSL_CONNECT_ERROR;
1360  }
1361  }
1362  else {
1363 #if CURL_SUPPORT_MAC_10_8
1364  (void)SSLSetProtocolVersionEnabled(BACKEND->ssl_ctx,
1365  kSSLProtocolAll,
1366  false);
1367  switch(conn->ssl_config.version) {
1369  case CURL_SSLVERSION_TLSv1:
1370  (void)SSLSetProtocolVersionEnabled(BACKEND->ssl_ctx,
1371  kTLSProtocol1,
1372  true);
1373  (void)SSLSetProtocolVersionEnabled(BACKEND->ssl_ctx,
1374  kTLSProtocol11,
1375  true);
1376  (void)SSLSetProtocolVersionEnabled(BACKEND->ssl_ctx,
1377  kTLSProtocol12,
1378  true);
1379  break;
1384  {
1385  CURLcode result = set_ssl_version_min_max(conn, sockindex);
1386  if(result != CURLE_OK)
1387  return result;
1388  break;
1389  }
1390  case CURL_SSLVERSION_SSLv3:
1391  err = SSLSetProtocolVersionEnabled(BACKEND->ssl_ctx,
1392  kSSLProtocol3,
1393  true);
1394  if(err != noErr) {
1395  failf(data, "Your version of the OS does not support SSLv3");
1396  return CURLE_SSL_CONNECT_ERROR;
1397  }
1398  break;
1399  case CURL_SSLVERSION_SSLv2:
1400  err = SSLSetProtocolVersionEnabled(BACKEND->ssl_ctx,
1401  kSSLProtocol2,
1402  true);
1403  if(err != noErr) {
1404  failf(data, "Your version of the OS does not support SSLv2");
1405  return CURLE_SSL_CONNECT_ERROR;
1406  }
1407  break;
1408  default:
1409  failf(data, "Unrecognized parameter passed via CURLOPT_SSLVERSION");
1410  return CURLE_SSL_CONNECT_ERROR;
1411  }
1412 #endif /* CURL_SUPPORT_MAC_10_8 */
1413  }
1414 #else
1416  failf(data, "Your version of the OS does not support to set maximum"
1417  " SSL/TLS version");
1418  return CURLE_SSL_CONNECT_ERROR;
1419  }
1420  (void)SSLSetProtocolVersionEnabled(BACKEND->ssl_ctx, kSSLProtocolAll, false);
1421  switch(conn->ssl_config.version) {
1423  case CURL_SSLVERSION_TLSv1:
1425  (void)SSLSetProtocolVersionEnabled(BACKEND->ssl_ctx,
1426  kTLSProtocol1,
1427  true);
1428  break;
1430  failf(data, "Your version of the OS does not support TLSv1.1");
1431  return CURLE_SSL_CONNECT_ERROR;
1433  failf(data, "Your version of the OS does not support TLSv1.2");
1434  return CURLE_SSL_CONNECT_ERROR;
1436  failf(data, "Your version of the OS does not support TLSv1.3");
1437  return CURLE_SSL_CONNECT_ERROR;
1438  case CURL_SSLVERSION_SSLv2:
1439  err = SSLSetProtocolVersionEnabled(BACKEND->ssl_ctx,
1440  kSSLProtocol2,
1441  true);
1442  if(err != noErr) {
1443  failf(data, "Your version of the OS does not support SSLv2");
1444  return CURLE_SSL_CONNECT_ERROR;
1445  }
1446  break;
1447  case CURL_SSLVERSION_SSLv3:
1448  err = SSLSetProtocolVersionEnabled(BACKEND->ssl_ctx,
1449  kSSLProtocol3,
1450  true);
1451  if(err != noErr) {
1452  failf(data, "Your version of the OS does not support SSLv3");
1453  return CURLE_SSL_CONNECT_ERROR;
1454  }
1455  break;
1456  default:
1457  failf(data, "Unrecognized parameter passed via CURLOPT_SSLVERSION");
1458  return CURLE_SSL_CONNECT_ERROR;
1459  }
1460 #endif /* CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS */
1461 
1462  if(SSL_SET_OPTION(key)) {
1463  infof(data, "WARNING: SSL: CURLOPT_SSLKEY is ignored by Secure "
1464  "Transport. The private key must be in the Keychain.\n");
1465  }
1466 
1467  if(ssl_cert) {
1468  SecIdentityRef cert_and_key = NULL;
1469  bool is_cert_file = is_file(ssl_cert);
1470 
1471  /* User wants to authenticate with a client cert. Look for it:
1472  If we detect that this is a file on disk, then let's load it.
1473  Otherwise, assume that the user wants to use an identity loaded
1474  from the Keychain. */
1475  if(is_cert_file) {
1476  if(!SSL_SET_OPTION(cert_type))
1477  infof(data, "WARNING: SSL: Certificate type not set, assuming "
1478  "PKCS#12 format.\n");
1479  else if(strncmp(SSL_SET_OPTION(cert_type), "P12",
1480  strlen(SSL_SET_OPTION(cert_type))) != 0)
1481  infof(data, "WARNING: SSL: The Security framework only supports "
1482  "loading identities that are in PKCS#12 format.\n");
1483 
1484  err = CopyIdentityFromPKCS12File(ssl_cert,
1485  SSL_SET_OPTION(key_passwd), &cert_and_key);
1486  }
1487  else
1488  err = CopyIdentityWithLabel(ssl_cert, &cert_and_key);
1489 
1490  if(err == noErr && cert_and_key) {
1491  SecCertificateRef cert = NULL;
1492  CFTypeRef certs_c[1];
1493  CFArrayRef certs;
1494 
1495  /* If we found one, print it out: */
1496  err = SecIdentityCopyCertificate(cert_and_key, &cert);
1497  if(err == noErr) {
1498  char *certp;
1499  CURLcode result = CopyCertSubject(data, cert, &certp);
1500  if(!result) {
1501  infof(data, "Client certificate: %s\n", certp);
1502  free(certp);
1503  }
1504 
1505  CFRelease(cert);
1506  if(result)
1507  return result;
1508  }
1509  certs_c[0] = cert_and_key;
1510  certs = CFArrayCreate(NULL, (const void **)certs_c, 1L,
1511  &kCFTypeArrayCallBacks);
1512  err = SSLSetCertificate(BACKEND->ssl_ctx, certs);
1513  if(certs)
1514  CFRelease(certs);
1515  if(err != noErr) {
1516  failf(data, "SSL: SSLSetCertificate() failed: OSStatus %d", err);
1517  return CURLE_SSL_CERTPROBLEM;
1518  }
1519  CFRelease(cert_and_key);
1520  }
1521  else {
1522  switch(err) {
1523  case errSecAuthFailed: case -25264: /* errSecPkcs12VerifyFailure */
1524  failf(data, "SSL: Incorrect password for the certificate \"%s\" "
1525  "and its private key.", ssl_cert);
1526  break;
1527  case -26275: /* errSecDecode */ case -25257: /* errSecUnknownFormat */
1528  failf(data, "SSL: Couldn't make sense of the data in the "
1529  "certificate \"%s\" and its private key.",
1530  ssl_cert);
1531  break;
1532  case -25260: /* errSecPassphraseRequired */
1533  failf(data, "SSL The certificate \"%s\" requires a password.",
1534  ssl_cert);
1535  break;
1536  case errSecItemNotFound:
1537  failf(data, "SSL: Can't find the certificate \"%s\" and its private "
1538  "key in the Keychain.", ssl_cert);
1539  break;
1540  default:
1541  failf(data, "SSL: Can't load the certificate \"%s\" and its private "
1542  "key: OSStatus %d", ssl_cert, err);
1543  break;
1544  }
1545  return CURLE_SSL_CERTPROBLEM;
1546  }
1547  }
1548 
1549  /* SSL always tries to verify the peer, this only says whether it should
1550  * fail to connect if the verification fails, or if it should continue
1551  * anyway. In the latter case the result of the verification is checked with
1552  * SSL_get_verify_result() below. */
1553 #if CURL_BUILD_MAC_10_6 || CURL_BUILD_IOS
1554  /* Snow Leopard introduced the SSLSetSessionOption() function, but due to
1555  a library bug with the way the kSSLSessionOptionBreakOnServerAuth flag
1556  works, it doesn't work as expected under Snow Leopard, Lion or
1557  Mountain Lion.
1558  So we need to call SSLSetEnableCertVerify() on those older cats in order
1559  to disable certificate validation if the user turned that off.
1560  (SecureTransport will always validate the certificate chain by
1561  default.)
1562  Note:
1563  Darwin 11.x.x is Lion (10.7)
1564  Darwin 12.x.x is Mountain Lion (10.8)
1565  Darwin 13.x.x is Mavericks (10.9)
1566  Darwin 14.x.x is Yosemite (10.10)
1567  Darwin 15.x.x is El Capitan (10.11)
1568  */
1569 #if CURL_BUILD_MAC
1570  if(SSLSetSessionOption != NULL && darwinver_maj >= 13) {
1571 #else
1572  if(SSLSetSessionOption != NULL) {
1573 #endif /* CURL_BUILD_MAC */
1574  bool break_on_auth = !conn->ssl_config.verifypeer || ssl_cafile;
1575  err = SSLSetSessionOption(BACKEND->ssl_ctx,
1576  kSSLSessionOptionBreakOnServerAuth,
1577  break_on_auth);
1578  if(err != noErr) {
1579  failf(data, "SSL: SSLSetSessionOption() failed: OSStatus %d", err);
1580  return CURLE_SSL_CONNECT_ERROR;
1581  }
1582  }
1583  else {
1584 #if CURL_SUPPORT_MAC_10_8
1585  err = SSLSetEnableCertVerify(BACKEND->ssl_ctx,
1586  conn->ssl_config.verifypeer?true:false);
1587  if(err != noErr) {
1588  failf(data, "SSL: SSLSetEnableCertVerify() failed: OSStatus %d", err);
1589  return CURLE_SSL_CONNECT_ERROR;
1590  }
1591 #endif /* CURL_SUPPORT_MAC_10_8 */
1592  }
1593 #else
1594  err = SSLSetEnableCertVerify(BACKEND->ssl_ctx,
1595  conn->ssl_config.verifypeer?true:false);
1596  if(err != noErr) {
1597  failf(data, "SSL: SSLSetEnableCertVerify() failed: OSStatus %d", err);
1598  return CURLE_SSL_CONNECT_ERROR;
1599  }
1600 #endif /* CURL_BUILD_MAC_10_6 || CURL_BUILD_IOS */
1601 
1602  if(ssl_cafile && verifypeer) {
1603  bool is_cert_file = is_file(ssl_cafile);
1604 
1605  if(!is_cert_file) {
1606  failf(data, "SSL: can't load CA certificate file %s", ssl_cafile);
1607  return CURLE_SSL_CACERT_BADFILE;
1608  }
1609  }
1610 
1611  /* Configure hostname check. SNI is used if available.
1612  * Both hostname check and SNI require SSLSetPeerDomainName().
1613  * Also: the verifyhost setting influences SNI usage */
1614  if(conn->ssl_config.verifyhost) {
1615  err = SSLSetPeerDomainName(BACKEND->ssl_ctx, hostname,
1616  strlen(hostname));
1617 
1618  if(err != noErr) {
1619  infof(data, "WARNING: SSL: SSLSetPeerDomainName() failed: OSStatus %d\n",
1620  err);
1621  }
1622 
1623  if((Curl_inet_pton(AF_INET, hostname, &addr))
1624  #ifdef ENABLE_IPV6
1625  || (Curl_inet_pton(AF_INET6, hostname, &addr))
1626  #endif
1627  ) {
1628  infof(data, "WARNING: using IP address, SNI is being disabled by "
1629  "the OS.\n");
1630  }
1631  }
1632  else {
1633  infof(data, "WARNING: disabling hostname validation also disables SNI.\n");
1634  }
1635 
1636  /* Disable cipher suites that ST supports but are not safe. These ciphers
1637  are unlikely to be used in any case since ST gives other ciphers a much
1638  higher priority, but it's probably better that we not connect at all than
1639  to give the user a false sense of security if the server only supports
1640  insecure ciphers. (Note: We don't care about SSLv2-only ciphers.) */
1641  (void)SSLGetNumberSupportedCiphers(BACKEND->ssl_ctx, &all_ciphers_count);
1642  all_ciphers = malloc(all_ciphers_count*sizeof(SSLCipherSuite));
1643  allowed_ciphers = malloc(all_ciphers_count*sizeof(SSLCipherSuite));
1644  if(all_ciphers && allowed_ciphers &&
1645  SSLGetSupportedCiphers(BACKEND->ssl_ctx, all_ciphers,
1646  &all_ciphers_count) == noErr) {
1647  for(i = 0UL ; i < all_ciphers_count ; i++) {
1648 #if CURL_BUILD_MAC
1649  /* There's a known bug in early versions of Mountain Lion where ST's ECC
1650  ciphers (cipher suite 0xC001 through 0xC032) simply do not work.
1651  Work around the problem here by disabling those ciphers if we are
1652  running in an affected version of OS X. */
1653  if(darwinver_maj == 12 && darwinver_min <= 3 &&
1654  all_ciphers[i] >= 0xC001 && all_ciphers[i] <= 0xC032) {
1655  continue;
1656  }
1657 #endif /* CURL_BUILD_MAC */
1658  switch(all_ciphers[i]) {
1659  /* Disable NULL ciphersuites: */
1660  case SSL_NULL_WITH_NULL_NULL:
1661  case SSL_RSA_WITH_NULL_MD5:
1662  case SSL_RSA_WITH_NULL_SHA:
1663  case 0x003B: /* TLS_RSA_WITH_NULL_SHA256 */
1664  case SSL_FORTEZZA_DMS_WITH_NULL_SHA:
1665  case 0xC001: /* TLS_ECDH_ECDSA_WITH_NULL_SHA */
1666  case 0xC006: /* TLS_ECDHE_ECDSA_WITH_NULL_SHA */
1667  case 0xC00B: /* TLS_ECDH_RSA_WITH_NULL_SHA */
1668  case 0xC010: /* TLS_ECDHE_RSA_WITH_NULL_SHA */
1669  case 0x002C: /* TLS_PSK_WITH_NULL_SHA */
1670  case 0x002D: /* TLS_DHE_PSK_WITH_NULL_SHA */
1671  case 0x002E: /* TLS_RSA_PSK_WITH_NULL_SHA */
1672  case 0x00B0: /* TLS_PSK_WITH_NULL_SHA256 */
1673  case 0x00B1: /* TLS_PSK_WITH_NULL_SHA384 */
1674  case 0x00B4: /* TLS_DHE_PSK_WITH_NULL_SHA256 */
1675  case 0x00B5: /* TLS_DHE_PSK_WITH_NULL_SHA384 */
1676  case 0x00B8: /* TLS_RSA_PSK_WITH_NULL_SHA256 */
1677  case 0x00B9: /* TLS_RSA_PSK_WITH_NULL_SHA384 */
1678  /* Disable anonymous ciphersuites: */
1679  case SSL_DH_anon_EXPORT_WITH_RC4_40_MD5:
1680  case SSL_DH_anon_WITH_RC4_128_MD5:
1681  case SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA:
1682  case SSL_DH_anon_WITH_DES_CBC_SHA:
1683  case SSL_DH_anon_WITH_3DES_EDE_CBC_SHA:
1684  case TLS_DH_anon_WITH_AES_128_CBC_SHA:
1685  case TLS_DH_anon_WITH_AES_256_CBC_SHA:
1686  case 0xC015: /* TLS_ECDH_anon_WITH_NULL_SHA */
1687  case 0xC016: /* TLS_ECDH_anon_WITH_RC4_128_SHA */
1688  case 0xC017: /* TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA */
1689  case 0xC018: /* TLS_ECDH_anon_WITH_AES_128_CBC_SHA */
1690  case 0xC019: /* TLS_ECDH_anon_WITH_AES_256_CBC_SHA */
1691  case 0x006C: /* TLS_DH_anon_WITH_AES_128_CBC_SHA256 */
1692  case 0x006D: /* TLS_DH_anon_WITH_AES_256_CBC_SHA256 */
1693  case 0x00A6: /* TLS_DH_anon_WITH_AES_128_GCM_SHA256 */
1694  case 0x00A7: /* TLS_DH_anon_WITH_AES_256_GCM_SHA384 */
1695  /* Disable weak key ciphersuites: */
1696  case SSL_RSA_EXPORT_WITH_RC4_40_MD5:
1697  case SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5:
1698  case SSL_RSA_EXPORT_WITH_DES40_CBC_SHA:
1699  case SSL_DH_DSS_EXPORT_WITH_DES40_CBC_SHA:
1700  case SSL_DH_RSA_EXPORT_WITH_DES40_CBC_SHA:
1701  case SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA:
1702  case SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA:
1703  case SSL_RSA_WITH_DES_CBC_SHA:
1704  case SSL_DH_DSS_WITH_DES_CBC_SHA:
1705  case SSL_DH_RSA_WITH_DES_CBC_SHA:
1706  case SSL_DHE_DSS_WITH_DES_CBC_SHA:
1707  case SSL_DHE_RSA_WITH_DES_CBC_SHA:
1708  /* Disable IDEA: */
1709  case SSL_RSA_WITH_IDEA_CBC_SHA:
1710  case SSL_RSA_WITH_IDEA_CBC_MD5:
1711  /* Disable RC4: */
1712  case SSL_RSA_WITH_RC4_128_MD5:
1713  case SSL_RSA_WITH_RC4_128_SHA:
1714  case 0xC002: /* TLS_ECDH_ECDSA_WITH_RC4_128_SHA */
1715  case 0xC007: /* TLS_ECDHE_ECDSA_WITH_RC4_128_SHA*/
1716  case 0xC00C: /* TLS_ECDH_RSA_WITH_RC4_128_SHA */
1717  case 0xC011: /* TLS_ECDHE_RSA_WITH_RC4_128_SHA */
1718  case 0x008A: /* TLS_PSK_WITH_RC4_128_SHA */
1719  case 0x008E: /* TLS_DHE_PSK_WITH_RC4_128_SHA */
1720  case 0x0092: /* TLS_RSA_PSK_WITH_RC4_128_SHA */
1721  break;
1722  default: /* enable everything else */
1723  allowed_ciphers[allowed_ciphers_count++] = all_ciphers[i];
1724  break;
1725  }
1726  }
1727  err = SSLSetEnabledCiphers(BACKEND->ssl_ctx, allowed_ciphers,
1728  allowed_ciphers_count);
1729  if(err != noErr) {
1730  failf(data, "SSL: SSLSetEnabledCiphers() failed: OSStatus %d", err);
1731  return CURLE_SSL_CONNECT_ERROR;
1732  }
1733  }
1734  else {
1735  Curl_safefree(all_ciphers);
1736  Curl_safefree(allowed_ciphers);
1737  failf(data, "SSL: Failed to allocate memory for allowed ciphers");
1738  return CURLE_OUT_OF_MEMORY;
1739  }
1740  Curl_safefree(all_ciphers);
1741  Curl_safefree(allowed_ciphers);
1742 
1743 #if CURL_BUILD_MAC_10_9 || CURL_BUILD_IOS_7
1744  /* We want to enable 1/n-1 when using a CBC cipher unless the user
1745  specifically doesn't want us doing that: */
1746  if(SSLSetSessionOption != NULL) {
1747  /* TODO s/data->set.ssl.enable_beast/SSL_SET_OPTION(enable_beast)/g */
1748  SSLSetSessionOption(BACKEND->ssl_ctx, kSSLSessionOptionSendOneByteRecord,
1749  !data->set.ssl.enable_beast);
1750  SSLSetSessionOption(BACKEND->ssl_ctx, kSSLSessionOptionFalseStart,
1751  data->set.ssl.falsestart); /* false start support */
1752  }
1753 #endif /* CURL_BUILD_MAC_10_9 || CURL_BUILD_IOS_7 */
1754 
1755  /* Check if there's a cached ID we can/should use here! */
1756  if(SSL_SET_OPTION(primary.sessionid)) {
1757  char *ssl_sessionid;
1758  size_t ssl_sessionid_len;
1759 
1760  Curl_ssl_sessionid_lock(conn);
1761  if(!Curl_ssl_getsessionid(conn, (void **)&ssl_sessionid,
1762  &ssl_sessionid_len, sockindex)) {
1763  /* we got a session id, use it! */
1764  err = SSLSetPeerID(BACKEND->ssl_ctx, ssl_sessionid, ssl_sessionid_len);
1765  Curl_ssl_sessionid_unlock(conn);
1766  if(err != noErr) {
1767  failf(data, "SSL: SSLSetPeerID() failed: OSStatus %d", err);
1768  return CURLE_SSL_CONNECT_ERROR;
1769  }
1770  /* Informational message */
1771  infof(data, "SSL re-using session ID\n");
1772  }
1773  /* If there isn't one, then let's make one up! This has to be done prior
1774  to starting the handshake. */
1775  else {
1776  CURLcode result;
1777  ssl_sessionid =
1778  aprintf("%s:%d:%d:%s:%hu", ssl_cafile,
1779  verifypeer, SSL_CONN_CONFIG(verifyhost), hostname, port);
1780  ssl_sessionid_len = strlen(ssl_sessionid);
1781 
1782  err = SSLSetPeerID(BACKEND->ssl_ctx, ssl_sessionid, ssl_sessionid_len);
1783  if(err != noErr) {
1784  Curl_ssl_sessionid_unlock(conn);
1785  failf(data, "SSL: SSLSetPeerID() failed: OSStatus %d", err);
1786  return CURLE_SSL_CONNECT_ERROR;
1787  }
1788 
1789  result = Curl_ssl_addsessionid(conn, ssl_sessionid, ssl_sessionid_len,
1790  sockindex);
1791  Curl_ssl_sessionid_unlock(conn);
1792  if(result) {
1793  failf(data, "failed to store ssl session");
1794  return result;
1795  }
1796  }
1797  }
1798 
1799  err = SSLSetIOFuncs(BACKEND->ssl_ctx, SocketRead, SocketWrite);
1800  if(err != noErr) {
1801  failf(data, "SSL: SSLSetIOFuncs() failed: OSStatus %d", err);
1802  return CURLE_SSL_CONNECT_ERROR;
1803  }
1804 
1805  /* pass the raw socket into the SSL layers */
1806  /* We need to store the FD in a constant memory address, because
1807  * SSLSetConnection() will not copy that address. I've found that
1808  * conn->sock[sockindex] may change on its own. */
1809  BACKEND->ssl_sockfd = sockfd;
1810  err = SSLSetConnection(BACKEND->ssl_ctx, connssl);
1811  if(err != noErr) {
1812  failf(data, "SSL: SSLSetConnection() failed: %d", err);
1813  return CURLE_SSL_CONNECT_ERROR;
1814  }
1815 
1816  connssl->connecting_state = ssl_connect_2;
1817  return CURLE_OK;
1818 }
1819 
1820 static long pem_to_der(const char *in, unsigned char **out, size_t *outlen)
1821 {
1822  char *sep_start, *sep_end, *cert_start, *cert_end;
1823  size_t i, j, err;
1824  size_t len;
1825  unsigned char *b64;
1826 
1827  /* Jump through the separators at the beginning of the certificate. */
1828  sep_start = strstr(in, "-----");
1829  if(sep_start == NULL)
1830  return 0;
1831  cert_start = strstr(sep_start + 1, "-----");
1832  if(cert_start == NULL)
1833  return -1;
1834 
1835  cert_start += 5;
1836 
1837  /* Find separator after the end of the certificate. */
1838  cert_end = strstr(cert_start, "-----");
1839  if(cert_end == NULL)
1840  return -1;
1841 
1842  sep_end = strstr(cert_end + 1, "-----");
1843  if(sep_end == NULL)
1844  return -1;
1845  sep_end += 5;
1846 
1847  len = cert_end - cert_start;
1848  b64 = malloc(len + 1);
1849  if(!b64)
1850  return -1;
1851 
1852  /* Create base64 string without linefeeds. */
1853  for(i = 0, j = 0; i < len; i++) {
1854  if(cert_start[i] != '\r' && cert_start[i] != '\n')
1855  b64[j++] = cert_start[i];
1856  }
1857  b64[j] = '\0';
1858 
1859  err = Curl_base64_decode((const char *)b64, out, outlen);
1860  free(b64);
1861  if(err) {
1862  free(*out);
1863  return -1;
1864  }
1865 
1866  return sep_end - in;
1867 }
1868 
1869 static int read_cert(const char *file, unsigned char **out, size_t *outlen)
1870 {
1871  int fd;
1872  ssize_t n, len = 0, cap = 512;
1873  unsigned char buf[512], *data;
1874 
1875  fd = open(file, 0);
1876  if(fd < 0)
1877  return -1;
1878 
1879  data = malloc(cap);
1880  if(!data) {
1881  close(fd);
1882  return -1;
1883  }
1884 
1885  for(;;) {
1886  n = read(fd, buf, sizeof(buf));
1887  if(n < 0) {
1888  close(fd);
1889  free(data);
1890  return -1;
1891  }
1892  else if(n == 0) {
1893  close(fd);
1894  break;
1895  }
1896 
1897  if(len + n >= cap) {
1898  cap *= 2;
1899  data = realloc(data, cap);
1900  if(!data) {
1901  close(fd);
1902  return -1;
1903  }
1904  }
1905 
1906  memcpy(data + len, buf, n);
1907  len += n;
1908  }
1909  data[len] = '\0';
1910 
1911  *out = data;
1912  *outlen = len;
1913 
1914  return 0;
1915 }
1916 
1917 static int sslerr_to_curlerr(struct Curl_easy *data, int err)
1918 {
1919  switch(err) {
1920  case errSSLXCertChainInvalid:
1921  failf(data, "SSL certificate problem: Invalid certificate chain");
1922  return CURLE_SSL_CACERT;
1923  case errSSLUnknownRootCert:
1924  failf(data, "SSL certificate problem: Untrusted root certificate");
1925  return CURLE_SSL_CACERT;
1926  case errSSLNoRootCert:
1927  failf(data, "SSL certificate problem: No root certificate");
1928  return CURLE_SSL_CACERT;
1929  case errSSLCertExpired:
1930  failf(data, "SSL certificate problem: Certificate chain had an "
1931  "expired certificate");
1932  return CURLE_SSL_CACERT;
1933  case errSSLBadCert:
1934  failf(data, "SSL certificate problem: Couldn't understand the server "
1935  "certificate format");
1936  return CURLE_SSL_CONNECT_ERROR;
1937  case errSSLHostNameMismatch:
1938  failf(data, "SSL certificate peer hostname mismatch");
1940  default:
1941  failf(data, "SSL unexpected certificate error %d", err);
1942  return CURLE_SSL_CACERT;
1943  }
1944 }
1945 
1946 static int append_cert_to_array(struct Curl_easy *data,
1947  unsigned char *buf, size_t buflen,
1948  CFMutableArrayRef array)
1949 {
1950  CFDataRef certdata = CFDataCreate(kCFAllocatorDefault, buf, buflen);
1951  char *certp;
1952  CURLcode result;
1953  if(!certdata) {
1954  failf(data, "SSL: failed to allocate array for CA certificate");
1955  return CURLE_OUT_OF_MEMORY;
1956  }
1957 
1958  SecCertificateRef cacert =
1959  SecCertificateCreateWithData(kCFAllocatorDefault, certdata);
1960  CFRelease(certdata);
1961  if(!cacert) {
1962  failf(data, "SSL: failed to create SecCertificate from CA certificate");
1963  return CURLE_SSL_CACERT;
1964  }
1965 
1966  /* Check if cacert is valid. */
1967  result = CopyCertSubject(data, cacert, &certp);
1968  if(result)
1969  return result;
1970  free(certp);
1971 
1972  CFArrayAppendValue(array, cacert);
1973  CFRelease(cacert);
1974 
1975  return CURLE_OK;
1976 }
1977 
1978 static int verify_cert(const char *cafile, struct Curl_easy *data,
1979  SSLContextRef ctx)
1980 {
1981  int n = 0, rc;
1982  long res;
1983  unsigned char *certbuf, *der;
1984  size_t buflen, derlen, offset = 0;
1985 
1986  if(read_cert(cafile, &certbuf, &buflen) < 0) {
1987  failf(data, "SSL: failed to read or invalid CA certificate");
1988  return CURLE_SSL_CACERT;
1989  }
1990 
1991  /*
1992  * Certbuf now contains the contents of the certificate file, which can be
1993  * - a single DER certificate,
1994  * - a single PEM certificate or
1995  * - a bunch of PEM certificates (certificate bundle).
1996  *
1997  * Go through certbuf, and convert any PEM certificate in it into DER
1998  * format.
1999  */
2000  CFMutableArrayRef array = CFArrayCreateMutable(kCFAllocatorDefault, 0,
2001  &kCFTypeArrayCallBacks);
2002  if(array == NULL) {
2003  free(certbuf);
2004  failf(data, "SSL: out of memory creating CA certificate array");
2005  return CURLE_OUT_OF_MEMORY;
2006  }
2007 
2008  while(offset < buflen) {
2009  n++;
2010 
2011  /*
2012  * Check if the certificate is in PEM format, and convert it to DER. If
2013  * this fails, we assume the certificate is in DER format.
2014  */
2015  res = pem_to_der((const char *)certbuf + offset, &der, &derlen);
2016  if(res < 0) {
2017  free(certbuf);
2018  CFRelease(array);
2019  failf(data, "SSL: invalid CA certificate #%d (offset %d) in bundle",
2020  n, offset);
2021  return CURLE_SSL_CACERT;
2022  }
2023  offset += res;
2024 
2025  if(res == 0 && offset == 0) {
2026  /* This is not a PEM file, probably a certificate in DER format. */
2027  rc = append_cert_to_array(data, certbuf, buflen, array);
2028  free(certbuf);
2029  if(rc != CURLE_OK) {
2030  CFRelease(array);
2031  return rc;
2032  }
2033  break;
2034  }
2035  else if(res == 0) {
2036  /* No more certificates in the bundle. */
2037  free(certbuf);
2038  break;
2039  }
2040 
2041  rc = append_cert_to_array(data, der, derlen, array);
2042  free(der);
2043  if(rc != CURLE_OK) {
2044  free(certbuf);
2045  CFRelease(array);
2046  return rc;
2047  }
2048  }
2049 
2050  SecTrustRef trust;
2051  OSStatus ret = SSLCopyPeerTrust(ctx, &trust);
2052  if(trust == NULL) {
2053  failf(data, "SSL: error getting certificate chain");
2054  CFRelease(array);
2055  return CURLE_OUT_OF_MEMORY;
2056  }
2057  else if(ret != noErr) {
2058  CFRelease(array);
2059  return sslerr_to_curlerr(data, ret);
2060  }
2061 
2062  ret = SecTrustSetAnchorCertificates(trust, array);
2063  if(ret != noErr) {
2064  CFRelease(trust);
2065  return sslerr_to_curlerr(data, ret);
2066  }
2067  ret = SecTrustSetAnchorCertificatesOnly(trust, true);
2068  if(ret != noErr) {
2069  CFRelease(trust);
2070  return sslerr_to_curlerr(data, ret);
2071  }
2072 
2073  SecTrustResultType trust_eval = 0;
2074  ret = SecTrustEvaluate(trust, &trust_eval);
2075  CFRelease(array);
2076  CFRelease(trust);
2077  if(ret != noErr) {
2078  return sslerr_to_curlerr(data, ret);
2079  }
2080 
2081  switch(trust_eval) {
2082  case kSecTrustResultUnspecified:
2083  case kSecTrustResultProceed:
2084  return CURLE_OK;
2085 
2086  case kSecTrustResultRecoverableTrustFailure:
2087  case kSecTrustResultDeny:
2088  default:
2089  failf(data, "SSL: certificate verification failed (result: %d)",
2090  trust_eval);
2092  }
2093 }
2094 
2095 #ifdef DARWIN_SSL_PINNEDPUBKEY
2096 static CURLcode pkp_pin_peer_pubkey(struct Curl_easy *data,
2097  SSLContextRef ctx,
2098  const char *pinnedpubkey)
2099 { /* Scratch */
2100  size_t pubkeylen, realpubkeylen, spkiHeaderLength = 24;
2101  unsigned char *pubkey = NULL, *realpubkey = NULL;
2102  const unsigned char *spkiHeader = NULL;
2103  CFDataRef publicKeyBits = NULL;
2104 
2105  /* Result is returned to caller */
2107 
2108  /* if a path wasn't specified, don't pin */
2109  if(!pinnedpubkey)
2110  return CURLE_OK;
2111 
2112 
2113  if(!ctx)
2114  return result;
2115 
2116  do {
2117  SecTrustRef trust;
2118  OSStatus ret = SSLCopyPeerTrust(ctx, &trust);
2119  if(ret != noErr || trust == NULL)
2120  break;
2121 
2122  SecKeyRef keyRef = SecTrustCopyPublicKey(trust);
2123  CFRelease(trust);
2124  if(keyRef == NULL)
2125  break;
2126 
2127 #ifdef DARWIN_SSL_PINNEDPUBKEY_V1
2128 
2129  publicKeyBits = SecKeyCopyExternalRepresentation(keyRef, NULL);
2130  CFRelease(keyRef);
2131  if(publicKeyBits == NULL)
2132  break;
2133 
2134 #elif DARWIN_SSL_PINNEDPUBKEY_V2
2135 
2136  OSStatus success = SecItemExport(keyRef, kSecFormatOpenSSL, 0, NULL,
2137  &publicKeyBits);
2138  CFRelease(keyRef);
2139  if(success != errSecSuccess || publicKeyBits == NULL)
2140  break;
2141 
2142 #endif /* DARWIN_SSL_PINNEDPUBKEY_V2 */
2143 
2144  pubkeylen = CFDataGetLength(publicKeyBits);
2145  pubkey = (unsigned char *)CFDataGetBytePtr(publicKeyBits);
2146 
2147  switch(pubkeylen) {
2148  case 526:
2149  /* 4096 bit RSA pubkeylen == 526 */
2150  spkiHeader = rsa4096SpkiHeader;
2151  break;
2152  case 270:
2153  /* 2048 bit RSA pubkeylen == 270 */
2154  spkiHeader = rsa2048SpkiHeader;
2155  break;
2156 #ifdef DARWIN_SSL_PINNEDPUBKEY_V1
2157  case 65:
2158  /* ecDSA secp256r1 pubkeylen == 65 */
2159  spkiHeader = ecDsaSecp256r1SpkiHeader;
2160  spkiHeaderLength = 26;
2161  break;
2162  case 97:
2163  /* ecDSA secp384r1 pubkeylen == 97 */
2164  spkiHeader = ecDsaSecp384r1SpkiHeader;
2165  spkiHeaderLength = 23;
2166  break;
2167  default:
2168  infof(data, "SSL: unhandled public key length: %d\n", pubkeylen);
2169 #elif DARWIN_SSL_PINNEDPUBKEY_V2
2170  default:
2171  /* ecDSA secp256r1 pubkeylen == 91 header already included?
2172  * ecDSA secp384r1 header already included too
2173  * we assume rest of algorithms do same, so do nothing
2174  */
2175  result = Curl_pin_peer_pubkey(data, pinnedpubkey, pubkey,
2176  pubkeylen);
2177 #endif /* DARWIN_SSL_PINNEDPUBKEY_V2 */
2178  continue; /* break from loop */
2179  }
2180 
2181  realpubkeylen = pubkeylen + spkiHeaderLength;
2182  realpubkey = malloc(realpubkeylen);
2183  if(!realpubkey)
2184  break;
2185 
2186  memcpy(realpubkey, spkiHeader, spkiHeaderLength);
2187  memcpy(realpubkey + spkiHeaderLength, pubkey, pubkeylen);
2188 
2189  result = Curl_pin_peer_pubkey(data, pinnedpubkey, realpubkey,
2190  realpubkeylen);
2191 
2192  } while(0);
2193 
2194  Curl_safefree(realpubkey);
2195  if(publicKeyBits != NULL)
2196  CFRelease(publicKeyBits);
2197 
2198  return result;
2199 }
2200 #endif /* DARWIN_SSL_PINNEDPUBKEY */
2201 
2202 static CURLcode
2203 darwinssl_connect_step2(struct connectdata *conn, int sockindex)
2204 {
2205  struct Curl_easy *data = conn->data;
2206  struct ssl_connect_data *connssl = &conn->ssl[sockindex];
2207  OSStatus err;
2208  SSLCipherSuite cipher;
2209  SSLProtocol protocol = 0;
2210  const char * const hostname = SSL_IS_PROXY() ? conn->http_proxy.host.name :
2211  conn->host.name;
2212 
2215  || ssl_connect_2_writing == connssl->connecting_state);
2216 
2217  /* Here goes nothing: */
2218  err = SSLHandshake(BACKEND->ssl_ctx);
2219 
2220  if(err != noErr) {
2221  switch(err) {
2222  case errSSLWouldBlock: /* they're not done with us yet */
2223  connssl->connecting_state = BACKEND->ssl_direction ?
2225  return CURLE_OK;
2226 
2227  /* The below is errSSLServerAuthCompleted; it's not defined in
2228  Leopard's headers */
2229  case -9841:
2230  if(SSL_CONN_CONFIG(CAfile) && SSL_CONN_CONFIG(verifypeer)) {
2231  int res = verify_cert(SSL_CONN_CONFIG(CAfile), data,
2232  BACKEND->ssl_ctx);
2233  if(res != CURLE_OK)
2234  return res;
2235  }
2236  /* the documentation says we need to call SSLHandshake() again */
2237  return darwinssl_connect_step2(conn, sockindex);
2238 
2239  /* These are all certificate problems with the server: */
2240  case errSSLXCertChainInvalid:
2241  failf(data, "SSL certificate problem: Invalid certificate chain");
2242  return CURLE_SSL_CACERT;
2243  case errSSLUnknownRootCert:
2244  failf(data, "SSL certificate problem: Untrusted root certificate");
2245  return CURLE_SSL_CACERT;
2246  case errSSLNoRootCert:
2247  failf(data, "SSL certificate problem: No root certificate");
2248  return CURLE_SSL_CACERT;
2249  case errSSLCertExpired:
2250  failf(data, "SSL certificate problem: Certificate chain had an "
2251  "expired certificate");
2252  return CURLE_SSL_CACERT;
2253  case errSSLBadCert:
2254  failf(data, "SSL certificate problem: Couldn't understand the server "
2255  "certificate format");
2256  return CURLE_SSL_CONNECT_ERROR;
2257 
2258  /* These are all certificate problems with the client: */
2259  case errSecAuthFailed:
2260  failf(data, "SSL authentication failed");
2261  return CURLE_SSL_CONNECT_ERROR;
2262  case errSSLPeerHandshakeFail:
2263  failf(data, "SSL peer handshake failed, the server most likely "
2264  "requires a client certificate to connect");
2265  return CURLE_SSL_CONNECT_ERROR;
2266  case errSSLPeerUnknownCA:
2267  failf(data, "SSL server rejected the client certificate due to "
2268  "the certificate being signed by an unknown certificate "
2269  "authority");
2270  return CURLE_SSL_CONNECT_ERROR;
2271 
2272  /* This error is raised if the server's cert didn't match the server's
2273  host name: */
2274  case errSSLHostNameMismatch:
2275  failf(data, "SSL certificate peer verification failed, the "
2276  "certificate did not match \"%s\"\n", conn->host.dispname);
2278 
2279  /* Generic handshake errors: */
2280  case errSSLConnectionRefused:
2281  failf(data, "Server dropped the connection during the SSL handshake");
2282  return CURLE_SSL_CONNECT_ERROR;
2283  case errSSLClosedAbort:
2284  failf(data, "Server aborted the SSL handshake");
2285  return CURLE_SSL_CONNECT_ERROR;
2286  case errSSLNegotiation:
2287  failf(data, "Could not negotiate an SSL cipher suite with the server");
2288  return CURLE_SSL_CONNECT_ERROR;
2289  /* Sometimes paramErr happens with buggy ciphers: */
2290  case paramErr: case errSSLInternal:
2291  failf(data, "Internal SSL engine error encountered during the "
2292  "SSL handshake");
2293  return CURLE_SSL_CONNECT_ERROR;
2294  case errSSLFatalAlert:
2295  failf(data, "Fatal SSL engine error encountered during the SSL "
2296  "handshake");
2297  return CURLE_SSL_CONNECT_ERROR;
2298  default:
2299  failf(data, "Unknown SSL protocol error in connection to %s:%d",
2300  hostname, err);
2301  return CURLE_SSL_CONNECT_ERROR;
2302  }
2303  }
2304  else {
2305  /* we have been connected fine, we're not waiting for anything else. */
2306  connssl->connecting_state = ssl_connect_3;
2307 
2308 #ifdef DARWIN_SSL_PINNEDPUBKEY
2310  CURLcode result = pkp_pin_peer_pubkey(data, BACKEND->ssl_ctx,
2312  if(result) {
2313  failf(data, "SSL: public key does not match pinned public key!");
2314  return result;
2315  }
2316  }
2317 #endif /* DARWIN_SSL_PINNEDPUBKEY */
2318 
2319  /* Informational message */
2320  (void)SSLGetNegotiatedCipher(BACKEND->ssl_ctx, &cipher);
2321  (void)SSLGetNegotiatedProtocolVersion(BACKEND->ssl_ctx, &protocol);
2322  switch(protocol) {
2323  case kSSLProtocol2:
2324  infof(data, "SSL 2.0 connection using %s\n",
2325  SSLCipherNameForNumber(cipher));
2326  break;
2327  case kSSLProtocol3:
2328  infof(data, "SSL 3.0 connection using %s\n",
2329  SSLCipherNameForNumber(cipher));
2330  break;
2331  case kTLSProtocol1:
2332  infof(data, "TLS 1.0 connection using %s\n",
2333  TLSCipherNameForNumber(cipher));
2334  break;
2335 #if CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS
2336  case kTLSProtocol11:
2337  infof(data, "TLS 1.1 connection using %s\n",
2338  TLSCipherNameForNumber(cipher));
2339  break;
2340  case kTLSProtocol12:
2341  infof(data, "TLS 1.2 connection using %s\n",
2342  TLSCipherNameForNumber(cipher));
2343  break;
2344 #endif
2345  default:
2346  infof(data, "Unknown protocol connection\n");
2347  break;
2348  }
2349 
2350  return CURLE_OK;
2351  }
2352 }
2353 
2354 #ifndef CURL_DISABLE_VERBOSE_STRINGS
2355 /* This should be called during step3 of the connection at the earliest */
2356 static void
2357 show_verbose_server_cert(struct connectdata *conn,
2358  int sockindex)
2359 {
2360  struct Curl_easy *data = conn->data;
2361  struct ssl_connect_data *connssl = &conn->ssl[sockindex];
2362  CFArrayRef server_certs = NULL;
2363  SecCertificateRef server_cert;
2364  OSStatus err;
2365  CFIndex i, count;
2366  SecTrustRef trust = NULL;
2367 
2368  if(!BACKEND->ssl_ctx)
2369  return;
2370 
2371 #if CURL_BUILD_MAC_10_7 || CURL_BUILD_IOS
2372 #if CURL_BUILD_IOS
2373 #pragma unused(server_certs)
2374  err = SSLCopyPeerTrust(BACKEND->ssl_ctx, &trust);
2375  /* For some reason, SSLCopyPeerTrust() can return noErr and yet return
2376  a null trust, so be on guard for that: */
2377  if(err == noErr && trust) {
2378  count = SecTrustGetCertificateCount(trust);
2379  for(i = 0L ; i < count ; i++) {
2380  CURLcode result;
2381  char *certp;
2382  server_cert = SecTrustGetCertificateAtIndex(trust, i);
2383  result = CopyCertSubject(data, server_cert, &certp);
2384  if(!result) {
2385  infof(data, "Server certificate: %s\n", certp);
2386  free(certp);
2387  }
2388  }
2389  CFRelease(trust);
2390  }
2391 #else
2392  /* SSLCopyPeerCertificates() is deprecated as of Mountain Lion.
2393  The function SecTrustGetCertificateAtIndex() is officially present
2394  in Lion, but it is unfortunately also present in Snow Leopard as
2395  private API and doesn't work as expected. So we have to look for
2396  a different symbol to make sure this code is only executed under
2397  Lion or later. */
2398  if(SecTrustEvaluateAsync != NULL) {
2399 #pragma unused(server_certs)
2400  err = SSLCopyPeerTrust(BACKEND->ssl_ctx, &trust);
2401  /* For some reason, SSLCopyPeerTrust() can return noErr and yet return
2402  a null trust, so be on guard for that: */
2403  if(err == noErr && trust) {
2404  count = SecTrustGetCertificateCount(trust);
2405  for(i = 0L ; i < count ; i++) {
2406  char *certp;
2407  CURLcode result;
2408  server_cert = SecTrustGetCertificateAtIndex(trust, i);
2409  result = CopyCertSubject(data, server_cert, &certp);
2410  if(!result) {
2411  infof(data, "Server certificate: %s\n", certp);
2412  free(certp);
2413  }
2414  }
2415  CFRelease(trust);
2416  }
2417  }
2418  else {
2419 #if CURL_SUPPORT_MAC_10_8
2420  err = SSLCopyPeerCertificates(BACKEND->ssl_ctx, &server_certs);
2421  /* Just in case SSLCopyPeerCertificates() returns null too... */
2422  if(err == noErr && server_certs) {
2423  count = CFArrayGetCount(server_certs);
2424  for(i = 0L ; i < count ; i++) {
2425  char *certp;
2426  CURLcode result;
2427  server_cert = (SecCertificateRef)CFArrayGetValueAtIndex(server_certs,
2428  i);
2429  result = CopyCertSubject(data, server_cert, &certp);
2430  if(!result) {
2431  infof(data, "Server certificate: %s\n", certp);
2432  free(certp);
2433  }
2434  }
2435  CFRelease(server_certs);
2436  }
2437 #endif /* CURL_SUPPORT_MAC_10_8 */
2438  }
2439 #endif /* CURL_BUILD_IOS */
2440 #else
2441 #pragma unused(trust)
2442  err = SSLCopyPeerCertificates(BACKEND->ssl_ctx, &server_certs);
2443  if(err == noErr) {
2444  count = CFArrayGetCount(server_certs);
2445  for(i = 0L ; i < count ; i++) {
2446  CURLcode result;
2447  char *certp;
2448  server_cert = (SecCertificateRef)CFArrayGetValueAtIndex(server_certs, i);
2449  result = CopyCertSubject(data, server_cert, &certp);
2450  if(!result) {
2451  infof(data, "Server certificate: %s\n", certp);
2452  free(certp);
2453  }
2454  }
2455  CFRelease(server_certs);
2456  }
2457 #endif /* CURL_BUILD_MAC_10_7 || CURL_BUILD_IOS */
2458 }
2459 #endif /* !CURL_DISABLE_VERBOSE_STRINGS */
2460 
2461 static CURLcode
2462 darwinssl_connect_step3(struct connectdata *conn,
2463  int sockindex)
2464 {
2465  struct Curl_easy *data = conn->data;
2466  struct ssl_connect_data *connssl = &conn->ssl[sockindex];
2467 
2468  /* There is no step 3!
2469  * Well, okay, if verbose mode is on, let's print the details of the
2470  * server certificates. */
2471 #ifndef CURL_DISABLE_VERBOSE_STRINGS
2472  if(data->set.verbose)
2473  show_verbose_server_cert(conn, sockindex);
2474 #endif
2475 
2477  return CURLE_OK;
2478 }
2479 
2480 static Curl_recv darwinssl_recv;
2481 static Curl_send darwinssl_send;
2482 
2483 static CURLcode
2484 darwinssl_connect_common(struct connectdata *conn,
2485  int sockindex,
2486  bool nonblocking,
2487  bool *done)
2488 {
2489  CURLcode result;
2490  struct Curl_easy *data = conn->data;
2491  struct ssl_connect_data *connssl = &conn->ssl[sockindex];
2492  curl_socket_t sockfd = conn->sock[sockindex];
2493  long timeout_ms;
2494  int what;
2495 
2496  /* check if the connection has already been established */
2497  if(ssl_connection_complete == connssl->state) {
2498  *done = TRUE;
2499  return CURLE_OK;
2500  }
2501 
2502  if(ssl_connect_1 == connssl->connecting_state) {
2503  /* Find out how much more time we're allowed */
2504  timeout_ms = Curl_timeleft(data, NULL, TRUE);
2505 
2506  if(timeout_ms < 0) {
2507  /* no need to continue if time already is up */
2508  failf(data, "SSL connection timeout");
2509  return CURLE_OPERATION_TIMEDOUT;
2510  }
2511 
2512  result = darwinssl_connect_step1(conn, sockindex);
2513  if(result)
2514  return result;
2515  }
2516 
2517  while(ssl_connect_2 == connssl->connecting_state ||
2520 
2521  /* check allowed time left */
2522  timeout_ms = Curl_timeleft(data, NULL, TRUE);
2523 
2524  if(timeout_ms < 0) {
2525  /* no need to continue if time already is up */
2526  failf(data, "SSL connection timeout");
2527  return CURLE_OPERATION_TIMEDOUT;
2528  }
2529 
2530  /* if ssl is expecting something, check if it's available. */
2531  if(connssl->connecting_state == ssl_connect_2_reading ||
2533 
2535  connssl->connecting_state?sockfd:CURL_SOCKET_BAD;
2537  connssl->connecting_state?sockfd:CURL_SOCKET_BAD;
2538 
2539  what = Curl_socket_check(readfd, CURL_SOCKET_BAD, writefd,
2540  nonblocking?0:timeout_ms);
2541  if(what < 0) {
2542  /* fatal error */
2543  failf(data, "select/poll on SSL socket, errno: %d", SOCKERRNO);
2544  return CURLE_SSL_CONNECT_ERROR;
2545  }
2546  else if(0 == what) {
2547  if(nonblocking) {
2548  *done = FALSE;
2549  return CURLE_OK;
2550  }
2551  else {
2552  /* timeout */
2553  failf(data, "SSL connection timeout");
2554  return CURLE_OPERATION_TIMEDOUT;
2555  }
2556  }
2557  /* socket is readable or writable */
2558  }
2559 
2560  /* Run transaction, and return to the caller if it failed or if this
2561  * connection is done nonblocking and this loop would execute again. This
2562  * permits the owner of a multi handle to abort a connection attempt
2563  * before step2 has completed while ensuring that a client using select()
2564  * or epoll() will always have a valid fdset to wait on.
2565  */
2566  result = darwinssl_connect_step2(conn, sockindex);
2567  if(result || (nonblocking &&
2568  (ssl_connect_2 == connssl->connecting_state ||
2571  return result;
2572 
2573  } /* repeat step2 until all transactions are done. */
2574 
2575 
2576  if(ssl_connect_3 == connssl->connecting_state) {
2577  result = darwinssl_connect_step3(conn, sockindex);
2578  if(result)
2579  return result;
2580  }
2581 
2582  if(ssl_connect_done == connssl->connecting_state) {
2583  connssl->state = ssl_connection_complete;
2584  conn->recv[sockindex] = darwinssl_recv;
2585  conn->send[sockindex] = darwinssl_send;
2586  *done = TRUE;
2587  }
2588  else
2589  *done = FALSE;
2590 
2591  /* Reset our connect state machine */
2592  connssl->connecting_state = ssl_connect_1;
2593 
2594  return CURLE_OK;
2595 }
2596 
2597 static CURLcode Curl_darwinssl_connect_nonblocking(struct connectdata *conn,
2598  int sockindex, bool *done)
2599 {
2600  return darwinssl_connect_common(conn, sockindex, TRUE, done);
2601 }
2602 
2603 static CURLcode Curl_darwinssl_connect(struct connectdata *conn, int sockindex)
2604 {
2605  CURLcode result;
2606  bool done = FALSE;
2607 
2608  result = darwinssl_connect_common(conn, sockindex, FALSE, &done);
2609 
2610  if(result)
2611  return result;
2612 
2613  DEBUGASSERT(done);
2614 
2615  return CURLE_OK;
2616 }
2617 
2618 static void Curl_darwinssl_close(struct connectdata *conn, int sockindex)
2619 {
2620  struct ssl_connect_data *connssl = &conn->ssl[sockindex];
2621 
2622  if(BACKEND->ssl_ctx) {
2623  (void)SSLClose(BACKEND->ssl_ctx);
2624 #if CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS
2625  if(SSLCreateContext != NULL)
2626  CFRelease(BACKEND->ssl_ctx);
2627 #if CURL_SUPPORT_MAC_10_8
2628  else
2629  (void)SSLDisposeContext(BACKEND->ssl_ctx);
2630 #endif /* CURL_SUPPORT_MAC_10_8 */
2631 #else
2632  (void)SSLDisposeContext(BACKEND->ssl_ctx);
2633 #endif /* CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS */
2634  BACKEND->ssl_ctx = NULL;
2635  }
2636  BACKEND->ssl_sockfd = 0;
2637 }
2638 
2639 static int Curl_darwinssl_shutdown(struct connectdata *conn, int sockindex)
2640 {
2641  struct ssl_connect_data *connssl = &conn->ssl[sockindex];
2642  struct Curl_easy *data = conn->data;
2643  ssize_t nread;
2644  int what;
2645  int rc;
2646  char buf[120];
2647 
2648  if(!BACKEND->ssl_ctx)
2649  return 0;
2650 
2651  if(data->set.ftp_ccc != CURLFTPSSL_CCC_ACTIVE)
2652  return 0;
2653 
2654  Curl_darwinssl_close(conn, sockindex);
2655 
2656  rc = 0;
2657 
2658  what = SOCKET_READABLE(conn->sock[sockindex], SSL_SHUTDOWN_TIMEOUT);
2659 
2660  for(;;) {
2661  if(what < 0) {
2662  /* anything that gets here is fatally bad */
2663  failf(data, "select/poll on SSL socket, errno: %d", SOCKERRNO);
2664  rc = -1;
2665  break;
2666  }
2667 
2668  if(!what) { /* timeout */
2669  failf(data, "SSL shutdown timeout");
2670  break;
2671  }
2672 
2673  /* Something to read, let's do it and hope that it is the close
2674  notify alert from the server. No way to SSL_Read now, so use read(). */
2675 
2676  nread = read(conn->sock[sockindex], buf, sizeof(buf));
2677 
2678  if(nread < 0) {
2679  failf(data, "read: %s", strerror(errno));
2680  rc = -1;
2681  }
2682 
2683  if(nread <= 0)
2684  break;
2685 
2686  what = SOCKET_READABLE(conn->sock[sockindex], 0);
2687  }
2688 
2689  return rc;
2690 }
2691 
2692 static void Curl_darwinssl_session_free(void *ptr)
2693 {
2694  /* ST, as of iOS 5 and Mountain Lion, has no public method of deleting a
2695  cached session ID inside the Security framework. There is a private
2696  function that does this, but I don't want to have to explain to you why I
2697  got your application rejected from the App Store due to the use of a
2698  private API, so the best we can do is free up our own char array that we
2699  created way back in darwinssl_connect_step1... */
2700  Curl_safefree(ptr);
2701 }
2702 
2703 static size_t Curl_darwinssl_version(char *buffer, size_t size)
2704 {
2705  return snprintf(buffer, size, "SecureTransport");
2706 }
2707 
2708 /*
2709  * This function uses SSLGetSessionState to determine connection status.
2710  *
2711  * Return codes:
2712  * 1 means the connection is still in place
2713  * 0 means the connection has been closed
2714  * -1 means the connection status is unknown
2715  */
2716 static int Curl_darwinssl_check_cxn(struct connectdata *conn)
2717 {
2718  struct ssl_connect_data *connssl = &conn->ssl[FIRSTSOCKET];
2719  OSStatus err;
2720  SSLSessionState state;
2721 
2722  if(BACKEND->ssl_ctx) {
2723  err = SSLGetSessionState(BACKEND->ssl_ctx, &state);
2724  if(err == noErr)
2725  return state == kSSLConnected || state == kSSLHandshake;
2726  return -1;
2727  }
2728  return 0;
2729 }
2730 
2731 static bool Curl_darwinssl_data_pending(const struct connectdata *conn,
2732  int connindex)
2733 {
2734  const struct ssl_connect_data *connssl = &conn->ssl[connindex];
2735  OSStatus err;
2736  size_t buffer;
2737 
2738  if(BACKEND->ssl_ctx) { /* SSL is in use */
2739  err = SSLGetBufferedReadSize(BACKEND->ssl_ctx, &buffer);
2740  if(err == noErr)
2741  return buffer > 0UL;
2742  return false;
2743  }
2744  else
2745  return false;
2746 }
2747 
2748 static CURLcode Curl_darwinssl_random(struct Curl_easy *data UNUSED_PARAM,
2749  unsigned char *entropy, size_t length)
2750 {
2751  /* arc4random_buf() isn't available on cats older than Lion, so let's
2752  do this manually for the benefit of the older cats. */
2753  size_t i;
2754  u_int32_t random_number = 0;
2755 
2756  (void)data;
2757 
2758  for(i = 0 ; i < length ; i++) {
2759  if(i % sizeof(u_int32_t) == 0)
2760  random_number = arc4random();
2761  entropy[i] = random_number & 0xFF;
2762  random_number >>= 8;
2763  }
2764  i = random_number = 0;
2765  return CURLE_OK;
2766 }
2767 
2768 static CURLcode Curl_darwinssl_md5sum(unsigned char *tmp, /* input */
2769  size_t tmplen,
2770  unsigned char *md5sum, /* output */
2771  size_t md5len)
2772 {
2773  (void)md5len;
2774  (void)CC_MD5(tmp, (CC_LONG)tmplen, md5sum);
2775  return CURLE_OK;
2776 }
2777 
2778 static void Curl_darwinssl_sha256sum(const unsigned char *tmp, /* input */
2779  size_t tmplen,
2780  unsigned char *sha256sum, /* output */
2781  size_t sha256len)
2782 {
2783  assert(sha256len >= CURL_SHA256_DIGEST_LENGTH);
2784  (void)CC_SHA256(tmp, (CC_LONG)tmplen, sha256sum);
2785 }
2786 
2787 static bool Curl_darwinssl_false_start(void)
2788 {
2789 #if CURL_BUILD_MAC_10_9 || CURL_BUILD_IOS_7
2790  if(SSLSetSessionOption != NULL)
2791  return TRUE;
2792 #endif
2793  return FALSE;
2794 }
2795 
2796 static ssize_t darwinssl_send(struct connectdata *conn,
2797  int sockindex,
2798  const void *mem,
2799  size_t len,
2800  CURLcode *curlcode)
2801 {
2802  /*struct Curl_easy *data = conn->data;*/
2803  struct ssl_connect_data *connssl = &conn->ssl[sockindex];
2804  size_t processed = 0UL;
2805  OSStatus err;
2806 
2807  /* The SSLWrite() function works a little differently than expected. The
2808  fourth argument (processed) is currently documented in Apple's
2809  documentation as: "On return, the length, in bytes, of the data actually
2810  written."
2811 
2812  Now, one could interpret that as "written to the socket," but actually,
2813  it returns the amount of data that was written to a buffer internal to
2814  the SSLContextRef instead. So it's possible for SSLWrite() to return
2815  errSSLWouldBlock and a number of bytes "written" because those bytes were
2816  encrypted and written to a buffer, not to the socket.
2817 
2818  So if this happens, then we need to keep calling SSLWrite() over and
2819  over again with no new data until it quits returning errSSLWouldBlock. */
2820 
2821  /* Do we have buffered data to write from the last time we were called? */
2822  if(BACKEND->ssl_write_buffered_length) {
2823  /* Write the buffered data: */
2824  err = SSLWrite(BACKEND->ssl_ctx, NULL, 0UL, &processed);
2825  switch(err) {
2826  case noErr:
2827  /* processed is always going to be 0 because we didn't write to
2828  the buffer, so return how much was written to the socket */
2829  processed = BACKEND->ssl_write_buffered_length;
2830  BACKEND->ssl_write_buffered_length = 0UL;
2831  break;
2832  case errSSLWouldBlock: /* argh, try again */
2833  *curlcode = CURLE_AGAIN;
2834  return -1L;
2835  default:
2836  failf(conn->data, "SSLWrite() returned error %d", err);
2837  *curlcode = CURLE_SEND_ERROR;
2838  return -1L;
2839  }
2840  }
2841  else {
2842  /* We've got new data to write: */
2843  err = SSLWrite(BACKEND->ssl_ctx, mem, len, &processed);
2844  if(err != noErr) {
2845  switch(err) {
2846  case errSSLWouldBlock:
2847  /* Data was buffered but not sent, we have to tell the caller
2848  to try sending again, and remember how much was buffered */
2849  BACKEND->ssl_write_buffered_length = len;
2850  *curlcode = CURLE_AGAIN;
2851  return -1L;
2852  default:
2853  failf(conn->data, "SSLWrite() returned error %d", err);
2854  *curlcode = CURLE_SEND_ERROR;
2855  return -1L;
2856  }
2857  }
2858  }
2859  return (ssize_t)processed;
2860 }
2861 
2862 static ssize_t darwinssl_recv(struct connectdata *conn,
2863  int num,
2864  char *buf,
2865  size_t buffersize,
2866  CURLcode *curlcode)
2867 {
2868  /*struct Curl_easy *data = conn->data;*/
2869  struct ssl_connect_data *connssl = &conn->ssl[num];
2870  size_t processed = 0UL;
2871  OSStatus err = SSLRead(BACKEND->ssl_ctx, buf, buffersize, &processed);
2872 
2873  if(err != noErr) {
2874  switch(err) {
2875  case errSSLWouldBlock: /* return how much we read (if anything) */
2876  if(processed)
2877  return (ssize_t)processed;
2878  *curlcode = CURLE_AGAIN;
2879  return -1L;
2880  break;
2881 
2882  /* errSSLClosedGraceful - server gracefully shut down the SSL session
2883  errSSLClosedNoNotify - server hung up on us instead of sending a
2884  closure alert notice, read() is returning 0
2885  Either way, inform the caller that the server disconnected. */
2886  case errSSLClosedGraceful:
2887  case errSSLClosedNoNotify:
2888  *curlcode = CURLE_OK;
2889  return -1L;
2890  break;
2891 
2892  default:
2893  failf(conn->data, "SSLRead() return error %d", err);
2894  *curlcode = CURLE_RECV_ERROR;
2895  return -1L;
2896  break;
2897  }
2898  }
2899  return (ssize_t)processed;
2900 }
2901 
2902 static void *Curl_darwinssl_get_internals(struct ssl_connect_data *connssl,
2903  CURLINFO info UNUSED_PARAM)
2904 {
2905  (void)info;
2906  return BACKEND->ssl_ctx;
2907 }
2908 
2909 const struct Curl_ssl Curl_ssl_darwinssl = {
2910  { CURLSSLBACKEND_DARWINSSL, "darwinssl" }, /* info */
2911 
2912  0, /* have_ca_path */
2913  0, /* have_certinfo */
2914 #ifdef DARWIN_SSL_PINNEDPUBKEY
2915  1, /* have_pinnedpubkey */
2916 #else
2917  0, /* have_pinnedpubkey */
2918 #endif /* DARWIN_SSL_PINNEDPUBKEY */
2919  0, /* have_ssl_ctx */
2920  0, /* support_https_proxy */
2921 
2922  sizeof(struct ssl_backend_data),
2923 
2924  Curl_none_init, /* init */
2925  Curl_none_cleanup, /* cleanup */
2926  Curl_darwinssl_version, /* version */
2927  Curl_darwinssl_check_cxn, /* check_cxn */
2928  Curl_darwinssl_shutdown, /* shutdown */
2929  Curl_darwinssl_data_pending, /* data_pending */
2930  Curl_darwinssl_random, /* random */
2931  Curl_none_cert_status_request, /* cert_status_request */
2932  Curl_darwinssl_connect, /* connect */
2933  Curl_darwinssl_connect_nonblocking, /* connect_nonblocking */
2934  Curl_darwinssl_get_internals, /* get_internals */
2935  Curl_darwinssl_close, /* close */
2936  Curl_none_close_all, /* close_all */
2937  Curl_darwinssl_session_free, /* session_free */
2938  Curl_none_set_engine, /* set_engine */
2939  Curl_none_set_engine_default, /* set_engine_default */
2940  Curl_none_engines_list, /* engines_list */
2941  Curl_darwinssl_false_start, /* false_start */
2942  Curl_darwinssl_md5sum, /* md5sum */
2943  Curl_darwinssl_sha256sum /* sha256sum */
2944 };
2945 
2946 #ifdef __clang__
2947 #pragma clang diagnostic pop
2948 #endif
2949 
2950 #endif /* USE_DARWINSSL */
#define free(ptr)
Definition: curl_memory.h:130
struct ssl_connect_data ssl[2]
Definition: urldata.h:887
#define UNUSED_PARAM
Definition: curl_setup.h:660
UNITTEST_START const char * values[]
Definition: unit1394.c:44
#define state(x, y)
Definition: ftp.c:100
ssize_t( Curl_recv)(struct connectdata *conn, int sockindex, char *buf, size_t len, CURLcode *err)
Definition: urldata.h:737
struct UserDefined set
Definition: urldata.h:1762
Curl_recv * recv[2]
Definition: urldata.h:881
#define SSL_CONN_CONFIG(var)
Definition: vtls.h:135
CURLcode Curl_base64_decode(const char *src, unsigned char **outptr, size_t *outlen)
Definition: base64.c:100
struct hostname host
Definition: urldata.h:758
#define FIRSTSOCKET
Definition: urldata.h:487
int stat(const char *path, struct stat *buffer)
unsigned long u_int32_t
Definition: setup-os400.h:33
#define CURL_SOCKET_BAD
Definition: curl.h:131
Definition: vtls.h:29
int Curl_none_init(void)
#define failf
Definition: sendf.h:48
#define SSL_SET_OPTION(var)
Definition: vtls.h:133
ssl_connect_state connecting_state
Definition: urldata.h:201
#define strdup(ptr)
Definition: curl_memory.h:122
#define SOCKERRNO
#define DEBUGASSERT(x)
UNITTEST_START char * ptr
Definition: unit1330.c:38
CURLcode
Definition: curl.h:454
CURLINFO
Definition: curl.h:2439
#define ENABLE_IPV6
Definition: config-os400.h:71
static int res
struct hostname host
Definition: urldata.h:833
static char * password
Definition: unit1304.c:27
#define realloc(ptr, size)
Definition: curl_memory.h:128
#define malloc(size)
Definition: curl_memory.h:124
char * name
Definition: urldata.h:444
UNITTEST_START int result
Definition: unit1304.c:49
int j
char buffer[]
Definition: unit1308.c:48
struct ssl_config_data ssl
Definition: urldata.h:1586
unsigned int i
Definition: unit1303.c:79
TypeWithSize< 4 >::UInt UInt32
Definition: gtest-port.h:2437
size_t len
Definition: curl_sasl.c:55
bool enable_beast
Definition: urldata.h:224
struct proxy_info http_proxy
Definition: urldata.h:839
curl_ftpccc ftp_ccc
Definition: urldata.h:1646
ssl_connection_state state
Definition: urldata.h:200
memcpy(filename, filename1, strlen(filename1))
bool falsestart
Definition: urldata.h:233
#define FALSE
time_t Curl_timeleft(struct Curl_easy *data, struct curltime *nowp, bool duringconnect)
Definition: connect.c:182
curl_easy_setopt expects a curl_off_t argument for this option curl_easy_setopt expects a curl_write_callback argument for this option curl_easy_setopt expects a curl_ioctl_callback argument for this option curl_easy_setopt expects a curl_opensocket_callback argument for this option curl_easy_setopt expects a curl_debug_callback argument for this option curl_easy_setopt expects a curl_conv_callback argument for this option curl_easy_setopt expects a private data pointer as argument for this option curl_easy_setopt expects a FILE *argument for this option curl_easy_setopt expects a struct curl_httppost *argument for this option curl_easy_setopt expects a struct curl_slist *argument for this option curl_easy_getinfo expects a pointer to char *for this info curl_easy_getinfo expects a pointer to double for this info curl_easy_getinfo expects a pointer to struct curl_tlssessioninfo *for this info curl_easy_getinfo expects a pointer to curl_socket_t for this info size_t
UNITTEST_START int rc
Definition: unit1301.c:31
#define EAGAIN
#define SOCKET_READABLE(x, z)
Definition: select.h:79
bool Curl_none_cert_status_request(void)
options
UNITTEST_START struct Curl_easy data
Definition: unit1399.c:82
#define CURL_SHA256_DIGEST_LENGTH
Definition: vtls.h:120
void Curl_none_cleanup(void)
Curl_send * send[2]
Definition: urldata.h:882
Definition: curl.h:455
ssize_t( Curl_send)(struct connectdata *conn, int sockindex, const void *buf, size_t len, CURLcode *err)
Definition: urldata.h:730
int Curl_inet_pton(int af, const char *src, void *dst)
Definition: inet_pton.c:66
static unsigned short port
Definition: sockfilt.c:137
#define Curl_safefree(ptr)
Definition: memdebug.h:170
#define aprintf
Definition: curl_printf.h:46
int Curl_socket_check(curl_socket_t readfd0, curl_socket_t readfd1, curl_socket_t writefd, time_t timeout_ms)
Definition: select.c:145
CURLcode Curl_none_set_engine(struct Curl_easy *data, const char *engine)
#define strtok_r
Definition: strtok.h:29
#define ssize_t
Definition: config-win32.h:382
curl_socket_t sock[2]
Definition: urldata.h:876
struct ssl_primary_config ssl_config
Definition: urldata.h:889
struct curl_slist * Curl_none_engines_list(struct Curl_easy *data)
char buf[3]
Definition: unit1398.c:32
bool verbose
Definition: urldata.h:1635
#define infof
Definition: sendf.h:44
char * str[STRING_LAST]
Definition: urldata.h:1663
TFSIMD_FORCE_INLINE tfScalar length(const Quaternion &q)
long port
Definition: urldata.h:841
size_t size
Definition: unit1302.c:52
#define snprintf
Definition: curl_printf.h:42
#define TRUE
ROSCPP_DECL bool search(const std::string &ns, const std::string &key, std::string &result)
int curl_socket_t
Definition: curl.h:130
const char * dispname
Definition: urldata.h:445
int key
Definition: unit1602.c:56
CURLcode Curl_none_set_engine_default(struct Curl_easy *data)
Definition: debug.c:29
int remote_port
Definition: urldata.h:842
void Curl_none_close_all(struct Curl_easy *data)
#define calloc(nbelem, size)
Definition: curl_memory.h:126
#define struct_stat
Definition: curl_setup.h:385
#define SSL_IS_PROXY()
Definition: vtls.h:130
struct Curl_easy * data
Definition: urldata.h:791


rc_tagdetect_client
Author(s): Monika Florek-Jasinska , Raphael Schaller
autogenerated on Sat Feb 13 2021 03:42:08