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@
25 #include <Security/Security.h>
26 #include <Security/SecBase.h>
28 #include "../sslViewer/sslAppUtils.h"
31 #include <sys/types.h>
32 #include <sys/socket.h>
33 #include <netinet/in.h>
34 #include <arpa/inet.h>
37 #include <unistd.h> /* close() */
38 #include <string.h> /* memset() */
43 #include <securityd/spi.h>
46 #include "ssl-utils.h"
48 #define SERVER "127.0.0.1"
49 //#define SERVER "17.201.58.114"
55 static void dumppacket(const unsigned char *data
, unsigned long len
)
60 if((i
&0xf)==0) printf("%04lx :",i
);
61 printf(" %02x", data
[i
]);
62 if((i
&0xf)==0xf) printf("\n");
68 /* 2K should be enough for everybody */
70 static unsigned char readBuffer
[MTU
];
71 static unsigned int readOff
=0;
72 static size_t readLeft
=0;
76 SSLConnectionRef connection
,
80 int fd
= (int)connection
;
82 uint8_t *d
=readBuffer
;
86 len
= read(fd
, readBuffer
, MTU
);
90 readLeft
=(size_t) len
;
91 printf("SocketRead: %ld bytes... epoch: %02x seq=%02x%02x\n",
92 len
, d
[4], d
[9], d
[10]);
98 //printf("SocketRead: EAGAIN\n");
100 /* nonblocking, no data */
101 return errSSLWouldBlock
;
103 perror("SocketRead");
109 if(readLeft
<*dataLength
) {
110 *dataLength
=readLeft
;
113 memcpy(data
, readBuffer
+readOff
, *dataLength
);
114 readLeft
-=*dataLength
;
115 readOff
+=*dataLength
;
117 return errSecSuccess
;
122 OSStatus
SocketWrite(
123 SSLConnectionRef connection
,
125 size_t *dataLength
) /* IN/OUT */
127 int fd
= (int)connection
;
129 OSStatus err
= errSecSuccess
;
130 const uint8_t *d
=data
;
135 /* drop 1/8th packets */
136 printf("SocketWrite: Drop %ld bytes... epoch: %02x seq=%02x%02x\n",
137 *dataLength
, d
[4], d
[9], d
[10]);
138 return errSecSuccess
;
143 len
= send(fd
, data
, *dataLength
, 0);
146 *dataLength
=(size_t)len
;
147 printf("SocketWrite: Sent %ld bytes... epoch: %02x seq=%02x%02x\n",
148 len
, d
[4], d
[9], d
[10]);
155 /* nonblocking, no data */
156 err
= errSSLWouldBlock
;
159 perror("SocketWrite");
169 int main(int argc
, char **argv
)
172 struct sockaddr_in sa
;
174 if ((fd
=socket(AF_INET
, SOCK_DGRAM
, 0))==-1) {
185 memset((char *) &sa
, 0, sizeof(sa
));
186 sa
.sin_family
= AF_INET
;
187 sa
.sin_port
= htons(PORT
);
188 if (inet_aton(SERVER
, &sa
.sin_addr
)==0) {
189 fprintf(stderr
, "inet_aton() failed\n");
193 time_t seed
=time(NULL
);
194 // time_t seed=1298952499;
195 srand((unsigned)seed
);
196 printf("Random drop initialized with seed = %lu\n", seed
);
198 if(connect(fd
, (struct sockaddr
*)&sa
, sizeof(sa
))==-1)
204 /* Change to non blocking io */
205 fcntl(fd
, F_SETFL
, O_NONBLOCK
);
207 SSLConnectionRef c
=(SSLConnectionRef
)(intptr_t)fd
;
211 SSLContextRef ctx
= NULL
;
213 SSLClientCertificateState certState
;
214 SSLCipherSuite negCipher
;
215 SSLProtocol negVersion
;
218 * Set up a SecureTransport session.
220 ortn
= SSLNewDatagramContext(false, &ctx
);
222 printSslErrStr("SSLNewDatagramContext", ortn
);
225 ortn
= SSLSetIOFuncs(ctx
, SocketRead
, SocketWrite
);
227 printSslErrStr("SSLSetIOFuncs", ortn
);
231 ortn
= SSLSetConnection(ctx
, c
);
233 printSslErrStr("SSLSetConnection", ortn
);
237 ortn
= SSLSetMaxDatagramRecordSize(ctx
, 400);
239 printSslErrStr("SSLSetMaxDatagramRecordSize", ortn
);
243 /* Lets not verify the cert, which is a random test cert */
244 ortn
= SSLSetEnableCertVerify(ctx
, false);
246 printSslErrStr("SSLSetEnableCertVerify", ortn
);
250 ortn
= SSLSetCertificate(ctx
, server_chain());
252 printSslErrStr("SSLSetCertificate", ortn
);
257 ortn
= SSLHandshake(ctx
);
258 if(ortn
== errSSLWouldBlock
) {
259 /* keep UI responsive */
262 } while (ortn
== errSSLWouldBlock
);
265 SSLGetClientCertificateState(ctx
, &certState
);
266 SSLGetNegotiatedCipher(ctx
, &negCipher
);
267 SSLGetNegotiatedProtocolVersion(ctx
, &negVersion
);
270 size_t len
, readLen
, writeLen
;
277 snprintf(buffer
, BUFLEN
, "Message %d", count
);
278 len
= strlen(buffer
);
280 ortn
=SSLWrite(ctx
, buffer
, len
, &writeLen
);
282 printSslErrStr("SSLWrite", ortn
);
285 printf("Wrote %lu bytes\n", writeLen
);
290 ortn
=SSLRead(ctx
, buffer
, BUFLEN
, &readLen
);
291 } while((ortn
==errSSLWouldBlock
) && (timeout
--));
292 if(ortn
==errSSLWouldBlock
) {
293 printf("Echo timeout...\n");
297 printSslErrStr("SSLRead", ortn
);
301 printf("Received %lu bytes: %s\n", readLen
, buffer
);
307 SSLDisposeContext(ctx
);