2 * Copyright (c) 2012-2015 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@
32 #include <CoreFoundation/CoreFoundation.h>
34 #include <AssertMacros.h>
35 #include <Security/SecureTransportPriv.h> /* SSLSetOption */
36 #include <Security/SecureTransport.h>
37 #include <Security/SecPolicy.h>
38 #include <Security/SecTrust.h>
39 #include <Security/SecIdentity.h>
40 #include <Security/SecIdentityPriv.h>
41 #include <Security/SecCertificatePriv.h>
42 #include <Security/SecKeyPriv.h>
43 #include <Security/SecItem.h>
44 #include <Security/SecRandom.h>
47 #include <sys/types.h>
48 #include <sys/socket.h>
51 #include <mach/mach_time.h>
54 #include <Security/SecRSAKey.h>
57 #include "ssl_regressions.h"
58 #include "ssl-utils.h"
71 #pragma mark SecureTransport support
74 static void hexdump(const char *s
, const uint8_t *bytes
, size_t len
) {
76 printf("socket %s(%p, %lu)\n", s
, bytes
, len
);
77 for (ix
= 0; ix
< len
; ++ix
) {
80 printf("%02X ", bytes
[ix
]);
85 #define hexdump(string, bytes, len)
88 static OSStatus
SocketWrite(SSLConnectionRef h
, const void *data
, size_t *length
)
90 int conn
= ((const ssl_test_handle
*)h
)->comm
;
92 uint8_t *ptr
= (uint8_t *)data
;
97 hexdump("write", ptr
, len
);
98 ret
= write((int)conn
, ptr
, len
);
99 } while ((ret
< 0) && (errno
== EAGAIN
|| errno
== EINTR
));
108 *length
= *length
- len
;
109 return errSecSuccess
;
112 static int changepad
=0;
114 static OSStatus
SocketRead(SSLConnectionRef h
, void *data
, size_t *length
)
116 const ssl_test_handle
*handle
=h
;
117 int conn
= handle
->comm
;
118 size_t len
= *length
;
119 uint8_t *ptr
= (uint8_t *)data
;
125 ret
= read((int)conn
, ptr
, len
);
126 } while ((ret
< 0) && (errno
== EAGAIN
|| errno
== EINTR
));
136 printf("Something went wrong here... len=%d\n", (int)len
);
138 *length
= *length
- len
;
142 /* change pad in the data */
145 ptr
[31]=ptr
[31]^0x08^0xff; // expected padding was 8, changing it to 0xff to trigger integer underflow.
148 /* We are reading the server cert */
149 if((ptr
[0]==0x0b) && (handle
->test
==3)) {
150 #if 1 // cert length for TARGET_OS_IPHONE
151 size_t expected_len
= 631;
153 size_t expected_len
= 500;
155 if(*length
!=expected_len
) {
156 fprintf(stderr
, "Expected cert length %ld, got %ld... test might fail\n",
157 (long)expected_len
, (long)*length
);
159 ptr
[0x16] = 0x4; // version = 4 certificate should cause error, but not crash .
162 /* We are reading a data application header */
163 if(*length
==5 && ptr
[0]==0x17) {
164 switch(handle
->test
) {
166 ptr
[4]=32; // reduce the size to 2 blocks and trigger integer underflow.
169 ptr
[4]=48; // reduce the size to 3 blocks and triggering integer underflow in the padding.
180 return errSecSuccess
;
185 static void *securetransport_ssl_thread(void *arg
)
188 ssl_test_handle
* ssl
= (ssl_test_handle
*)arg
;
189 SSLContextRef ctx
= ssl
->st
;
190 bool got_server_auth
= false;
192 //uint64_t start = mach_absolute_time();
194 ortn
= SSLHandshake(ctx
);
196 if (ortn
== errSSLServerAuthCompleted
)
198 require_string(!got_server_auth
, out
, "second server auth");
199 got_server_auth
= true;
201 } while (ortn
== errSSLWouldBlock
202 || ortn
== errSSLServerAuthCompleted
);
204 require_noerr_quiet(ortn
, out
);
206 unsigned char ibuf
[8], obuf
[8];
208 if (ssl
->is_server
) {
209 SecRandomCopyBytes(kSecRandomDefault
, sizeof(obuf
), obuf
);
210 require_noerr_quiet(ortn
= SSLWrite(ctx
, obuf
, sizeof(obuf
), &len
), out
);
211 require_action_quiet(len
== sizeof(obuf
), out
, ortn
= -1);
213 require_noerr_quiet(ortn
= SSLRead(ctx
, ibuf
, sizeof(ibuf
), &len
), out
);
214 require_action_quiet(len
== sizeof(ibuf
), out
, ortn
= -1);
221 pthread_exit((void *)(intptr_t)ortn
);
226 static ssl_test_handle
*
227 ssl_test_handle_create(bool server
, int comm
, CFArrayRef certs
)
229 ssl_test_handle
*handle
= calloc(1, sizeof(ssl_test_handle
));
230 SSLContextRef ctx
= SSLCreateContext(kCFAllocatorDefault
, server
?kSSLServerSide
:kSSLClientSide
, kSSLStreamType
);
232 require(handle
, out
);
235 require_noerr(SSLSetIOFuncs(ctx
,
236 (SSLReadFunc
)SocketRead
, (SSLWriteFunc
)SocketWrite
), out
);
237 require_noerr(SSLSetConnection(ctx
, (SSLConnectionRef
)handle
), out
);
240 require_noerr(SSLSetCertificate(ctx
, certs
), out
);
242 require_noerr(SSLSetSessionOption(ctx
,
243 kSSLSessionOptionBreakOnServerAuth
, true), out
);
245 /* Tell SecureTransport to not check certs itself: it will break out of the
246 handshake to let us take care of it instead. */
247 require_noerr(SSLSetEnableCertVerify(ctx
, false), out
);
249 handle
->is_server
= server
;
251 handle
->certs
= certs
;
257 if (handle
) free(handle
);
258 if (ctx
) CFRelease(ctx
);
265 pthread_t client_thread
, server_thread
;
266 CFArrayRef server_certs
= server_chain();
267 ok(server_certs
, "got server certs");
274 if (socketpair(AF_UNIX
, SOCK_STREAM
, 0, sp
)) exit(errno
);
275 fcntl(sp
[0], F_SETNOSIGPIPE
, 1);
276 fcntl(sp
[1], F_SETNOSIGPIPE
, 1);
278 ssl_test_handle
*server
, *client
;
280 server
= ssl_test_handle_create(true /*server*/, sp
[0], server_certs
);
281 client
= ssl_test_handle_create(false/*client*/, sp
[1], NULL
);
286 require(client
, out
);
287 require(server
, out
);
289 SSLCipherSuite cipher
= TLS_RSA_WITH_AES_128_CBC_SHA256
;
290 require_noerr(SSLSetEnabledCiphers(client
->st
, &cipher
, 1), out
);
292 pthread_create(&client_thread
, NULL
, securetransport_ssl_thread
, client
);
293 pthread_create(&server_thread
, NULL
, securetransport_ssl_thread
, server
);
295 int server_err
, client_err
;
296 pthread_join(client_thread
, (void*)&client_err
);
297 pthread_join(server_thread
, (void*)&server_err
);
299 // errors expected for TARGET_OS_IPHONE implementation
300 int expected_client_error3
= errSSLBadCert
;
301 int expected_server_error3
= errSSLClosedGraceful
;
303 // allow OS X errors if we are not yet using unified SecTrust
304 if (server_err
== errSSLProtocol
) { expected_server_error3
= errSSLProtocol
; }
305 if (client_err
== errSSLIllegalParam
) { expected_client_error3
= errSSLIllegalParam
; }
307 ok(server_err
==((i
==3)?expected_server_error3
:0), "Server error = %d (i=%d)", server_err
, i
);
308 /* tests 0/1 should cause errSSLClosedAbort, 2 should cause errSSLBadRecordMac, 3 should cause errSSLBadCert */
309 ok(client_err
==((i
==3)?expected_client_error3
:(i
==2)?errSSLBadRecordMac
:errSSLClosedAbort
), "Client error = %d (i=%d)", client_err
, i
);
316 CFReleaseNull(server_certs
);
319 int ssl_44_crashes(int argc
, char *const *argv
)
322 plan_tests(4*2 + 1 /*cert*/);