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