2 * Copyright (c) 2011-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 <sys/types.h>
31 #include <netinet/in.h>
32 #include <sys/socket.h>
34 #include <arpa/inet.h>
35 #include <CoreFoundation/CoreFoundation.h>
37 #include <AssertMacros.h>
38 #include <Security/SecureTransportPriv.h> /* SSLSetOption */
39 #include <Security/SecureTransport.h>
40 #include <Security/SecPolicy.h>
41 #include <Security/SecTrust.h>
42 #include <Security/SecIdentity.h>
43 #include <Security/SecIdentityPriv.h>
44 #include <Security/SecCertificatePriv.h>
45 #include <Security/SecKeyPriv.h>
46 #include <Security/SecItem.h>
47 #include <Security/SecRandom.h>
50 #include <sys/types.h>
51 #include <sys/socket.h>
54 #include <mach/mach_time.h>
56 #include "ssl_regressions.h"
60 bool is_session_resume
;
63 bool client_side_auth
;
72 static void hexdump(const uint8_t *bytes
, size_t len
) {
74 printf("socket write(%p, %lu)\n", bytes
, len
);
75 for (ix
= 0; ix
< len
; ++ix
) {
78 printf("%02X ", bytes
[ix
]);
83 #define hexdump(bytes, len)
86 static int SocketConnect(const char *hostName
, int port
)
88 struct sockaddr_in addr
;
94 if (hostName
[0] >= '0' && hostName
[0] <= '9')
96 host
.s_addr
= inet_addr(hostName
);
100 #define GETHOST_RETRIES 5
101 /* seeing a lot of soft failures here that I really don't want to track down */
102 for(dex
=0; dex
<GETHOST_RETRIES
; dex
++) {
104 printf("\n...retrying gethostbyname(%s)", hostName
);
106 ent
= gethostbyname(hostName
);
112 printf("\n***gethostbyname(%s) returned: %s\n", hostName
, hstrerror(h_errno
));
115 memcpy(&host
, ent
->h_addr
, sizeof(struct in_addr
));
119 sock
= socket(AF_INET
, SOCK_STREAM
, 0);
120 addr
.sin_addr
= host
;
121 addr
.sin_port
= htons((u_short
)port
);
123 addr
.sin_family
= AF_INET
;
124 err
= connect(sock
, (struct sockaddr
*) &addr
, sizeof(struct sockaddr_in
));
128 perror("connect failed");
136 static OSStatus
SocketWrite(SSLConnectionRef conn
, const void *data
, size_t *length
)
138 size_t len
= *length
;
139 uint8_t *ptr
= (uint8_t *)data
;
145 ret
= write((int)conn
, ptr
, len
);
148 } while ((ret
< 0) && (errno
== EAGAIN
|| errno
== EINTR
));
157 *length
= *length
- len
;
158 return errSecSuccess
;
161 static OSStatus
SocketRead(SSLConnectionRef conn
, void *data
, size_t *length
)
163 size_t len
= *length
;
164 uint8_t *ptr
= (uint8_t *)data
;
169 ret
= read((int)conn
, ptr
, len
);
172 } while ((ret
< 0) && (errno
== EAGAIN
|| errno
== EINTR
));
181 *length
= *length
- len
;
182 return errSecSuccess
;
185 static SSLContextRef
make_ssl_ref(int sock
, SSLProtocol maxprot
)
187 SSLContextRef ctx
= NULL
;
189 require_noerr(SSLNewContext(false, &ctx
), out
);
190 require_noerr(SSLSetIOFuncs(ctx
,
191 (SSLReadFunc
)SocketRead
, (SSLWriteFunc
)SocketWrite
), out
);
192 require_noerr(SSLSetConnection(ctx
, (SSLConnectionRef
)(intptr_t)sock
), out
);
194 require_noerr(SSLSetSessionOption(ctx
,
195 kSSLSessionOptionBreakOnServerAuth
, true), out
);
197 require_noerr(SSLSetProtocolVersionMax(ctx
, maxprot
), out
);
198 /* Tell SecureTransport to not check certs itself: it will break out of the
199 handshake to let us take care of it instead. */
200 require_noerr(SSLSetEnableCertVerify(ctx
, false), out
);
205 SSLDisposeContext(ctx
);
209 static OSStatus
securetransport(ssl_test_handle
* ssl
)
212 SSLContextRef ctx
= ssl
->st
;
213 SecTrustRef trust
= NULL
;
214 bool got_server_auth
= false, got_client_cert_req
= false;
216 //uint64_t start = mach_absolute_time();
218 ortn
= SSLHandshake(ctx
);
220 if (ortn
== errSSLServerAuthCompleted
)
222 require_string(!got_server_auth
, out
, "second server auth");
223 require_string(!got_client_cert_req
, out
, "got client cert req before server auth");
224 got_server_auth
= true;
225 require_string(!trust
, out
, "Got errSSLServerAuthCompleted twice?");
226 /* verify peer cert chain */
227 require_noerr(SSLCopyPeerTrust(ctx
, &trust
), out
);
228 SecTrustResultType trust_result
= 0;
229 /* this won't verify without setting up a trusted anchor */
230 require_noerr(SecTrustEvaluate(trust
, &trust_result
), out
);
232 } } while (ortn
== errSSLWouldBlock
233 || ortn
== errSSLServerAuthCompleted
);
234 require_noerr_action_quiet(ortn
, out
,
235 fprintf(stderr
, "Fell out of SSLHandshake with error: %d\n", (int)ortn
));
237 require_string(got_server_auth
, out
, "never got server auth");
239 //uint64_t elapsed = mach_absolute_time() - start;
240 //fprintf(stderr, "setr elapsed: %lld\n", elapsed);
243 SSLProtocol proto = kSSLProtocolUnknown;
244 require_noerr_quiet(SSLGetNegotiatedProtocolVersion(ctx, &proto), out); */
246 SSLCipherSuite cipherSuite
;
247 require_noerr_quiet(ortn
= SSLGetNegotiatedCipher(ctx
, &cipherSuite
), out
);
248 //fprintf(stderr, "st negotiated %02x\n", cipherSuite);
253 SSLDisposeContext(ctx
);
254 if (trust
) CFRelease(trust
);
261 static ssl_test_handle
*
262 ssl_test_handle_create(int comm
, SSLProtocol maxprot
)
264 ssl_test_handle
*handle
= calloc(1, sizeof(ssl_test_handle
));
267 handle
->st
= make_ssl_ref(comm
, maxprot
);
277 /* Good tls 1.2 servers */
278 {"encrypted.google.com", 443, kTLSProtocol12
},
279 {"www.amazon.com",443, kTLSProtocol12
},
280 //{"www.mikestoolbox.org",443, kTLSProtocol12 },
281 /* servers with issues */
282 {"vpp.visa.co.uk", 443, kTLSProtocol12
}, // Doesnt like SSL 3.0 in initial record layer version
283 {"imap.softbank.jp",993, kTLSProtocol1
}, // softbank imap server, there are multiple servers behind this, one of them is not able to handle downgrading to TLS 1.2 properly (126.240.66.17).
284 {"mobile.charter.net",993, kTLSProtocol1
}, // Support 1.2 but fail to negotiate properly
285 {"mybill.vodafone.com.au", 443, kTLSProtocol1
}, /* 2056 bit server key */
288 #define NSERVERS (int)(sizeof(servers)/sizeof(servers[0]))
296 for(p
=0; p
<NSERVERS
;p
++) {
297 for(int loops
=0; loops
<NLOOPS
; loops
++) {
299 ssl_test_handle
*client
;
304 s
=SocketConnect(servers
[p
].host
, servers
[p
].port
);
306 fail("connect failed with err=%d - %s:%d (try %d)", s
, servers
[p
].host
, servers
[p
].port
, loops
);
310 client
= ssl_test_handle_create(s
, servers
[p
].maxprot
);
312 r
=securetransport(client
);
313 ok(!r
, "handshake failed with err=%ld - %s:%d (try %d)", (long)r
, servers
[p
].host
, servers
[p
].port
, loops
);
320 int ssl_45_tls12(int argc
, char *const *argv
)
322 plan_tests(NSERVERS
*NLOOPS
);