]> git.saurik.com Git - apple/security.git/blob - OSX/libsecurity_ssl/sslViewer/sslAppUtils.cpp
Security-57336.1.9.tar.gz
[apple/security.git] / OSX / libsecurity_ssl / sslViewer / sslAppUtils.cpp
1 /*
2 * Copyright (c) 2006-2008,2010-2014 Apple Inc. All Rights Reserved.
3 */
4
5 #include "sslAppUtils.h"
6 #include "fileIo.h"
7 #include <stdlib.h>
8 #include <stdio.h>
9 #include <sys/param.h>
10 #include <Security/SecBase.h>
11
12 #include <CoreFoundation/CoreFoundation.h>
13 #include <Security/Security.h>
14 #include <Security/SecIdentityPriv.h>
15 #include <AssertMacros.h>
16
17 #define CFReleaseSafe(CF) { CFTypeRef _cf = (CF); if (_cf) CFRelease(_cf); }
18
19 const char *sslGetCipherSuiteString(SSLCipherSuite cs)
20 {
21 static char noSuite[40];
22
23 switch (cs) {
24 /* TLS cipher suites, RFC 2246 */
25 case SSL_NULL_WITH_NULL_NULL: return "TLS_NULL_WITH_NULL_NULL";
26 case SSL_RSA_WITH_NULL_MD5: return "TLS_RSA_WITH_NULL_MD5";
27 case SSL_RSA_WITH_NULL_SHA: return "TLS_RSA_WITH_NULL_SHA";
28 case SSL_RSA_EXPORT_WITH_RC4_40_MD5: return "TLS_RSA_EXPORT_WITH_RC4_40_MD5";
29 case SSL_RSA_WITH_RC4_128_MD5: return "TLS_RSA_WITH_RC4_128_MD5";
30 case SSL_RSA_WITH_RC4_128_SHA: return "TLS_RSA_WITH_RC4_128_SHA";
31 case SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5: return "TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5";
32 case SSL_RSA_WITH_IDEA_CBC_SHA: return "TLS_RSA_WITH_IDEA_CBC_SHA";
33 case SSL_RSA_EXPORT_WITH_DES40_CBC_SHA: return "TLS_RSA_EXPORT_WITH_DES40_CBC_SHA";
34 case SSL_RSA_WITH_DES_CBC_SHA: return "TLS_RSA_WITH_DES_CBC_SHA";
35 case SSL_RSA_WITH_3DES_EDE_CBC_SHA: return "TLS_RSA_WITH_3DES_EDE_CBC_SHA";
36 case SSL_DH_DSS_EXPORT_WITH_DES40_CBC_SHA: return "TLS_DH_DSS_EXPORT_WITH_DES40_CBC_SHA";
37 case SSL_DH_DSS_WITH_DES_CBC_SHA: return "TLS_DH_DSS_WITH_DES_CBC_SHA";
38 case SSL_DH_DSS_WITH_3DES_EDE_CBC_SHA: return "TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA";
39 case SSL_DH_RSA_EXPORT_WITH_DES40_CBC_SHA: return "TLS_DH_RSA_EXPORT_WITH_DES40_CBC_SHA";
40 case SSL_DH_RSA_WITH_DES_CBC_SHA: return "TLS_DH_RSA_WITH_DES_CBC_SHA";
41 case SSL_DH_RSA_WITH_3DES_EDE_CBC_SHA: return "TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA";
42 case SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA: return "TLS_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA";
43 case SSL_DHE_DSS_WITH_DES_CBC_SHA: return "TLS_DHE_DSS_WITH_DES_CBC_SHA";
44 case SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA: return "TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA";
45 case SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA: return "TLS_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA";
46 case SSL_DHE_RSA_WITH_DES_CBC_SHA: return "TLS_DHE_RSA_WITH_DES_CBC_SHA";
47 case SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA: return "TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA";
48 case SSL_DH_anon_EXPORT_WITH_RC4_40_MD5: return "TLS_DH_anon_EXPORT_WITH_RC4_40_MD5";
49 case SSL_DH_anon_WITH_RC4_128_MD5: return "TLS_DH_anon_WITH_RC4_128_MD5";
50 case SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA: return "TLS_DH_anon_EXPORT_WITH_DES40_CBC_SHA";
51 case SSL_DH_anon_WITH_DES_CBC_SHA: return "TLS_DH_anon_WITH_DES_CBC_SHA";
52 case SSL_DH_anon_WITH_3DES_EDE_CBC_SHA: return "TLS_DH_anon_WITH_3DES_EDE_CBC_SHA";
53
54 /* SSLv3 Fortezza cipher suites, from NSS */
55 case SSL_FORTEZZA_DMS_WITH_NULL_SHA: return "SSL_FORTEZZA_DMS_WITH_NULL_SHA";
56 case SSL_FORTEZZA_DMS_WITH_FORTEZZA_CBC_SHA:return "SSL_FORTEZZA_DMS_WITH_FORTEZZA_CBC_SHA";
57
58 /* TLS addenda using AES-CBC, RFC 3268 */
59 case TLS_RSA_WITH_AES_128_CBC_SHA: return "TLS_RSA_WITH_AES_128_CBC_SHA";
60 case TLS_DH_DSS_WITH_AES_128_CBC_SHA: return "TLS_DH_DSS_WITH_AES_128_CBC_SHA";
61 case TLS_DH_RSA_WITH_AES_128_CBC_SHA: return "TLS_DH_RSA_WITH_AES_128_CBC_SHA";
62 case TLS_DHE_DSS_WITH_AES_128_CBC_SHA: return "TLS_DHE_DSS_WITH_AES_128_CBC_SHA";
63 case TLS_DHE_RSA_WITH_AES_128_CBC_SHA: return "TLS_DHE_RSA_WITH_AES_128_CBC_SHA";
64 case TLS_DH_anon_WITH_AES_128_CBC_SHA: return "TLS_DH_anon_WITH_AES_128_CBC_SHA";
65 case TLS_RSA_WITH_AES_256_CBC_SHA: return "TLS_RSA_WITH_AES_256_CBC_SHA";
66 case TLS_DH_DSS_WITH_AES_256_CBC_SHA: return "TLS_DH_DSS_WITH_AES_256_CBC_SHA";
67 case TLS_DH_RSA_WITH_AES_256_CBC_SHA: return "TLS_DH_RSA_WITH_AES_256_CBC_SHA";
68 case TLS_DHE_DSS_WITH_AES_256_CBC_SHA: return "TLS_DHE_DSS_WITH_AES_256_CBC_SHA";
69 case TLS_DHE_RSA_WITH_AES_256_CBC_SHA: return "TLS_DHE_RSA_WITH_AES_256_CBC_SHA";
70 case TLS_DH_anon_WITH_AES_256_CBC_SHA: return "TLS_DH_anon_WITH_AES_256_CBC_SHA";
71
72 /* ECDSA addenda, RFC 4492 */
73 case TLS_ECDH_ECDSA_WITH_NULL_SHA: return "TLS_ECDH_ECDSA_WITH_NULL_SHA";
74 case TLS_ECDH_ECDSA_WITH_RC4_128_SHA: return "TLS_ECDH_ECDSA_WITH_RC4_128_SHA";
75 case TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA: return "TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA";
76 case TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA: return "TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA";
77 case TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA: return "TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA";
78 case TLS_ECDHE_ECDSA_WITH_NULL_SHA: return "TLS_ECDHE_ECDSA_WITH_NULL_SHA";
79 case TLS_ECDHE_ECDSA_WITH_RC4_128_SHA: return "TLS_ECDHE_ECDSA_WITH_RC4_128_SHA";
80 case TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA: return "TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA";
81 case TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA: return "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA";
82 case TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA: return "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA";
83 case TLS_ECDH_RSA_WITH_NULL_SHA: return "TLS_ECDH_RSA_WITH_NULL_SHA";
84 case TLS_ECDH_RSA_WITH_RC4_128_SHA: return "TLS_ECDH_RSA_WITH_RC4_128_SHA";
85 case TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA: return "TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA";
86 case TLS_ECDH_RSA_WITH_AES_128_CBC_SHA: return "TLS_ECDH_RSA_WITH_AES_128_CBC_SHA";
87 case TLS_ECDH_RSA_WITH_AES_256_CBC_SHA: return "TLS_ECDH_RSA_WITH_AES_256_CBC_SHA";
88 case TLS_ECDHE_RSA_WITH_NULL_SHA: return "TLS_ECDHE_RSA_WITH_NULL_SHA";
89 case TLS_ECDHE_RSA_WITH_RC4_128_SHA: return "TLS_ECDHE_RSA_WITH_RC4_128_SHA";
90 case TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA: return "TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA";
91 case TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA: return "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA";
92 case TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA: return "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA";
93 case TLS_ECDH_anon_WITH_NULL_SHA: return "TLS_ECDH_anon_WITH_NULL_SHA";
94 case TLS_ECDH_anon_WITH_RC4_128_SHA: return "TLS_ECDH_anon_WITH_RC4_128_SHA";
95 case TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA: return "TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA";
96 case TLS_ECDH_anon_WITH_AES_128_CBC_SHA: return "TLS_ECDH_anon_WITH_AES_128_CBC_SHA";
97 case TLS_ECDH_anon_WITH_AES_256_CBC_SHA: return "TLS_ECDH_anon_WITH_AES_256_CBC_SHA";
98
99 /* TLS 1.2 addenda, RFC 5246 */
100 case TLS_RSA_WITH_AES_128_CBC_SHA256: return "TLS_RSA_WITH_AES_128_CBC_SHA256";
101 case TLS_RSA_WITH_AES_256_CBC_SHA256: return "TLS_RSA_WITH_AES_256_CBC_SHA256";
102 case TLS_DH_DSS_WITH_AES_128_CBC_SHA256: return "TLS_DH_DSS_WITH_AES_128_CBC_SHA256";
103 case TLS_DH_RSA_WITH_AES_128_CBC_SHA256: return "TLS_DH_RSA_WITH_AES_128_CBC_SHA256";
104 case TLS_DHE_DSS_WITH_AES_128_CBC_SHA256: return "TLS_DHE_DSS_WITH_AES_128_CBC_SHA256";
105 case TLS_DHE_RSA_WITH_AES_128_CBC_SHA256: return "TLS_DHE_RSA_WITH_AES_128_CBC_SHA256";
106 case TLS_DH_DSS_WITH_AES_256_CBC_SHA256: return "TLS_DH_DSS_WITH_AES_256_CBC_SHA256";
107 case TLS_DH_RSA_WITH_AES_256_CBC_SHA256: return "TLS_DH_RSA_WITH_AES_256_CBC_SHA256";
108 case TLS_DHE_DSS_WITH_AES_256_CBC_SHA256: return "TLS_DHE_DSS_WITH_AES_256_CBC_SHA256";
109 case TLS_DHE_RSA_WITH_AES_256_CBC_SHA256: return "TLS_DHE_RSA_WITH_AES_256_CBC_SHA256";
110 case TLS_DH_anon_WITH_AES_128_CBC_SHA256: return "TLS_DH_anon_WITH_AES_128_CBC_SHA256";
111 case TLS_DH_anon_WITH_AES_256_CBC_SHA256: return "TLS_DH_anon_WITH_AES_256_CBC_SHA256";
112
113 /* TLS addenda using AES-GCM, RFC 5288 */
114 case TLS_RSA_WITH_AES_128_GCM_SHA256: return "TLS_RSA_WITH_AES_128_GCM_SHA256";
115 case TLS_RSA_WITH_AES_256_GCM_SHA384: return "TLS_DHE_RSA_WITH_AES_128_GCM_SHA256";
116 case TLS_DHE_RSA_WITH_AES_128_GCM_SHA256: return "TLS_DHE_RSA_WITH_AES_128_GCM_SHA256";
117 case TLS_DHE_RSA_WITH_AES_256_GCM_SHA384: return "TLS_DHE_RSA_WITH_AES_256_GCM_SHA384";
118 case TLS_DH_RSA_WITH_AES_128_GCM_SHA256: return "TLS_DH_RSA_WITH_AES_128_GCM_SHA256";
119 case TLS_DH_RSA_WITH_AES_256_GCM_SHA384: return "TLS_DH_RSA_WITH_AES_256_GCM_SHA384";
120 case TLS_DHE_DSS_WITH_AES_128_GCM_SHA256: return "TLS_DHE_DSS_WITH_AES_128_GCM_SHA256";
121 case TLS_DHE_DSS_WITH_AES_256_GCM_SHA384: return "TLS_DHE_DSS_WITH_AES_256_GCM_SHA384";
122 case TLS_DH_DSS_WITH_AES_128_GCM_SHA256: return "TLS_DH_DSS_WITH_AES_128_GCM_SHA256";
123 case TLS_DH_DSS_WITH_AES_256_GCM_SHA384: return "TLS_DH_DSS_WITH_AES_256_GCM_SHA384";
124 case TLS_DH_anon_WITH_AES_128_GCM_SHA256: return "TLS_DH_anon_WITH_AES_128_GCM_SHA256";
125 case TLS_DH_anon_WITH_AES_256_GCM_SHA384: return "TLS_DH_anon_WITH_AES_256_GCM_SHA384";
126
127 /* ECDSA addenda, RFC 5289 */
128 case TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256: return "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256";
129 case TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384: return "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384";
130 case TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256: return "TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256";
131 case TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384: return "TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384";
132 case TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256: return "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256";
133 case TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384: return "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384";
134 case TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256: return "TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256";
135 case TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384: return "TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384";
136 case TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256: return "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256";
137 case TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384: return "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384";
138 case TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256: return "TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256";
139 case TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384: return "TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384";
140 case TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256: return "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256";
141 case TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384: return "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384";
142 case TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256: return "TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256";
143 case TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384: return "TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384";
144
145 /*
146 * Tags for SSL 2 cipher kinds which are not specified for SSL 3.
147 */
148 case SSL_RSA_WITH_RC2_CBC_MD5: return "TLS_RSA_WITH_RC2_CBC_MD5";
149 case SSL_RSA_WITH_IDEA_CBC_MD5: return "TLS_RSA_WITH_IDEA_CBC_MD5";
150 case SSL_RSA_WITH_DES_CBC_MD5: return "TLS_RSA_WITH_DES_CBC_MD5";
151 case SSL_RSA_WITH_3DES_EDE_CBC_MD5: return "TLS_RSA_WITH_3DES_EDE_CBC_MD5";
152 case SSL_NO_SUCH_CIPHERSUITE: return "SSL_NO_SUCH_CIPHERSUITE";
153
154 default:
155 snprintf(noSuite, sizeof(noSuite), "Unknown ciphersuite 0x%04x", (unsigned)cs);
156 return noSuite;
157 }
158 }
159
160 /*
161 * Given a SSLProtocolVersion - typically from SSLGetProtocolVersion -
162 * return a string representation.
163 */
164 const char *sslGetProtocolVersionString(SSLProtocol prot)
165 {
166 static char noProt[20];
167
168 switch(prot) {
169 case kSSLProtocolUnknown: return "kSSLProtocolUnknown";
170 case kSSLProtocol2: return "kSSLProtocol2";
171 case kSSLProtocol3: return "kSSLProtocol3";
172 case kSSLProtocol3Only: return "kSSLProtocol3Only";
173 case kTLSProtocol1: return "kTLSProtocol1";
174 case kTLSProtocol1Only: return "kTLSProtocol1Only";
175 case kTLSProtocol11: return "kTLSProtocol11";
176 case kTLSProtocol12: return "kTLSProtocol12";
177 default:
178 sprintf(noProt, "Unknown (%d)", (unsigned)prot);
179 return noProt;
180 }
181 }
182
183 /*
184 * Return string representation of SecureTransport-related OSStatus.
185 */
186 const char *sslGetSSLErrString(OSStatus err)
187 {
188 static char errSecSuccessStr[20];
189
190 switch(err) {
191 case errSecSuccess: return "errSecSuccess";
192 case errSecAllocate: return "errSecAllocate";
193 case errSecParam: return "errSecParam";
194 case errSecUnimplemented: return "errSecUnimplemented";
195 case errSecIO: return "errSecIO";
196 case errSecBadReq: return "errSecBadReq";
197 /* SSL errors */
198 case errSSLProtocol: return "errSSLProtocol";
199 case errSSLNegotiation: return "errSSLNegotiation";
200 case errSSLFatalAlert: return "errSSLFatalAlert";
201 case errSSLWouldBlock: return "errSSLWouldBlock";
202 case errSSLSessionNotFound: return "errSSLSessionNotFound";
203 case errSSLClosedGraceful: return "errSSLClosedGraceful";
204 case errSSLClosedAbort: return "errSSLClosedAbort";
205 case errSSLXCertChainInvalid: return "errSSLXCertChainInvalid";
206 case errSSLBadCert: return "errSSLBadCert";
207 case errSSLCrypto: return "errSSLCrypto";
208 case errSSLInternal: return "errSSLInternal";
209 case errSSLModuleAttach: return "errSSLModuleAttach";
210 case errSSLUnknownRootCert: return "errSSLUnknownRootCert";
211 case errSSLNoRootCert: return "errSSLNoRootCert";
212 case errSSLCertExpired: return "errSSLCertExpired";
213 case errSSLCertNotYetValid: return "errSSLCertNotYetValid";
214 case errSSLClosedNoNotify: return "errSSLClosedNoNotify";
215 case errSSLBufferOverflow: return "errSSLBufferOverflow";
216 case errSSLBadCipherSuite: return "errSSLBadCipherSuite";
217 /* TLS/Panther addenda */
218 case errSSLPeerUnexpectedMsg: return "errSSLPeerUnexpectedMsg";
219 case errSSLPeerBadRecordMac: return "errSSLPeerBadRecordMac";
220 case errSSLPeerDecryptionFail: return "errSSLPeerDecryptionFail";
221 case errSSLPeerRecordOverflow: return "errSSLPeerRecordOverflow";
222 case errSSLPeerDecompressFail: return "errSSLPeerDecompressFail";
223 case errSSLPeerHandshakeFail: return "errSSLPeerHandshakeFail";
224 case errSSLPeerBadCert: return "errSSLPeerBadCert";
225 case errSSLPeerUnsupportedCert: return "errSSLPeerUnsupportedCert";
226 case errSSLPeerCertRevoked: return "errSSLPeerCertRevoked";
227 case errSSLPeerCertExpired: return "errSSLPeerCertExpired";
228 case errSSLPeerCertUnknown: return "errSSLPeerCertUnknown";
229 case errSSLIllegalParam: return "errSSLIllegalParam";
230 case errSSLPeerUnknownCA: return "errSSLPeerUnknownCA";
231 case errSSLPeerAccessDenied: return "errSSLPeerAccessDenied";
232 case errSSLPeerDecodeError: return "errSSLPeerDecodeError";
233 case errSSLPeerDecryptError: return "errSSLPeerDecryptError";
234 case errSSLPeerExportRestriction: return "errSSLPeerExportRestriction";
235 case errSSLPeerProtocolVersion: return "errSSLPeerProtocolVersion";
236 case errSSLPeerInsufficientSecurity:return "errSSLPeerInsufficientSecurity";
237 case errSSLPeerInternalError: return "errSSLPeerInternalError";
238 case errSSLPeerUserCancelled: return "errSSLPeerUserCancelled";
239 case errSSLPeerNoRenegotiation: return "errSSLPeerNoRenegotiation";
240 case errSSLHostNameMismatch: return "errSSLHostNameMismatch";
241 case errSSLConnectionRefused: return "errSSLConnectionRefused";
242 case errSSLDecryptionFail: return "errSSLDecryptionFail";
243 case errSSLBadRecordMac: return "errSSLBadRecordMac";
244 case errSSLRecordOverflow: return "errSSLRecordOverflow";
245 case errSSLBadConfiguration: return "errSSLBadConfiguration";
246
247 /* some from the Sec layer */
248 case errSecNotAvailable: return "errSecNotAvailable";
249 case errSecDuplicateItem: return "errSecDuplicateItem";
250 case errSecItemNotFound: return "errSecItemNotFound";
251 #if !TARGET_OS_IPHONE
252 case errSecReadOnly: return "errSecReadOnly";
253 case errSecAuthFailed: return "errSecAuthFailed";
254 case errSecNoSuchKeychain: return "errSecNoSuchKeychain";
255 case errSecInvalidKeychain: return "errSecInvalidKeychain";
256 case errSecNoSuchAttr: return "errSecNoSuchAttr";
257 case errSecInvalidItemRef: return "errSecInvalidItemRef";
258 case errSecInvalidSearchRef: return "errSecInvalidSearchRef";
259 case errSecNoSuchClass: return "errSecNoSuchClass";
260 case errSecNoDefaultKeychain: return "errSecNoDefaultKeychain";
261 case errSecWrongSecVersion: return "errSecWrongSecVersion";
262 case errSecInvalidTrustSettings: return "errSecInvalidTrustSettings";
263 case errSecNoTrustSettings: return "errSecNoTrustSettings";
264 #endif
265 default:
266 #if 0
267 if (err < (CSSM_BASE_ERROR +
268 (CSSM_ERRORCODE_MODULE_EXTENT * 8)))
269 {
270 /* assume CSSM error */
271 return cssmErrToStr(err);
272 }
273 else
274 #endif
275 {
276 sprintf(errSecSuccessStr, "Unknown (%d)", (unsigned)err);
277 return errSecSuccessStr;
278 }
279 }
280 }
281
282 void printSslErrStr(
283 const char *op,
284 OSStatus err)
285 {
286 printf("*** %s: %s\n", op, sslGetSSLErrString(err));
287 }
288
289 const char *sslGetClientCertStateString(SSLClientCertificateState state)
290 {
291 static char noState[20];
292
293 switch(state) {
294 case kSSLClientCertNone: return "ClientCertNone";
295 case kSSLClientCertRequested: return "CertRequested";
296 case kSSLClientCertSent: return "ClientCertSent";
297 case kSSLClientCertRejected: return "ClientCertRejected";
298 default:
299 sprintf(noState, "Unknown (%d)", (unsigned)state);
300 return noState;
301 }
302
303 }
304
305 const char *sslGetClientAuthTypeString(SSLClientAuthenticationType authType)
306 {
307 static char noType[20];
308
309 switch(authType) {
310 case SSLClientAuthNone: return "None";
311 case SSLClientAuth_RSASign: return "RSASign";
312 case SSLClientAuth_DSSSign: return "DSSSign";
313 case SSLClientAuth_RSAFixedDH: return "RSAFixedDH";
314 case SSLClientAuth_DSS_FixedDH: return "DSS_FixedDH";
315 case SSLClientAuth_ECDSASign: return "ECDSASign";
316 case SSLClientAuth_RSAFixedECDH: return "RSAFixedECDH";
317 case SSLClientAuth_ECDSAFixedECDH: return "ECDSAFixedECDH";
318 default:
319 sprintf(noType, "Unknown (%d)", (unsigned)authType);
320 return noType;
321 }
322 }
323
324 /*
325 * Convert a keychain name (which may be NULL) into the CFArrayRef required
326 * by SSLSetCertificate. This is a bare-bones example of this operation,
327 * since it requires and assumes that there is exactly one SecIdentity
328 * in the keychain - i.e., there is exactly one matching cert/private key
329 * pair. A real world server would probably search a keychain for a SecIdentity
330 * matching some specific criteria.
331 */
332 CFArrayRef getSslCerts(
333 const char *kcName, // may be NULL, i.e., use default
334 bool encryptOnly,
335 bool completeCertChain,
336 const char *anchorFile, // optional trusted anchor
337 SecKeychainRef *pKcRef) // RETURNED
338 {
339 #if 0
340 SecKeychainRef kcRef = nil;
341 OSStatus ortn;
342
343 *pKcRef = nil;
344
345 /* pick a keychain */
346 if(kcName) {
347 ortn = SecKeychainOpen(kcName, &kcRef);
348 if(ortn) {
349 printf("SecKeychainOpen returned %d.\n", (int)ortn);
350 printf("Cannot open keychain at %s. Aborting.\n", kcName);
351 return NULL;
352 }
353 }
354 else {
355 /* use default keychain */
356 ortn = SecKeychainCopyDefault(&kcRef);
357 if(ortn) {
358 printf("SecKeychainCopyDefault returned %d; aborting.\n", (int)ortn);
359 return nil;
360 }
361 }
362 *pKcRef = kcRef;
363 return sslKcRefToCertArray(kcRef, encryptOnly, completeCertChain, anchorFile);
364 #elif TARGET_OS_IOS
365 SecCertificateRef cert = NULL;
366 SecIdentityRef identity = NULL;
367 CFMutableArrayRef certificates = NULL, result = NULL;
368 CFMutableDictionaryRef certQuery = NULL, keyQuery = NULL, keyResult = NULL;
369 SecTrustRef trust = NULL;
370 SecKeyRef key = NULL;
371 CFTypeRef pkdigest = NULL;
372
373 // Find the first private key in the keychain and return both its
374 // attributes and a ref to it.
375 require(keyQuery = CFDictionaryCreateMutable(NULL, 0, NULL, NULL), errOut);
376 CFDictionaryAddValue(keyQuery, kSecClass, kSecClassKey);
377 CFDictionaryAddValue(keyQuery, kSecAttrKeyClass, kSecAttrKeyClassPrivate);
378 CFDictionaryAddValue(keyQuery, kSecReturnRef, kCFBooleanTrue);
379 CFDictionaryAddValue(keyQuery, kSecReturnAttributes, kCFBooleanTrue);
380 require_noerr(SecItemCopyMatching(keyQuery, (CFTypeRef *)&keyResult),
381 errOut);
382 require(key = (SecKeyRef)CFDictionaryGetValue(keyResult, kSecValueRef),
383 errOut);
384 require(pkdigest = CFDictionaryGetValue(keyResult, kSecAttrApplicationLabel),
385 errOut);
386
387 // Find the first certificate that has the same public key hash as the
388 // returned private key and return it as a ref.
389 require(certQuery = CFDictionaryCreateMutable(NULL, 0, NULL, NULL), errOut);
390 CFDictionaryAddValue(certQuery, kSecClass, kSecClassCertificate);
391 CFDictionaryAddValue(certQuery, kSecAttrPublicKeyHash, pkdigest);
392 CFDictionaryAddValue(certQuery, kSecReturnRef, kCFBooleanTrue);
393 require_noerr(SecItemCopyMatching(certQuery, (CFTypeRef *)&cert), errOut);
394
395 // Create an identity from the key and certificate.
396 require(identity = SecIdentityCreate(NULL, cert, key), errOut);
397
398 // Build a (partial) certificate chain from cert
399 require(certificates = CFArrayCreateMutable(NULL, 0,
400 &kCFTypeArrayCallBacks), errOut);
401 CFArrayAppendValue(certificates, cert);
402 require_noerr(SecTrustCreateWithCertificates(certificates, NULL, &trust),
403 errOut);
404 SecTrustResultType tresult;
405 require_noerr(SecTrustEvaluate(trust, &tresult), errOut);
406
407 CFIndex certCount, ix;
408 // We need at least 1 certificate
409 require(certCount = SecTrustGetCertificateCount(trust), errOut);
410
411 // Build a result where element 0 is the identity and the other elements
412 // are the certs in the chain starting at the first intermediate up to the
413 // anchor, if we found one, or as far as we were able to build the chain
414 // if not.
415 require(result = CFArrayCreateMutable(NULL, certCount, &kCFTypeArrayCallBacks),
416 errOut);
417
418 // We are commited to returning a result now, so do not use require below
419 // this line without setting result to NULL again.
420 CFArrayAppendValue(result, identity);
421 for (ix = 1; ix < certCount; ++ix) {
422 CFArrayAppendValue(result, SecTrustGetCertificateAtIndex(trust, ix));
423 }
424
425 errOut:
426 CFReleaseSafe(trust);
427 CFReleaseSafe(certificates);
428 CFReleaseSafe(identity);
429 CFReleaseSafe(cert);
430 CFReleaseSafe(certQuery);
431 CFReleaseSafe(keyResult);
432 CFReleaseSafe(keyQuery);
433
434 return result;
435
436 #else /* !TARGET_OS_IOS */
437 SecIdentityRef identity = NULL;
438 CFMutableDictionaryRef query = NULL;
439 CFArrayRef items = NULL;
440 require(query = CFDictionaryCreateMutable(NULL, 0, NULL, NULL), errOut);
441 CFDictionaryAddValue(query, kSecClass, kSecClassIdentity);
442 CFDictionaryAddValue(query, kSecReturnRef, kCFBooleanTrue);
443 require_noerr(SecItemCopyMatching(query, (CFTypeRef *)&identity), errOut);
444
445 items = CFArrayCreate(kCFAllocatorDefault,
446 (const void **)&identity, 1, &kCFTypeArrayCallBacks);
447
448 errOut:
449 CFReleaseSafe(identity);
450 CFReleaseSafe(query);
451
452 return items;
453
454 #endif
455
456 }
457
458 #if 0
459 /*
460 * Determine if specified SecCertificateRef is a self-signed cert.
461 * We do this by comparing the subject and issuerr names; no cryptographic
462 * verification is performed.
463 *
464 * Returns true if the cert appears to be a root.
465 */
466 static bool isCertRefRoot(
467 SecCertificateRef certRef)
468 {
469 bool brtn = false;
470 #if 0
471 /* just search for the two attrs we want */
472 UInt32 tags[2] = {kSecSubjectItemAttr, kSecIssuerItemAttr};
473 SecKeychainAttributeInfo attrInfo;
474 attrInfo.count = 2;
475 attrInfo.tag = tags;
476 attrInfo.format = NULL;
477 SecKeychainAttributeList *attrList = NULL;
478 SecKeychainAttribute *attr1 = NULL;
479 SecKeychainAttribute *attr2 = NULL;
480
481 OSStatus ortn = SecKeychainItemCopyAttributesAndData(
482 (SecKeychainItemRef)certRef,
483 &attrInfo,
484 NULL, // itemClass
485 &attrList,
486 NULL, // length - don't need the data
487 NULL); // outData
488 if(ortn) {
489 cssmPerror("SecKeychainItemCopyAttributesAndData", ortn);
490 /* may want to be a bit more robust here, but this should
491 * never happen */
492 return false;
493 }
494 /* subsequent errors to errOut: */
495
496 if((attrList == NULL) || (attrList->count != 2)) {
497 printf("***Unexpected result fetching label attr\n");
498 goto errOut;
499 }
500
501 /* rootness is just byte-for-byte compare of the two names */
502 attr1 = &attrList->attr[0];
503 attr2 = &attrList->attr[1];
504 if(attr1->length == attr2->length) {
505 if(memcmp(attr1->data, attr2->data, attr1->length) == 0) {
506 brtn = true;
507 }
508 }
509 errOut:
510 SecKeychainItemFreeAttributesAndData(attrList, NULL);
511 #endif
512 return brtn;
513 }
514 #endif
515
516 #if 0
517 /*
518 * Given a SecIdentityRef, do our best to construct a complete, ordered, and
519 * verified cert chain, returning the result in a CFArrayRef. The result is
520 * suitable for use when calling SSLSetCertificate().
521 */
522 OSStatus sslCompleteCertChain(
523 SecIdentityRef identity,
524 SecCertificateRef trustedAnchor, // optional additional trusted anchor
525 bool includeRoot, // include the root in outArray
526 CFArrayRef *outArray) // created and RETURNED
527 {
528 CFMutableArrayRef certArray;
529 SecTrustRef secTrust = NULL;
530 SecPolicyRef policy = NULL;
531 SecPolicySearchRef policySearch = NULL;
532 SecTrustResultType secTrustResult;
533 CSSM_TP_APPLE_EVIDENCE_INFO *dummyEv; // not used
534 CFArrayRef certChain = NULL; // constructed chain
535 CFIndex numResCerts;
536
537 certArray = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
538 CFArrayAppendValue(certArray, identity);
539
540 /*
541 * Case 1: identity is a root; we're done. Note that this case
542 * overrides the includeRoot argument.
543 */
544 SecCertificateRef certRef;
545 OSStatus ortn = SecIdentityCopyCertificate(identity, &certRef);
546 if(ortn) {
547 /* should never happen */
548 cssmPerror("SecIdentityCopyCertificate", ortn);
549 return ortn;
550 }
551 bool isRoot = isCertRefRoot(certRef);
552 if(isRoot) {
553 *outArray = certArray;
554 CFRelease(certRef);
555 return errSecSuccess;
556 }
557
558 /*
559 * Now use SecTrust to get a complete cert chain, using all of the
560 * user's keychains to look for intermediate certs.
561 * NOTE this does NOT handle root certs which are not in the system
562 * root cert DB. (The above case, where the identity is a root cert, does.)
563 */
564 CFMutableArrayRef subjCerts = CFArrayCreateMutable(NULL, 1, &kCFTypeArrayCallBacks);
565 CFArraySetValueAtIndex(subjCerts, 0, certRef);
566
567 /* the array owns the subject cert ref now */
568 CFRelease(certRef);
569
570 /* Get a SecPolicyRef for generic X509 cert chain verification */
571 ortn = SecPolicySearchCreate(CSSM_CERT_X_509v3,
572 &CSSMOID_APPLE_X509_BASIC,
573 NULL, // value
574 &policySearch);
575 if(ortn) {
576 cssmPerror("SecPolicySearchCreate", ortn);
577 goto errOut;
578 }
579 ortn = SecPolicySearchCopyNext(policySearch, &policy);
580 if(ortn) {
581 cssmPerror("SecPolicySearchCopyNext", ortn);
582 goto errOut;
583 }
584
585 /* build a SecTrustRef for specified policy and certs */
586 ortn = SecTrustCreateWithCertificates(subjCerts,
587 policy, &secTrust);
588 if(ortn) {
589 cssmPerror("SecTrustCreateWithCertificates", ortn);
590 goto errOut;
591 }
592
593 if(trustedAnchor) {
594 /*
595 * Tell SecTrust to trust this one in addition to the current
596 * trusted system-wide anchors.
597 */
598 CFMutableArrayRef newAnchors;
599 CFArrayRef currAnchors;
600
601 ortn = SecTrustCopyAnchorCertificates(&currAnchors);
602 if(ortn) {
603 /* should never happen */
604 cssmPerror("SecTrustCopyAnchorCertificates", ortn);
605 goto errOut;
606 }
607 newAnchors = CFArrayCreateMutableCopy(NULL,
608 CFArrayGetCount(currAnchors) + 1,
609 currAnchors);
610 CFRelease(currAnchors);
611 CFArrayAppendValue(newAnchors, trustedAnchor);
612 ortn = SecTrustSetAnchorCertificates(secTrust, newAnchors);
613 CFRelease(newAnchors);
614 if(ortn) {
615 cssmPerror("SecTrustSetAnchorCertificates", ortn);
616 goto errOut;
617 }
618 }
619 /* evaluate: GO */
620 ortn = SecTrustEvaluate(secTrust, &secTrustResult);
621 if(ortn) {
622 cssmPerror("SecTrustEvaluate", ortn);
623 goto errOut;
624 }
625 switch(secTrustResult) {
626 case kSecTrustResultUnspecified:
627 /* cert chain valid, no special UserTrust assignments */
628 case kSecTrustResultProceed:
629 /* cert chain valid AND user explicitly trusts this */
630 break;
631 default:
632 /*
633 * Cert chain construction failed.
634 * Just go with the single subject cert we were given.
635 */
636 printf("***Warning: could not construct completed cert chain\n");
637 ortn = errSecSuccess;
638 goto errOut;
639 }
640
641 /* get resulting constructed cert chain */
642 ortn = SecTrustGetResult(secTrust, &secTrustResult, &certChain, &dummyEv);
643 if(ortn) {
644 cssmPerror("SecTrustEvaluate", ortn);
645 goto errOut;
646 }
647
648 /*
649 * Copy certs from constructed chain to our result array, skipping
650 * the leaf (which is already there, as a SecIdentityRef) and possibly
651 * a root.
652 */
653 numResCerts = CFArrayGetCount(certChain);
654 if(numResCerts < 2) {
655 /*
656 * Can't happen: if subject was a root, we'd already have returned.
657 * If chain doesn't verify to a root, we'd have bailed after
658 * SecTrustEvaluate().
659 */
660 printf("***sslCompleteCertChain screwup: numResCerts %d\n",
661 (int)numResCerts);
662 ortn = errSecSuccess;
663 goto errOut;
664 }
665 if(!includeRoot) {
666 /* skip the last (root) cert) */
667 numResCerts--;
668 }
669 for(CFIndex dex=1; dex<numResCerts; dex++) {
670 certRef = (SecCertificateRef)CFArrayGetValueAtIndex(certChain, dex);
671 CFArrayAppendValue(certArray, certRef);
672 }
673 errOut:
674 /* clean up */
675 if(secTrust) {
676 CFRelease(secTrust);
677 }
678 if(subjCerts) {
679 CFRelease(subjCerts);
680 }
681 if(policy) {
682 CFRelease(policy);
683 }
684 if(policySearch) {
685 CFRelease(policySearch);
686 }
687 *outArray = certArray;
688 return ortn;
689 }
690
691
692 /*
693 * Given an open keychain, find a SecIdentityRef and munge it into
694 * a CFArrayRef required by SSLSetCertificate().
695 */
696 CFArrayRef sslKcRefToCertArray(
697 SecKeychainRef kcRef,
698 bool encryptOnly,
699 bool completeCertChain,
700 const char *trustedAnchorFile)
701 {
702 /* quick check to make sure the keychain exists */
703 SecKeychainStatus kcStat;
704 OSStatus ortn = SecKeychainGetStatus(kcRef, &kcStat);
705 if(ortn) {
706 printSslErrStr("SecKeychainGetStatus", ortn);
707 printf("Can not open keychain. Aborting.\n");
708 return nil;
709 }
710
711 /*
712 * Search for "any" identity matching specified key use;
713 * in this app, we expect there to be exactly one.
714 */
715 SecIdentitySearchRef srchRef = nil;
716 ortn = SecIdentitySearchCreate(kcRef,
717 encryptOnly ? CSSM_KEYUSE_DECRYPT : CSSM_KEYUSE_SIGN,
718 &srchRef);
719 if(ortn) {
720 printf("SecIdentitySearchCreate returned %d.\n", (int)ortn);
721 printf("Cannot find signing key in keychain. Aborting.\n");
722 return nil;
723 }
724 SecIdentityRef identity = nil;
725 ortn = SecIdentitySearchCopyNext(srchRef, &identity);
726 if(ortn) {
727 printf("SecIdentitySearchCopyNext returned %d.\n", (int)ortn);
728 printf("Cannot find signing key in keychain. Aborting.\n");
729 return nil;
730 }
731 if(CFGetTypeID(identity) != SecIdentityGetTypeID()) {
732 printf("SecIdentitySearchCopyNext CFTypeID failure!\n");
733 return nil;
734 }
735
736 /*
737 * Found one.
738 */
739 if(completeCertChain) {
740 /*
741 * Place it and the other certs needed to verify it -
742 * up to but not including the root - in a CFArray.
743 */
744 SecCertificateRef anchorCert = NULL;
745 if(trustedAnchorFile) {
746 ortn = sslReadAnchor(trustedAnchorFile, &anchorCert);
747 if(ortn) {
748 printf("***Error reading anchor file\n");
749 }
750 }
751 CFArrayRef ca;
752 ortn = sslCompleteCertChain(identity, anchorCert, false, &ca);
753 if(anchorCert) {
754 CFRelease(anchorCert);
755 }
756 return ca;
757 }
758 else {
759 /* simple case, just this one identity */
760 CFArrayRef ca = CFArrayCreate(NULL,
761 (const void **)&identity,
762 1,
763 NULL);
764 if(ca == nil) {
765 printf("CFArrayCreate error\n");
766 }
767 return ca;
768 }
769 }
770 #endif
771
772 OSStatus addTrustedSecCert(
773 SSLContextRef ctx,
774 SecCertificateRef secCert,
775 bool replaceAnchors)
776 {
777 OSStatus ortn;
778 CFMutableArrayRef array;
779
780 if(secCert == NULL) {
781 printf("***addTrustedSecCert screwup\n");
782 return errSecParam;
783 }
784 array = CFArrayCreateMutable(kCFAllocatorDefault,
785 (CFIndex)1, &kCFTypeArrayCallBacks);
786 if(array == NULL) {
787 return errSecAllocate;
788 }
789 CFArrayAppendValue(array, secCert);
790 ortn = SSLSetTrustedRoots(ctx, array, replaceAnchors ? true : false);
791 if(ortn) {
792 printSslErrStr("SSLSetTrustedRoots", ortn);
793 }
794 CFRelease(array);
795 return ortn;
796 }
797
798 OSStatus sslReadAnchor(
799 const char *anchorFile,
800 SecCertificateRef *certRef)
801 {
802 SecCertificateRef secCert;
803 unsigned char *certData;
804 unsigned certLen;
805 CFDataRef dataRef;
806
807 if(readFile(anchorFile, &certData, &certLen)) {
808 return -1;
809 }
810 dataRef = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault,
811 (const UInt8 *)certData, (CFIndex)certLen, kCFAllocatorNull);
812 secCert = SecCertificateCreateWithData(kCFAllocatorDefault, dataRef);
813 CFReleaseSafe(dataRef);
814 free(certData);
815 if(!secCert) {
816 printf("***SecCertificateCreateWithData returned NULL\n");
817 return errSecParam;
818 }
819 if (certRef) {
820 *certRef = secCert;
821 }
822 return errSecSuccess;
823 }
824
825 OSStatus sslAddTrustedRoot(
826 SSLContextRef ctx,
827 const char *anchorFile,
828 bool replaceAnchors)
829 {
830 return 0;
831 }
832
833 OSStatus addIdentityAsTrustedRoot(
834 SSLContextRef ctx,
835 CFArrayRef identArray)
836 {
837 return errSecSuccess;
838 }
839
840 /*
841 * Lists of SSLCipherSuites used in sslSetCipherRestrictions. Note that the
842 * SecureTransport library does not implement all of these; we only specify
843 * the ones it claims to support.
844 */
845 const SSLCipherSuite suites40[] = {
846 SSL_RSA_EXPORT_WITH_RC4_40_MD5,
847 SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5,
848 SSL_RSA_EXPORT_WITH_DES40_CBC_SHA,
849 SSL_DH_DSS_EXPORT_WITH_DES40_CBC_SHA,
850 SSL_DH_RSA_EXPORT_WITH_DES40_CBC_SHA,
851 SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA,
852 SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA,
853 SSL_DH_anon_EXPORT_WITH_RC4_40_MD5,
854 SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA,
855 SSL_NO_SUCH_CIPHERSUITE
856 };
857 const SSLCipherSuite suitesDES[] = {
858 SSL_RSA_WITH_DES_CBC_SHA,
859 SSL_DH_DSS_WITH_DES_CBC_SHA,
860 SSL_DH_RSA_WITH_DES_CBC_SHA,
861 SSL_DHE_DSS_WITH_DES_CBC_SHA,
862 SSL_DHE_RSA_WITH_DES_CBC_SHA,
863 SSL_DH_anon_WITH_DES_CBC_SHA,
864 SSL_RSA_WITH_DES_CBC_MD5,
865 SSL_NO_SUCH_CIPHERSUITE
866 };
867 const SSLCipherSuite suitesDES40[] = {
868 SSL_RSA_EXPORT_WITH_DES40_CBC_SHA,
869 SSL_DH_DSS_EXPORT_WITH_DES40_CBC_SHA,
870 SSL_DH_RSA_EXPORT_WITH_DES40_CBC_SHA,
871 SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA,
872 SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA,
873 SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA,
874 SSL_NO_SUCH_CIPHERSUITE
875 };
876 const SSLCipherSuite suites3DES[] = {
877 SSL_RSA_WITH_3DES_EDE_CBC_SHA,
878 SSL_DH_DSS_WITH_3DES_EDE_CBC_SHA,
879 SSL_DH_RSA_WITH_3DES_EDE_CBC_SHA,
880 SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA,
881 SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA,
882 SSL_DH_anon_WITH_3DES_EDE_CBC_SHA,
883 SSL_RSA_WITH_3DES_EDE_CBC_MD5,
884 SSL_NO_SUCH_CIPHERSUITE
885 };
886 const SSLCipherSuite suitesRC4[] = {
887 SSL_RSA_WITH_RC4_128_MD5,
888 SSL_RSA_WITH_RC4_128_SHA,
889 SSL_DH_anon_WITH_RC4_128_MD5,
890 SSL_NO_SUCH_CIPHERSUITE
891 };
892 const SSLCipherSuite suitesRC4_40[] = {
893 SSL_RSA_EXPORT_WITH_RC4_40_MD5,
894 SSL_DH_anon_EXPORT_WITH_RC4_40_MD5,
895 SSL_NO_SUCH_CIPHERSUITE
896 };
897 const SSLCipherSuite suitesRC2[] = {
898 SSL_RSA_WITH_RC2_CBC_MD5,
899 SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5,
900 SSL_NO_SUCH_CIPHERSUITE
901 };
902 const SSLCipherSuite suitesAES128[] = {
903 TLS_RSA_WITH_AES_128_CBC_SHA,
904 TLS_DH_DSS_WITH_AES_128_CBC_SHA,
905 TLS_DH_RSA_WITH_AES_128_CBC_SHA,
906 TLS_DHE_DSS_WITH_AES_128_CBC_SHA,
907 TLS_DHE_RSA_WITH_AES_128_CBC_SHA,
908 TLS_DH_anon_WITH_AES_128_CBC_SHA,
909 SSL_NO_SUCH_CIPHERSUITE
910 };
911 const SSLCipherSuite suitesAES256[] = {
912 TLS_RSA_WITH_AES_256_CBC_SHA,
913 TLS_DH_DSS_WITH_AES_256_CBC_SHA,
914 TLS_DH_RSA_WITH_AES_256_CBC_SHA,
915 TLS_DHE_DSS_WITH_AES_256_CBC_SHA,
916 TLS_DHE_RSA_WITH_AES_256_CBC_SHA,
917 TLS_DH_anon_WITH_AES_256_CBC_SHA,
918 SSL_NO_SUCH_CIPHERSUITE
919 };
920 const SSLCipherSuite suitesDH[] = {
921 SSL_DH_DSS_WITH_DES_CBC_SHA,
922 SSL_DH_DSS_WITH_3DES_EDE_CBC_SHA,
923 SSL_DH_DSS_EXPORT_WITH_DES40_CBC_SHA,
924 SSL_DH_RSA_WITH_DES_CBC_SHA,
925 SSL_DH_RSA_WITH_3DES_EDE_CBC_SHA,
926 SSL_DH_RSA_EXPORT_WITH_DES40_CBC_SHA,
927 SSL_DHE_DSS_WITH_DES_CBC_SHA,
928 SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA,
929 SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA,
930 SSL_DHE_RSA_WITH_DES_CBC_SHA,
931 SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA,
932 SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA,
933 SSL_DH_anon_WITH_RC4_128_MD5,
934 SSL_DH_anon_WITH_DES_CBC_SHA,
935 SSL_DH_anon_WITH_3DES_EDE_CBC_SHA,
936 SSL_DH_anon_EXPORT_WITH_RC4_40_MD5,
937 SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA,
938 TLS_DH_DSS_WITH_AES_128_CBC_SHA,
939 TLS_DH_RSA_WITH_AES_128_CBC_SHA,
940 TLS_DHE_DSS_WITH_AES_128_CBC_SHA,
941 TLS_DHE_RSA_WITH_AES_128_CBC_SHA,
942 TLS_DH_anon_WITH_AES_128_CBC_SHA,
943 TLS_DH_DSS_WITH_AES_256_CBC_SHA,
944 TLS_DH_RSA_WITH_AES_256_CBC_SHA,
945 TLS_DHE_DSS_WITH_AES_256_CBC_SHA,
946 TLS_DHE_RSA_WITH_AES_256_CBC_SHA,
947 TLS_DH_anon_WITH_AES_256_CBC_SHA,
948 SSL_NO_SUCH_CIPHERSUITE
949 };
950 const SSLCipherSuite suitesDHAnon[] = {
951 SSL_DH_anon_WITH_RC4_128_MD5,
952 SSL_DH_anon_WITH_DES_CBC_SHA,
953 SSL_DH_anon_WITH_3DES_EDE_CBC_SHA,
954 SSL_DH_anon_EXPORT_WITH_RC4_40_MD5,
955 SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA,
956 TLS_DH_anon_WITH_AES_128_CBC_SHA,
957 TLS_DH_anon_WITH_AES_256_CBC_SHA,
958 SSL_NO_SUCH_CIPHERSUITE
959 };
960 const SSLCipherSuite suitesDH_RSA[] = {
961 SSL_DH_RSA_WITH_DES_CBC_SHA,
962 SSL_DH_RSA_WITH_3DES_EDE_CBC_SHA,
963 SSL_DHE_RSA_WITH_DES_CBC_SHA,
964 SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA,
965 SSL_DH_RSA_EXPORT_WITH_DES40_CBC_SHA,
966 SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA,
967 TLS_DH_RSA_WITH_AES_128_CBC_SHA,
968 TLS_DHE_RSA_WITH_AES_128_CBC_SHA,
969 TLS_DH_RSA_WITH_AES_256_CBC_SHA,
970 TLS_DHE_RSA_WITH_AES_256_CBC_SHA,
971 SSL_NO_SUCH_CIPHERSUITE
972 };
973 const SSLCipherSuite suitesDH_DSS[] = {
974 SSL_DH_DSS_WITH_DES_CBC_SHA,
975 SSL_DH_DSS_WITH_3DES_EDE_CBC_SHA,
976 SSL_DHE_DSS_WITH_DES_CBC_SHA,
977 SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA,
978 SSL_DH_DSS_EXPORT_WITH_DES40_CBC_SHA,
979 SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA,
980 TLS_DH_DSS_WITH_AES_128_CBC_SHA,
981 TLS_DHE_DSS_WITH_AES_128_CBC_SHA,
982 TLS_DH_DSS_WITH_AES_256_CBC_SHA,
983 TLS_DHE_DSS_WITH_AES_256_CBC_SHA,
984 SSL_NO_SUCH_CIPHERSUITE
985 };
986 const SSLCipherSuite suites_SHA1[] = {
987 SSL_RSA_WITH_RC4_128_SHA,
988 SSL_RSA_EXPORT_WITH_DES40_CBC_SHA,
989 SSL_RSA_WITH_IDEA_CBC_SHA,
990 SSL_RSA_EXPORT_WITH_DES40_CBC_SHA,
991 SSL_RSA_WITH_DES_CBC_SHA,
992 SSL_RSA_WITH_3DES_EDE_CBC_SHA,
993 SSL_DH_DSS_EXPORT_WITH_DES40_CBC_SHA,
994 SSL_DH_DSS_WITH_DES_CBC_SHA,
995 SSL_DH_DSS_WITH_3DES_EDE_CBC_SHA,
996 SSL_DH_RSA_EXPORT_WITH_DES40_CBC_SHA,
997 SSL_DH_RSA_WITH_DES_CBC_SHA,
998 SSL_DH_RSA_WITH_3DES_EDE_CBC_SHA,
999 SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA,
1000 SSL_DHE_DSS_WITH_DES_CBC_SHA,
1001 SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA,
1002 SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA,
1003 SSL_DHE_RSA_WITH_DES_CBC_SHA,
1004 SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA,
1005 SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA,
1006 SSL_DH_anon_WITH_DES_CBC_SHA,
1007 SSL_DH_anon_WITH_3DES_EDE_CBC_SHA,
1008 SSL_FORTEZZA_DMS_WITH_NULL_SHA,
1009 SSL_FORTEZZA_DMS_WITH_FORTEZZA_CBC_SHA,
1010 TLS_RSA_WITH_AES_128_CBC_SHA,
1011 TLS_DH_DSS_WITH_AES_128_CBC_SHA,
1012 TLS_DH_RSA_WITH_AES_128_CBC_SHA,
1013 TLS_DHE_DSS_WITH_AES_128_CBC_SHA,
1014 TLS_DHE_RSA_WITH_AES_128_CBC_SHA,
1015 TLS_DH_anon_WITH_AES_128_CBC_SHA,
1016 TLS_RSA_WITH_AES_256_CBC_SHA,
1017 TLS_DH_DSS_WITH_AES_256_CBC_SHA,
1018 TLS_DH_RSA_WITH_AES_256_CBC_SHA,
1019 TLS_DHE_DSS_WITH_AES_256_CBC_SHA,
1020 TLS_DHE_RSA_WITH_AES_256_CBC_SHA,
1021 TLS_DH_anon_WITH_AES_256_CBC_SHA,
1022 SSL_NO_SUCH_CIPHERSUITE
1023 };
1024 const SSLCipherSuite suites_MD5[] = {
1025 SSL_RSA_EXPORT_WITH_RC4_40_MD5,
1026 SSL_RSA_WITH_RC4_128_MD5,
1027 SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5,
1028 SSL_DH_anon_EXPORT_WITH_RC4_40_MD5,
1029 SSL_DH_anon_WITH_RC4_128_MD5,
1030 SSL_NO_SUCH_CIPHERSUITE
1031 };
1032 const SSLCipherSuite suites_NULL[] = {
1033 SSL_RSA_WITH_NULL_MD5,
1034 SSL_NO_SUCH_CIPHERSUITE
1035 };
1036
1037 const SSLCipherSuite suites_ECDHE[] = {
1038 TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,
1039 TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,
1040 TLS_ECDHE_ECDSA_WITH_RC4_128_SHA,
1041 TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA,
1042 TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,
1043 TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,
1044 TLS_ECDHE_RSA_WITH_RC4_128_SHA,
1045 TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA,
1046 SSL_NO_SUCH_CIPHERSUITE
1047 };
1048
1049 const SSLCipherSuite suites_ECDH[] = {
1050 TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA,
1051 TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA,
1052 TLS_ECDH_ECDSA_WITH_RC4_128_SHA,
1053 TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA,
1054 TLS_ECDH_RSA_WITH_AES_128_CBC_SHA,
1055 TLS_ECDH_RSA_WITH_AES_256_CBC_SHA,
1056 TLS_ECDH_RSA_WITH_RC4_128_SHA,
1057 TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA,
1058 SSL_NO_SUCH_CIPHERSUITE
1059 };
1060
1061 /*
1062 * Given an SSLContextRef and an array of SSLCipherSuites, terminated by
1063 * SSL_NO_SUCH_CIPHERSUITE, select those SSLCipherSuites which the library
1064 * supports and do a SSLSetEnabledCiphers() specifying those.
1065 */
1066 OSStatus sslSetEnabledCiphers(
1067 SSLContextRef ctx,
1068 const SSLCipherSuite *ciphers)
1069 {
1070 size_t numSupported;
1071 OSStatus ortn;
1072 SSLCipherSuite *supported = NULL;
1073 SSLCipherSuite *enabled = NULL;
1074 unsigned enabledDex = 0; // index into enabled
1075 unsigned supportedDex = 0; // index into supported
1076 unsigned inDex = 0; // index into ciphers
1077
1078 /* first get all the supported ciphers */
1079 ortn = SSLGetNumberSupportedCiphers(ctx, &numSupported);
1080 if(ortn) {
1081 printSslErrStr("SSLGetNumberSupportedCiphers", ortn);
1082 return ortn;
1083 }
1084 supported = (SSLCipherSuite *)malloc(numSupported * sizeof(SSLCipherSuite));
1085 ortn = SSLGetSupportedCiphers(ctx, supported, &numSupported);
1086 if(ortn) {
1087 printSslErrStr("SSLGetSupportedCiphers", ortn);
1088 return ortn;
1089 }
1090
1091 /*
1092 * Malloc an array we'll use for SSLGetEnabledCiphers - this will be
1093 * bigger than the number of suites we actually specify
1094 */
1095 enabled = (SSLCipherSuite *)malloc(numSupported * sizeof(SSLCipherSuite));
1096
1097 /*
1098 * For each valid suite in ciphers, see if it's in the list of
1099 * supported ciphers. If it is, add it to the list of ciphers to be
1100 * enabled.
1101 */
1102 for(inDex=0; ciphers[inDex] != SSL_NO_SUCH_CIPHERSUITE; inDex++) {
1103 for(supportedDex=0; supportedDex<numSupported; supportedDex++) {
1104 if(ciphers[inDex] == supported[supportedDex]) {
1105 enabled[enabledDex++] = ciphers[inDex];
1106 break;
1107 }
1108 }
1109 }
1110
1111 /* send it on down. */
1112 ortn = SSLSetEnabledCiphers(ctx, enabled, enabledDex);
1113 if(ortn) {
1114 printSslErrStr("SSLSetEnabledCiphers", ortn);
1115 }
1116 free(enabled);
1117 free(supported);
1118 return ortn;
1119 }
1120
1121 /*
1122 * Specify a restricted set of cipherspecs.
1123 */
1124 OSStatus sslSetCipherRestrictions(
1125 SSLContextRef ctx,
1126 char cipherRestrict)
1127 {
1128 OSStatus ortn;
1129
1130 if(cipherRestrict == '\0') {
1131 return errSecSuccess; // actually should not have been called
1132 }
1133 switch(cipherRestrict) {
1134 case 'e':
1135 ortn = sslSetEnabledCiphers(ctx, suites40);
1136 break;
1137 case 'd':
1138 ortn = sslSetEnabledCiphers(ctx, suitesDES);
1139 break;
1140 case 'D':
1141 ortn = sslSetEnabledCiphers(ctx, suitesDES40);
1142 break;
1143 case '3':
1144 ortn = sslSetEnabledCiphers(ctx, suites3DES);
1145 break;
1146 case '4':
1147 ortn = sslSetEnabledCiphers(ctx, suitesRC4);
1148 break;
1149 case '$':
1150 ortn = sslSetEnabledCiphers(ctx, suitesRC4_40);
1151 break;
1152 case '2':
1153 ortn = sslSetEnabledCiphers(ctx, suitesRC2);
1154 break;
1155 case 'a':
1156 ortn = sslSetEnabledCiphers(ctx, suitesAES128);
1157 break;
1158 case 'A':
1159 ortn = sslSetEnabledCiphers(ctx, suitesAES256);
1160 break;
1161 case 'h':
1162 ortn = sslSetEnabledCiphers(ctx, suitesDH);
1163 break;
1164 case 'H':
1165 ortn = sslSetEnabledCiphers(ctx, suitesDHAnon);
1166 break;
1167 case 'r':
1168 ortn = sslSetEnabledCiphers(ctx, suitesDH_RSA);
1169 break;
1170 case 's':
1171 ortn = sslSetEnabledCiphers(ctx, suitesDH_DSS);
1172 break;
1173 case 'n':
1174 ortn = sslSetEnabledCiphers(ctx, suites_NULL);
1175 break;
1176 case 'E':
1177 ortn = sslSetEnabledCiphers(ctx, suites_ECDHE);
1178 break;
1179 case 'F':
1180 ortn = sslSetEnabledCiphers(ctx, suites_ECDH);
1181 break;
1182 default:
1183 printf("***bad cipherSpec***\n");
1184 exit(1);
1185 }
1186 return ortn;
1187 }
1188
1189 #if 0
1190 int sslVerifyClientCertState(
1191 const char *whichSide, // "client" or "server"
1192 SSLClientCertificateState expectState,
1193 SSLClientCertificateState gotState)
1194 {
1195 if(expectState == SSL_CLIENT_CERT_IGNORE) {
1196 /* app says "don't bother checking" */
1197 return 0;
1198 }
1199 if(expectState == gotState) {
1200 return 0;
1201 }
1202 printf("***%s: Expected clientCertState %s; got %s\n", whichSide,
1203 sslGetClientCertStateString(expectState),
1204 sslGetClientCertStateString(gotState));
1205 return 1;
1206 }
1207
1208 int sslVerifyRtn(
1209 char *whichSide, // "client" or "server"
1210 OSStatus expectRtn,
1211 OSStatus gotRtn)
1212 {
1213 if(expectRtn == gotRtn) {
1214 return 0;
1215 }
1216 printf("***%s: Expected return %s; got %s\n", whichSide,
1217 sslGetSSLErrString(expectRtn),
1218 sslGetSSLErrString(gotRtn));
1219 return 1;
1220 }
1221
1222 int sslVerifyProtVers(
1223 char *whichSide, // "client" or "server"
1224 SSLProtocol expectProt,
1225 SSLProtocol gotProt)
1226 {
1227 if(expectProt == SSL_PROTOCOL_IGNORE) {
1228 /* app says "don't bopther checking" */
1229 return 0;
1230 }
1231 if(expectProt == gotProt) {
1232 return 0;
1233 }
1234 printf("***%s: Expected return %s; got %s\n", whichSide,
1235 sslGetProtocolVersionString(expectProt),
1236 sslGetProtocolVersionString(gotProt));
1237 return 1;
1238 }
1239
1240 int sslVerifyCipher(
1241 char *whichSide, // "client" or "server"
1242 SSLCipherSuite expectCipher,
1243 SSLCipherSuite gotCipher)
1244 {
1245 if(expectCipher == SSL_CIPHER_IGNORE) {
1246 /* app says "don't bopther checking" */
1247 return 0;
1248 }
1249 if(expectCipher == gotCipher) {
1250 return 0;
1251 }
1252 printf("***%s: Expected return %s; got %s\n", whichSide,
1253 sslGetCipherSuiteString(expectCipher),
1254 sslGetCipherSuiteString(gotCipher));
1255 return 1;
1256 }
1257
1258
1259 OSStatus sslSetProtocols(
1260 SSLContextRef ctx,
1261 const char *acceptedProts,
1262 SSLProtocol tryVersion) // only used if acceptedProts NULL
1263 {
1264 OSStatus ortn;
1265
1266 if(acceptedProts) {
1267 ortn = SSLSetProtocolVersionEnabled(ctx, kSSLProtocolAll, false);
1268 if(ortn) {
1269 printSslErrStr("SSLSetProtocolVersionEnabled(all off)", ortn);
1270 return ortn;
1271 }
1272 for(const char *cp = acceptedProts; *cp; cp++) {
1273 SSLProtocol prot;
1274 switch(*cp) {
1275 case '2':
1276 prot = kSSLProtocol2;
1277 break;
1278 case '3':
1279 prot = kSSLProtocol3;
1280 break;
1281 case 't':
1282 prot = kTLSProtocol1;
1283 break;
1284 default:
1285 printf("***BRRZAP! Bad acceptedProts string %s. Aborting.\n", acceptedProts);
1286 exit(1);
1287 }
1288 ortn = SSLSetProtocolVersionEnabled(ctx, prot, true);
1289 if(ortn) {
1290 printSslErrStr("SSLSetProtocolVersionEnabled", ortn);
1291 return ortn;
1292 }
1293 }
1294 }
1295 else {
1296 ortn = SSLSetProtocolVersion(ctx, tryVersion);
1297 if(ortn) {
1298 printSslErrStr("SSLSetProtocolVersion", ortn);
1299 return ortn;
1300 }
1301 }
1302 return errSecSuccess;
1303 }
1304
1305 void sslShowResult(
1306 const char *whichSide, // "client" or "server"
1307 SslAppTestParams *params)
1308 {
1309 printf("%s status:\n", whichSide);
1310 if(params->acceptedProts) {
1311 printf(" Allowed SSL versions : %s\n", params->acceptedProts);
1312 }
1313 else {
1314 printf(" Attempted SSL version : %s\n",
1315 sslGetProtocolVersionString(params->tryVersion));
1316 }
1317 printf(" Result : %s\n", sslGetSSLErrString(params->ortn));
1318 printf(" Negotiated SSL version : %s\n",
1319 sslGetProtocolVersionString(params->negVersion));
1320 printf(" Negotiated CipherSuite : %s\n",
1321 sslGetCipherSuiteString(params->negCipher));
1322 if(params->certState != kSSLClientCertNone) {
1323 printf(" Client Cert State : %s\n",
1324 sslGetClientCertStateString(params->certState));
1325 }
1326 }
1327 #endif
1328
1329 /* print a '.' every few seconds to keep UI alive while connecting */
1330 static CFAbsoluteTime lastTime = (CFAbsoluteTime)0.0;
1331 #define TIME_INTERVAL 3.0
1332
1333 void sslOutputDot()
1334 {
1335 CFAbsoluteTime thisTime = CFAbsoluteTimeGetCurrent();
1336
1337 // throttle down.
1338 usleep(1000);
1339
1340 if(lastTime == 0.0) {
1341 /* avoid printing first time thru */
1342 lastTime = thisTime;
1343 return;
1344 }
1345 if((thisTime - lastTime) >= TIME_INTERVAL) {
1346 printf("."); fflush(stdout);
1347 lastTime = thisTime;
1348 }
1349 }
1350
1351 #if 0
1352 /* main server pthread body */
1353 static void *sslServerThread(void *arg)
1354 {
1355 SslAppTestParams *testParams = (SslAppTestParams *)arg;
1356 OSStatus status;
1357
1358 status = sslAppServe(testParams);
1359 pthread_exit((void*)status);
1360 /* NOT REACHED */
1361 return (void *)status;
1362 }
1363
1364 /*
1365 * Run one session, with the server in a separate thread.
1366 * On entry, serverParams->port is the port we attempt to run on;
1367 * the server thread may overwrite that with a different port if it's
1368 * unable to open the port we specify. Whatever is left in
1369 * serverParams->port is what's used for the client side.
1370 */
1371 #define CLIENT_WAIT_SECONDS 1
1372 int sslRunSession(
1373 SslAppTestParams*serverParams,
1374 SslAppTestParams *clientParams,
1375 const char *testDesc)
1376 {
1377 pthread_t serverPthread;
1378 OSStatus clientRtn;
1379 void *serverRtn;
1380
1381 if(testDesc && !clientParams->quiet) {
1382 printf("===== %s =====\n", testDesc);
1383 }
1384
1385 if(pthread_mutex_init(&serverParams->pthreadMutex, NULL)) {
1386 printf("***Error initializing mutex; aborting.\n");
1387 return -1;
1388 }
1389 if(pthread_cond_init(&serverParams->pthreadCond, NULL)) {
1390 printf("***Error initializing pthreadCond; aborting.\n");
1391 return -1;
1392 }
1393 serverParams->serverReady = false; // server sets true
1394
1395 int result = pthread_create(&serverPthread, NULL,
1396 sslServerThread, serverParams);
1397 if(result) {
1398 printf("***Error starting up server thread; aborting.\n");
1399 return result;
1400 }
1401
1402 /* wait for server to set up a socket we can connect to */
1403 if(pthread_mutex_lock(&serverParams->pthreadMutex)) {
1404 printf("***Error acquiring server lock; aborting.\n");
1405 return -1;
1406 }
1407 while(!serverParams->serverReady) {
1408 if(pthread_cond_wait(&serverParams->pthreadCond, &serverParams->pthreadMutex)) {
1409 printf("***Error waiting server thread; aborting.\n");
1410 return -1;
1411 }
1412 }
1413 pthread_mutex_unlock(&serverParams->pthreadMutex);
1414 pthread_cond_destroy(&serverParams->pthreadCond);
1415 pthread_mutex_destroy(&serverParams->pthreadMutex);
1416
1417 clientParams->port = serverParams->port;
1418 clientRtn = sslAppClient(clientParams);
1419 /* server doesn't shut down its socket until it sees this */
1420 serverParams->clientDone = 1;
1421 result = pthread_join(serverPthread, &serverRtn);
1422 if(result) {
1423 printf("***pthread_join returned %d, aborting\n", result);
1424 return result;
1425 }
1426
1427 if(serverParams->verbose) {
1428 sslShowResult("server", serverParams);
1429 }
1430 if(clientParams->verbose) {
1431 sslShowResult("client", clientParams);
1432 }
1433
1434 /* verify results */
1435 int ourRtn = 0;
1436 ourRtn += sslVerifyRtn("server", serverParams->expectRtn, serverParams->ortn);
1437 ourRtn += sslVerifyRtn("client", clientParams->expectRtn, clientParams->ortn);
1438 ourRtn += sslVerifyProtVers("server", serverParams->expectVersion,
1439 serverParams->negVersion);
1440 ourRtn += sslVerifyProtVers("client", clientParams->expectVersion,
1441 clientParams->negVersion);
1442 ourRtn += sslVerifyClientCertState("server", serverParams->expectCertState,
1443 serverParams->certState);
1444 ourRtn += sslVerifyClientCertState("client", clientParams->expectCertState,
1445 clientParams->certState);
1446 if(serverParams->ortn == errSecSuccess) {
1447 ourRtn += sslVerifyCipher("server", serverParams->expectCipher,
1448 serverParams->negCipher);
1449 }
1450 if(clientParams->ortn == errSecSuccess) {
1451 ourRtn += sslVerifyCipher("client", clientParams->expectCipher,
1452 clientParams->negCipher);
1453 }
1454 return ourRtn;
1455 }
1456
1457 /*
1458 * Add all of the roots in a given KC to SSL ctx's trusted anchors.
1459 */
1460 OSStatus sslAddTrustedRoots(
1461 SSLContextRef ctx,
1462 SecKeychainRef keychain,
1463 bool *foundOne) // RETURNED, true if we found
1464 // at least one root cert
1465 {
1466 OSStatus ortn;
1467 SecCertificateRef secCert;
1468 SecKeychainSearchRef srch;
1469
1470 *foundOne = false;
1471 ortn = SecKeychainSearchCreateFromAttributes(keychain,
1472 kSecCertificateItemClass,
1473 NULL, // any attrs
1474 &srch);
1475 if(ortn) {
1476 printSslErrStr("SecKeychainSearchCreateFromAttributes", ortn);
1477 return ortn;
1478 }
1479
1480 /*
1481 * Only use root certs. Not an error if we don't find any.
1482 */
1483 do {
1484 ortn = SecKeychainSearchCopyNext(srch,
1485 (SecKeychainItemRef *)&secCert);
1486 if(ortn) {
1487 break;
1488 }
1489
1490 /* see if it's a root */
1491 if(!isCertRoot(secCert)) {
1492 continue;
1493 }
1494
1495 /* Tell Secure Transport to trust this one. */
1496 ortn = addTrustedSecCert(ctx, secCert, false);
1497 if(ortn) {
1498 /* fatal */
1499 printSslErrStr("addTrustedSecCert", ortn);
1500 return ortn;
1501 }
1502 CFRelease(secCert);
1503 *foundOne = true;
1504 } while(ortn == errSecSuccess);
1505 CFRelease(srch);
1506 return errSecSuccess;
1507 }
1508
1509 /*
1510 * Wrapper for sslIdentPicker, with optional trusted anchor specified as a filename.
1511 */
1512 OSStatus sslIdentityPicker(
1513 SecKeychainRef kcRef, // NULL means use default list
1514 const char *trustedAnchor, // optional additional trusted anchor
1515 bool includeRoot, // true --> root is appended to outArray
1516 // false --> root not included
1517 CFArrayRef *outArray) // created and RETURNED
1518 {
1519 SecCertificateRef trustedCert = NULL;
1520 OSStatus ortn;
1521
1522 if(trustedAnchor) {
1523 ortn = sslReadAnchor(trustedAnchor, &trustedCert);
1524 if(ortn) {
1525 printf("***Error reading %s. sslIdentityPicker proceeding with no anchor.\n",
1526 trustedAnchor);
1527 trustedCert = NULL;
1528 }
1529 }
1530 ortn = sslIdentPicker(kcRef, trustedCert, includeRoot, outArray);
1531 if(trustedCert) {
1532 CFRelease(trustedCert);
1533 }
1534 return ortn;
1535 }
1536
1537 /*
1538 * Given a keychain name, convert it into a full path using the "SSL regression
1539 * test suite algorithm". The Sec layer by default locates root root's keychains
1540 * in different places depending on whether we're actually logged in as root
1541 * or running via e.g. cron, so we force the location of root keychains to
1542 * a hard-coded path. User keychain names we leave alone.
1543 */
1544 void sslKeychainPath(
1545 const char *kcName,
1546 char *kcPath) // allocd by caller, MAXPATHLEN
1547 {
1548 if(kcName[0] == '\0') {
1549 kcPath[0] = '\0';
1550 }
1551 else if(geteuid() == 0) {
1552 /* root */
1553 sprintf(kcPath, "/Library/Keychains/%s", kcName);
1554 }
1555 else {
1556 /* user, leave alone */
1557 strcpy(kcPath, kcName);
1558 }
1559 }
1560
1561 /* Verify presence of required file. Returns nonzero if not found. */
1562 int sslCheckFile(const char *path)
1563 {
1564 struct stat sb;
1565
1566 if(stat(path, &sb)) {
1567 printf("***Can't find file %s.\n", path);
1568 printf(" Try running in the build directory, perhaps after running the\n"
1569 " makeLocalCert script.\n");
1570 return 1;
1571 }
1572 return 0;
1573 }
1574
1575 #endif
1576
1577 /* Stringify a SSL_ECDSA_NamedCurve */
1578 extern const char *sslCurveString(
1579 SSL_ECDSA_NamedCurve namedCurve)
1580 {
1581 static char unk[100];
1582
1583 switch(namedCurve) {
1584 case SSL_Curve_None: return "Curve_None";
1585 case SSL_Curve_secp256r1: return "secp256r1";
1586 case SSL_Curve_secp384r1: return "secp384r1";
1587 case SSL_Curve_secp521r1: return "secp521r1";
1588 default:
1589 sprintf(unk, "Unknown <%d>", (int)namedCurve);
1590 return unk;
1591 }
1592 }