2 * Copyright (c) 2012-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 <CoreFoundation/CoreFoundation.h>
32 #include <AssertMacros.h>
33 #include <Security/SecureTransportPriv.h> /* SSLSetOption */
34 #include <Security/SecureTransport.h>
35 #include <Security/SecPolicy.h>
36 #include <Security/SecTrust.h>
37 #include <Security/SecIdentity.h>
38 #include <Security/SecIdentityPriv.h>
39 #include <Security/SecCertificatePriv.h>
40 #include <Security/SecKeyPriv.h>
41 #include <Security/SecItem.h>
42 #include <Security/SecRandom.h>
45 #include <sys/types.h>
46 #include <sys/socket.h>
49 #include <mach/mach_time.h>
52 #include <Security/SecRSAKey.h>
55 #include "ssl_regressions.h"
56 #include "ssl-utils.h"
69 #pragma mark SecureTransport support
72 static void hexdump(const char *s
, const uint8_t *bytes
, size_t len
) {
74 printf("socket %s(%p, %lu)\n", s
, bytes
, len
);
75 for (ix
= 0; ix
< len
; ++ix
) {
78 printf("%02X ", bytes
[ix
]);
83 #define hexdump(string, bytes, len)
86 static OSStatus
SocketWrite(SSLConnectionRef h
, const void *data
, size_t *length
)
88 int conn
= ((const ssl_test_handle
*)h
)->comm
;
90 uint8_t *ptr
= (uint8_t *)data
;
95 hexdump("write", ptr
, len
);
96 ret
= write((int)conn
, ptr
, len
);
97 } while ((ret
< 0) && (errno
== EAGAIN
|| errno
== EINTR
));
106 *length
= *length
- len
;
107 return errSecSuccess
;
110 static int changepad
=0;
112 static OSStatus
SocketRead(SSLConnectionRef h
, void *data
, size_t *length
)
114 const ssl_test_handle
*handle
=h
;
115 int conn
= handle
->comm
;
116 size_t len
= *length
;
117 uint8_t *ptr
= (uint8_t *)data
;
123 ret
= read((int)conn
, ptr
, len
);
124 } while ((ret
< 0) && (errno
== EAGAIN
|| errno
== EINTR
));
134 printf("Something went wrong here... len=%d\n", (int)len
);
136 *length
= *length
- len
;
140 /* change pad in the data */
143 ptr
[31]=ptr
[31]^0x08^0xff; // expected padding was 8, changing it to 0xff to trigger integer underflow.
146 /* We are reading the server cert */
147 if((*length
==765) && (ptr
[0]==0x0b) && (handle
->test
==3)) {
148 ptr
[0xc] = 0x4; // version = 4 certificate should cause error, but not crash .
151 /* We are reading a data application header */
152 if(*length
==5 && ptr
[0]==0x17) {
153 switch(handle
->test
) {
155 ptr
[4]=32; // reduce the size to 2 blocks and trigger integer underflow.
158 ptr
[4]=48; // reduce the size to 3 blocks and triggering integer underflow in the padding.
169 return errSecSuccess
;
174 static void *securetransport_ssl_thread(void *arg
)
177 ssl_test_handle
* ssl
= (ssl_test_handle
*)arg
;
178 SSLContextRef ctx
= ssl
->st
;
179 bool got_server_auth
= false;
181 //uint64_t start = mach_absolute_time();
183 ortn
= SSLHandshake(ctx
);
185 if (ortn
== errSSLServerAuthCompleted
)
187 require_string(!got_server_auth
, out
, "second server auth");
188 got_server_auth
= true;
190 } while (ortn
== errSSLWouldBlock
191 || ortn
== errSSLServerAuthCompleted
);
193 require_noerr_quiet(ortn
, out
);
195 unsigned char ibuf
[8], obuf
[8];
197 if (ssl
->is_server
) {
198 SecRandomCopyBytes(kSecRandomDefault
, sizeof(obuf
), obuf
);
199 require_noerr_quiet(ortn
= SSLWrite(ctx
, obuf
, sizeof(obuf
), &len
), out
);
200 require_action_quiet(len
== sizeof(obuf
), out
, ortn
= -1);
202 require_noerr_quiet(ortn
= SSLRead(ctx
, ibuf
, sizeof(ibuf
), &len
), out
);
203 require_action_quiet(len
== sizeof(ibuf
), out
, ortn
= -1);
210 pthread_exit((void *)(intptr_t)ortn
);
215 static ssl_test_handle
*
216 ssl_test_handle_create(bool server
, int comm
, CFArrayRef certs
)
218 ssl_test_handle
*handle
= calloc(1, sizeof(ssl_test_handle
));
219 SSLContextRef ctx
= SSLCreateContext(kCFAllocatorDefault
, server
?kSSLServerSide
:kSSLClientSide
, kSSLStreamType
);
221 require(handle
, out
);
224 require_noerr(SSLSetIOFuncs(ctx
,
225 (SSLReadFunc
)SocketRead
, (SSLWriteFunc
)SocketWrite
), out
);
226 require_noerr(SSLSetConnection(ctx
, (SSLConnectionRef
)handle
), out
);
229 require_noerr(SSLSetCertificate(ctx
, certs
), out
);
231 require_noerr(SSLSetSessionOption(ctx
,
232 kSSLSessionOptionBreakOnServerAuth
, true), out
);
234 /* Tell SecureTransport to not check certs itself: it will break out of the
235 handshake to let us take care of it instead. */
236 require_noerr(SSLSetEnableCertVerify(ctx
, false), out
);
238 handle
->is_server
= server
;
240 handle
->certs
= certs
;
246 if (handle
) free(handle
);
247 if (ctx
) CFRelease(ctx
);
254 pthread_t client_thread
, server_thread
;
255 CFArrayRef server_certs
= server_chain();
256 ok(server_certs
, "got server certs");
263 if (socketpair(AF_UNIX
, SOCK_STREAM
, 0, sp
)) exit(errno
);
264 fcntl(sp
[0], F_SETNOSIGPIPE
, 1);
265 fcntl(sp
[1], F_SETNOSIGPIPE
, 1);
267 ssl_test_handle
*server
, *client
;
269 server
= ssl_test_handle_create(true /*server*/, sp
[0], server_certs
);
270 client
= ssl_test_handle_create(false/*client*/, sp
[1], NULL
);
275 require(client
, out
);
276 require(server
, out
);
278 SSLCipherSuite cipher
= TLS_RSA_WITH_AES_128_CBC_SHA256
;
279 require_noerr(SSLSetEnabledCiphers(client
->st
, &cipher
, 1), out
);
281 pthread_create(&client_thread
, NULL
, securetransport_ssl_thread
, client
);
282 pthread_create(&server_thread
, NULL
, securetransport_ssl_thread
, server
);
284 int server_err
, client_err
;
285 pthread_join(client_thread
, (void*)&client_err
);
286 pthread_join(server_thread
, (void*)&server_err
);
288 ok(server_err
==((i
==3)?errSSLClosedGraceful
:0), "Server error = %d", server_err
);
289 /* tests 0/1 should cause errSSLClosedAbort, 2 should cause errSSLBadRecordMac, 3 can be either errSSLXCertChainInvalid or errSSLCrypto */
291 int test_3_expected_error
= errSSLXCertChainInvalid
;
293 int test_3_expected_error
= errSSLBadCert
;
295 ok(client_err
==((i
==3)?test_3_expected_error
:(i
==2)?errSSLBadRecordMac
:errSSLClosedAbort
), "Client error = %d", client_err
);
302 CFReleaseNull(server_certs
);
305 int ssl_44_crashes(int argc
, char *const *argv
)
308 plan_tests(4*2 + 1 /*cert*/);