8 #include <CoreFoundation/CoreFoundation.h>
10 #include <AssertMacros.h>
11 #include <Security/SecureTransportPriv.h> /* SSLSetOption */
12 #include <Security/SecureTransport.h>
13 #include <Security/SecPolicy.h>
14 #include <Security/SecTrust.h>
15 #include <Security/SecIdentity.h>
16 #include <Security/SecIdentityPriv.h>
17 #include <Security/SecCertificatePriv.h>
18 #include <Security/SecKeyPriv.h>
19 #include <Security/SecItem.h>
20 #include <Security/SecRandom.h>
22 #include <utilities/array_size.h>
23 #include <utilities/SecCFRelease.h>
25 #include <sys/types.h>
26 #include <sys/socket.h>
29 #include <mach/mach_time.h>
32 #include <Security/SecRSAKey.h>
35 #include "ssl_regressions.h"
36 #include "ssl-utils.h"
41 Test both the client and server side.
44 - Make sure that handshake fail when dh param size is too small.
47 - handshake pass or fail
52 static OSStatus
SocketWrite(SSLConnectionRef conn
, const void *data
, size_t *length
)
55 uint8_t *ptr
= (uint8_t *)data
;
60 ret
= write((int)conn
, ptr
, len
);
61 } while ((ret
< 0) && (errno
== EAGAIN
|| errno
== EINTR
));
70 *length
= *length
- len
;
74 static OSStatus
SocketRead(SSLConnectionRef conn
, void *data
, size_t *length
)
77 uint8_t *ptr
= (uint8_t *)data
;
82 ret
= read((int)conn
, ptr
, len
);
83 } while ((ret
< 0) && (errno
== EINPROGRESS
|| errno
== EAGAIN
|| errno
== EINTR
));
88 printf("read error(%d): ret=%zd, errno=%d\n", (int)conn
, ret
, errno
);
93 *length
= *length
- len
;
103 static ssl_client_handle
*
104 ssl_client_handle_create(int comm
, CFArrayRef trustedCA
, unsigned dhe_size
)
106 ssl_client_handle
*handle
= calloc(1, sizeof(ssl_client_handle
));
107 SSLContextRef ctx
= SSLCreateContext(kCFAllocatorDefault
, kSSLClientSide
, kSSLStreamType
);
109 require(handle
, out
);
112 require_noerr(SSLSetIOFuncs(ctx
,
113 (SSLReadFunc
)SocketRead
, (SSLWriteFunc
)SocketWrite
), out
);
114 require_noerr(SSLSetConnection(ctx
, (SSLConnectionRef
)(intptr_t)comm
), out
);
115 static const char *peer_domain_name
= "localhost";
116 require_noerr(SSLSetPeerDomainName(ctx
, peer_domain_name
,
117 strlen(peer_domain_name
)), out
);
119 require_noerr(SSLSetTrustedRoots(ctx
, trustedCA
, true), out
);
121 require_noerr(SSLSetDHEEnabled(ctx
, true), out
);
124 require_noerr(SSLSetMinimumDHGroupSize(ctx
, dhe_size
), out
);
128 handle
->dhe_size
= dhe_size
;
142 ssl_client_handle_destroy(ssl_client_handle
*handle
)
145 SSLClose(handle
->st
);
146 CFRelease(handle
->st
);
151 static void *securetransport_ssl_client_thread(void *arg
)
154 ssl_client_handle
* ssl
= (ssl_client_handle
*)arg
;
155 SSLContextRef ctx
= ssl
->st
;
156 SSLSessionState ssl_state
;
158 pthread_setname_np("client thread");
160 require_noerr(ortn
=SSLGetSessionState(ctx
,&ssl_state
), out
);
161 require_action(ssl_state
==kSSLIdle
, out
, ortn
= -1);
164 ortn
= SSLHandshake(ctx
);
165 require_noerr(SSLGetSessionState(ctx
,&ssl_state
), out
);
167 if (ortn
== errSSLWouldBlock
) {
168 require_string(ssl_state
==kSSLHandshake
, out
, "Wrong client handshake state after errSSLWouldBlock");
170 } while (ortn
== errSSLWouldBlock
);
175 pthread_exit((void *)(intptr_t)ortn
);
187 static ssl_server_handle
*
188 ssl_server_handle_create(int comm
, CFArrayRef certs
, const void *dhParams
, size_t dhParamsLen
)
190 ssl_server_handle
*handle
= calloc(1, sizeof(ssl_server_handle
));
191 SSLContextRef ctx
= SSLCreateContext(kCFAllocatorDefault
, kSSLServerSide
, kSSLStreamType
);
192 SSLCipherSuite cipher
= TLS_DHE_RSA_WITH_AES_256_CBC_SHA256
;
194 require(handle
, out
);
197 require_noerr(SSLSetIOFuncs(ctx
,
198 (SSLReadFunc
)SocketRead
, (SSLWriteFunc
)SocketWrite
), out
);
199 require_noerr(SSLSetConnection(ctx
, (SSLConnectionRef
)(intptr_t)comm
), out
);
201 require_noerr(SSLSetCertificate(ctx
, certs
), out
);
203 require_noerr(SSLSetEnabledCiphers(ctx
, &cipher
, 1), out
);
206 require_noerr(SSLSetDiffieHellmanParams(ctx
, dhParams
, dhParamsLen
), out
);
209 handle
->certs
= certs
;
224 ssl_server_handle_destroy(ssl_server_handle
*handle
)
227 SSLClose(handle
->st
);
228 CFRelease(handle
->st
);
233 static void *securetransport_ssl_server_thread(void *arg
)
236 ssl_server_handle
* ssl
= (ssl_server_handle
*)arg
;
237 SSLContextRef ctx
= ssl
->st
;
238 SSLSessionState ssl_state
;
240 pthread_setname_np("server thread");
242 require_noerr(ortn
=SSLGetSessionState(ctx
,&ssl_state
), out
);
243 require_action(ssl_state
==kSSLIdle
, out
, ortn
= -1);
246 ortn
= SSLHandshake(ctx
);
247 require_noerr(SSLGetSessionState(ctx
,&ssl_state
), out
);
249 if (ortn
== errSSLWouldBlock
) {
250 require_action(ssl_state
==kSSLHandshake
, out
, ortn
= -1);
252 } while (ortn
== errSSLWouldBlock
);
254 require_noerr_quiet(ortn
, out
);
256 require_action(ssl_state
==kSSLConnected
, out
, ortn
= -1);
261 pthread_exit((void *)(intptr_t)ortn
);
268 unsigned client_dhe_sizes
[] = {
269 0, // default, don't set.
270 256, // will resolve to 512.
275 4096, // will resolve to 2048.
279 static const unsigned n_client_dhe_sizes
= sizeof(client_dhe_sizes
)/sizeof(client_dhe_sizes
[0]);
281 static uint8_t dh_parameters_256_data
[] = {
282 0x30, 0x26, 0x02, 0x21, 0x00, 0xd8, 0x23, 0xeb, 0xcb, 0x41, 0xd0, 0x3a,
283 0xc4, 0x9a, 0x2a, 0x2a, 0x4f, 0x35, 0xf7, 0x4f, 0xd9, 0xc5, 0x2e, 0xf8,
284 0x44, 0xa7, 0x74, 0xe3, 0x84, 0x98, 0x9f, 0xad, 0x58, 0xd5, 0x15, 0xb4,
285 0xf3, 0x02, 0x01, 0x02
288 static uint8_t dh_parameters_512_data
[] = {
289 0x30, 0x46, 0x02, 0x41, 0x00, 0x85, 0xcd, 0xc1, 0x7e, 0x26, 0xeb, 0x37,
290 0x84, 0x13, 0xd0, 0x3b, 0x07, 0xc1, 0x57, 0x7d, 0xf3, 0x55, 0x8d, 0xa0,
291 0xc4, 0xa5, 0x03, 0xc4, 0x2c, 0xc6, 0xd5, 0xa6, 0x31, 0xcb, 0x68, 0xdf,
292 0x5d, 0x96, 0x20, 0x1a, 0x15, 0x57, 0x49, 0x7d, 0xd7, 0x51, 0x65, 0x6e,
293 0x37, 0xa8, 0xe3, 0xe9, 0xe1, 0x59, 0x2e, 0xd4, 0x57, 0x4a, 0xf0, 0xcb,
294 0x0e, 0x85, 0x07, 0xdd, 0x35, 0xa7, 0xe3, 0xc6, 0xbb, 0x02, 0x01, 0x02
297 static uint8_t dh_parameters_768_data
[] = {
298 0x30, 0x66, 0x02, 0x61, 0x00, 0xe1, 0xa2, 0x50, 0xab, 0xb0, 0xdc, 0xef,
299 0xe1, 0x2f, 0xd9, 0xde, 0x59, 0x86, 0x24, 0x43, 0x3b, 0xf3, 0x40, 0x9d,
300 0x02, 0xcc, 0xe2, 0x70, 0x63, 0x46, 0x8d, 0x0f, 0xf3, 0x8a, 0xc6, 0xa0,
301 0x1d, 0x7b, 0x30, 0x83, 0x10, 0x48, 0x40, 0x28, 0xa4, 0x3e, 0xbe, 0x4d,
302 0xb6, 0xea, 0x90, 0x02, 0xae, 0x25, 0x93, 0xc0, 0xe8, 0x36, 0x5c, 0xc8,
303 0xc8, 0x0b, 0x04, 0xd5, 0x05, 0xac, 0x67, 0x24, 0x4b, 0xa9, 0x42, 0x5a,
304 0x03, 0x65, 0x4d, 0xd0, 0xc0, 0xbd, 0x78, 0x32, 0xd0, 0x8c, 0x0a, 0xf4,
305 0xbf, 0xd1, 0x61, 0x86, 0x13, 0x13, 0x3b, 0x83, 0xce, 0xbf, 0x3b, 0xbc,
306 0x8f, 0xf9, 0x4e, 0x50, 0xe3, 0x02, 0x01, 0x02
309 static uint8_t dh_parameters_1024_data
[] = {
310 0x30, 0x81, 0x87, 0x02, 0x81, 0x81, 0x00, 0xd5, 0x06, 0x69, 0xc6, 0xd4,
311 0x98, 0x2b, 0xe3, 0x49, 0xe2, 0xa1, 0x9b, 0x82, 0xaf, 0x3f, 0xaa, 0xc3,
312 0x86, 0x2a, 0x7a, 0xfa, 0x62, 0x12, 0x33, 0x45, 0x9f, 0x34, 0x57, 0xc6,
313 0x6c, 0x88, 0x81, 0xa6, 0x5d, 0xa3, 0x43, 0xe5, 0x4d, 0x87, 0x4f, 0x69,
314 0x3d, 0x2b, 0xc8, 0x18, 0xb6, 0xd7, 0x29, 0x53, 0x94, 0x0d, 0x73, 0x9b,
315 0x08, 0x22, 0x73, 0x84, 0x7b, 0x5a, 0x03, 0x2e, 0xfc, 0x10, 0x9b, 0x35,
316 0xc6, 0xa1, 0xca, 0x36, 0xd0, 0xcc, 0x3e, 0xa2, 0x04, 0x3a, 0x8a, 0xe8,
317 0x87, 0xe8, 0x60, 0x72, 0xee, 0x99, 0xf3, 0x04, 0x0a, 0xd8, 0x1a, 0xe6,
318 0xfc, 0xbc, 0xe1, 0xc5, 0x9d, 0x3a, 0xca, 0xf9, 0xfd, 0xbf, 0x58, 0xd3,
319 0x4d, 0xde, 0x8b, 0x4a, 0xb5, 0x37, 0x1e, 0x6d, 0xf4, 0x22, 0x0f, 0xb7,
320 0x48, 0x0a, 0xda, 0x82, 0x40, 0xc9, 0x55, 0x20, 0x01, 0x3b, 0x35, 0xb2,
321 0x94, 0x68, 0xab, 0x02, 0x01, 0x02
327 const void *dhParams
;
329 } server_dhe_params
[] = {
330 {dh_parameters_256_data
, sizeof(dh_parameters_256_data
)},
331 {dh_parameters_512_data
, sizeof(dh_parameters_512_data
)},
332 {dh_parameters_768_data
, sizeof(dh_parameters_768_data
)},
333 {dh_parameters_1024_data
, sizeof(dh_parameters_1024_data
)},
334 {NULL
, 0}, // default is a 2048
337 static const unsigned n_server_dhe_params
= sizeof(server_dhe_params
)/sizeof(server_dhe_params
[0]);
340 int expected_client_error
[n_server_dhe_params
][n_client_dhe_sizes
] = {
343 // 1024, 512, 512, 768, 1024, 2048, 2048 // Server:
344 { -9850, -9850, -9850, -9850, -9850, -9850, -9850}, // 256
345 { -9850, 0, 0, -9850, -9850, -9850, -9850}, // 512
346 { -9850, 0, 0, 0, -9850, -9850, -9850}, // 768
347 { 0, 0, 0, 0, 0, -9850, -9850}, // 1024
348 { 0, 0, 0, 0, 0, 0, 0}, // default(2048)
354 pthread_t client_thread
, server_thread
;
355 CFArrayRef server_certs
= server_chain();
356 CFArrayRef trusted_ca
= trusted_roots();
358 ok(server_certs
, "got server certs");
359 ok(trusted_ca
, "got trusted roots");
363 for (i
=0; i
<n_server_dhe_params
; i
++) {
364 for (j
=0; j
<n_client_dhe_sizes
; j
++) {
367 if (socketpair(AF_UNIX
, SOCK_STREAM
, 0, sp
)) exit(errno
);
368 fcntl(sp
[0], F_SETNOSIGPIPE
, 1);
369 fcntl(sp
[1], F_SETNOSIGPIPE
, 1);
371 ssl_client_handle
*client
;
372 client
= ssl_client_handle_create(sp
[0], trusted_ca
, client_dhe_sizes
[j
]);
373 ok(client
!=NULL
, "could not create client handle (%d:%d)", i
, j
);
376 ssl_server_handle
*server
;
377 server
= ssl_server_handle_create(sp
[1], server_certs
, server_dhe_params
[i
].dhParams
, server_dhe_params
[i
].dhParamsLen
);
378 ok(server
!=NULL
, "could not create server handle (%d:%d)", i
, j
);
380 pthread_create(&client_thread
, NULL
, securetransport_ssl_client_thread
, client
);
381 pthread_create(&server_thread
, NULL
, securetransport_ssl_server_thread
, server
);
383 intptr_t server_err
, client_err
;
385 pthread_join(client_thread
, (void*)&client_err
);
386 pthread_join(server_thread
, (void*)&server_err
);
389 ok(client_err
==expected_client_error
[i
][j
], "unexpected error %d!=%d (client %d:%d)", (int)client_err
, expected_client_error
[i
][j
], i
, j
);
391 ssl_server_handle_destroy(server
);
392 ssl_client_handle_destroy(client
);
396 CFReleaseSafe(server_certs
);
397 CFReleaseSafe(trusted_ca
);
400 int ssl_54_dhe(int argc
, char *const *argv
)
403 plan_tests(n_server_dhe_params
* n_client_dhe_sizes
* 3 + 2 /*cert*/);