]> git.saurik.com Git - apple/security.git/blob - SecurityTests/clxutils/clAppUtils/sslClient.cpp
Security-57336.1.9.tar.gz
[apple/security.git] / SecurityTests / clxutils / clAppUtils / sslClient.cpp
1 /*
2 * sslClient.cpp : perform one SSL client side sesssion
3 */
4 #include <Security/SecureTransport.h>
5 #include <Security/Security.h>
6 #include <clAppUtils/sslAppUtils.h>
7 #include <clAppUtils/ioSock.h>
8 #include <clAppUtils/sslThreading.h>
9 #include <clAppUtils/ringBufferIo.h>
10 #include <utilLib/common.h>
11 #include <security_cdsa_utils/cuPrintCert.h>
12
13 #include <CoreServices/../Frameworks/CarbonCore.framework/Headers/MacErrors.h>
14 #include <stdio.h>
15 #include <stdlib.h>
16 #include <string.h>
17 #include <time.h>
18 #include <ctype.h>
19 #include <sys/param.h>
20
21 /* when true, keep listening until server disconnects */
22 #define KEEP_CONNECTED 1
23
24 #define CLIENT_GETMSG "GET / HTTP/1.0\r\n\r\n"
25
26 #define READBUF_LEN 256
27
28 /* relies on SSLSetProtocolVersionEnabled */
29 OSStatus sslAppClient(
30 SslAppTestParams *params)
31 {
32 PeerSpec peerId;
33 otSocket sock = 0;
34 OSStatus ortn;
35 SSLContextRef ctx = NULL;
36 SecKeychainRef clientKc = nil;
37 CFArrayRef clientCerts = nil;
38 RingBuffers ringBufs = {params->serverToClientRing, params->clientToServerRing};
39
40 sslThrDebug("Client", "starting");
41 params->negVersion = kSSLProtocolUnknown;
42 params->negCipher = SSL_NULL_WITH_NULL_NULL;
43 params->ortn = noHardwareErr;
44
45 if(params->serverToClientRing == NULL) {
46 /* first make sure requested server is there */
47 ortn = MakeServerConnection(params->hostName, params->port,
48 params->nonBlocking, &sock, &peerId);
49 if(ortn) {
50 printf("MakeServerConnection returned %d; aborting\n", (int)ortn);
51 return ortn;
52 }
53 }
54
55 /*
56 * Set up a SecureTransport session.
57 */
58 ortn = SSLNewContext(false, &ctx);
59 if(ortn) {
60 printSslErrStr("SSLNewContext", ortn);
61 goto cleanup;
62 }
63 if(params->serverToClientRing) {
64 ortn = SSLSetIOFuncs(ctx, ringReadFunc, ringWriteFunc);
65 if(ortn) {
66 printSslErrStr("SSLSetIOFuncs", ortn);
67 goto cleanup;
68 }
69 ortn = SSLSetConnection(ctx, (SSLConnectionRef)&ringBufs);
70 if(ortn) {
71 printSslErrStr("SSLSetConnection", ortn);
72 goto cleanup;
73 }
74 }
75 else {
76 ortn = SSLSetIOFuncs(ctx, SocketRead, SocketWrite);
77 if(ortn) {
78 printSslErrStr("SSLSetIOFuncs", ortn);
79 goto cleanup;
80 }
81 ortn = SSLSetConnection(ctx, (SSLConnectionRef)sock);
82 if(ortn) {
83 printSslErrStr("SSLSetConnection", ortn);
84 goto cleanup;
85 }
86 }
87 if(!params->skipHostNameCheck) {
88 ortn = SSLSetPeerDomainName(ctx, params->hostName,
89 strlen(params->hostName) + 1);
90 if(ortn) {
91 printSslErrStr("SSLSetPeerDomainName", ortn);
92 goto cleanup;
93 }
94 }
95
96 /* remainder of setup is optional */
97 if(params->anchorFile) {
98 ortn = sslAddTrustedRoot(ctx, params->anchorFile, params->replaceAnchors);
99 if(ortn) {
100 goto cleanup;
101 }
102 }
103 if(!params->noProtSpec) {
104 ortn = sslSetProtocols(ctx, params->acceptedProts, params->tryVersion);
105 if(ortn) {
106 goto cleanup;
107 }
108 }
109 if(params->resumeEnable) {
110 ortn = SSLSetPeerID(ctx, &peerId, sizeof(PeerSpec));
111 if(ortn) {
112 printSslErrStr("SSLSetPeerID", ortn);
113 goto cleanup;
114 }
115 }
116 if(params->disableCertVerify) {
117 ortn = SSLSetEnableCertVerify(ctx, false);
118 if(ortn) {
119 printSslErrStr("SSLSetEnableCertVerify", ortn);
120 goto cleanup;
121 }
122 }
123 if(params->ciphers != NULL) {
124 ortn = sslSetEnabledCiphers(ctx, params->ciphers);
125 if(ortn) {
126 goto cleanup;
127 }
128 }
129 if(params->myCertKcName) {
130 clientCerts = getSslCerts(params->myCertKcName, CSSM_FALSE, CSSM_FALSE, NULL, &clientKc);
131 if(clientCerts == nil) {
132 exit(1);
133 }
134 if(params->password) {
135 ortn = SecKeychainUnlock(clientKc, strlen(params->password),
136 (void *)params->password, true);
137 if(ortn) {
138 printf("SecKeychainUnlock returned %d\n", (int)ortn);
139 /* oh well */
140 }
141 }
142 if(params->idIsTrustedRoot) {
143 /* assume this is a root we want to implicitly trust */
144 ortn = addIdentityAsTrustedRoot(ctx, clientCerts);
145 if(ortn) {
146 goto cleanup;
147 }
148 }
149 ortn = SSLSetCertificate(ctx, clientCerts);
150 if(ortn) {
151 printSslErrStr("SSLSetCertificate", ortn);
152 goto cleanup;
153 }
154 }
155 do {
156 ortn = SSLHandshake(ctx);
157 if((ortn == errSSLWouldBlock) && !params->silent) {
158 /* keep UI responsive */
159 sslOutputDot();
160 }
161 } while (ortn == errSSLWouldBlock);
162
163 SSLGetClientCertificateState(ctx, &params->certState);
164 SSLGetNegotiatedCipher(ctx, &params->negCipher);
165 SSLGetNegotiatedProtocolVersion(ctx, &params->negVersion);
166
167 if(ortn != noErr) {
168 goto cleanup;
169 }
170
171 /* send a GET msg */
172 size_t actLen;
173 ortn = SSLWrite(ctx, CLIENT_GETMSG, strlen(CLIENT_GETMSG), &actLen);
174 if(ortn) {
175 printSslErrStr("SSLWrite", ortn);
176 goto cleanup;
177 }
178
179 #if KEEP_CONNECTED
180
181 /*
182 * Consume any server data and wait for server to disconnect
183 */
184 char readBuf[READBUF_LEN];
185 do {
186 ortn = SSLRead(ctx, readBuf, READBUF_LEN, &actLen);
187 } while (ortn == errSSLWouldBlock);
188
189 /* convert normal "shutdown" into zero err rtn */
190 if(ortn == errSSLClosedGraceful) {
191 ortn = noErr;
192 }
193 #endif /* KEEP_CONNECTED */
194
195 cleanup:
196 if(ctx) {
197 OSStatus cerr = SSLClose(ctx);
198 if(ortn == noErr) {
199 ortn = cerr;
200 }
201 }
202 if(sock) {
203 endpointShutdown(sock);
204 }
205 ringBuffersClose(&ringBufs); /* tolerates NULLs */
206 if(ctx) {
207 SSLDisposeContext(ctx);
208 }
209 params->ortn = ortn;
210 sslThrDebug("Client", "done");
211 return ortn;
212 }