]> git.saurik.com Git - apple/security.git/blob - OSX/libsecurity_ssl/regressions/ssl-43-ciphers.c
Security-57740.1.18.tar.gz
[apple/security.git] / OSX / libsecurity_ssl / regressions / ssl-43-ciphers.c
1 /*
2 * Copyright (c) 2011-2014 Apple Inc. All Rights Reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
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
11 * file.
12 *
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.
20 *
21 * @APPLE_LICENSE_HEADER_END@
22 */
23
24
25 #include <stdbool.h>
26 #include <pthread.h>
27 #include <fcntl.h>
28 #include <sys/mman.h>
29 #include <unistd.h>
30 #include <sys/types.h>
31 #include <netinet/in.h>
32 #include <sys/socket.h>
33 #include <netdb.h>
34 #include <arpa/inet.h>
35 #include <CoreFoundation/CoreFoundation.h>
36
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>
48
49 #include <utilities/array_size.h>
50 #include <utilities/SecIOFormat.h>
51
52 #include <string.h>
53 #include <sys/types.h>
54 #include <sys/socket.h>
55 #include <errno.h>
56 #include <stdlib.h>
57 #include <mach/mach_time.h>
58
59
60 #include "ssl_regressions.h"
61 #include "ssl-utils.h"
62
63 /*
64 SSL CipherSuite tests
65
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).
69
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,
77
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,
82
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,
86
87 SSLv3 ciphersuites disabled by securetransport on phone:
88 SSL_RSA_WITH_IDEA_CBC_SHA, SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5
89
90 */
91
92
93 //#define OPENSSL_SERVER "ariadne.apple.com"
94 //#define GNUTLS_SERVER "ariadne.apple.com"
95 //#define OPENSSL_SERVER "kuip.apple.com"
96 //#define GNUTLS_SERVER "kuip.apple.com"
97 #define OPENSSL_SERVER "192.168.2.1"
98 #define GNUTLS_SERVER "192.168.2.1"
99
100 static struct {
101 const char *host;
102 int base_port;
103 int cs_index;
104 bool client_auth;
105 } servers[] = {
106 { OPENSSL_SERVER, 4000, 0, false}, //openssl s_server w/o client side auth
107 { GNUTLS_SERVER, 5000, 1, false}, // gnutls-serv w/o client side auth
108 // { "www.mikestoolbox.org", 442, 2, false}, // mike's w/o client side auth
109 // { "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
110 { OPENSSL_SERVER, 4010, 0, true}, //openssl s_server w/ client side auth
111 { GNUTLS_SERVER, 5010, 1, true}, // gnutls-serv w/ client side auth
112 // { "www.mikestoolbox.net", 442, 2, true}, // mike's w/ client side auth
113 // { "tls.secg.org", 8442, 3}, //secg ecc server w/ client side auth
114 };
115 int nservers = sizeof(servers)/sizeof(servers[0]);
116
117 int protos[]={ kSSLProtocol3, kTLSProtocol1, kTLSProtocol11, kTLSProtocol12 };
118 int nprotos = sizeof(protos)/sizeof(protos[0]);
119
120 typedef struct _CipherSuiteName {
121 int prot;
122 SSLCipherSuite cipher;
123 const char *name;
124 int portoffset[4]; // 0=not supported , else = port offset for this ciphersuite
125 bool dh_anonymous;
126 } CipherSuiteName;
127
128 /* prot: 0 = SSL3, 1=TLSv1.0, 2=TLSv1.1, 3=TLSv1.2 */
129 #define CIPHER(prot, cipher, offsets...) { prot, cipher, #cipher, offsets},
130
131 const CipherSuiteName ciphers[] = {
132 //SSL_NULL_WITH_NULL_NULL, unsupported
133 #if 1
134 /* RSA cipher suites */
135 CIPHER(1, SSL_RSA_WITH_NULL_MD5, {1, 1, 0, 1}, false)
136 CIPHER(1, SSL_RSA_WITH_NULL_SHA, {1, 1, 0, 1}, false)
137 CIPHER(3, TLS_RSA_WITH_NULL_SHA256, {0, 1, 0, 0}, false)
138 #endif
139
140 #if 1
141 CIPHER(1, SSL_RSA_WITH_RC4_128_MD5, {1, 1, 1, 1}, false)
142 CIPHER(1, SSL_RSA_WITH_RC4_128_SHA, {1, 1, 1, 1}, false)
143 CIPHER(1, SSL_RSA_WITH_3DES_EDE_CBC_SHA, {1, 1, 1, 1}, false)
144 CIPHER(1, TLS_RSA_WITH_AES_128_CBC_SHA, {1, 1, 1, 1}, false)
145 CIPHER(3, TLS_RSA_WITH_AES_128_CBC_SHA256, {0, 1, 1, 0}, false)
146 CIPHER(1, TLS_RSA_WITH_AES_256_CBC_SHA, {1, 1, 1, 1}, false)
147 CIPHER(3, TLS_RSA_WITH_AES_256_CBC_SHA256, {0, 1, 1, 0}, false)
148 #endif
149
150 #if 1
151 /* DHE_RSA ciphers suites */
152 CIPHER(1, SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA, {1, 1, 1, 1}, false)
153 CIPHER(1, TLS_DHE_RSA_WITH_AES_128_CBC_SHA, {1, 1, 1, 1}, false)
154 CIPHER(3, TLS_DHE_RSA_WITH_AES_128_CBC_SHA256, {0, 1, 1, 0}, false)
155 CIPHER(1, TLS_DHE_RSA_WITH_AES_256_CBC_SHA, {1, 1, 1, 1}, false)
156 CIPHER(3, TLS_DHE_RSA_WITH_AES_256_CBC_SHA256, {0, 1, 1, 0}, false)
157 #endif
158
159
160 #if 1
161 /* DH_anon cipher suites */
162 CIPHER(0, SSL_DH_anon_WITH_RC4_128_MD5, {1, 1, 0, 1}, true)
163 CIPHER(0, SSL_DH_anon_WITH_3DES_EDE_CBC_SHA, {1, 1, 0, 1}, true)
164 CIPHER(0, TLS_DH_anon_WITH_AES_128_CBC_SHA, {1, 1, 0, 1}, true)
165 CIPHER(3, TLS_DH_anon_WITH_AES_128_CBC_SHA256, {0, 1, 0, 1}, true)
166 CIPHER(0, TLS_DH_anon_WITH_AES_256_CBC_SHA, {1, 1, 0, 1}, true)
167 CIPHER(3, TLS_DH_anon_WITH_AES_256_CBC_SHA256, {0, 1, 0, 1}, true)
168 #endif
169
170 #if 1
171 /* ECDHE_ECDSA cipher suites */
172 CIPHER(1, TLS_ECDHE_ECDSA_WITH_NULL_SHA, {4, 4, 0, 1}, false)
173 CIPHER(1, TLS_ECDHE_ECDSA_WITH_RC4_128_SHA, {4, 0, 0, 1}, false)
174 CIPHER(1, TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA, {4, 4, 0, 1}, false)
175 CIPHER(1, TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, {4, 4, 0, 1}, false)
176 CIPHER(3, TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, {0, 4, 0, 1}, false)
177 CIPHER(1, TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, {4, 4, 0, 1}, false)
178 CIPHER(3, TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384, {0, 4, 0, 1}, false)
179 #endif
180
181 #if 1
182 /* ECDHE_RSA cipher suites */
183 CIPHER(1, TLS_ECDHE_RSA_WITH_RC4_128_SHA, {1, 0, 0, 1}, false)
184 CIPHER(1, TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, {1, 1, 0, 1}, false)
185 CIPHER(1, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, {1, 1, 0, 1}, false)
186 CIPHER(3, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, {0, 1, 0, 0}, false)
187 CIPHER(1, TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, {1, 1, 0, 1}, false)
188 CIPHER(3, TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384, {0, 0, 0, 0}, false) // Not supported by either gnutls or openssl
189 #endif
190
191 #if 0
192 CIPHER(1, TLS_PSK_WITH_RC4_128_SHA, {1, 1, 0, 0}, true)
193 CIPHER(1, TLS_PSK_WITH_3DES_EDE_CBC_SHA, {1, 1, 0, 0}, true)
194 CIPHER(1, TLS_PSK_WITH_AES_128_CBC_SHA, {1, 1, 0, 0}, true)
195 CIPHER(1, TLS_PSK_WITH_AES_256_CBC_SHA, {1, 1, 0, 0}, true)
196 CIPHER(3, TLS_PSK_WITH_AES_128_CBC_SHA256, {0, 1, 0, 0}, true)
197 CIPHER(3, TLS_PSK_WITH_AES_256_CBC_SHA384, {0, 0, 0, 0}, true)
198 CIPHER(1, TLS_PSK_WITH_NULL_SHA, {0, 0, 0, 0}, true)
199 CIPHER(3, TLS_PSK_WITH_NULL_SHA256, {0, 1, 0, 0}, true)
200 CIPHER(3, TLS_PSK_WITH_NULL_SHA384, {0, 0, 0, 0}, true)
201 #endif
202
203 #if 1
204 CIPHER(3, TLS_RSA_WITH_AES_128_GCM_SHA256, {1, 1, 0, 0}, false)
205 CIPHER(3, TLS_RSA_WITH_AES_256_GCM_SHA384, {1, 0, 0, 0}, false)
206
207 CIPHER(3, TLS_DHE_RSA_WITH_AES_128_GCM_SHA256, {1, 1, 0, 0}, false)
208 CIPHER(3, TLS_DHE_RSA_WITH_AES_256_GCM_SHA384, {1, 0, 0, 0}, false)
209
210 CIPHER(3, TLS_DH_anon_WITH_AES_128_GCM_SHA256, {1, 1, 0, 0}, true)
211 CIPHER(3, TLS_DH_anon_WITH_AES_256_GCM_SHA384, {1, 0, 0, 0}, true)
212
213 CIPHER(3, TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, {1, 1, 0, 0}, false)
214 CIPHER(3, TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, {1, 1, 0, 0}, false)
215
216 CIPHER(3, TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, {4, 4, 0, 0}, false)
217 CIPHER(3, TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, {4, 0, 0, 0}, false)
218 #endif
219
220
221
222 #if 0
223 CIPHER(SSL_RSA_EXPORT_WITH_RC4_40_MD5, true, false, true,false)
224 CIPHER(SSL_RSA_EXPORT_WITH_DES40_CBC_SHA, true, false, true, false)
225 CIPHER(SSL_RSA_WITH_DES_CBC_SHA, true, false, true, false)
226 CIPHER(SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA, true, false, true, false)
227 CIPHER(SSL_DHE_RSA_WITH_DES_CBC_SHA, true, false, true, false)
228 CIPHER(SSL_DH_anon_EXPORT_WITH_RC4_40_MD5, true, false, true, true)
229 CIPHER(SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA, true, false, true, true)
230 CIPHER(SSL_DH_anon_WITH_DES_CBC_SHA, true, false, true, true)
231 #endif
232
233 #if 0
234 /* "Any" cipher suite - test the default configuration */
235 {0, SSL_NO_SUCH_CIPHERSUITE, "Any cipher 1", {1, 1, 1, 1}, false},
236 {0, SSL_NO_SUCH_CIPHERSUITE, "Any cipher 2", {2, 2, 0, 0}, false},
237
238 // Those servers wont talk SSL3.0 because they have EC certs
239 {1, SSL_NO_SUCH_CIPHERSUITE, "Any cipher 3", {3, 3, 0, 0}, false},
240 {1, SSL_NO_SUCH_CIPHERSUITE, "Any cipher 4", {4, 4, 0, 0}, false},
241 #endif
242
243 { -1, -1, NULL, }
244 };
245
246 static int ciphers_len = array_size(ciphers);
247
248
249
250 #if 0 // currently unused
251 static SSLCipherSuite sslcipher_atoi(const char *name)
252 {
253 const CipherSuiteName *a = ciphers;
254 while(a->name) {
255 if (0 == strcmp(a->name, name)) break;
256 a++;
257 }
258 return a->cipher;
259 }
260
261 static const char * sslcipher_itoa(SSLCipherSuite num)
262 {
263 const CipherSuiteName *a = ciphers;
264 while(a->cipher >= 0) {
265 if (num == a->cipher) break;
266 a++;
267 }
268 return a->name;
269 }
270 #endif // currently unused
271
272 unsigned char dh_param_512_bytes[] = {
273 0x30, 0x46, 0x02, 0x41, 0x00, 0xdb, 0x3c, 0xfa, 0x13, 0xa6, 0xd2, 0x64,
274 0xdf, 0xcc, 0x40, 0xb1, 0x21, 0xd4, 0xf2, 0xad, 0x22, 0x7f, 0xce, 0xa0,
275 0xb9, 0x5b, 0x95, 0x1c, 0x2e, 0x99, 0xb0, 0x27, 0xd0, 0xed, 0xf4, 0xbd,
276 0xbb, 0x36, 0x93, 0xd0, 0x9d, 0x2b, 0x32, 0xa3, 0x56, 0x53, 0xe3, 0x7b,
277 0xed, 0xa1, 0x71, 0x82, 0x2e, 0x83, 0x14, 0xf9, 0xc0, 0x2f, 0x15, 0xcb,
278 0xcf, 0x97, 0xab, 0x88, 0x49, 0x20, 0x28, 0x2e, 0x63, 0x02, 0x01, 0x02
279 };
280 unsigned char *dh_param_512_der = dh_param_512_bytes;
281 unsigned int dh_param_512_der_len = 72;
282
283 typedef struct {
284 uint32_t session_id;
285 bool is_session_resume;
286 SSLContextRef st;
287 bool is_server;
288 bool client_side_auth;
289 bool dh_anonymous;
290 int comm;
291 CFArrayRef certs;
292 } ssl_test_handle;
293
294
295
296
297 #if 0
298 static void hexdump(const uint8_t *bytes, size_t len) {
299 size_t ix;
300 printf("socket write(%p, %lu)\n", bytes, len);
301 for (ix = 0; ix < len; ++ix) {
302 if (!(ix % 16))
303 printf("\n");
304 printf("%02X ", bytes[ix]);
305 }
306 printf("\n");
307 }
308 #else
309 #define hexdump(bytes, len)
310 #endif
311
312 static int SocketConnect(const char *hostName, int port)
313 {
314 struct sockaddr_in addr;
315 struct in_addr host;
316 int sock;
317 int err;
318 struct hostent *ent;
319
320 if (hostName[0] >= '0' && hostName[0] <= '9')
321 {
322 host.s_addr = inet_addr(hostName);
323 }
324 else {
325 unsigned dex;
326 #define GETHOST_RETRIES 5
327 /* seeing a lot of soft failures here that I really don't want to track down */
328 for(dex=0; dex<GETHOST_RETRIES; dex++) {
329 if(dex != 0) {
330 printf("\n...retrying gethostbyname(%s)", hostName);
331 }
332 ent = gethostbyname(hostName);
333 if(ent != NULL) {
334 break;
335 }
336 }
337 if(ent == NULL) {
338 printf("\n***gethostbyname(%s) returned: %s\n", hostName, hstrerror(h_errno));
339 return -1;
340 }
341 memcpy(&host, ent->h_addr, sizeof(struct in_addr));
342 }
343
344 sock = socket(AF_INET, SOCK_STREAM, 0);
345 addr.sin_addr = host;
346 addr.sin_port = htons((u_short)port);
347
348 addr.sin_family = AF_INET;
349 err = connect(sock, (struct sockaddr *) &addr, sizeof(struct sockaddr_in));
350
351 if(err!=0)
352 {
353 perror("connect failed");
354 return err;
355 }
356
357 return sock;
358 }
359
360
361 static OSStatus SocketWrite(SSLConnectionRef conn, const void *data, size_t *length)
362 {
363 size_t len = *length;
364 uint8_t *ptr = (uint8_t *)data;
365
366 do {
367 ssize_t ret;
368 do {
369 hexdump(ptr, len);
370 ret = write((int)conn, ptr, len);
371 if (ret < 0)
372 perror("send");
373 } while ((ret < 0) && (errno == EAGAIN || errno == EINTR));
374 if (ret > 0) {
375 len -= ret;
376 ptr += ret;
377 }
378 else
379 return -36;
380 } while (len > 0);
381
382 *length = *length - len;
383 return errSecSuccess;
384 }
385
386 static OSStatus SocketRead(SSLConnectionRef conn, void *data, size_t *length)
387 {
388 size_t len = *length;
389 uint8_t *ptr = (uint8_t *)data;
390
391 do {
392 ssize_t ret;
393 do {
394 ret = read((int)conn, ptr, len);
395 if (ret < 0)
396 perror("send");
397 } while ((ret < 0) && (errno == EAGAIN || errno == EINTR));
398 if (ret > 0) {
399 len -= ret;
400 ptr += ret;
401 }
402 else
403 return -36;
404 } while (len > 0);
405
406 *length = *length - len;
407 return errSecSuccess;
408 }
409
410 unsigned char dn[] = {
411 0x30, 0x5e, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13,
412 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x0a,
413 0x13, 0x0a, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x49, 0x6e, 0x63, 0x2e,
414 0x31, 0x26, 0x30, 0x24, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x1d, 0x41,
415 0x70, 0x70, 0x6c, 0x65, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69,
416 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f,
417 0x72, 0x69, 0x74, 0x79, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04,
418 0x03, 0x13, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f, 0x73, 0x74
419 };
420 unsigned int dn_len = 96;
421
422 static SSLContextRef make_ssl_ref(bool server, bool client_side_auth, bool dh_anonymous,
423 bool dtls, int sock, CFArrayRef certs, SSLProtocol prot)
424 {
425 SSLContextRef ctx = NULL;
426 if(dtls)
427 require_noerr(SSLNewDatagramContext(server, &ctx), out);
428 else
429 require_noerr(SSLNewContext(server, &ctx), out);
430 require_noerr(SSLSetProtocolVersionMax(ctx, prot), out);
431 require_noerr(SSLSetIOFuncs(ctx,
432 (SSLReadFunc)SocketRead, (SSLWriteFunc)SocketWrite), out);
433 require_noerr(SSLSetConnection(ctx, (SSLConnectionRef)(intptr_t)sock), out);
434 //static const char *peer_domain_name = "localhost";
435 //require_noerr(SSLSetPeerDomainName(ctx, peer_domain_name,
436 // strlen(peer_domain_name)), out);
437
438
439 if (!dh_anonymous) {
440 if (server)
441 require_noerr(SSLSetCertificate(ctx, certs), out);
442 if (client_side_auth && server) {
443 require_noerr(SSLSetClientSideAuthenticate(ctx, kAlwaysAuthenticate), out);
444 require_noerr(SSLAddDistinguishedName(ctx, dn, dn_len), out);
445 }
446 #if 0 /* Setting client certificate in advance */
447 if (client_side_auth && !server)
448 require_noerr(SSLSetCertificate(ctx, certs), out);
449 #endif
450 if (client_side_auth && !server) /* enable break from SSLHandshake */
451 require_noerr(SSLSetSessionOption(ctx,
452 kSSLSessionOptionBreakOnCertRequested, true), out);
453 require_noerr(SSLSetSessionOption(ctx,
454 kSSLSessionOptionBreakOnServerAuth, true), out);
455 }
456
457 /* Tell SecureTransport to not check certs itself: it will break out of the
458 handshake to let us take care of it instead. */
459 require_noerr(SSLSetEnableCertVerify(ctx, false), out);
460
461 require_noerr(SSLSetPSKIdentity(ctx, "Client_identity", 15), out);
462 require_noerr(SSLSetPSKSharedSecret(ctx, "123456789", 9), out);
463
464
465 if (server) {
466 require_noerr(SSLSetDiffieHellmanParams(ctx,
467 dh_param_512_der, dh_param_512_der_len), out);
468 }
469 else /* if client */ {
470 }
471
472 return ctx;
473 out:
474 if (ctx)
475 SSLDisposeContext(ctx);
476 return NULL;
477 }
478
479 static OSStatus securetransport(ssl_test_handle * ssl)
480 {
481 OSStatus ortn;
482 SSLContextRef ctx = ssl->st;
483 SecTrustRef trust = NULL;
484 bool got_server_auth = false, got_client_cert_req = false;
485 CFMutableArrayRef peer_cert_array = NULL;
486 CFMutableArrayRef orig_peer_cert_array = NULL;
487
488 //uint64_t start = mach_absolute_time();
489 do {
490 ortn = SSLHandshake(ctx);
491
492 if (ortn == errSSLServerAuthCompleted)
493 {
494 require_string(!got_server_auth, out, "second server auth");
495 got_server_auth = true;
496 require_string(!trust, out, "Got errSSLServerAuthCompleted twice?");
497 /* verify peer cert chain */
498 require_noerr(SSLCopyPeerTrust(ctx, &trust), out);
499 SecTrustResultType trust_result = 0;
500 /* this won't verify without setting up a trusted anchor */
501 require_noerr(SecTrustEvaluate(trust, &trust_result), out);
502
503 CFIndex n_certs = SecTrustGetCertificateCount(trust);
504 /*fprintf(stderr, "%ld certs; trust_eval: %d\n", n_certs, trust_result); */
505
506 peer_cert_array = CFArrayCreateMutable(NULL, n_certs, &kCFTypeArrayCallBacks);
507 orig_peer_cert_array = CFArrayCreateMutableCopy(NULL, n_certs, ssl->certs);
508 while (n_certs--)
509 CFArrayInsertValueAtIndex(peer_cert_array, 0,
510 SecTrustGetCertificateAtIndex(trust, n_certs));
511
512 SecIdentityRef ident = (SecIdentityRef)CFArrayGetValueAtIndex(orig_peer_cert_array, 0);
513 SecCertificateRef peer_cert = NULL;
514 require_noerr(SecIdentityCopyCertificate(ident, &peer_cert), out);
515 CFArraySetValueAtIndex(orig_peer_cert_array, 0, peer_cert);
516 CFRelease(peer_cert);
517
518 #if 0
519 require(CFEqual(orig_peer_cert_array, peer_cert_array), out);
520 #endif
521
522 /*
523 CFStringRef cert_name = SecCertificateCopySubjectSummary(cert);
524 char cert_name_buffer[1024];
525 require(CFStringGetFileSystemRepresentation(cert_name,
526 cert_name_buffer, sizeof(cert_name_buffer)), out);
527 fprintf(stderr, "cert name: %s\n", cert_name_buffer);
528 CFRelease(trust);
529 */
530 } else if (ortn == errSSLClientCertRequested) {
531 require_string(!got_client_cert_req, out, "second client cert req");
532 got_client_cert_req = true;
533
534 /* set client cert */
535 require_string(!ssl->is_server, out, "errSSLClientCertRequested while running server");
536 require_string(!ssl->dh_anonymous, out, "errSSLClientCertRequested while running anon DH");
537 /*
538 CFArrayRef DNs = NULL;
539 require_noerr(SSLCopyDistinguishedNames (ctx, &DNs), out);
540 require(DNs, out);
541 CFRelease(DNs);
542 */
543 require_string(ssl->client_side_auth, out, "errSSLClientCertRequested in run not testing that");
544 require_noerr(SSLSetCertificate(ctx, ssl->certs), out);
545 }
546 } while (ortn == errSSLWouldBlock
547 || ortn == errSSLServerAuthCompleted
548 || ortn == errSSLClientCertRequested);
549 require_noerr_action_quiet(ortn, out,
550 fprintf(stderr, "Fell out of SSLHandshake with error: %d\n", (int)ortn));
551
552 if (!ssl->is_server && !ssl->dh_anonymous && !ssl->is_session_resume) {
553 require_action_string(got_server_auth, out, ortn=-1, "never got server auth.");
554 if (ssl->client_side_auth)
555 require_string(got_client_cert_req, out, "never got client cert req");
556 }
557 //uint64_t elapsed = mach_absolute_time() - start;
558 //fprintf(stderr, "setr elapsed: %lld\n", elapsed);
559
560 /*
561 SSLProtocol proto = kSSLProtocolUnknown;
562 require_noerr_quiet(SSLGetNegotiatedProtocolVersion(ctx, &proto), out); */
563
564 SSLCipherSuite cipherSuite;
565 require_noerr_quiet(ortn = SSLGetNegotiatedCipher(ctx, &cipherSuite), out);
566 //fprintf(stderr, "st negotiated %s\n", sslcipher_itoa(cipherSuite));
567
568 Boolean sessionWasResumed = false;
569 uint8_t session_id_data[MAX_SESSION_ID_LENGTH];
570 size_t session_id_length = sizeof(session_id_data);
571 require_noerr_quiet(ortn = SSLGetResumableSessionInfo(ctx, &sessionWasResumed, session_id_data, &session_id_length), out);
572 require_action(ssl->dh_anonymous || (ssl->is_session_resume == sessionWasResumed), out, ortn = -1);
573 // if (sessionWasResumed) fprintf(stderr, "st resumed session\n");
574 //hexdump(session_id_data, session_id_length);
575
576 #if 1
577 char *req="GET / HTTP/1.0\r\n\r\n";
578 char ibuf[4096];
579 size_t len;
580 if (!ssl->is_server) {
581 require_noerr_quiet(ortn = SSLWrite(ctx, req, strlen(req), &len), out);
582 require_action_quiet(len == strlen(req), out, ortn = -1);
583 require_noerr_quiet(ortn = SSLRead(ctx, ibuf, sizeof(ibuf), &len), out);
584 ibuf[len]=0;
585 // printf(">>>\n%s<<<\n", ibuf);
586 }
587 #endif
588
589 out:
590 CFReleaseSafe(orig_peer_cert_array);
591 CFReleaseSafe(peer_cert_array);
592 SSLClose(ctx);
593 SSLDisposeContext(ctx);
594 if (trust) CFRelease(trust);
595
596 return ortn;
597 }
598
599
600
601 static ssl_test_handle *
602 ssl_test_handle_create(uint32_t session_id, bool resume, bool server, bool client_side_auth, bool dh_anonymous, bool dtls,
603 int comm, CFArrayRef certs, SSLProtocol prot)
604 {
605 ssl_test_handle *handle = calloc(1, sizeof(ssl_test_handle));
606 if (handle) {
607 handle->session_id = session_id;
608 handle->is_session_resume = resume;
609 handle->is_server = server;
610 handle->client_side_auth = client_side_auth;
611 handle->dh_anonymous = dh_anonymous;
612 handle->comm = comm;
613 handle->certs = certs;
614 handle->st = make_ssl_ref(server, client_side_auth, dh_anonymous, dtls, comm, certs, prot);
615 }
616 return handle;
617 }
618
619 static void
620 tests(void)
621 {
622 CFArrayRef client_certs = trusted_ec_client_chain();
623 ok(client_certs, "got client certs");
624
625 int i;
626 int p, pr;
627
628 for (p=0; p<nservers; p++) {
629 for (pr=0; pr<nprotos; pr++) {
630 for (i=0; ciphers[i].name != NULL; i++) {
631
632 ssl_test_handle *client;
633 SSLProtocol proto = protos[pr];
634 int port;
635
636 int s;
637
638 SKIP: {
639 skip("This ciphersuite is not supported for this protocol version", 2, ciphers[i].prot<=pr);
640 skip("This server doesn't support this ciphersuite", 2, ciphers[i].portoffset[servers[p].cs_index]);
641
642 port=servers[p].base_port + ciphers[i].portoffset[servers[p].cs_index];
643 uint32_t session_id = (pr<<16) | (port<<8) | (i+1);
644
645 s=SocketConnect(servers[p].host, port);
646
647 ok(s,
648 "Connect failed: %40s to %s:%d proto=%d", ciphers[i].name, servers[p].host, port, pr);
649
650 skip("Could not connect to the server", 1, s);
651
652 //fprintf(stderr, "session_id: %d\n", session_id);
653 client = ssl_test_handle_create(session_id, false, false/*client*/,
654 servers[p].client_auth, ciphers[i].dh_anonymous, 0,
655 s, client_certs, proto);
656
657 /* set fixed cipher on client and server */
658 if(ciphers[i].cipher != SSL_NO_SUCH_CIPHERSUITE) {
659 if(SSLSetEnabledCiphers(client->st, &ciphers[i].cipher, 1)!=0)
660 printf("Invalid cipher %04x (i=%d, p=%d, pr=%d)\n", ciphers[i].cipher, i, p, pr);
661 }
662
663 printf("Handshake : %40s to %s:%d proto=%d\n", ciphers[i].name, servers[p].host, port, pr);
664 OSStatus ok = securetransport(client);
665 printf("Result = %d\n", (int)ok);
666
667 ok(!ok, "Handshake failed: %40s to %s:%d proto=%d", ciphers[i].name, servers[p].host, port, pr);
668
669 close(s);
670 free(client);
671
672 } /* SKIP block */
673 }
674 } /* all ciphers */
675 } /* all servers */
676
677 CFReleaseNull(client_certs);
678 }
679
680 int ssl_43_ciphers(int argc, char *const *argv)
681 {
682 plan_tests(1 + 2*nservers*nprotos*(ciphers_len-1));
683
684 tests();
685
686 return 0;
687 }
688
689 /*
690 TODO: count errSSLWouldBlock
691 TODO: skip tests that don't matter: client_auth and anonymous dh
692 TODO: we seem to only be negotiating tls - force a round of sslv3
693 TODO: allow secure transport to also defer client side auth to client
694 TODO: make sure anonymous dh is never selected if not expicitly enabled
695 TODO: make sure DHE is not available if not explicitly enabled and no parameters
696 are set
697 TODO: resumable sessions
698 */