]> git.saurik.com Git - apple/security.git/blob - Security/tlsnke/tlsnketest/dtls_client.c
Security-57031.1.35.tar.gz
[apple/security.git] / Security / tlsnke / tlsnketest / dtls_client.c
1 /*
2 * Copyright (c) 2012-2014 Apple Inc. All Rights Reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
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
11 * file.
12 *
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.
20 *
21 * @APPLE_LICENSE_HEADER_END@
22 */
23
24
25 /*
26 * dtlsEchoClient.c
27 * Security
28 *
29 * Copyright (c) 2011-2014 Apple Inc. All Rights Reserved.
30 *
31 */
32
33 #include <Security/Security.h>
34
35 #include "ssl-utils.h"
36
37 #include <stdlib.h>
38 #include <sys/types.h>
39 #include <sys/socket.h>
40 #include <netinet/in.h>
41 #include <arpa/inet.h>
42 #include <stdio.h>
43 #include <errno.h>
44 #include <unistd.h> /* close() */
45 #include <string.h> /* memset() */
46 #include <fcntl.h>
47 #include <time.h>
48
49 #include "tlssocket.h"
50
51 #define SERVER "10.0.2.1"
52 #define PORT 23232
53 #define BUFLEN 128
54 #define COUNT 10
55
56 #if 0
57 static void dumppacket(const unsigned char *data, unsigned long len)
58 {
59 unsigned long i;
60 for(i=0;i<len;i++)
61 {
62 if((i&0xf)==0) printf("%04lx :",i);
63 printf(" %02x", data[i]);
64 if((i&0xf)==0xf) printf("\n");
65 }
66 printf("\n");
67 }
68 #endif
69
70
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
74
75 static void sslOutputDot()
76 {
77 time_t thisTime = time(0);
78
79 if((thisTime - lastTime) >= TIME_INTERVAL) {
80 printf("."); fflush(stdout);
81 lastTime = thisTime;
82 }
83 }
84
85 static void printSslErrStr(
86 const char *op,
87 OSStatus err)
88 {
89 printf("*** %s: %ld\n", op, (long)err);
90 }
91
92 /* 2K should be enough for everybody */
93 #define MTU 2048
94
95
96 int dtls_client(const char *hostname, int bypass);
97
98 int dtls_client(const char *hostname, int bypass)
99 {
100 int fd;
101 int tlsfd;
102 struct sockaddr_in sa;
103
104 printf("Running dtls_client test with hostname=%s, bypass=%d\n", hostname, bypass);
105
106 if ((fd=socket(AF_INET, SOCK_DGRAM, 0))==-1) {
107 perror("socket");
108 exit(-1);
109 }
110
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");
116 exit(1);
117 }
118
119 if(connect(fd, (struct sockaddr *)&sa, sizeof(sa))==-1)
120 {
121 perror("connect");
122 return errno;
123 }
124
125 /* Change to non blocking io */
126 fcntl(fd, F_SETFL, O_NONBLOCK);
127
128 SSLRecordContextRef c=(intptr_t)fd;
129
130
131 OSStatus ortn;
132 SSLContextRef ctx = NULL;
133
134 SSLClientCertificateState certState;
135 SSLCipherSuite negCipher;
136 SSLProtocol negVersion;
137
138 /*
139 * Set up a SecureTransport session.
140 */
141
142 ctx = SSLCreateContextWithRecordFuncs(kCFAllocatorDefault, kSSLClientSide, kSSLDatagramType, &TLSSocket_Funcs);
143 if(!ctx) {
144 printSslErrStr("SSLCreateContextWithRecordFuncs", -1);
145 return -1;
146 }
147
148 printf("Attaching filter\n");
149 ortn = TLSSocket_Attach(fd);
150 if(ortn) {
151 printSslErrStr("TLSSocket_Attach", ortn);
152 return ortn;
153 }
154
155 if(bypass) {
156 tlsfd = open("/dev/tlsnke", O_RDWR);
157 if(tlsfd<0) {
158 perror("opening tlsnke dev");
159 exit(-1);
160 }
161 }
162
163 ortn = SSLSetRecordContext(ctx, c);
164 if(ortn) {
165 printSslErrStr("SSLSetRecordContext", ortn);
166 return ortn;
167 }
168
169 ortn = SSLSetMaxDatagramRecordSize(ctx, 600);
170 if(ortn) {
171 printSslErrStr("SSLSetMaxDatagramRecordSize", ortn);
172 return ortn;
173 }
174
175 /* Lets not verify the cert, which is a random test cert */
176 ortn = SSLSetEnableCertVerify(ctx, false);
177 if(ortn) {
178 printSslErrStr("SSLSetEnableCertVerify", ortn);
179 return ortn;
180 }
181
182 ortn = SSLSetCertificate(ctx, server_chain());
183 if(ortn) {
184 printSslErrStr("SSLSetCertificate", ortn);
185 return ortn;
186 }
187
188 printf("Handshake...\n");
189
190 do {
191 ortn = SSLHandshake(ctx);
192 if(ortn == errSSLWouldBlock) {
193 /* keep UI responsive */
194 sslOutputDot();
195 }
196 } while (ortn == errSSLWouldBlock);
197
198
199 SSLGetClientCertificateState(ctx, &certState);
200 SSLGetNegotiatedCipher(ctx, &negCipher);
201 SSLGetNegotiatedProtocolVersion(ctx, &negVersion);
202
203 int count;
204 size_t len;
205 ssize_t sreadLen, swriteLen;
206 size_t readLen, writeLen;
207
208 char buffer[BUFLEN];
209
210 count = 0;
211 while(count<COUNT) {
212 int timeout = 10000;
213
214 snprintf(buffer, BUFLEN, "Message %d", count);
215 len = strlen(buffer);
216
217 if(bypass) {
218 /* Send data through the side channel, kind of like utun would */
219 swriteLen=write(tlsfd, buffer, len);
220 if(swriteLen<0) {
221 perror("write to tlsfd");
222 break;
223 }
224 writeLen=swriteLen;
225 } else {
226 ortn=SSLWrite(ctx, buffer, len, &writeLen);
227 if(ortn) {
228 printSslErrStr("SSLWrite", ortn);
229 break;
230 }
231 }
232
233 printf("Wrote %lu bytes\n", writeLen);
234
235 count++;
236
237 if(bypass) {
238 do {
239 sreadLen=read(tlsfd, buffer, BUFLEN);
240 } while((sreadLen==-1) && (errno==EAGAIN) && (timeout--));
241 if((sreadLen==-1) && (errno==EAGAIN)) {
242 printf("Read timeout...\n");
243 continue;
244 }
245 if(sreadLen<0) {
246 perror("read from tlsfd");
247 break;
248 }
249 readLen=sreadLen;
250 }
251 else {
252 do {
253 ortn=SSLRead(ctx, buffer, BUFLEN, &readLen);
254 } while((ortn==errSSLWouldBlock) && (timeout--));
255 if(ortn==errSSLWouldBlock) {
256 printf("SSLRead timeout...\n");
257 continue;
258 }
259 if(ortn) {
260 printSslErrStr("SSLRead", ortn);
261 break;
262 }
263 }
264
265 buffer[readLen]=0;
266 printf("Received %lu bytes: %s\n", readLen, buffer);
267
268 }
269
270 SSLClose(ctx);
271
272 SSLDisposeContext(ctx);
273
274 return ortn;
275 }
276