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>
46 #include <utilities/SecCFRelease.h>
48 #include <sys/types.h>
49 #include <sys/socket.h>
52 #include <mach/mach_time.h>
55 #include <Security/SecRSAKey.h>
58 #include "ssl_regressions.h"
59 #include "ssl-utils.h"
72 #pragma mark SecureTransport support
75 static void hexdump(const char *s
, const uint8_t *bytes
, size_t len
) {
77 printf("socket %s(%p, %lu)\n", s
, bytes
, len
);
78 for (ix
= 0; ix
< len
; ++ix
) {
81 printf("%02X ", bytes
[ix
]);
86 #define hexdump(string, bytes, len)
89 static OSStatus
SocketWrite(SSLConnectionRef h
, const void *data
, size_t *length
)
91 int conn
= ((const ssl_test_handle
*)h
)->comm
;
93 uint8_t *ptr
= (uint8_t *)data
;
98 hexdump("write", ptr
, len
);
99 ret
= write((int)conn
, ptr
, len
);
100 } while ((ret
< 0) && (errno
== EAGAIN
|| errno
== EINTR
));
109 *length
= *length
- len
;
110 return errSecSuccess
;
113 static int changepad
=0;
115 static OSStatus
SocketRead(SSLConnectionRef h
, void *data
, size_t *length
)
117 const ssl_test_handle
*handle
=h
;
118 int conn
= handle
->comm
;
119 size_t len
= *length
;
120 uint8_t *ptr
= (uint8_t *)data
;
126 ret
= read((int)conn
, ptr
, len
);
127 } while ((ret
< 0) && (errno
== EAGAIN
|| errno
== EINTR
));
137 printf("Something went wrong here... len=%d\n", (int)len
);
139 *length
= *length
- len
;
143 /* change pad in the data */
146 ptr
[31]=ptr
[31]^0x08^0xff; // expected padding was 8, changing it to 0xff to trigger integer underflow.
149 /* We are reading the server cert */
150 if((ptr
[0]==0x0b) && (handle
->test
==3)) {
151 #if 1 // cert length for TARGET_OS_IPHONE
152 size_t expected_len
= 631;
154 size_t expected_len
= 500;
156 if(*length
!=expected_len
) {
157 fprintf(stderr
, "Expected cert length %ld, got %ld... test might fail\n",
158 (long)expected_len
, (long)*length
);
160 ptr
[0x16] = 0x4; // version = 4 certificate should cause error, but not crash .
163 /* We are reading a data application header */
164 if(*length
==5 && ptr
[0]==0x17) {
165 switch(handle
->test
) {
167 ptr
[4]=32; // reduce the size to 2 blocks and trigger integer underflow.
170 ptr
[4]=48; // reduce the size to 3 blocks and triggering integer underflow in the padding.
181 return errSecSuccess
;
186 static void *securetransport_ssl_thread(void *arg
)
189 ssl_test_handle
* ssl
= (ssl_test_handle
*)arg
;
190 SSLContextRef ctx
= ssl
->st
;
191 bool got_server_auth
= false;
193 //uint64_t start = mach_absolute_time();
195 ortn
= SSLHandshake(ctx
);
197 if (ortn
== errSSLServerAuthCompleted
)
199 require_string(!got_server_auth
, out
, "second server auth");
200 got_server_auth
= true;
202 } while (ortn
== errSSLWouldBlock
203 || ortn
== errSSLServerAuthCompleted
);
205 require_noerr_quiet(ortn
, out
);
207 unsigned char ibuf
[8], obuf
[8];
209 if (ssl
->is_server
) {
210 require_action_quiet(errSecSuccess
==SecRandomCopyBytes(kSecRandomDefault
, sizeof(obuf
), obuf
), out
, ortn
= -1);
211 require_noerr_quiet(ortn
= SSLWrite(ctx
, obuf
, sizeof(obuf
), &len
), out
);
212 require_action_quiet(len
== sizeof(obuf
), out
, ortn
= -1);
214 require_noerr_quiet(ortn
= SSLRead(ctx
, ibuf
, sizeof(ibuf
), &len
), out
);
215 require_action_quiet(len
== sizeof(ibuf
), out
, ortn
= -1);
222 pthread_exit((void *)(intptr_t)ortn
);
227 static ssl_test_handle
*
228 ssl_test_handle_create(bool server
, int comm
, CFArrayRef certs
)
230 ssl_test_handle
*handle
= calloc(1, sizeof(ssl_test_handle
));
231 SSLContextRef ctx
= SSLCreateContext(kCFAllocatorDefault
, server
?kSSLServerSide
:kSSLClientSide
, kSSLStreamType
);
233 require(handle
, out
);
236 require_noerr(SSLSetIOFuncs(ctx
,
237 (SSLReadFunc
)SocketRead
, (SSLWriteFunc
)SocketWrite
), out
);
238 require_noerr(SSLSetConnection(ctx
, (SSLConnectionRef
)handle
), out
);
241 require_noerr(SSLSetCertificate(ctx
, certs
), out
);
243 require_noerr(SSLSetSessionOption(ctx
,
244 kSSLSessionOptionBreakOnServerAuth
, true), out
);
246 /* Tell SecureTransport to not check certs itself: it will break out of the
247 handshake to let us take care of it instead. */
248 require_noerr(SSLSetEnableCertVerify(ctx
, false), out
);
250 handle
->is_server
= server
;
252 handle
->certs
= certs
;
258 if (handle
) free(handle
);
259 if (ctx
) CFRelease(ctx
);
266 pthread_t client_thread
, server_thread
;
267 CFArrayRef server_certs
= server_chain();
268 ok(server_certs
, "got server certs");
275 if (socketpair(AF_UNIX
, SOCK_STREAM
, 0, sp
)) exit(errno
);
276 fcntl(sp
[0], F_SETNOSIGPIPE
, 1);
277 fcntl(sp
[1], F_SETNOSIGPIPE
, 1);
279 ssl_test_handle
*server
, *client
;
281 server
= ssl_test_handle_create(true /*server*/, sp
[0], server_certs
);
282 client
= ssl_test_handle_create(false/*client*/, sp
[1], NULL
);
287 require(client
, out
);
288 require(server
, out
);
290 SSLCipherSuite cipher
= TLS_RSA_WITH_AES_128_CBC_SHA256
;
291 require_noerr(SSLSetEnabledCiphers(client
->st
, &cipher
, 1), out
);
293 pthread_create(&client_thread
, NULL
, securetransport_ssl_thread
, client
);
294 pthread_create(&server_thread
, NULL
, securetransport_ssl_thread
, server
);
296 intptr_t server_err
, client_err
;
297 pthread_join(client_thread
, (void*)&client_err
);
298 pthread_join(server_thread
, (void*)&server_err
);
300 ok(server_err
==((i
==3)?errSSLPeerCertUnknown
:0), "Server error = %zu (i=%d)", server_err
, i
);
301 /* tests 0/1 should cause errSSLClosedAbort, 2 should cause errSSLBadRecordMac, 3 should cause errSSLXCertChainInvalid */
302 ok(client_err
==((i
==3)?errSSLXCertChainInvalid
:(i
==2)?errSSLBadRecordMac
:errSSLClosedAbort
), "Client error = %zu (i=%d)", client_err
, i
);
309 CFReleaseNull(server_certs
);
312 int ssl_44_crashes(int argc
, char *const *argv
)
315 plan_tests(4*2 + 1 /*cert*/);