5 // Created by Fabrice Gautier on 10/1/12.
16 #include <CoreFoundation/CoreFoundation.h>
18 #include <AssertMacros.h>
19 #include <Security/SecureTransportPriv.h> /* SSLSetOption */
20 #include <Security/SecureTransport.h>
21 #include <Security/SecPolicy.h>
22 #include <Security/SecTrust.h>
23 #include <Security/SecIdentity.h>
24 #include <Security/SecIdentityPriv.h>
25 #include <Security/SecCertificatePriv.h>
26 #include <Security/SecKeyPriv.h>
27 #include <Security/SecItem.h>
28 #include <Security/SecRandom.h>
31 #include <sys/types.h>
32 #include <sys/socket.h>
35 #include <mach/mach_time.h>
38 #include <Security/SecRSAKey.h>
41 #include "ssl_regressions.h"
42 #include "ssl-utils.h"
55 #pragma mark SecureTransport support
58 static void hexdump(const uint8_t *bytes
, size_t len
) {
60 printf("socket write(%p, %lu)\n", bytes
, len
);
61 for (ix
= 0; ix
< len
; ++ix
) {
64 printf("%02X ", bytes
[ix
]);
69 #define hexdump(bytes, len)
72 static OSStatus
SocketWrite(SSLConnectionRef h
, const void *data
, size_t *length
)
74 int conn
= ((const ssl_test_handle
*)h
)->comm
;
76 uint8_t *ptr
= (uint8_t *)data
;
82 ret
= write((int)conn
, ptr
, len
);
83 } while ((ret
< 0) && (errno
== EAGAIN
|| errno
== EINTR
));
92 *length
= *length
- len
;
96 static int changepad
=0;
98 static OSStatus
SocketRead(SSLConnectionRef h
, void *data
, size_t *length
)
100 const ssl_test_handle
*handle
=h
;
101 int conn
= handle
->comm
;
102 size_t len
= *length
;
103 uint8_t *ptr
= (uint8_t *)data
;
109 ret
= read((int)conn
, ptr
, len
);
110 } while ((ret
< 0) && (errno
== EAGAIN
|| errno
== EINTR
));
120 printf("Something went wrong here... len=%d\n", (int)len
);
122 *length
= *length
- len
;
126 /* change pad in the data */
129 ptr
[31]=ptr
[31]^0x08^0xff; // expected padding was 8, changing it to 0xff to trigger integer underflow.
132 /* We are reading a data application header */
133 if(*length
==5 && ptr
[0]==0x17) {
134 switch(handle
->test
) {
136 ptr
[4]=32; // reduce the size to 2 blocks and trigger integer underflow.
139 ptr
[4]=48; // reduce the size to 3 blocks and triggering integer underflow in the padding.
150 return errSecSuccess
;
155 static void *securetransport_ssl_thread(void *arg
)
158 ssl_test_handle
* ssl
= (ssl_test_handle
*)arg
;
159 SSLContextRef ctx
= ssl
->st
;
160 bool got_server_auth
= false;
162 //uint64_t start = mach_absolute_time();
164 ortn
= SSLHandshake(ctx
);
166 if (ortn
== errSSLServerAuthCompleted
)
168 require_string(!got_server_auth
, out
, "second server auth");
169 got_server_auth
= true;
171 } while (ortn
== errSSLWouldBlock
172 || ortn
== errSSLServerAuthCompleted
);
174 require_noerr_action_quiet(ortn
, out
,
175 fprintf(stderr
, "Fell out of SSLHandshake with error: %d\n", (int)ortn
));
177 unsigned char ibuf
[8], obuf
[8];
179 if (ssl
->is_server
) {
180 SecRandomCopyBytes(kSecRandomDefault
, sizeof(obuf
), obuf
);
181 require_noerr_quiet(ortn
= SSLWrite(ctx
, obuf
, sizeof(obuf
), &len
), out
);
182 require_action_quiet(len
== sizeof(obuf
), out
, ortn
= -1);
184 require_noerr_quiet(ortn
= SSLRead(ctx
, ibuf
, sizeof(ibuf
), &len
), out
);
185 require_action_quiet(len
== sizeof(ibuf
), out
, ortn
= -1);
192 pthread_exit((void *)(intptr_t)ortn
);
197 static ssl_test_handle
*
198 ssl_test_handle_create(bool server
, int comm
, CFArrayRef certs
)
200 ssl_test_handle
*handle
= calloc(1, sizeof(ssl_test_handle
));
201 SSLContextRef ctx
= SSLCreateContext(kCFAllocatorDefault
, server
?kSSLServerSide
:kSSLClientSide
, kSSLStreamType
);
203 require(handle
, out
);
206 require_noerr(SSLSetIOFuncs(ctx
,
207 (SSLReadFunc
)SocketRead
, (SSLWriteFunc
)SocketWrite
), out
);
208 require_noerr(SSLSetConnection(ctx
, (SSLConnectionRef
)handle
), out
);
211 require_noerr(SSLSetCertificate(ctx
, certs
), out
);
213 require_noerr(SSLSetSessionOption(ctx
,
214 kSSLSessionOptionBreakOnServerAuth
, true), out
);
216 /* Tell SecureTransport to not check certs itself: it will break out of the
217 handshake to let us take care of it instead. */
218 require_noerr(SSLSetEnableCertVerify(ctx
, false), out
);
220 handle
->is_server
= server
;
222 handle
->certs
= certs
;
228 if (handle
) free(handle
);
229 if (ctx
) CFRelease(ctx
);
236 pthread_t client_thread
, server_thread
;
237 CFArrayRef server_certs
= server_chain();
238 ok(server_certs
, "got server certs");
245 if (socketpair(AF_UNIX
, SOCK_STREAM
, 0, sp
)) exit(errno
);
246 fcntl(sp
[0], F_SETNOSIGPIPE
, 1);
247 fcntl(sp
[1], F_SETNOSIGPIPE
, 1);
249 ssl_test_handle
*server
, *client
;
251 server
= ssl_test_handle_create(true /*server*/, sp
[0], server_certs
);
252 client
= ssl_test_handle_create(false/*client*/, sp
[1], NULL
);
257 require(client
, out
);
258 require(server
, out
);
260 SSLCipherSuite cipher
= TLS_RSA_WITH_AES_128_CBC_SHA256
;
261 require_noerr(SSLSetEnabledCiphers(client
->st
, &cipher
, 1), out
);
263 pthread_create(&client_thread
, NULL
, securetransport_ssl_thread
, client
);
264 pthread_create(&server_thread
, NULL
, securetransport_ssl_thread
, server
);
266 int server_err
, client_err
;
267 pthread_join(client_thread
, (void*)&client_err
);
268 pthread_join(server_thread
, (void*)&server_err
);
271 ok(!server_err
, "Server error = %d", server_err
);
272 /* test i=0 should cause errSSLClosedAbort, 1 & 2 should cause errSSLBadRecordMac */
273 ok(client_err
==(i
?errSSLBadRecordMac
:errSSLClosedAbort
), "Client error = %d", client_err
);
280 CFReleaseNull(server_certs
);
283 int ssl_44_crashes(int argc
, char *const *argv
)
286 plan_tests(3*2 + 1 /*cert*/);