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@
29 * Copyright (c) 2011-2014 Apple Inc. All Rights Reserved.
33 #include <Security/Security.h>
35 #include "ssl-utils.h"
38 #include <sys/types.h>
39 #include <sys/socket.h>
40 #include <netinet/in.h>
41 #include <arpa/inet.h>
44 #include <unistd.h> /* close() */
45 #include <string.h> /* memset() */
49 #include "tlssocket.h"
51 #define SERVER "10.0.2.1"
57 static void dumppacket(const unsigned char *data
, unsigned long len
)
62 if((i
&0xf)==0) printf("%04lx :",i
);
63 printf(" %02x", data
[i
]);
64 if((i
&0xf)==0xf) printf("\n");
71 /* print a '.' every few seconds to keep UI alive while connecting */
72 static time_t lastTime
= (time_t)0;
73 #define TIME_INTERVAL 3
75 static void sslOutputDot()
77 time_t thisTime
= time(0);
79 if((thisTime
- lastTime
) >= TIME_INTERVAL
) {
80 printf("."); fflush(stdout
);
85 static void printSslErrStr(
89 printf("*** %s: %ld\n", op
, (long)err
);
92 /* 2K should be enough for everybody */
96 int dtls_client(const char *hostname
, int bypass
);
98 int dtls_client(const char *hostname
, int bypass
)
102 struct sockaddr_in sa
;
104 printf("Running dtls_client test with hostname=%s, bypass=%d\n", hostname
, bypass
);
106 if ((fd
=socket(AF_INET
, SOCK_DGRAM
, 0))==-1) {
111 memset((char *) &sa
, 0, sizeof(sa
));
112 sa
.sin_family
= AF_INET
;
113 sa
.sin_port
= htons(PORT
);
114 if (inet_aton(hostname
, &sa
.sin_addr
)==0) {
115 fprintf(stderr
, "inet_aton() failed\n");
119 if(connect(fd
, (struct sockaddr
*)&sa
, sizeof(sa
))==-1)
125 /* Change to non blocking io */
126 fcntl(fd
, F_SETFL
, O_NONBLOCK
);
128 SSLRecordContextRef c
=(intptr_t)fd
;
132 SSLContextRef ctx
= NULL
;
134 SSLClientCertificateState certState
;
135 SSLCipherSuite negCipher
;
136 SSLProtocol negVersion
;
139 * Set up a SecureTransport session.
142 ctx
= SSLCreateContextWithRecordFuncs(kCFAllocatorDefault
, kSSLClientSide
, kSSLDatagramType
, &TLSSocket_Funcs
);
144 printSslErrStr("SSLCreateContextWithRecordFuncs", -1);
148 printf("Attaching filter\n");
149 ortn
= TLSSocket_Attach(fd
);
151 printSslErrStr("TLSSocket_Attach", ortn
);
156 tlsfd
= open("/dev/tlsnke", O_RDWR
);
158 perror("opening tlsnke dev");
163 ortn
= SSLSetRecordContext(ctx
, c
);
165 printSslErrStr("SSLSetRecordContext", ortn
);
169 ortn
= SSLSetMaxDatagramRecordSize(ctx
, 600);
171 printSslErrStr("SSLSetMaxDatagramRecordSize", ortn
);
175 /* Lets not verify the cert, which is a random test cert */
176 ortn
= SSLSetEnableCertVerify(ctx
, false);
178 printSslErrStr("SSLSetEnableCertVerify", ortn
);
182 ortn
= SSLSetCertificate(ctx
, server_chain());
184 printSslErrStr("SSLSetCertificate", ortn
);
188 printf("Handshake...\n");
191 ortn
= SSLHandshake(ctx
);
192 if(ortn
== errSSLWouldBlock
) {
193 /* keep UI responsive */
196 } while (ortn
== errSSLWouldBlock
);
199 SSLGetClientCertificateState(ctx
, &certState
);
200 SSLGetNegotiatedCipher(ctx
, &negCipher
);
201 SSLGetNegotiatedProtocolVersion(ctx
, &negVersion
);
205 ssize_t sreadLen
, swriteLen
;
206 size_t readLen
, writeLen
;
214 snprintf(buffer
, BUFLEN
, "Message %d", count
);
215 len
= strlen(buffer
);
218 /* Send data through the side channel, kind of like utun would */
219 swriteLen
=write(tlsfd
, buffer
, len
);
221 perror("write to tlsfd");
226 ortn
=SSLWrite(ctx
, buffer
, len
, &writeLen
);
228 printSslErrStr("SSLWrite", ortn
);
233 printf("Wrote %lu bytes\n", writeLen
);
239 sreadLen
=read(tlsfd
, buffer
, BUFLEN
);
240 } while((sreadLen
==-1) && (errno
==EAGAIN
) && (timeout
--));
241 if((sreadLen
==-1) && (errno
==EAGAIN
)) {
242 printf("Read timeout...\n");
246 perror("read from tlsfd");
253 ortn
=SSLRead(ctx
, buffer
, BUFLEN
, &readLen
);
254 } while((ortn
==errSSLWouldBlock
) && (timeout
--));
255 if(ortn
==errSSLWouldBlock
) {
256 printf("SSLRead timeout...\n");
260 printSslErrStr("SSLRead", ortn
);
266 printf("Received %lu bytes: %s\n", readLen
, buffer
);
272 SSLDisposeContext(ctx
);