2 * Copyright (c) 2011-2014 Apple Inc. All Rights Reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
21 * @APPLE_LICENSE_HEADER_END@
30 #include <sys/types.h>
31 #include <netinet/in.h>
32 #include <sys/socket.h>
34 #include <arpa/inet.h>
35 #include <CoreFoundation/CoreFoundation.h>
37 #include <AssertMacros.h>
38 #include <Security/SecureTransportPriv.h> /* SSLSetOption */
39 #include <Security/SecureTransport.h>
40 #include <Security/SecPolicy.h>
41 #include <Security/SecTrust.h>
42 #include <Security/SecIdentity.h>
43 #include <Security/SecIdentityPriv.h>
44 #include <Security/SecCertificatePriv.h>
45 #include <Security/SecKeyPriv.h>
46 #include <Security/SecItem.h>
47 #include <Security/SecRandom.h>
49 #include <utilities/array_size.h>
50 #include <utilities/SecIOFormat.h>
53 #include <sys/types.h>
54 #include <sys/socket.h>
57 #include <mach/mach_time.h>
60 #include "ssl_regressions.h"
61 #include "ssl-utils.h"
66 Below are all the ciphers that are individually tested. The first element
67 is the SecureTransport/RFC name; the second is what openssl calls it, which
68 can be looked up in ciphers(1).
70 All SSL_DH_* and TLS_DH_* are disabled because neither openssl nor
71 securetransport support them:
72 SSL_DH_DSS_EXPORT_WITH_DES40_CBC_SHA, SSL_DH_DSS_WITH_DES_CBC_SHA,
73 SSL_DH_DSS_WITH_3DES_EDE_CBC_SHA, SSL_DH_RSA_EXPORT_WITH_DES40_CBC_SHA,
74 SSL_DH_RSA_WITH_DES_CBC_SHA, SSL_DH_RSA_WITH_3DES_EDE_CBC_SHA,
75 TLS_DH_DSS_WITH_AES_128_CBC_SHA, TLS_DH_RSA_WITH_AES_128_CBC_SHA,
76 TLS_DH_DSS_WITH_AES_256_CBC_SHA, TLS_DH_RSA_WITH_AES_256_CBC_SHA,
78 DSS is unimplemented by securetransport on the phone:
79 SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA, SSL_DHE_DSS_WITH_DES_CBC_SHA,
80 SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA, TLS_DHE_DSS_WITH_AES_128_CBC_SHA,
81 TLS_DHE_DSS_WITH_AES_256_CBC_SHA,
83 SSLv2 ciphersuites disabled by securetransport on phone:
84 SSL_RSA_WITH_RC2_CBC_MD5, SSL_RSA_WITH_IDEA_CBC_MD5,
85 SSL_RSA_WITH_DES_CBC_MD5, SSL_RSA_WITH_3DES_EDE_CBC_MD5,
87 SSLv3 ciphersuites disabled by securetransport on phone:
88 SSL_RSA_WITH_IDEA_CBC_SHA, SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5
92 #define OPENSSL_SERVER "ariadne.apple.com"
93 //#define OPENSSL_SERVER "kuip.apple.com"
94 #define GNUTLS_SERVER "ariadne.apple.com"
95 //#define GNUTLS_SERVER "kuip.apple.com"
103 { OPENSSL_SERVER
, 4000, 0, false}, //openssl s_server w/o client side auth
104 { GNUTLS_SERVER
, 5000, 1, false}, // gnutls-serv w/o client side auth
105 // { "www.mikestoolbox.org", 442, 2, false}, // mike's w/o client side auth
106 // { "tls.secg.org", 40022, 3, false}, // secg ecc server w/o client side auth - This server generate DH params we didnt support, but this should be fixed now
107 { OPENSSL_SERVER
, 4010, 0, true}, //openssl s_server w/ client side auth
108 { GNUTLS_SERVER
, 5010, 1, true}, // gnutls-serv w/ client side auth
109 // { "www.mikestoolbox.net", 442, 2, true}, // mike's w/ client side auth
110 // { "tls.secg.org", 8442, 3}, //secg ecc server w/ client side auth
112 int nservers
= sizeof(servers
)/sizeof(servers
[0]);
114 int protos
[]={ kSSLProtocol3
, kTLSProtocol1
, kTLSProtocol11
, kTLSProtocol12
};
115 int nprotos
= sizeof(protos
)/sizeof(protos
[0]);
117 typedef struct _CipherSuiteName
{
119 SSLCipherSuite cipher
;
121 int portoffset
[4]; // 0=not supported , else = port offset for this ciphersuite
125 /* prot: 0 = SSL3, 1=TLSv1.0, 2=TLSv1.1, 3=TLSv1.2 */
126 #define CIPHER(prot, cipher, offsets...) { prot, cipher, #cipher, offsets},
128 const CipherSuiteName ciphers
[] = {
129 //SSL_NULL_WITH_NULL_NULL, unsupported
131 /* RSA cipher suites */
132 CIPHER(0, SSL_RSA_WITH_NULL_MD5
, {1, 1, 0, 1}, false)
133 CIPHER(0, SSL_RSA_WITH_NULL_SHA
, {1, 1, 0, 1}, false)
134 CIPHER(3, TLS_RSA_WITH_NULL_SHA256
, {0, 1, 0, 0}, false)
138 CIPHER(0, SSL_RSA_WITH_RC4_128_MD5
, {1, 1, 1, 1}, false)
139 CIPHER(0, SSL_RSA_WITH_RC4_128_SHA
, {1, 1, 1, 1}, false)
140 CIPHER(0, SSL_RSA_WITH_3DES_EDE_CBC_SHA
, {1, 1, 1, 1}, false)
141 CIPHER(0, TLS_RSA_WITH_AES_128_CBC_SHA
, {1, 1, 1, 1}, false)
142 CIPHER(3, TLS_RSA_WITH_AES_128_CBC_SHA256
, {0, 1, 1, 0}, false)
143 CIPHER(0, TLS_RSA_WITH_AES_256_CBC_SHA
, {1, 1, 1, 1}, false)
144 CIPHER(3, TLS_RSA_WITH_AES_256_CBC_SHA256
, {0, 1, 1, 0}, false)
148 /* DHE_RSA ciphers suites */
149 CIPHER(0, SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA
, {1, 1, 1, 1}, false)
150 CIPHER(0, TLS_DHE_RSA_WITH_AES_128_CBC_SHA
, {1, 1, 1, 1}, false)
151 CIPHER(3, TLS_DHE_RSA_WITH_AES_128_CBC_SHA256
, {0, 1, 1, 0}, false)
152 CIPHER(0, TLS_DHE_RSA_WITH_AES_256_CBC_SHA
, {1, 1, 1, 1}, false)
153 CIPHER(3, TLS_DHE_RSA_WITH_AES_256_CBC_SHA256
, {0, 1, 1, 0}, false)
158 /* DH_anon cipher suites */
159 CIPHER(0, SSL_DH_anon_WITH_RC4_128_MD5
, {1, 1, 0, 1}, true)
160 CIPHER(0, SSL_DH_anon_WITH_3DES_EDE_CBC_SHA
, {1, 1, 0, 1}, true)
161 CIPHER(0, TLS_DH_anon_WITH_AES_128_CBC_SHA
, {1, 1, 0, 1}, true)
162 CIPHER(3, TLS_DH_anon_WITH_AES_128_CBC_SHA256
, {0, 1, 0, 1}, true)
163 CIPHER(0, TLS_DH_anon_WITH_AES_256_CBC_SHA
, {1, 1, 0, 1}, true)
164 CIPHER(3, TLS_DH_anon_WITH_AES_256_CBC_SHA256
, {0, 1, 0, 1}, true)
168 /* ECDHE_ECDSA cipher suites */
169 CIPHER(1, TLS_ECDHE_ECDSA_WITH_NULL_SHA
, {4, 4, 0, 1}, false)
170 CIPHER(1, TLS_ECDHE_ECDSA_WITH_RC4_128_SHA
, {4, 0, 0, 1}, false)
171 CIPHER(1, TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA
, {4, 4, 0, 1}, false)
172 CIPHER(1, TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA
, {4, 4, 0, 1}, false)
173 CIPHER(3, TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256
, {0, 4, 0, 1}, false)
174 CIPHER(1, TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA
, {4, 4, 0, 1}, false)
175 CIPHER(3, TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384
, {0, 4, 0, 1}, false)
179 /* ECDHE_RSA cipher suites */
180 CIPHER(1, TLS_ECDHE_RSA_WITH_RC4_128_SHA
, {1, 0, 0, 1}, false)
181 CIPHER(1, TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA
, {1, 1, 0, 1}, false)
182 CIPHER(1, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA
, {1, 1, 0, 1}, false)
183 CIPHER(3, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256
, {0, 1, 0, 0}, false)
184 CIPHER(1, TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA
, {1, 1, 0, 1}, false)
185 CIPHER(3, TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384
, {0, 0, 0, 0}, false) // Not supported by either gnutls or openssl
189 /* ECDH_ECDSA cipher suites */
190 CIPHER(1, TLS_ECDH_ECDSA_WITH_RC4_128_SHA
, {4, 0, 0, 1}, false)
191 CIPHER(1, TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA
, {4, 0, 0, 1}, false)
192 CIPHER(1, TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA
, {4, 0, 0, 1}, false)
193 CIPHER(3, TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256
, {0, 0, 0, 1}, false)
194 CIPHER(1, TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA
, {4, 0, 0, 1}, false)
195 CIPHER(3, TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384
, {0, 0, 0, 1}, false)
199 /* ECDH_RSA cipher suites */
200 CIPHER(1, TLS_ECDH_RSA_WITH_RC4_128_SHA
, {3, 0, 0, 1}, false)
201 CIPHER(1, TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA
, {3, 0, 0, 1}, false)
202 CIPHER(1, TLS_ECDH_RSA_WITH_AES_128_CBC_SHA
, {3, 0, 0, 1}, false)
203 CIPHER(3, TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256
, {0, 0, 0, 1}, false)
204 CIPHER(1, TLS_ECDH_RSA_WITH_AES_256_CBC_SHA
, {3, 0, 0, 1}, false)
205 CIPHER(3, TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384
, {0, 0, 0, 1}, false)
209 CIPHER(1, TLS_PSK_WITH_RC4_128_SHA
, {1, 1, 0, 0}, true)
210 CIPHER(1, TLS_PSK_WITH_3DES_EDE_CBC_SHA
, {1, 1, 0, 0}, true)
211 CIPHER(1, TLS_PSK_WITH_AES_128_CBC_SHA
, {1, 1, 0, 0}, true)
212 CIPHER(1, TLS_PSK_WITH_AES_256_CBC_SHA
, {1, 1, 0, 0}, true)
213 CIPHER(3, TLS_PSK_WITH_AES_128_CBC_SHA256
, {0, 1, 0, 0}, true)
214 CIPHER(3, TLS_PSK_WITH_AES_256_CBC_SHA384
, {0, 0, 0, 0}, true)
215 CIPHER(1, TLS_PSK_WITH_NULL_SHA
, {0, 0, 0, 0}, true)
216 CIPHER(3, TLS_PSK_WITH_NULL_SHA256
, {0, 1, 0, 0}, true)
217 CIPHER(3, TLS_PSK_WITH_NULL_SHA384
, {0, 0, 0, 0}, true)
221 CIPHER(3, TLS_RSA_WITH_AES_128_GCM_SHA256
, {0, 1, 0, 0}, false)
222 CIPHER(3, TLS_RSA_WITH_AES_256_GCM_SHA384
, {0, 0, 0, 0}, false)
224 CIPHER(3, TLS_DHE_RSA_WITH_AES_128_GCM_SHA256
, {0, 1, 0, 0}, false)
225 CIPHER(3, TLS_DHE_RSA_WITH_AES_256_GCM_SHA384
, {0, 0, 0, 0}, false)
227 CIPHER(3, TLS_DH_anon_WITH_AES_128_GCM_SHA256
, {0, 1, 0, 0}, false)
228 CIPHER(3, TLS_DH_anon_WITH_AES_256_GCM_SHA384
, {0, 0, 0, 0}, false)
230 CIPHER(3, TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384
, {0, 0, 0, 0}, false)
231 CIPHER(3, TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256
, {0, 0, 0, 0}, false)
233 CIPHER(3, TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256
, {0, 0, 0, 0}, false)
234 CIPHER(3, TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384
, {0, 0, 0, 0}, false)
236 CIPHER(3, TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
, {0, 1, 0, 0}, false)
237 CIPHER(3, TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
, {0, 0, 0, 0}, false)
239 CIPHER(3, TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
, {0, 1, 0, 0}, false)
240 CIPHER(3, TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
, {0, 0, 0, 0}, false)
246 CIPHER(SSL_RSA_EXPORT_WITH_RC4_40_MD5
, true, false, true,false)
247 CIPHER(SSL_RSA_EXPORT_WITH_DES40_CBC_SHA
, true, false, true, false)
248 CIPHER(SSL_RSA_WITH_DES_CBC_SHA
, true, false, true, false)
249 CIPHER(SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA
, true, false, true, false)
250 CIPHER(SSL_DHE_RSA_WITH_DES_CBC_SHA
, true, false, true, false)
251 CIPHER(SSL_DH_anon_EXPORT_WITH_RC4_40_MD5
, true, false, true, true)
252 CIPHER(SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA
, true, false, true, true)
253 CIPHER(SSL_DH_anon_WITH_DES_CBC_SHA
, true, false, true, true)
257 /* "Any" cipher suite - test the default configuration */
258 {0, SSL_NO_SUCH_CIPHERSUITE
, "Any cipher 1", {1, 1, 1, 1}, false},
259 {0, SSL_NO_SUCH_CIPHERSUITE
, "Any cipher 2", {2, 2, 0, 0}, false},
261 // Those servers wont talk SSL3.0 because they have EC certs
262 {1, SSL_NO_SUCH_CIPHERSUITE
, "Any cipher 3", {3, 3, 0, 0}, false},
263 {1, SSL_NO_SUCH_CIPHERSUITE
, "Any cipher 4", {4, 4, 0, 0}, false},
269 static int ciphers_len
= array_size(ciphers
);
273 #if 0 // currently unused
274 static SSLCipherSuite
sslcipher_atoi(const char *name
)
276 const CipherSuiteName
*a
= ciphers
;
278 if (0 == strcmp(a
->name
, name
)) break;
284 static const char * sslcipher_itoa(SSLCipherSuite num
)
286 const CipherSuiteName
*a
= ciphers
;
287 while(a
->cipher
>= 0) {
288 if (num
== a
->cipher
) break;
293 #endif // currently unused
295 unsigned char dh_param_512_bytes
[] = {
296 0x30, 0x46, 0x02, 0x41, 0x00, 0xdb, 0x3c, 0xfa, 0x13, 0xa6, 0xd2, 0x64,
297 0xdf, 0xcc, 0x40, 0xb1, 0x21, 0xd4, 0xf2, 0xad, 0x22, 0x7f, 0xce, 0xa0,
298 0xb9, 0x5b, 0x95, 0x1c, 0x2e, 0x99, 0xb0, 0x27, 0xd0, 0xed, 0xf4, 0xbd,
299 0xbb, 0x36, 0x93, 0xd0, 0x9d, 0x2b, 0x32, 0xa3, 0x56, 0x53, 0xe3, 0x7b,
300 0xed, 0xa1, 0x71, 0x82, 0x2e, 0x83, 0x14, 0xf9, 0xc0, 0x2f, 0x15, 0xcb,
301 0xcf, 0x97, 0xab, 0x88, 0x49, 0x20, 0x28, 0x2e, 0x63, 0x02, 0x01, 0x02
303 unsigned char *dh_param_512_der
= dh_param_512_bytes
;
304 unsigned int dh_param_512_der_len
= 72;
308 bool is_session_resume
;
311 bool client_side_auth
;
321 static void hexdump(const uint8_t *bytes
, size_t len
) {
323 printf("socket write(%p, %lu)\n", bytes
, len
);
324 for (ix
= 0; ix
< len
; ++ix
) {
327 printf("%02X ", bytes
[ix
]);
332 #define hexdump(bytes, len)
335 static int SocketConnect(const char *hostName
, int port
)
337 struct sockaddr_in addr
;
343 if (hostName
[0] >= '0' && hostName
[0] <= '9')
345 host
.s_addr
= inet_addr(hostName
);
349 #define GETHOST_RETRIES 5
350 /* seeing a lot of soft failures here that I really don't want to track down */
351 for(dex
=0; dex
<GETHOST_RETRIES
; dex
++) {
353 printf("\n...retrying gethostbyname(%s)", hostName
);
355 ent
= gethostbyname(hostName
);
361 printf("\n***gethostbyname(%s) returned: %s\n", hostName
, hstrerror(h_errno
));
364 memcpy(&host
, ent
->h_addr
, sizeof(struct in_addr
));
367 sock
= socket(AF_INET
, SOCK_STREAM
, 0);
368 addr
.sin_addr
= host
;
369 addr
.sin_port
= htons((u_short
)port
);
371 addr
.sin_family
= AF_INET
;
372 err
= connect(sock
, (struct sockaddr
*) &addr
, sizeof(struct sockaddr_in
));
376 perror("connect failed");
384 static OSStatus
SocketWrite(SSLConnectionRef conn
, const void *data
, size_t *length
)
386 size_t len
= *length
;
387 uint8_t *ptr
= (uint8_t *)data
;
393 ret
= write((int)conn
, ptr
, len
);
396 } while ((ret
< 0) && (errno
== EAGAIN
|| errno
== EINTR
));
405 *length
= *length
- len
;
406 return errSecSuccess
;
409 static OSStatus
SocketRead(SSLConnectionRef conn
, void *data
, size_t *length
)
411 size_t len
= *length
;
412 uint8_t *ptr
= (uint8_t *)data
;
417 ret
= read((int)conn
, ptr
, len
);
420 } while ((ret
< 0) && (errno
== EAGAIN
|| errno
== EINTR
));
429 *length
= *length
- len
;
430 return errSecSuccess
;
433 unsigned char dn
[] = {
434 0x30, 0x5e, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13,
435 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0a,
436 0x13, 0x0a, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x49, 0x6e, 0x63, 0x2e,
437 0x31, 0x26, 0x30, 0x24, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x1d, 0x41,
438 0x70, 0x70, 0x6c, 0x65, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69,
439 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f,
440 0x72, 0x69, 0x74, 0x79, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04,
441 0x03, 0x13, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f, 0x73, 0x74
443 unsigned int dn_len
= 96;
445 static SSLContextRef
make_ssl_ref(bool server
, bool client_side_auth
, bool dh_anonymous
,
446 bool dtls
, int sock
, CFArrayRef certs
, SSLProtocol prot
)
448 SSLContextRef ctx
= NULL
;
450 require_noerr(SSLNewDatagramContext(server
, &ctx
), out
);
452 require_noerr(SSLNewContext(server
, &ctx
), out
);
453 require_noerr(SSLSetProtocolVersionMax(ctx
, prot
), out
);
454 require_noerr(SSLSetIOFuncs(ctx
,
455 (SSLReadFunc
)SocketRead
, (SSLWriteFunc
)SocketWrite
), out
);
456 require_noerr(SSLSetConnection(ctx
, (SSLConnectionRef
)(intptr_t)sock
), out
);
457 //static const char *peer_domain_name = "localhost";
458 //require_noerr(SSLSetPeerDomainName(ctx, peer_domain_name,
459 // strlen(peer_domain_name)), out);
464 require_noerr(SSLSetCertificate(ctx
, certs
), out
);
465 if (client_side_auth
&& server
) {
466 require_noerr(SSLSetClientSideAuthenticate(ctx
, kAlwaysAuthenticate
), out
);
467 require_noerr(SSLAddDistinguishedName(ctx
, dn
, dn_len
), out
);
469 #if 0 /* Setting client certificate in advance */
470 if (client_side_auth
&& !server
)
471 require_noerr(SSLSetCertificate(ctx
, certs
), out
);
473 if (client_side_auth
&& !server
) /* enable break from SSLHandshake */
474 require_noerr(SSLSetSessionOption(ctx
,
475 kSSLSessionOptionBreakOnCertRequested
, true), out
);
476 require_noerr(SSLSetSessionOption(ctx
,
477 kSSLSessionOptionBreakOnServerAuth
, true), out
);
480 /* Tell SecureTransport to not check certs itself: it will break out of the
481 handshake to let us take care of it instead. */
482 require_noerr(SSLSetEnableCertVerify(ctx
, false), out
);
484 require_noerr(SSLSetPSKIdentity(ctx
, "Client_identity", 15), out
);
485 require_noerr(SSLSetPSKSharedSecret(ctx
, "123456789", 9), out
);
489 require_noerr(SSLSetDiffieHellmanParams(ctx
,
490 dh_param_512_der
, dh_param_512_der_len
), out
);
492 else /* if client */ {
498 SSLDisposeContext(ctx
);
502 static OSStatus
securetransport(ssl_test_handle
* ssl
)
505 SSLContextRef ctx
= ssl
->st
;
506 SecTrustRef trust
= NULL
;
507 bool got_server_auth
= false, got_client_cert_req
= false;
509 //uint64_t start = mach_absolute_time();
511 ortn
= SSLHandshake(ctx
);
513 if (ortn
== errSSLServerAuthCompleted
)
515 require_string(!got_server_auth
, out
, "second server auth");
516 require_string(!got_client_cert_req
, out
, "got client cert req before server auth");
517 got_server_auth
= true;
518 require_string(!trust
, out
, "Got errSSLServerAuthCompleted twice?");
519 /* verify peer cert chain */
520 require_noerr(SSLCopyPeerTrust(ctx
, &trust
), out
);
521 SecTrustResultType trust_result
= 0;
522 /* this won't verify without setting up a trusted anchor */
523 require_noerr(SecTrustEvaluate(trust
, &trust_result
), out
);
525 CFIndex n_certs
= SecTrustGetCertificateCount(trust
);
526 /*fprintf(stderr, "%ld certs; trust_eval: %d\n", n_certs, trust_result); */
528 CFMutableArrayRef peer_cert_array
= CFArrayCreateMutable(NULL
, n_certs
, &kCFTypeArrayCallBacks
);
529 CFMutableArrayRef orig_peer_cert_array
= CFArrayCreateMutableCopy(NULL
, n_certs
, ssl
->certs
);
531 CFArrayInsertValueAtIndex(peer_cert_array
, 0,
532 SecTrustGetCertificateAtIndex(trust
, n_certs
));
534 SecIdentityRef ident
= (SecIdentityRef
)CFArrayGetValueAtIndex(orig_peer_cert_array
, 0);
535 SecCertificateRef peer_cert
= NULL
;
536 require_noerr(SecIdentityCopyCertificate(ident
, &peer_cert
), out
);
537 CFArraySetValueAtIndex(orig_peer_cert_array
, 0, peer_cert
);
538 CFRelease(peer_cert
);
541 require(CFEqual(orig_peer_cert_array
, peer_cert_array
), out
);
543 CFRelease(orig_peer_cert_array
);
544 CFRelease(peer_cert_array
);
547 CFStringRef cert_name = SecCertificateCopySubjectSummary(cert);
548 char cert_name_buffer[1024];
549 require(CFStringGetFileSystemRepresentation(cert_name,
550 cert_name_buffer, sizeof(cert_name_buffer)), out);
551 fprintf(stderr, "cert name: %s\n", cert_name_buffer);
554 } else if (ortn
== errSSLClientCertRequested
) {
555 require_string(!got_client_cert_req
, out
, "second client cert req");
556 require_string(got_server_auth
, out
, "didn't get server auth first");
557 got_client_cert_req
= true;
559 /* set client cert */
560 require_string(!ssl
->is_server
, out
, "errSSLClientCertRequested while running server");
561 require_string(!ssl
->dh_anonymous
, out
, "errSSLClientCertRequested while running anon DH");
563 CFArrayRef DNs = NULL;
564 require_noerr(SSLCopyDistinguishedNames (ctx, &DNs), out);
568 require_string(ssl
->client_side_auth
, out
, "errSSLClientCertRequested in run not testing that");
569 require_noerr(SSLSetCertificate(ctx
, ssl
->certs
), out
);
571 } while (ortn
== errSSLWouldBlock
572 || ortn
== errSSLServerAuthCompleted
573 || ortn
== errSSLClientCertRequested
);
574 require_noerr_action_quiet(ortn
, out
,
575 fprintf(stderr
, "Fell out of SSLHandshake with error: %d\n", (int)ortn
));
577 if (!ssl
->is_server
&& !ssl
->dh_anonymous
&& !ssl
->is_session_resume
) {
578 require_action_string(got_server_auth
, out
, ortn
=-1, "never got server auth.");
579 if (ssl
->client_side_auth
)
580 require_string(got_client_cert_req
, out
, "never got client cert req");
582 //uint64_t elapsed = mach_absolute_time() - start;
583 //fprintf(stderr, "setr elapsed: %lld\n", elapsed);
586 SSLProtocol proto = kSSLProtocolUnknown;
587 require_noerr_quiet(SSLGetNegotiatedProtocolVersion(ctx, &proto), out); */
589 SSLCipherSuite cipherSuite
;
590 require_noerr_quiet(ortn
= SSLGetNegotiatedCipher(ctx
, &cipherSuite
), out
);
591 //fprintf(stderr, "st negotiated %s\n", sslcipher_itoa(cipherSuite));
593 Boolean sessionWasResumed
= false;
594 uint8_t session_id_data
[MAX_SESSION_ID_LENGTH
];
595 size_t session_id_length
= sizeof(session_id_data
);
596 require_noerr_quiet(ortn
= SSLGetResumableSessionInfo(ctx
, &sessionWasResumed
, session_id_data
, &session_id_length
), out
);
597 require_action(ssl
->dh_anonymous
|| (ssl
->is_session_resume
== sessionWasResumed
), out
, ortn
= -1);
598 // if (sessionWasResumed) fprintf(stderr, "st resumed session\n");
599 //hexdump(session_id_data, session_id_length);
602 char *req
="GET / HTTP/1.0\r\n\r\n";
605 if (!ssl
->is_server
) {
606 require_noerr_quiet(ortn
= SSLWrite(ctx
, req
, strlen(req
), &len
), out
);
607 require_action_quiet(len
== strlen(req
), out
, ortn
= -1);
608 require_noerr_quiet(ortn
= SSLRead(ctx
, ibuf
, sizeof(ibuf
), &len
), out
);
610 // printf(">>>\n%s<<<\n", ibuf);
616 SSLDisposeContext(ctx
);
617 if (trust
) CFRelease(trust
);
624 static ssl_test_handle
*
625 ssl_test_handle_create(uint32_t session_id
, bool resume
, bool server
, bool client_side_auth
, bool dh_anonymous
, bool dtls
,
626 int comm
, CFArrayRef certs
, SSLProtocol prot
)
628 ssl_test_handle
*handle
= calloc(1, sizeof(ssl_test_handle
));
630 handle
->session_id
= session_id
;
631 handle
->is_session_resume
= resume
;
632 handle
->is_server
= server
;
633 handle
->client_side_auth
= client_side_auth
;
634 handle
->dh_anonymous
= dh_anonymous
;
636 handle
->certs
= certs
;
637 handle
->st
= make_ssl_ref(server
, client_side_auth
, dh_anonymous
, dtls
, comm
, certs
, prot
);
645 CFArrayRef client_certs
= client_chain();
646 ok(client_certs
, "got client certs");
651 for (p
=0; p
<nservers
; p
++) {
652 for (pr
=0; pr
<nprotos
; pr
++) {
654 for (i
=0; ciphers
[i
].name
!= NULL
; i
++) {
656 ssl_test_handle
*client
;
657 SSLProtocol proto
= protos
[pr
];
663 skip("This ciphersuite is not supported for this protocol version", 2, ciphers
[i
].prot
<=pr
);
664 skip("This server doesn't support this ciphersuite", 2, ciphers
[i
].portoffset
[servers
[p
].cs_index
]);
666 port
=servers
[p
].base_port
+ ciphers
[i
].portoffset
[servers
[p
].cs_index
];
667 uint32_t session_id
= (pr
<<16) | (port
<<8) | (i
+1);
669 s
=SocketConnect(servers
[p
].host
, port
);
672 "Connect failed: %40s to %s:%d proto=%d", ciphers
[i
].name
, servers
[p
].host
, port
, pr
);
674 skip("Could not connect to the server", 1, s
);
676 //fprintf(stderr, "session_id: %d\n", session_id);
677 client
= ssl_test_handle_create(session_id
, false, false/*client*/,
678 servers
[p
].client_auth
, ciphers
[i
].dh_anonymous
, 0,
679 s
, client_certs
, proto
);
681 /* set fixed cipher on client and server */
682 if(ciphers
[i
].cipher
!= SSL_NO_SUCH_CIPHERSUITE
) {
683 if(SSLSetEnabledCiphers(client
->st
, &ciphers
[i
].cipher
, 1)!=0)
684 printf("Invalid cipher %04x (i=%d, p=%d, pr=%d)\n", ciphers
[i
].cipher
, i
, p
, pr
);
687 printf("Handshake : %40s to %s:%d proto=%d\n", ciphers
[i
].name
, servers
[p
].host
, port
, pr
);
688 OSStatus ok
= securetransport(client
);
689 printf("Result = %d\n", (int)ok
);
691 ok(!ok
, "Handshake failed: %40s to %s:%d proto=%d", ciphers
[i
].name
, servers
[p
].host
, port
, pr
);
700 CFReleaseNull(client_certs
);
703 int ssl_43_ciphers(int argc
, char *const *argv
)
705 plan_tests(1 + 2*nservers
*nprotos
*(ciphers_len
-1));
713 TODO: count errSSLWouldBlock
714 TODO: skip tests that don't matter: client_auth and anonymous dh
715 TODO: we seem to only be negotiating tls - force a round of sslv3
716 TODO: allow secure transport to also defer client side auth to client
717 TODO: make sure anonymous dh is never selected if not expicitly enabled
718 TODO: make sure DHE is not available if not explicitly enabled and no parameters
720 TODO: resumable sessions