5 // Created by Fabrice Gautier on 2/7/12.
6 // Copyright (c) 2012 Apple, Inc. All rights reserved.
13 * Created by Fabrice Gautier on 1/31/11.
14 * Copyright 2011 Apple, Inc. All rights reserved.
18 #include <Security/Security.h>
20 #include "ssl-utils.h"
23 #include <sys/types.h>
24 #include <sys/socket.h>
25 #include <netinet/in.h>
26 #include <arpa/inet.h>
29 #include <unistd.h> /* close() */
30 #include <string.h> /* memset() */
34 #include "tlssocket.h"
36 #define SERVER "10.0.2.1"
42 static void dumppacket(const unsigned char *data
, unsigned long len
)
47 if((i
&0xf)==0) printf("%04lx :",i
);
48 printf(" %02x", data
[i
]);
49 if((i
&0xf)==0xf) printf("\n");
56 /* print a '.' every few seconds to keep UI alive while connecting */
57 static time_t lastTime
= (time_t)0;
58 #define TIME_INTERVAL 3
60 static void sslOutputDot()
62 time_t thisTime
= time(0);
64 if((thisTime
- lastTime
) >= TIME_INTERVAL
) {
65 printf("."); fflush(stdout
);
70 static void printSslErrStr(
74 printf("*** %s: %ld\n", op
, (long)err
);
77 /* 2K should be enough for everybody */
81 int dtls_client(const char *hostname
, int bypass
);
83 int dtls_client(const char *hostname
, int bypass
)
87 struct sockaddr_in sa
;
89 printf("Running dtls_client test with hostname=%s, bypass=%d\n", hostname
, bypass
);
91 if ((fd
=socket(AF_INET
, SOCK_DGRAM
, 0))==-1) {
96 memset((char *) &sa
, 0, sizeof(sa
));
97 sa
.sin_family
= AF_INET
;
98 sa
.sin_port
= htons(PORT
);
99 if (inet_aton(hostname
, &sa
.sin_addr
)==0) {
100 fprintf(stderr
, "inet_aton() failed\n");
104 if(connect(fd
, (struct sockaddr
*)&sa
, sizeof(sa
))==-1)
110 /* Change to non blocking io */
111 fcntl(fd
, F_SETFL
, O_NONBLOCK
);
113 SSLRecordContextRef c
=(intptr_t)fd
;
117 SSLContextRef ctx
= NULL
;
119 SSLClientCertificateState certState
;
120 SSLCipherSuite negCipher
;
121 SSLProtocol negVersion
;
124 * Set up a SecureTransport session.
127 ctx
= SSLCreateContextWithRecordFuncs(kCFAllocatorDefault
, kSSLClientSide
, kSSLDatagramType
, &TLSSocket_Funcs
);
129 printSslErrStr("SSLCreateContextWithRecordFuncs", -1);
133 printf("Attaching filter\n");
134 ortn
= TLSSocket_Attach(fd
);
136 printSslErrStr("TLSSocket_Attach", ortn
);
141 tlsfd
= open("/dev/tlsnke", O_RDWR
);
143 perror("opening tlsnke dev");
148 ortn
= SSLSetRecordContext(ctx
, c
);
150 printSslErrStr("SSLSetRecordContext", ortn
);
154 ortn
= SSLSetMaxDatagramRecordSize(ctx
, 600);
156 printSslErrStr("SSLSetMaxDatagramRecordSize", ortn
);
160 /* Lets not verify the cert, which is a random test cert */
161 ortn
= SSLSetEnableCertVerify(ctx
, false);
163 printSslErrStr("SSLSetEnableCertVerify", ortn
);
167 ortn
= SSLSetCertificate(ctx
, server_chain());
169 printSslErrStr("SSLSetCertificate", ortn
);
173 printf("Handshake...\n");
176 ortn
= SSLHandshake(ctx
);
177 if(ortn
== errSSLWouldBlock
) {
178 /* keep UI responsive */
181 } while (ortn
== errSSLWouldBlock
);
184 SSLGetClientCertificateState(ctx
, &certState
);
185 SSLGetNegotiatedCipher(ctx
, &negCipher
);
186 SSLGetNegotiatedProtocolVersion(ctx
, &negVersion
);
190 ssize_t sreadLen
, swriteLen
;
191 size_t readLen
, writeLen
;
199 snprintf(buffer
, BUFLEN
, "Message %d", count
);
200 len
= strlen(buffer
);
203 /* Send data through the side channel, kind of like utun would */
204 swriteLen
=write(tlsfd
, buffer
, len
);
206 perror("write to tlsfd");
211 ortn
=SSLWrite(ctx
, buffer
, len
, &writeLen
);
213 printSslErrStr("SSLWrite", ortn
);
218 printf("Wrote %lu bytes\n", writeLen
);
224 sreadLen
=read(tlsfd
, buffer
, BUFLEN
);
225 } while((sreadLen
==-1) && (errno
==EAGAIN
) && (timeout
--));
226 if((sreadLen
==-1) && (errno
==EAGAIN
)) {
227 printf("Read timeout...\n");
231 perror("read from tlsfd");
238 ortn
=SSLRead(ctx
, buffer
, BUFLEN
, &readLen
);
239 } while((ortn
==errSSLWouldBlock
) && (timeout
--));
240 if(ortn
==errSSLWouldBlock
) {
241 printf("SSLRead timeout...\n");
245 printSslErrStr("SSLRead", ortn
);
251 printf("Received %lu bytes: %s\n", readLen
, buffer
);
257 SSLDisposeContext(ctx
);