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/SecCFRelease.h>
51 #include <utilities/SecIOFormat.h>
54 #include <sys/types.h>
55 #include <sys/socket.h>
58 #include <mach/mach_time.h>
61 #include "ssl_regressions.h"
62 #include "ssl-utils.h"
67 Below are all the ciphers that are individually tested. The first element
68 is the SecureTransport/RFC name; the second is what openssl calls it, which
69 can be looked up in ciphers(1).
71 All SSL_DH_* and TLS_DH_* are disabled because neither openssl nor
72 securetransport support them:
73 SSL_DH_DSS_EXPORT_WITH_DES40_CBC_SHA, SSL_DH_DSS_WITH_DES_CBC_SHA,
74 SSL_DH_DSS_WITH_3DES_EDE_CBC_SHA, SSL_DH_RSA_EXPORT_WITH_DES40_CBC_SHA,
75 SSL_DH_RSA_WITH_DES_CBC_SHA, SSL_DH_RSA_WITH_3DES_EDE_CBC_SHA,
76 TLS_DH_DSS_WITH_AES_128_CBC_SHA, TLS_DH_RSA_WITH_AES_128_CBC_SHA,
77 TLS_DH_DSS_WITH_AES_256_CBC_SHA, TLS_DH_RSA_WITH_AES_256_CBC_SHA,
79 DSS is unimplemented by securetransport on the phone:
80 SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA, SSL_DHE_DSS_WITH_DES_CBC_SHA,
81 SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA, TLS_DHE_DSS_WITH_AES_128_CBC_SHA,
82 TLS_DHE_DSS_WITH_AES_256_CBC_SHA,
84 SSLv2 ciphersuites disabled by securetransport on phone:
85 SSL_RSA_WITH_RC2_CBC_MD5, SSL_RSA_WITH_IDEA_CBC_MD5,
86 SSL_RSA_WITH_DES_CBC_MD5, SSL_RSA_WITH_3DES_EDE_CBC_MD5,
88 SSLv3 ciphersuites disabled by securetransport on phone:
89 SSL_RSA_WITH_IDEA_CBC_SHA, SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5
94 //#define OPENSSL_SERVER "ariadne.apple.com"
95 //#define GNUTLS_SERVER "ariadne.apple.com"
96 //#define OPENSSL_SERVER "kuip.apple.com"
97 //#define GNUTLS_SERVER "kuip.apple.com"
98 #define OPENSSL_SERVER "192.168.2.1"
99 #define GNUTLS_SERVER "192.168.2.1"
107 { OPENSSL_SERVER
, 4000, 0, false}, //openssl s_server w/o client side auth
108 { GNUTLS_SERVER
, 5000, 1, false}, // gnutls-serv w/o client side auth
109 // { "www.mikestoolbox.org", 442, 2, false}, // mike's w/o client side auth
110 // { "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
111 { OPENSSL_SERVER
, 4010, 0, true}, //openssl s_server w/ client side auth
112 { GNUTLS_SERVER
, 5010, 1, true}, // gnutls-serv w/ client side auth
113 // { "www.mikestoolbox.net", 442, 2, true}, // mike's w/ client side auth
114 // { "tls.secg.org", 8442, 3}, //secg ecc server w/ client side auth
116 int nservers
= sizeof(servers
)/sizeof(servers
[0]);
118 int protos
[]={ kSSLProtocol3
, kTLSProtocol1
, kTLSProtocol11
, kTLSProtocol12
};
119 int nprotos
= sizeof(protos
)/sizeof(protos
[0]);
121 typedef struct _CipherSuiteName
{
123 SSLCipherSuite cipher
;
125 int portoffset
[4]; // 0=not supported , else = port offset for this ciphersuite
129 /* prot: 0 = SSL3, 1=TLSv1.0, 2=TLSv1.1, 3=TLSv1.2 */
130 #define CIPHER(prot, cipher, offsets...) { prot, cipher, #cipher, offsets},
132 const CipherSuiteName ciphers
[] = {
133 //SSL_NULL_WITH_NULL_NULL, unsupported
135 /* RSA cipher suites */
136 CIPHER(1, SSL_RSA_WITH_NULL_MD5
, {1, 1, 0, 1}, false)
137 CIPHER(1, SSL_RSA_WITH_NULL_SHA
, {1, 1, 0, 1}, false)
138 CIPHER(3, TLS_RSA_WITH_NULL_SHA256
, {0, 1, 0, 0}, false)
142 CIPHER(1, SSL_RSA_WITH_RC4_128_MD5
, {1, 1, 1, 1}, false)
143 CIPHER(1, SSL_RSA_WITH_RC4_128_SHA
, {1, 1, 1, 1}, false)
144 CIPHER(1, SSL_RSA_WITH_3DES_EDE_CBC_SHA
, {1, 1, 1, 1}, false)
145 CIPHER(1, TLS_RSA_WITH_AES_128_CBC_SHA
, {1, 1, 1, 1}, false)
146 CIPHER(3, TLS_RSA_WITH_AES_128_CBC_SHA256
, {0, 1, 1, 0}, false)
147 CIPHER(1, TLS_RSA_WITH_AES_256_CBC_SHA
, {1, 1, 1, 1}, false)
148 CIPHER(3, TLS_RSA_WITH_AES_256_CBC_SHA256
, {0, 1, 1, 0}, false)
152 /* DHE_RSA ciphers suites */
153 CIPHER(1, SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA
, {1, 1, 1, 1}, false)
154 CIPHER(1, TLS_DHE_RSA_WITH_AES_128_CBC_SHA
, {1, 1, 1, 1}, false)
155 CIPHER(3, TLS_DHE_RSA_WITH_AES_128_CBC_SHA256
, {0, 1, 1, 0}, false)
156 CIPHER(1, TLS_DHE_RSA_WITH_AES_256_CBC_SHA
, {1, 1, 1, 1}, false)
157 CIPHER(3, TLS_DHE_RSA_WITH_AES_256_CBC_SHA256
, {0, 1, 1, 0}, false)
162 /* DH_anon cipher suites */
163 CIPHER(0, SSL_DH_anon_WITH_RC4_128_MD5
, {1, 1, 0, 1}, true)
164 CIPHER(0, SSL_DH_anon_WITH_3DES_EDE_CBC_SHA
, {1, 1, 0, 1}, true)
165 CIPHER(0, TLS_DH_anon_WITH_AES_128_CBC_SHA
, {1, 1, 0, 1}, true)
166 CIPHER(3, TLS_DH_anon_WITH_AES_128_CBC_SHA256
, {0, 1, 0, 1}, true)
167 CIPHER(0, TLS_DH_anon_WITH_AES_256_CBC_SHA
, {1, 1, 0, 1}, true)
168 CIPHER(3, TLS_DH_anon_WITH_AES_256_CBC_SHA256
, {0, 1, 0, 1}, true)
172 /* ECDHE_ECDSA cipher suites */
173 CIPHER(1, TLS_ECDHE_ECDSA_WITH_NULL_SHA
, {4, 4, 0, 1}, false)
174 CIPHER(1, TLS_ECDHE_ECDSA_WITH_RC4_128_SHA
, {4, 0, 0, 1}, false)
175 CIPHER(1, TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA
, {4, 4, 0, 1}, false)
176 CIPHER(1, TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA
, {4, 4, 0, 1}, false)
177 CIPHER(3, TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256
, {0, 4, 0, 1}, false)
178 CIPHER(1, TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA
, {4, 4, 0, 1}, false)
179 CIPHER(3, TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384
, {0, 4, 0, 1}, false)
183 /* ECDHE_RSA cipher suites */
184 CIPHER(1, TLS_ECDHE_RSA_WITH_RC4_128_SHA
, {1, 0, 0, 1}, false)
185 CIPHER(1, TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA
, {1, 1, 0, 1}, false)
186 CIPHER(1, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA
, {1, 1, 0, 1}, false)
187 CIPHER(3, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256
, {0, 1, 0, 0}, false)
188 CIPHER(1, TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA
, {1, 1, 0, 1}, false)
189 CIPHER(3, TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384
, {0, 0, 0, 0}, false) // Not supported by either gnutls or openssl
193 CIPHER(1, TLS_PSK_WITH_RC4_128_SHA
, {1, 1, 0, 0}, true)
194 CIPHER(1, TLS_PSK_WITH_3DES_EDE_CBC_SHA
, {1, 1, 0, 0}, true)
195 CIPHER(1, TLS_PSK_WITH_AES_128_CBC_SHA
, {1, 1, 0, 0}, true)
196 CIPHER(1, TLS_PSK_WITH_AES_256_CBC_SHA
, {1, 1, 0, 0}, true)
197 CIPHER(3, TLS_PSK_WITH_AES_128_CBC_SHA256
, {0, 1, 0, 0}, true)
198 CIPHER(3, TLS_PSK_WITH_AES_256_CBC_SHA384
, {0, 0, 0, 0}, true)
199 CIPHER(1, TLS_PSK_WITH_NULL_SHA
, {0, 0, 0, 0}, true)
200 CIPHER(3, TLS_PSK_WITH_NULL_SHA256
, {0, 1, 0, 0}, true)
201 CIPHER(3, TLS_PSK_WITH_NULL_SHA384
, {0, 0, 0, 0}, true)
205 CIPHER(3, TLS_RSA_WITH_AES_128_GCM_SHA256
, {1, 1, 0, 0}, false)
206 CIPHER(3, TLS_RSA_WITH_AES_256_GCM_SHA384
, {1, 0, 0, 0}, false)
208 CIPHER(3, TLS_DHE_RSA_WITH_AES_128_GCM_SHA256
, {1, 1, 0, 0}, false)
209 CIPHER(3, TLS_DHE_RSA_WITH_AES_256_GCM_SHA384
, {1, 0, 0, 0}, false)
211 CIPHER(3, TLS_DH_anon_WITH_AES_128_GCM_SHA256
, {1, 1, 0, 0}, true)
212 CIPHER(3, TLS_DH_anon_WITH_AES_256_GCM_SHA384
, {1, 0, 0, 0}, true)
214 CIPHER(3, TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
, {1, 1, 0, 0}, false)
215 CIPHER(3, TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
, {1, 1, 0, 0}, false)
217 CIPHER(3, TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
, {4, 4, 0, 0}, false)
218 CIPHER(3, TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
, {4, 0, 0, 0}, false)
224 CIPHER(SSL_RSA_EXPORT_WITH_RC4_40_MD5
, true, false, true,false)
225 CIPHER(SSL_RSA_EXPORT_WITH_DES40_CBC_SHA
, true, false, true, false)
226 CIPHER(SSL_RSA_WITH_DES_CBC_SHA
, true, false, true, false)
227 CIPHER(SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA
, true, false, true, false)
228 CIPHER(SSL_DHE_RSA_WITH_DES_CBC_SHA
, true, false, true, false)
229 CIPHER(SSL_DH_anon_EXPORT_WITH_RC4_40_MD5
, true, false, true, true)
230 CIPHER(SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA
, true, false, true, true)
231 CIPHER(SSL_DH_anon_WITH_DES_CBC_SHA
, true, false, true, true)
235 /* "Any" cipher suite - test the default configuration */
236 {0, SSL_NO_SUCH_CIPHERSUITE
, "Any cipher 1", {1, 1, 1, 1}, false},
237 {0, SSL_NO_SUCH_CIPHERSUITE
, "Any cipher 2", {2, 2, 0, 0}, false},
239 // Those servers wont talk SSL3.0 because they have EC certs
240 {1, SSL_NO_SUCH_CIPHERSUITE
, "Any cipher 3", {3, 3, 0, 0}, false},
241 {1, SSL_NO_SUCH_CIPHERSUITE
, "Any cipher 4", {4, 4, 0, 0}, false},
247 static int ciphers_len
= array_size(ciphers
);
251 #if 0 // currently unused
252 static SSLCipherSuite
sslcipher_atoi(const char *name
)
254 const CipherSuiteName
*a
= ciphers
;
256 if (0 == strcmp(a
->name
, name
)) break;
262 static const char * sslcipher_itoa(SSLCipherSuite num
)
264 const CipherSuiteName
*a
= ciphers
;
265 while(a
->cipher
>= 0) {
266 if (num
== a
->cipher
) break;
271 #endif // currently unused
273 unsigned char dh_param_512_bytes
[] = {
274 0x30, 0x46, 0x02, 0x41, 0x00, 0xdb, 0x3c, 0xfa, 0x13, 0xa6, 0xd2, 0x64,
275 0xdf, 0xcc, 0x40, 0xb1, 0x21, 0xd4, 0xf2, 0xad, 0x22, 0x7f, 0xce, 0xa0,
276 0xb9, 0x5b, 0x95, 0x1c, 0x2e, 0x99, 0xb0, 0x27, 0xd0, 0xed, 0xf4, 0xbd,
277 0xbb, 0x36, 0x93, 0xd0, 0x9d, 0x2b, 0x32, 0xa3, 0x56, 0x53, 0xe3, 0x7b,
278 0xed, 0xa1, 0x71, 0x82, 0x2e, 0x83, 0x14, 0xf9, 0xc0, 0x2f, 0x15, 0xcb,
279 0xcf, 0x97, 0xab, 0x88, 0x49, 0x20, 0x28, 0x2e, 0x63, 0x02, 0x01, 0x02
281 unsigned char *dh_param_512_der
= dh_param_512_bytes
;
282 unsigned int dh_param_512_der_len
= 72;
286 bool is_session_resume
;
289 bool client_side_auth
;
299 static void hexdump(const uint8_t *bytes
, size_t len
) {
301 printf("socket write(%p, %lu)\n", bytes
, len
);
302 for (ix
= 0; ix
< len
; ++ix
) {
305 printf("%02X ", bytes
[ix
]);
310 #define hexdump(bytes, len)
313 static int SocketConnect(const char *hostName
, int port
)
315 struct sockaddr_in addr
;
319 struct hostent
*ent
= NULL
;
321 if (hostName
[0] >= '0' && hostName
[0] <= '9')
323 host
.s_addr
= inet_addr(hostName
);
327 #define GETHOST_RETRIES 5
328 /* seeing a lot of soft failures here that I really don't want to track down */
329 for(dex
=0; dex
<GETHOST_RETRIES
; dex
++) {
331 printf("\n...retrying gethostbyname(%s)", hostName
);
333 ent
= gethostbyname(hostName
);
339 printf("\n***gethostbyname(%s) returned: %s\n", hostName
, hstrerror(h_errno
));
342 memcpy(&host
, ent
->h_addr
, sizeof(struct in_addr
));
345 sock
= socket(AF_INET
, SOCK_STREAM
, 0);
346 addr
.sin_addr
= host
;
347 addr
.sin_port
= htons((u_short
)port
);
349 addr
.sin_family
= AF_INET
;
350 err
= connect(sock
, (struct sockaddr
*) &addr
, sizeof(struct sockaddr_in
));
354 perror("connect failed");
362 static OSStatus
SocketWrite(SSLConnectionRef conn
, const void *data
, size_t *length
)
364 size_t len
= *length
;
365 uint8_t *ptr
= (uint8_t *)data
;
371 ret
= write((int)conn
, ptr
, len
);
374 } while ((ret
< 0) && (errno
== EAGAIN
|| errno
== EINTR
));
383 *length
= *length
- len
;
384 return errSecSuccess
;
387 static OSStatus
SocketRead(SSLConnectionRef conn
, void *data
, size_t *length
)
389 size_t len
= *length
;
390 uint8_t *ptr
= (uint8_t *)data
;
395 ret
= read((int)conn
, ptr
, len
);
398 } while ((ret
< 0) && (errno
== EAGAIN
|| errno
== EINTR
));
407 *length
= *length
- len
;
408 return errSecSuccess
;
411 unsigned char dn
[] = {
412 0x30, 0x5e, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13,
413 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0a,
414 0x13, 0x0a, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x49, 0x6e, 0x63, 0x2e,
415 0x31, 0x26, 0x30, 0x24, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x1d, 0x41,
416 0x70, 0x70, 0x6c, 0x65, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69,
417 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f,
418 0x72, 0x69, 0x74, 0x79, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04,
419 0x03, 0x13, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f, 0x73, 0x74
421 unsigned int dn_len
= 96;
423 static SSLContextRef
make_ssl_ref(bool server
, bool client_side_auth
, bool dh_anonymous
,
424 bool dtls
, int sock
, CFArrayRef certs
, SSLProtocol prot
)
426 SSLContextRef ctx
= NULL
;
428 require_noerr(SSLNewDatagramContext(server
, &ctx
), out
);
430 require_noerr(SSLNewContext(server
, &ctx
), out
);
431 require_noerr(SSLSetProtocolVersionMax(ctx
, prot
), out
);
432 require_noerr(SSLSetIOFuncs(ctx
,
433 (SSLReadFunc
)SocketRead
, (SSLWriteFunc
)SocketWrite
), out
);
434 require_noerr(SSLSetConnection(ctx
, (SSLConnectionRef
)(intptr_t)sock
), out
);
435 //static const char *peer_domain_name = "localhost";
436 //require_noerr(SSLSetPeerDomainName(ctx, peer_domain_name,
437 // strlen(peer_domain_name)), out);
442 require_noerr(SSLSetCertificate(ctx
, certs
), out
);
443 if (client_side_auth
&& server
) {
444 require_noerr(SSLSetClientSideAuthenticate(ctx
, kAlwaysAuthenticate
), out
);
445 require_noerr(SSLAddDistinguishedName(ctx
, dn
, dn_len
), out
);
447 #if 0 /* Setting client certificate in advance */
448 if (client_side_auth
&& !server
)
449 require_noerr(SSLSetCertificate(ctx
, certs
), out
);
451 if (client_side_auth
&& !server
) /* enable break from SSLHandshake */
452 require_noerr(SSLSetSessionOption(ctx
,
453 kSSLSessionOptionBreakOnCertRequested
, true), out
);
454 require_noerr(SSLSetSessionOption(ctx
,
455 kSSLSessionOptionBreakOnServerAuth
, true), out
);
458 /* Tell SecureTransport to not check certs itself: it will break out of the
459 handshake to let us take care of it instead. */
460 require_noerr(SSLSetEnableCertVerify(ctx
, false), out
);
462 require_noerr(SSLSetPSKIdentity(ctx
, "Client_identity", 15), out
);
463 require_noerr(SSLSetPSKSharedSecret(ctx
, "123456789", 9), out
);
467 require_noerr(SSLSetDiffieHellmanParams(ctx
,
468 dh_param_512_der
, dh_param_512_der_len
), out
);
470 else /* if client */ {
476 SSLDisposeContext(ctx
);
480 static OSStatus
securetransport(ssl_test_handle
* ssl
)
483 SSLContextRef ctx
= ssl
->st
;
484 SecTrustRef trust
= NULL
;
485 bool got_server_auth
= false, got_client_cert_req
= false;
486 CFMutableArrayRef peer_cert_array
= NULL
;
487 CFMutableArrayRef orig_peer_cert_array
= NULL
;
489 //uint64_t start = mach_absolute_time();
491 ortn
= SSLHandshake(ctx
);
493 if (ortn
== errSSLServerAuthCompleted
)
495 require_string(!got_server_auth
, out
, "second server auth");
496 got_server_auth
= true;
497 require_string(!trust
, out
, "Got errSSLServerAuthCompleted twice?");
498 /* verify peer cert chain */
499 require_noerr(SSLCopyPeerTrust(ctx
, &trust
), out
);
500 SecTrustResultType trust_result
= 0;
501 /* this won't verify without setting up a trusted anchor */
502 require_noerr(SecTrustEvaluate(trust
, &trust_result
), out
);
504 CFIndex n_certs
= SecTrustGetCertificateCount(trust
);
505 /*fprintf(stderr, "%ld certs; trust_eval: %d\n", n_certs, trust_result); */
507 peer_cert_array
= CFArrayCreateMutable(NULL
, n_certs
, &kCFTypeArrayCallBacks
);
508 orig_peer_cert_array
= CFArrayCreateMutableCopy(NULL
, n_certs
, ssl
->certs
);
510 CFArrayInsertValueAtIndex(peer_cert_array
, 0,
511 SecTrustGetCertificateAtIndex(trust
, n_certs
));
513 SecIdentityRef ident
= (SecIdentityRef
)CFArrayGetValueAtIndex(orig_peer_cert_array
, 0);
514 SecCertificateRef peer_cert
= NULL
;
515 require_noerr(SecIdentityCopyCertificate(ident
, &peer_cert
), out
);
516 CFArraySetValueAtIndex(orig_peer_cert_array
, 0, peer_cert
);
517 CFRelease(peer_cert
);
520 require(CFEqual(orig_peer_cert_array
, peer_cert_array
), out
);
524 CFStringRef cert_name = SecCertificateCopySubjectSummary(cert);
525 char cert_name_buffer[1024];
526 require(CFStringGetFileSystemRepresentation(cert_name,
527 cert_name_buffer, sizeof(cert_name_buffer)), out);
528 fprintf(stderr, "cert name: %s\n", cert_name_buffer);
531 } else if (ortn
== errSSLClientCertRequested
) {
532 require_string(!got_client_cert_req
, out
, "second client cert req");
533 got_client_cert_req
= true;
535 /* set client cert */
536 require_string(!ssl
->is_server
, out
, "errSSLClientCertRequested while running server");
537 require_string(!ssl
->dh_anonymous
, out
, "errSSLClientCertRequested while running anon DH");
539 CFArrayRef DNs = NULL;
540 require_noerr(SSLCopyDistinguishedNames (ctx, &DNs), out);
544 require_string(ssl
->client_side_auth
, out
, "errSSLClientCertRequested in run not testing that");
545 require_noerr(SSLSetCertificate(ctx
, ssl
->certs
), out
);
547 } while (ortn
== errSSLWouldBlock
548 || ortn
== errSSLServerAuthCompleted
549 || ortn
== errSSLClientCertRequested
);
550 require_noerr_action_quiet(ortn
, out
,
551 fprintf(stderr
, "Fell out of SSLHandshake with error: %d\n", (int)ortn
));
553 if (!ssl
->is_server
&& !ssl
->dh_anonymous
&& !ssl
->is_session_resume
) {
554 require_action_string(got_server_auth
, out
, ortn
=-1, "never got server auth.");
555 if (ssl
->client_side_auth
)
556 require_string(got_client_cert_req
, out
, "never got client cert req");
558 //uint64_t elapsed = mach_absolute_time() - start;
559 //fprintf(stderr, "setr elapsed: %lld\n", elapsed);
562 SSLProtocol proto = kSSLProtocolUnknown;
563 require_noerr_quiet(SSLGetNegotiatedProtocolVersion(ctx, &proto), out); */
565 SSLCipherSuite cipherSuite
;
566 require_noerr_quiet(ortn
= SSLGetNegotiatedCipher(ctx
, &cipherSuite
), out
);
567 //fprintf(stderr, "st negotiated %s\n", sslcipher_itoa(cipherSuite));
569 Boolean sessionWasResumed
= false;
570 uint8_t session_id_data
[MAX_SESSION_ID_LENGTH
];
571 size_t session_id_length
= sizeof(session_id_data
);
572 require_noerr_quiet(ortn
= SSLGetResumableSessionInfo(ctx
, &sessionWasResumed
, session_id_data
, &session_id_length
), out
);
573 require_action(ssl
->dh_anonymous
|| (ssl
->is_session_resume
== sessionWasResumed
), out
, ortn
= -1);
574 // if (sessionWasResumed) fprintf(stderr, "st resumed session\n");
575 //hexdump(session_id_data, session_id_length);
578 char *req
="GET / HTTP/1.0\r\n\r\n";
581 if (!ssl
->is_server
) {
582 require_noerr_quiet(ortn
= SSLWrite(ctx
, req
, strlen(req
), &len
), out
);
583 require_action_quiet(len
== strlen(req
), out
, ortn
= -1);
584 require_noerr_quiet(ortn
= SSLRead(ctx
, ibuf
, sizeof(ibuf
), &len
), out
);
586 // printf(">>>\n%s<<<\n", ibuf);
591 CFReleaseSafe(orig_peer_cert_array
);
592 CFReleaseSafe(peer_cert_array
);
594 SSLDisposeContext(ctx
);
595 if (trust
) CFRelease(trust
);
602 static ssl_test_handle
*
603 ssl_test_handle_create(uint32_t session_id
, bool resume
, bool server
, bool client_side_auth
, bool dh_anonymous
, bool dtls
,
604 int comm
, CFArrayRef certs
, SSLProtocol prot
)
606 ssl_test_handle
*handle
= calloc(1, sizeof(ssl_test_handle
));
608 handle
->session_id
= session_id
;
609 handle
->is_session_resume
= resume
;
610 handle
->is_server
= server
;
611 handle
->client_side_auth
= client_side_auth
;
612 handle
->dh_anonymous
= dh_anonymous
;
614 handle
->certs
= certs
;
615 handle
->st
= make_ssl_ref(server
, client_side_auth
, dh_anonymous
, dtls
, comm
, certs
, prot
);
623 CFArrayRef client_certs
= trusted_ec_client_chain();
624 ok(client_certs
, "got client certs");
629 for (p
=0; p
<nservers
; p
++) {
630 for (pr
=0; pr
<nprotos
; pr
++) {
631 for (i
=0; ciphers
[i
].name
!= NULL
; i
++) {
633 ssl_test_handle
*client
;
634 SSLProtocol proto
= protos
[pr
];
640 skip("This ciphersuite is not supported for this protocol version", 2, ciphers
[i
].prot
<=pr
);
641 skip("This server doesn't support this ciphersuite", 2, ciphers
[i
].portoffset
[servers
[p
].cs_index
]);
643 port
=servers
[p
].base_port
+ ciphers
[i
].portoffset
[servers
[p
].cs_index
];
644 uint32_t session_id
= (pr
<<16) | (port
<<8) | (i
+1);
646 s
=SocketConnect(servers
[p
].host
, port
);
649 "Connect failed: %40s to %s:%d proto=%d", ciphers
[i
].name
, servers
[p
].host
, port
, pr
);
651 skip("Could not connect to the server", 1, s
);
653 //fprintf(stderr, "session_id: %d\n", session_id);
654 client
= ssl_test_handle_create(session_id
, false, false/*client*/,
655 servers
[p
].client_auth
, ciphers
[i
].dh_anonymous
, 0,
656 s
, client_certs
, proto
);
658 /* set fixed cipher on client and server */
659 if(ciphers
[i
].cipher
!= SSL_NO_SUCH_CIPHERSUITE
) {
660 if(SSLSetEnabledCiphers(client
->st
, &ciphers
[i
].cipher
, 1)!=0)
661 printf("Invalid cipher %04x (i=%d, p=%d, pr=%d)\n", ciphers
[i
].cipher
, i
, p
, pr
);
664 printf("Handshake : %40s to %s:%d proto=%d\n", ciphers
[i
].name
, servers
[p
].host
, port
, pr
);
665 OSStatus ok
= securetransport(client
);
666 printf("Result = %d\n", (int)ok
);
668 ok(!ok
, "Handshake failed: %40s to %s:%d proto=%d", ciphers
[i
].name
, servers
[p
].host
, port
, pr
);
678 CFReleaseNull(client_certs
);
681 int ssl_43_ciphers(int argc
, char *const *argv
)
683 plan_tests(1 + 2*nservers
*nprotos
*(ciphers_len
-1));
691 TODO: count errSSLWouldBlock
692 TODO: skip tests that don't matter: client_auth and anonymous dh
693 TODO: we seem to only be negotiating tls - force a round of sslv3
694 TODO: allow secure transport to also defer client side auth to client
695 TODO: make sure anonymous dh is never selected if not expicitly enabled
696 TODO: make sure DHE is not available if not explicitly enabled and no parameters
698 TODO: resumable sessions