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"
65 struct s_server
*server
;
67 bool is_session_resume
;
69 bool client_side_auth
;
78 static void hexdump(const uint8_t *bytes
, size_t len
) {
80 printf("socket write(%p, %lu)\n", bytes
, len
);
81 for (ix
= 0; ix
< len
; ++ix
) {
84 printf("%02X ", bytes
[ix
]);
89 #define hexdump(bytes, len)
92 static int SocketConnect(const char *hostName
, int port
)
94 struct sockaddr_in addr
;
100 if (hostName
[0] >= '0' && hostName
[0] <= '9') {
101 host
.s_addr
= inet_addr(hostName
);
103 ent
= gethostbyname(hostName
);
105 printf("\n***gethostbyname(%s) returned: %s\n", hostName
, hstrerror(h_errno
));
108 memcpy(&host
, ent
->h_addr
, sizeof(struct in_addr
));
111 sock
= socket(AF_INET
, SOCK_STREAM
, 0);
112 addr
.sin_addr
= host
;
113 addr
.sin_port
= htons((u_short
)port
);
115 addr
.sin_family
= AF_INET
;
116 err
= connect(sock
, (struct sockaddr
*) &addr
, sizeof(struct sockaddr_in
));
120 perror("connect failed");
128 static OSStatus
SocketWrite(SSLConnectionRef conn
, const void *data
, size_t *length
)
130 size_t len
= *length
;
131 uint8_t *ptr
= (uint8_t *)data
;
137 ret
= write((int)conn
, ptr
, len
);
140 } while ((ret
< 0) && (errno
== EAGAIN
|| errno
== EINTR
));
149 *length
= *length
- len
;
150 return errSecSuccess
;
153 static OSStatus
SocketRead(SSLConnectionRef conn
, void *data
, size_t *length
)
155 size_t len
= *length
;
156 uint8_t *ptr
= (uint8_t *)data
;
161 ret
= read((int)conn
, ptr
, len
);
164 } while ((ret
< 0) && (errno
== EAGAIN
|| errno
== EINTR
));
173 *length
= *length
- len
;
174 return errSecSuccess
;
177 static SSLContextRef
make_ssl_ref(int sock
, SSLProtocol maxprot
, const char *peerName
)
179 SSLContextRef ctx
= NULL
;
181 require_noerr(SSLNewContext(false, &ctx
), out
);
182 require_noerr(SSLSetIOFuncs(ctx
,
183 (SSLReadFunc
)SocketRead
, (SSLWriteFunc
)SocketWrite
), out
);
184 require_noerr(SSLSetConnection(ctx
, (SSLConnectionRef
)(intptr_t)sock
), out
);
186 require_noerr(SSLSetSessionOption(ctx
,
187 kSSLSessionOptionBreakOnServerAuth
, true), out
);
189 require_noerr(SSLSetProtocolVersionMax(ctx
, maxprot
), out
);
191 require_noerr(SSLSetPeerDomainName(ctx
, peerName
, strlen(peerName
)), out
);
192 /* Tell SecureTransport to not check certs itself: it will break out of the
193 handshake to let us take care of it instead. */
194 require_noerr(SSLSetEnableCertVerify(ctx
, false), out
);
199 SSLDisposeContext(ctx
);
203 static OSStatus
securetransport(ssl_test_handle
* ssl
)
206 SSLContextRef ctx
= ssl
->st
;
207 SecTrustRef trust
= NULL
;
208 bool got_server_auth
= false, got_client_cert_req
= false;
210 //uint64_t start = mach_absolute_time();
212 ortn
= SSLHandshake(ctx
);
214 if (ortn
== errSSLServerAuthCompleted
)
216 require_string(!got_server_auth
, out
, "second server auth");
217 require_string(!got_client_cert_req
, out
, "got client cert req before server auth");
218 got_server_auth
= true;
219 require_string(!trust
, out
, "Got errSSLServerAuthCompleted twice?");
220 /* verify peer cert chain */
221 require_noerr(SSLCopyPeerTrust(ctx
, &trust
), out
);
222 SecTrustResultType trust_result
= 0;
223 /* this won't verify without setting up a trusted anchor */
224 require_noerr(SecTrustEvaluate(trust
, &trust_result
), out
);
225 require((trust_result
== kSecTrustResultUnspecified
), out
);
228 } while (ortn
== errSSLWouldBlock
229 || ortn
== errSSLServerAuthCompleted
);
230 require_noerr_action_quiet(ortn
, out
,
231 fprintf(stderr
, "Fell out of SSLHandshake with error: %d\n", (int)ortn
));
233 require_string(got_server_auth
, out
, "never got server auth");
235 //uint64_t elapsed = mach_absolute_time() - start;
236 //fprintf(stderr, "setr elapsed: %lld\n", elapsed);
239 SSLProtocol proto = kSSLProtocolUnknown;
240 require_noerr_quiet(SSLGetNegotiatedProtocolVersion(ctx, &proto), out); */
242 SSLCipherSuite cipherSuite
;
243 require_noerr_quiet(ortn
= SSLGetNegotiatedCipher(ctx
, &cipherSuite
), out
);
244 //fprintf(stderr, "st negotiated %02x\n", cipherSuite);
249 SSLDisposeContext(ctx
);
250 if (trust
) CFRelease(trust
);
257 #define CONNECT_TRIES 3
259 static ssl_test_handle
*
260 ssl_test_handle_create(struct s_server
*server
)
264 for(int try = 0; comm
<0 && try<CONNECT_TRIES
; try++) {
265 comm
=SocketConnect(server
->host
, server
->port
);
269 fail("connect failed with err=%d - %s:%d", comm
, server
->host
, server
->port
);
273 ssl_test_handle
*handle
= calloc(1, sizeof(ssl_test_handle
));
276 handle
->st
= make_ssl_ref(comm
, server
->maxprot
, server
->host
);
277 handle
->server
= server
;
283 ssl_test_handle_destroy(ssl_test_handle
*handle
)
290 struct s_server servers
[] = {
291 #if !TARGET_OS_IPHONE //This test run on AppleWifi on iPhone, so we can't connect to internal servers.
292 {"nod.apple.com", 636, kTLSProtocol12
}, // This one has only the server eku, not the client one.
294 {"gsa.apple.com", 443, kTLSProtocol12
}, // This one has only the server eku, not the client one.
295 /* Good tls 1.2 servers */
296 {"sslanalyzer.comodoca.com", 443, kTLSProtocol12
}, // This one has a stapled OCSP response with SCTs.
297 {"encrypted.google.com", 443, kTLSProtocol12
},
298 {"www.amazon.com",443, kTLSProtocol12
},
299 //{"www.mikestoolbox.org",443, kTLSProtocol12 },
300 /* servers with issues */
301 // This server went offline as of May 2016 -- {"vpp.visa.co.uk", 443, kTLSProtocol12 }, // Doesnt like SSL 3.0 in initial record layer version
302 {"imap.softbank.jp",993, kTLSProtocol12
}, // 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).
303 {"mobile.charter.net",993, kTLSProtocol12
}, // Support 1.2 but fail to negotiate properly
304 {"mybill.vodafone.com.au", 443, kTLSProtocol1
}, /* 2056 bit server key */
307 #define NSERVERS (int)(sizeof(servers)/sizeof(servers[0]))
316 for(p
=0; p
<NSERVERS
;p
++) {
317 for(int loops
=0; loops
<NLOOPS
; loops
++) {
318 ssl_test_handle
*client
;
321 skip("failed to create transport", 1,
322 client
= ssl_test_handle_create(&servers
[p
]));
324 r
=securetransport(client
);
325 ok(!r
, "handshake failed with err=%ld - %s:%d (try %d)", (long)r
, servers
[p
].host
, servers
[p
].port
, loops
);
327 ssl_test_handle_destroy(client
);
333 int ssl_45_tls12(int argc
, char *const *argv
)
335 plan_tests(NSERVERS
*NLOOPS
);