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@
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 a data application header */
149 if(*length
==5 && ptr
[0]==0x17) {
150 switch(handle
->test
) {
152 ptr
[4]=32; // reduce the size to 2 blocks and trigger integer underflow.
155 ptr
[4]=48; // reduce the size to 3 blocks and triggering integer underflow in the padding.
166 return errSecSuccess
;
171 static void *securetransport_ssl_thread(void *arg
)
174 ssl_test_handle
* ssl
= (ssl_test_handle
*)arg
;
175 SSLContextRef ctx
= ssl
->st
;
176 bool got_server_auth
= false;
178 //uint64_t start = mach_absolute_time();
180 ortn
= SSLHandshake(ctx
);
182 if (ortn
== errSSLServerAuthCompleted
)
184 require_string(!got_server_auth
, out
, "second server auth");
185 got_server_auth
= true;
187 } while (ortn
== errSSLWouldBlock
188 || ortn
== errSSLServerAuthCompleted
);
190 require_noerr_action_quiet(ortn
, out
,
191 fprintf(stderr
, "Fell out of SSLHandshake with error: %d\n", (int)ortn
));
193 unsigned char ibuf
[8], obuf
[8];
195 if (ssl
->is_server
) {
196 SecRandomCopyBytes(kSecRandomDefault
, sizeof(obuf
), obuf
);
197 require_noerr_quiet(ortn
= SSLWrite(ctx
, obuf
, sizeof(obuf
), &len
), out
);
198 require_action_quiet(len
== sizeof(obuf
), out
, ortn
= -1);
200 require_noerr_quiet(ortn
= SSLRead(ctx
, ibuf
, sizeof(ibuf
), &len
), out
);
201 require_action_quiet(len
== sizeof(ibuf
), out
, ortn
= -1);
208 pthread_exit((void *)(intptr_t)ortn
);
213 static ssl_test_handle
*
214 ssl_test_handle_create(bool server
, int comm
, CFArrayRef certs
)
216 ssl_test_handle
*handle
= calloc(1, sizeof(ssl_test_handle
));
217 SSLContextRef ctx
= SSLCreateContext(kCFAllocatorDefault
, server
?kSSLServerSide
:kSSLClientSide
, kSSLStreamType
);
219 require(handle
, out
);
222 require_noerr(SSLSetIOFuncs(ctx
,
223 (SSLReadFunc
)SocketRead
, (SSLWriteFunc
)SocketWrite
), out
);
224 require_noerr(SSLSetConnection(ctx
, (SSLConnectionRef
)handle
), out
);
227 require_noerr(SSLSetCertificate(ctx
, certs
), out
);
229 require_noerr(SSLSetSessionOption(ctx
,
230 kSSLSessionOptionBreakOnServerAuth
, true), out
);
232 /* Tell SecureTransport to not check certs itself: it will break out of the
233 handshake to let us take care of it instead. */
234 require_noerr(SSLSetEnableCertVerify(ctx
, false), out
);
236 handle
->is_server
= server
;
238 handle
->certs
= certs
;
244 if (handle
) free(handle
);
245 if (ctx
) CFRelease(ctx
);
252 pthread_t client_thread
, server_thread
;
253 CFArrayRef server_certs
= server_chain();
254 ok(server_certs
, "got server certs");
261 if (socketpair(AF_UNIX
, SOCK_STREAM
, 0, sp
)) exit(errno
);
262 fcntl(sp
[0], F_SETNOSIGPIPE
, 1);
263 fcntl(sp
[1], F_SETNOSIGPIPE
, 1);
265 ssl_test_handle
*server
, *client
;
267 server
= ssl_test_handle_create(true /*server*/, sp
[0], server_certs
);
268 client
= ssl_test_handle_create(false/*client*/, sp
[1], NULL
);
273 require(client
, out
);
274 require(server
, out
);
276 SSLCipherSuite cipher
= TLS_RSA_WITH_AES_128_CBC_SHA256
;
277 require_noerr(SSLSetEnabledCiphers(client
->st
, &cipher
, 1), out
);
279 pthread_create(&client_thread
, NULL
, securetransport_ssl_thread
, client
);
280 pthread_create(&server_thread
, NULL
, securetransport_ssl_thread
, server
);
282 int server_err
, client_err
;
283 pthread_join(client_thread
, (void*)&client_err
);
284 pthread_join(server_thread
, (void*)&server_err
);
287 ok(!server_err
, "Server error = %d", server_err
);
288 /* tests 0/1 should cause errSSLClosedAbort, 2 should cause errSSLBadRecordMac */
289 ok(client_err
==((i
==2)?errSSLBadRecordMac
:errSSLClosedAbort
), "Client error = %d", client_err
);
296 CFReleaseNull(server_certs
);
299 int ssl_44_crashes(int argc
, char *const *argv
)
302 plan_tests(3*2 + 1 /*cert*/);