5 // Created by Fabrice Gautier on 6/7/11.
6 // Copyright 2011 Apple, Inc. All rights reserved.
14 #include <sys/types.h>
15 #include <netinet/in.h>
16 #include <sys/socket.h>
18 #include <arpa/inet.h>
19 #include <CoreFoundation/CoreFoundation.h>
21 #include <AssertMacros.h>
22 #include <Security/SecureTransportPriv.h> /* SSLSetOption */
23 #include <Security/SecureTransport.h>
24 #include <Security/SecPolicy.h>
25 #include <Security/SecTrust.h>
26 #include <Security/SecIdentity.h>
27 #include <Security/SecIdentityPriv.h>
28 #include <Security/SecCertificatePriv.h>
29 #include <Security/SecKeyPriv.h>
30 #include <Security/SecItem.h>
31 #include <Security/SecRandom.h>
34 #include <sys/types.h>
35 #include <sys/socket.h>
38 #include <mach/mach_time.h>
40 #include "ssl_regressions.h"
44 bool is_session_resume
;
47 bool client_side_auth
;
56 static void hexdump(const uint8_t *bytes
, size_t len
) {
58 printf("socket write(%p, %lu)\n", bytes
, len
);
59 for (ix
= 0; ix
< len
; ++ix
) {
62 printf("%02X ", bytes
[ix
]);
67 #define hexdump(bytes, len)
70 static int SocketConnect(const char *hostName
, int port
)
72 struct sockaddr_in addr
;
78 if (hostName
[0] >= '0' && hostName
[0] <= '9')
80 host
.s_addr
= inet_addr(hostName
);
84 #define GETHOST_RETRIES 5
85 /* seeing a lot of soft failures here that I really don't want to track down */
86 for(dex
=0; dex
<GETHOST_RETRIES
; dex
++) {
88 printf("\n...retrying gethostbyname(%s)", hostName
);
90 ent
= gethostbyname(hostName
);
96 printf("\n***gethostbyname(%s) returned: %s\n", hostName
, hstrerror(h_errno
));
99 memcpy(&host
, ent
->h_addr
, sizeof(struct in_addr
));
103 sock
= socket(AF_INET
, SOCK_STREAM
, 0);
104 addr
.sin_addr
= host
;
105 addr
.sin_port
= htons((u_short
)port
);
107 addr
.sin_family
= AF_INET
;
108 err
= connect(sock
, (struct sockaddr
*) &addr
, sizeof(struct sockaddr_in
));
112 perror("connect failed");
120 static OSStatus
SocketWrite(SSLConnectionRef conn
, const void *data
, size_t *length
)
122 size_t len
= *length
;
123 uint8_t *ptr
= (uint8_t *)data
;
129 ret
= write((int)conn
, ptr
, len
);
132 } while ((ret
< 0) && (errno
== EAGAIN
|| errno
== EINTR
));
141 *length
= *length
- len
;
142 return errSecSuccess
;
145 static OSStatus
SocketRead(SSLConnectionRef conn
, void *data
, size_t *length
)
147 size_t len
= *length
;
148 uint8_t *ptr
= (uint8_t *)data
;
153 ret
= read((int)conn
, ptr
, len
);
156 } while ((ret
< 0) && (errno
== EAGAIN
|| errno
== EINTR
));
165 *length
= *length
- len
;
166 return errSecSuccess
;
169 static SSLContextRef
make_ssl_ref(int sock
, SSLProtocol maxprot
)
171 SSLContextRef ctx
= NULL
;
173 require_noerr(SSLNewContext(false, &ctx
), out
);
174 require_noerr(SSLSetIOFuncs(ctx
,
175 (SSLReadFunc
)SocketRead
, (SSLWriteFunc
)SocketWrite
), out
);
176 require_noerr(SSLSetConnection(ctx
, (SSLConnectionRef
)(intptr_t)sock
), out
);
178 require_noerr(SSLSetSessionOption(ctx
,
179 kSSLSessionOptionBreakOnServerAuth
, true), out
);
181 require_noerr(SSLSetProtocolVersionMax(ctx
, maxprot
), out
);
182 /* Tell SecureTransport to not check certs itself: it will break out of the
183 handshake to let us take care of it instead. */
184 require_noerr(SSLSetEnableCertVerify(ctx
, false), out
);
189 SSLDisposeContext(ctx
);
193 static OSStatus
securetransport(ssl_test_handle
* ssl
)
196 SSLContextRef ctx
= ssl
->st
;
197 SecTrustRef trust
= NULL
;
198 bool got_server_auth
= false, got_client_cert_req
= false;
200 //uint64_t start = mach_absolute_time();
202 ortn
= SSLHandshake(ctx
);
204 if (ortn
== errSSLServerAuthCompleted
)
206 require_string(!got_server_auth
, out
, "second server auth");
207 require_string(!got_client_cert_req
, out
, "got client cert req before server auth");
208 got_server_auth
= true;
209 require_string(!trust
, out
, "Got errSSLServerAuthCompleted twice?");
210 /* verify peer cert chain */
211 require_noerr(SSLCopyPeerTrust(ctx
, &trust
), out
);
212 SecTrustResultType trust_result
= 0;
213 /* this won't verify without setting up a trusted anchor */
214 require_noerr(SecTrustEvaluate(trust
, &trust_result
), out
);
216 } } while (ortn
== errSSLWouldBlock
217 || ortn
== errSSLServerAuthCompleted
);
218 require_noerr_action_quiet(ortn
, out
,
219 fprintf(stderr
, "Fell out of SSLHandshake with error: %d\n", (int)ortn
));
221 require_string(got_server_auth
, out
, "never got server auth");
223 //uint64_t elapsed = mach_absolute_time() - start;
224 //fprintf(stderr, "setr elapsed: %lld\n", elapsed);
227 SSLProtocol proto = kSSLProtocolUnknown;
228 require_noerr_quiet(SSLGetNegotiatedProtocolVersion(ctx, &proto), out); */
230 SSLCipherSuite cipherSuite
;
231 require_noerr_quiet(ortn
= SSLGetNegotiatedCipher(ctx
, &cipherSuite
), out
);
232 //fprintf(stderr, "st negotiated %02x\n", cipherSuite);
237 SSLDisposeContext(ctx
);
238 if (trust
) CFRelease(trust
);
245 static ssl_test_handle
*
246 ssl_test_handle_create(int comm
, SSLProtocol maxprot
)
248 ssl_test_handle
*handle
= calloc(1, sizeof(ssl_test_handle
));
251 handle
->st
= make_ssl_ref(comm
, maxprot
);
262 /* Good tls 1.2 servers */
263 {"encrypted.google.com", 443, kTLSProtocol12
},
264 {"www.amazon.com",443, kTLSProtocol12
},
265 {"www.mikestoolbox.org",443, kTLSProtocol12
},
266 /* servers with issues */
267 {"vpp.visa.co.uk", 443, kTLSProtocol12
}, // Doesnt like SSL 3.0 in initial record layer version
268 {"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).
269 {"mobile.charter.net",993, kTLSProtocol1
}, // Support 1.2 but fail to negotiate properly
270 {"mybill.vodafone.com.au", 443, kTLSProtocol1
}, /* 2056 bit server key */
273 #define NSERVERS (int)(sizeof(servers)/sizeof(servers[0]))
281 for(p
=0; p
<NSERVERS
;p
++) {
282 for(int loops
=0; loops
<NLOOPS
; loops
++) {
284 ssl_test_handle
*client
;
289 s
=SocketConnect(servers
[p
].host
, servers
[p
].port
);
291 fail("connect failed with err=%d - %s:%d (try %d)", s
, servers
[p
].host
, servers
[p
].port
, loops
);
295 client
= ssl_test_handle_create(s
, servers
[p
].maxprot
);
297 r
=securetransport(client
);
298 ok(!r
, "handshake failed with err=%ld - %s:%d (try %d)", (long)r
, servers
[p
].host
, servers
[p
].port
, loops
);
304 int ssl_45_tls12(int argc
, char *const *argv
)
306 plan_tests(NSERVERS
*NLOOPS
);