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>
24 #include <sys/types.h>
25 #include <sys/socket.h>
28 #include <mach/mach_time.h>
31 #include <Security/SecRSAKey.h>
34 #include "ssl_regressions.h"
35 #include "ssl-utils.h"
40 Test both the client and server side.
43 - Make sure that handshake fail when dh param size is too small.
46 - handshake pass or fail
51 static OSStatus
SocketWrite(SSLConnectionRef conn
, const void *data
, size_t *length
)
54 uint8_t *ptr
= (uint8_t *)data
;
59 ret
= write((int)conn
, ptr
, len
);
60 } while ((ret
< 0) && (errno
== EAGAIN
|| errno
== EINTR
));
69 *length
= *length
- len
;
73 static OSStatus
SocketRead(SSLConnectionRef conn
, void *data
, size_t *length
)
76 uint8_t *ptr
= (uint8_t *)data
;
81 ret
= read((int)conn
, ptr
, len
);
82 } while ((ret
< 0) && (errno
== EINPROGRESS
|| errno
== EAGAIN
|| errno
== EINTR
));
87 printf("read error(%d): ret=%zd, errno=%d\n", (int)conn
, ret
, errno
);
92 *length
= *length
- len
;
102 static ssl_client_handle
*
103 ssl_client_handle_create(int comm
, CFArrayRef trustedCA
, unsigned dhe_size
)
105 ssl_client_handle
*handle
= calloc(1, sizeof(ssl_client_handle
));
106 SSLContextRef ctx
= SSLCreateContext(kCFAllocatorDefault
, kSSLClientSide
, kSSLStreamType
);
108 require(handle
, out
);
111 require_noerr(SSLSetIOFuncs(ctx
,
112 (SSLReadFunc
)SocketRead
, (SSLWriteFunc
)SocketWrite
), out
);
113 require_noerr(SSLSetConnection(ctx
, (SSLConnectionRef
)(intptr_t)comm
), out
);
114 static const char *peer_domain_name
= "localhost";
115 require_noerr(SSLSetPeerDomainName(ctx
, peer_domain_name
,
116 strlen(peer_domain_name
)), out
);
118 require_noerr(SSLSetTrustedRoots(ctx
, trustedCA
, true), out
);
120 require_noerr(SSLSetDHEEnabled(ctx
, true), out
);
123 require_noerr(SSLSetMinimumDHGroupSize(ctx
, dhe_size
), out
);
127 handle
->dhe_size
= dhe_size
;
141 ssl_client_handle_destroy(ssl_client_handle
*handle
)
144 SSLClose(handle
->st
);
145 CFRelease(handle
->st
);
150 static void *securetransport_ssl_client_thread(void *arg
)
153 ssl_client_handle
* ssl
= (ssl_client_handle
*)arg
;
154 SSLContextRef ctx
= ssl
->st
;
155 SSLSessionState ssl_state
;
157 pthread_setname_np("client thread");
159 require_noerr(ortn
=SSLGetSessionState(ctx
,&ssl_state
), out
);
160 require_action(ssl_state
==kSSLIdle
, out
, ortn
= -1);
163 ortn
= SSLHandshake(ctx
);
164 require_noerr(SSLGetSessionState(ctx
,&ssl_state
), out
);
166 if (ortn
== errSSLWouldBlock
) {
167 require_string(ssl_state
==kSSLHandshake
, out
, "Wrong client handshake state after errSSLWouldBlock");
169 } while (ortn
== errSSLWouldBlock
);
174 pthread_exit((void *)(intptr_t)ortn
);
186 static ssl_server_handle
*
187 ssl_server_handle_create(int comm
, CFArrayRef certs
, const void *dhParams
, size_t dhParamsLen
)
189 ssl_server_handle
*handle
= calloc(1, sizeof(ssl_server_handle
));
190 SSLContextRef ctx
= SSLCreateContext(kCFAllocatorDefault
, kSSLServerSide
, kSSLStreamType
);
191 SSLCipherSuite cipher
= TLS_DHE_RSA_WITH_AES_256_CBC_SHA256
;
193 require(handle
, out
);
196 require_noerr(SSLSetIOFuncs(ctx
,
197 (SSLReadFunc
)SocketRead
, (SSLWriteFunc
)SocketWrite
), out
);
198 require_noerr(SSLSetConnection(ctx
, (SSLConnectionRef
)(intptr_t)comm
), out
);
200 require_noerr(SSLSetCertificate(ctx
, certs
), out
);
202 require_noerr(SSLSetEnabledCiphers(ctx
, &cipher
, 1), out
);
205 require_noerr(SSLSetDiffieHellmanParams(ctx
, dhParams
, dhParamsLen
), out
);
208 handle
->certs
= certs
;
223 ssl_server_handle_destroy(ssl_server_handle
*handle
)
226 SSLClose(handle
->st
);
227 CFRelease(handle
->st
);
232 static void *securetransport_ssl_server_thread(void *arg
)
235 ssl_server_handle
* ssl
= (ssl_server_handle
*)arg
;
236 SSLContextRef ctx
= ssl
->st
;
237 SSLSessionState ssl_state
;
239 pthread_setname_np("server thread");
241 require_noerr(ortn
=SSLGetSessionState(ctx
,&ssl_state
), out
);
242 require_action(ssl_state
==kSSLIdle
, out
, ortn
= -1);
245 ortn
= SSLHandshake(ctx
);
246 require_noerr(SSLGetSessionState(ctx
,&ssl_state
), out
);
248 if (ortn
== errSSLWouldBlock
) {
249 require_action(ssl_state
==kSSLHandshake
, out
, ortn
= -1);
251 } while (ortn
== errSSLWouldBlock
);
253 require_noerr_quiet(ortn
, out
);
255 require_action(ssl_state
==kSSLConnected
, out
, ortn
= -1);
260 pthread_exit((void *)(intptr_t)ortn
);
267 unsigned client_dhe_sizes
[] = {
268 0, // default, don't set.
269 256, // will resolve to 512.
274 4096, // will resolve to 2048.
278 static const unsigned n_client_dhe_sizes
= sizeof(client_dhe_sizes
)/sizeof(client_dhe_sizes
[0]);
280 static uint8_t dh_parameters_256_data
[] = {
281 0x30, 0x26, 0x02, 0x21, 0x00, 0xd8, 0x23, 0xeb, 0xcb, 0x41, 0xd0, 0x3a,
282 0xc4, 0x9a, 0x2a, 0x2a, 0x4f, 0x35, 0xf7, 0x4f, 0xd9, 0xc5, 0x2e, 0xf8,
283 0x44, 0xa7, 0x74, 0xe3, 0x84, 0x98, 0x9f, 0xad, 0x58, 0xd5, 0x15, 0xb4,
284 0xf3, 0x02, 0x01, 0x02
287 static uint8_t dh_parameters_512_data
[] = {
288 0x30, 0x46, 0x02, 0x41, 0x00, 0x85, 0xcd, 0xc1, 0x7e, 0x26, 0xeb, 0x37,
289 0x84, 0x13, 0xd0, 0x3b, 0x07, 0xc1, 0x57, 0x7d, 0xf3, 0x55, 0x8d, 0xa0,
290 0xc4, 0xa5, 0x03, 0xc4, 0x2c, 0xc6, 0xd5, 0xa6, 0x31, 0xcb, 0x68, 0xdf,
291 0x5d, 0x96, 0x20, 0x1a, 0x15, 0x57, 0x49, 0x7d, 0xd7, 0x51, 0x65, 0x6e,
292 0x37, 0xa8, 0xe3, 0xe9, 0xe1, 0x59, 0x2e, 0xd4, 0x57, 0x4a, 0xf0, 0xcb,
293 0x0e, 0x85, 0x07, 0xdd, 0x35, 0xa7, 0xe3, 0xc6, 0xbb, 0x02, 0x01, 0x02
296 static uint8_t dh_parameters_768_data
[] = {
297 0x30, 0x66, 0x02, 0x61, 0x00, 0xe1, 0xa2, 0x50, 0xab, 0xb0, 0xdc, 0xef,
298 0xe1, 0x2f, 0xd9, 0xde, 0x59, 0x86, 0x24, 0x43, 0x3b, 0xf3, 0x40, 0x9d,
299 0x02, 0xcc, 0xe2, 0x70, 0x63, 0x46, 0x8d, 0x0f, 0xf3, 0x8a, 0xc6, 0xa0,
300 0x1d, 0x7b, 0x30, 0x83, 0x10, 0x48, 0x40, 0x28, 0xa4, 0x3e, 0xbe, 0x4d,
301 0xb6, 0xea, 0x90, 0x02, 0xae, 0x25, 0x93, 0xc0, 0xe8, 0x36, 0x5c, 0xc8,
302 0xc8, 0x0b, 0x04, 0xd5, 0x05, 0xac, 0x67, 0x24, 0x4b, 0xa9, 0x42, 0x5a,
303 0x03, 0x65, 0x4d, 0xd0, 0xc0, 0xbd, 0x78, 0x32, 0xd0, 0x8c, 0x0a, 0xf4,
304 0xbf, 0xd1, 0x61, 0x86, 0x13, 0x13, 0x3b, 0x83, 0xce, 0xbf, 0x3b, 0xbc,
305 0x8f, 0xf9, 0x4e, 0x50, 0xe3, 0x02, 0x01, 0x02
308 static uint8_t dh_parameters_1024_data
[] = {
309 0x30, 0x81, 0x87, 0x02, 0x81, 0x81, 0x00, 0xd5, 0x06, 0x69, 0xc6, 0xd4,
310 0x98, 0x2b, 0xe3, 0x49, 0xe2, 0xa1, 0x9b, 0x82, 0xaf, 0x3f, 0xaa, 0xc3,
311 0x86, 0x2a, 0x7a, 0xfa, 0x62, 0x12, 0x33, 0x45, 0x9f, 0x34, 0x57, 0xc6,
312 0x6c, 0x88, 0x81, 0xa6, 0x5d, 0xa3, 0x43, 0xe5, 0x4d, 0x87, 0x4f, 0x69,
313 0x3d, 0x2b, 0xc8, 0x18, 0xb6, 0xd7, 0x29, 0x53, 0x94, 0x0d, 0x73, 0x9b,
314 0x08, 0x22, 0x73, 0x84, 0x7b, 0x5a, 0x03, 0x2e, 0xfc, 0x10, 0x9b, 0x35,
315 0xc6, 0xa1, 0xca, 0x36, 0xd0, 0xcc, 0x3e, 0xa2, 0x04, 0x3a, 0x8a, 0xe8,
316 0x87, 0xe8, 0x60, 0x72, 0xee, 0x99, 0xf3, 0x04, 0x0a, 0xd8, 0x1a, 0xe6,
317 0xfc, 0xbc, 0xe1, 0xc5, 0x9d, 0x3a, 0xca, 0xf9, 0xfd, 0xbf, 0x58, 0xd3,
318 0x4d, 0xde, 0x8b, 0x4a, 0xb5, 0x37, 0x1e, 0x6d, 0xf4, 0x22, 0x0f, 0xb7,
319 0x48, 0x0a, 0xda, 0x82, 0x40, 0xc9, 0x55, 0x20, 0x01, 0x3b, 0x35, 0xb2,
320 0x94, 0x68, 0xab, 0x02, 0x01, 0x02
326 const void *dhParams
;
328 } server_dhe_params
[] = {
329 {dh_parameters_256_data
, sizeof(dh_parameters_256_data
)},
330 {dh_parameters_512_data
, sizeof(dh_parameters_512_data
)},
331 {dh_parameters_768_data
, sizeof(dh_parameters_768_data
)},
332 {dh_parameters_1024_data
, sizeof(dh_parameters_1024_data
)},
333 {NULL
, 0}, // default is a 2048
336 static const unsigned n_server_dhe_params
= sizeof(server_dhe_params
)/sizeof(server_dhe_params
[0]);
339 int expected_client_error
[n_server_dhe_params
][n_client_dhe_sizes
] = {
342 // 1024, 512, 512, 768, 1024, 2048, 2048 // Server:
343 { -9850, -9850, -9850, -9850, -9850, -9850, -9850}, // 256
344 { -9850, 0, 0, -9850, -9850, -9850, -9850}, // 512
345 { -9850, 0, 0, 0, -9850, -9850, -9850}, // 768
346 { 0, 0, 0, 0, 0, -9850, -9850}, // 1024
347 { 0, 0, 0, 0, 0, 0, 0}, // default(2048)
353 pthread_t client_thread
, server_thread
;
354 CFArrayRef server_certs
= server_chain();
355 CFArrayRef trusted_ca
= trusted_roots();
357 ok(server_certs
, "got server certs");
358 ok(trusted_ca
, "got trusted roots");
362 for (i
=0; i
<n_server_dhe_params
; i
++) {
363 for (j
=0; j
<n_client_dhe_sizes
; j
++) {
366 if (socketpair(AF_UNIX
, SOCK_STREAM
, 0, sp
)) exit(errno
);
367 fcntl(sp
[0], F_SETNOSIGPIPE
, 1);
368 fcntl(sp
[1], F_SETNOSIGPIPE
, 1);
370 ssl_client_handle
*client
;
371 client
= ssl_client_handle_create(sp
[0], trusted_ca
, client_dhe_sizes
[j
]);
372 ok(client
!=NULL
, "could not create client handle (%d:%d)", i
, j
);
375 ssl_server_handle
*server
;
376 server
= ssl_server_handle_create(sp
[1], server_certs
, server_dhe_params
[i
].dhParams
, server_dhe_params
[i
].dhParamsLen
);
377 ok(server
!=NULL
, "could not create server handle (%d:%d)", i
, j
);
379 pthread_create(&client_thread
, NULL
, securetransport_ssl_client_thread
, client
);
380 pthread_create(&server_thread
, NULL
, securetransport_ssl_server_thread
, server
);
382 intptr_t server_err
, client_err
;
384 pthread_join(client_thread
, (void*)&client_err
);
385 pthread_join(server_thread
, (void*)&server_err
);
388 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
);
390 ssl_server_handle_destroy(server
);
391 ssl_client_handle_destroy(client
);
398 CFReleaseSafe(server_certs
);
399 CFReleaseSafe(trusted_ca
);
402 int ssl_54_dhe(int argc
, char *const *argv
)
405 plan_tests(n_server_dhe_params
* n_client_dhe_sizes
* 3 + 2 /*cert*/);