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 19const 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 sprintf(noSuite, "Unknown (0x%04X)", (unsigned)cs); 156 return noSuite; 157 } 158} 159 160/* 161 * Given a SSLProtocolVersion - typically from SSLGetProtocolVersion - 162 * return a string representation. 163 */ 164const 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 */ 186const 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 282void printSslErrStr( 283 const char *op, 284 OSStatus err) 285{ 286 printf("*** %s: %s\n", op, sslGetSSLErrString(err)); 287} 288 289const 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 305const 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 */ 332CFArrayRef 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 425errOut: 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 448errOut: 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 */ 466static 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 } 509errOut: 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 */ 522OSStatus 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 } 673errOut: 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 */ 696CFArrayRef 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 772OSStatus 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 798OSStatus 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 825OSStatus sslAddTrustedRoot( 826 SSLContextRef ctx, 827 const char *anchorFile, 828 bool replaceAnchors) 829{ 830#if 0 831 OSStatus ortn; 832 SecCertificateRef secCert; 833 834 ortn = sslReadAnchor(anchorFile, &secCert); 835 if(ortn) { 836 printf("***Error reading %s. SSLSetTrustedRoots skipped.\n", 837 anchorFile); 838 return ortn; 839 } 840 return addTrustedSecCert(ctx, secCert, replaceAnchors); 841#else 842 return 0; 843#endif 844} 845 846#if 0 847/* Per 3537606 this is no longer necessary */ 848/* 849 * Assume incoming identity contains a root (e.g., created by 850 * certtool) and add that cert to ST's trusted anchors. This 851 * enables ST's verify of the incoming chain to succeed without 852 * a kludgy "AllowAnyRoot" specification. 853 */ 854OSStatus addIdentityAsTrustedRoot( 855 SSLContextRef ctx, 856 CFArrayRef identArray) 857{ 858 CFIndex numItems = CFArrayGetCount(identArray); 859 if(numItems == 0) { 860 printf("***addIdentityAsTrustedRoot: empty identArray\n"); 861 return errSecParam; 862 } 863 864 /* Root should be the last item - could be identity, could be cert */ 865 CFTypeRef theItem = CFArrayGetValueAtIndex(identArray, numItems - 1); 866 if(CFGetTypeID(theItem) == SecIdentityGetTypeID()) { 867 /* identity */ 868 SecCertificateRef certRef; 869 OSStatus ortn = SecIdentityCopyCertificate( 870 (SecIdentityRef)theItem, &certRef); 871 if(ortn) { 872 cssmPerror("SecIdentityCopyCertificate", ortn); 873 printf("***Error gettting cert from identity\n"); 874 return ortn; 875 } 876 ortn = addTrustedSecCert(ctx, certRef, false); 877 CFRelease(certRef); 878 return ortn; 879 } 880 else if(CFGetTypeID(theItem) == SecCertificateGetTypeID()) { 881 /* certificate */ 882 return addTrustedSecCert(ctx, (SecCertificateRef)theItem, false); 883 } 884 else { 885 printf("***Bogus item in identity array\n"); 886 return errSecParam; 887 } 888} 889#else 890OSStatus addIdentityAsTrustedRoot( 891 SSLContextRef ctx, 892 CFArrayRef identArray) 893{ 894 return errSecSuccess; 895} 896#endif 897 898/* 899 * Lists of SSLCipherSuites used in sslSetCipherRestrictions. Note that the 900 * SecureTransport library does not implement all of these; we only specify 901 * the ones it claims to support. 902 */ 903const SSLCipherSuite suites40[] = { 904 SSL_RSA_EXPORT_WITH_RC4_40_MD5, 905 SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5, 906 SSL_RSA_EXPORT_WITH_DES40_CBC_SHA, 907 SSL_DH_DSS_EXPORT_WITH_DES40_CBC_SHA, 908 SSL_DH_RSA_EXPORT_WITH_DES40_CBC_SHA, 909 SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA, 910 SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA, 911 SSL_DH_anon_EXPORT_WITH_RC4_40_MD5, 912 SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA, 913 SSL_NO_SUCH_CIPHERSUITE 914}; 915const SSLCipherSuite suitesDES[] = { 916 SSL_RSA_WITH_DES_CBC_SHA, 917 SSL_DH_DSS_WITH_DES_CBC_SHA, 918 SSL_DH_RSA_WITH_DES_CBC_SHA, 919 SSL_DHE_DSS_WITH_DES_CBC_SHA, 920 SSL_DHE_RSA_WITH_DES_CBC_SHA, 921 SSL_DH_anon_WITH_DES_CBC_SHA, 922 SSL_RSA_WITH_DES_CBC_MD5, 923 SSL_NO_SUCH_CIPHERSUITE 924}; 925const SSLCipherSuite suitesDES40[] = { 926 SSL_RSA_EXPORT_WITH_DES40_CBC_SHA, 927 SSL_DH_DSS_EXPORT_WITH_DES40_CBC_SHA, 928 SSL_DH_RSA_EXPORT_WITH_DES40_CBC_SHA, 929 SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA, 930 SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA, 931 SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA, 932 SSL_NO_SUCH_CIPHERSUITE 933}; 934const SSLCipherSuite suites3DES[] = { 935 SSL_RSA_WITH_3DES_EDE_CBC_SHA, 936 SSL_DH_DSS_WITH_3DES_EDE_CBC_SHA, 937 SSL_DH_RSA_WITH_3DES_EDE_CBC_SHA, 938 SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA, 939 SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA, 940 SSL_DH_anon_WITH_3DES_EDE_CBC_SHA, 941 SSL_RSA_WITH_3DES_EDE_CBC_MD5, 942 SSL_NO_SUCH_CIPHERSUITE 943}; 944const SSLCipherSuite suitesRC4[] = { 945 SSL_RSA_WITH_RC4_128_MD5, 946 SSL_RSA_WITH_RC4_128_SHA, 947 SSL_DH_anon_WITH_RC4_128_MD5, 948 SSL_NO_SUCH_CIPHERSUITE 949}; 950const SSLCipherSuite suitesRC4_40[] = { 951 SSL_RSA_EXPORT_WITH_RC4_40_MD5, 952 SSL_DH_anon_EXPORT_WITH_RC4_40_MD5, 953 SSL_NO_SUCH_CIPHERSUITE 954}; 955const SSLCipherSuite suitesRC2[] = { 956 SSL_RSA_WITH_RC2_CBC_MD5, 957 SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5, 958 SSL_NO_SUCH_CIPHERSUITE 959}; 960const SSLCipherSuite suitesAES128[] = { 961 TLS_RSA_WITH_AES_128_CBC_SHA, 962 TLS_DH_DSS_WITH_AES_128_CBC_SHA, 963 TLS_DH_RSA_WITH_AES_128_CBC_SHA, 964 TLS_DHE_DSS_WITH_AES_128_CBC_SHA, 965 TLS_DHE_RSA_WITH_AES_128_CBC_SHA, 966 TLS_DH_anon_WITH_AES_128_CBC_SHA, 967 SSL_NO_SUCH_CIPHERSUITE 968}; 969const SSLCipherSuite suitesAES256[] = { 970 TLS_RSA_WITH_AES_256_CBC_SHA, 971 TLS_DH_DSS_WITH_AES_256_CBC_SHA, 972 TLS_DH_RSA_WITH_AES_256_CBC_SHA, 973 TLS_DHE_DSS_WITH_AES_256_CBC_SHA, 974 TLS_DHE_RSA_WITH_AES_256_CBC_SHA, 975 TLS_DH_anon_WITH_AES_256_CBC_SHA, 976 SSL_NO_SUCH_CIPHERSUITE 977}; 978const SSLCipherSuite suitesDH[] = { 979 SSL_DH_DSS_WITH_DES_CBC_SHA, 980 SSL_DH_DSS_WITH_3DES_EDE_CBC_SHA, 981 SSL_DH_DSS_EXPORT_WITH_DES40_CBC_SHA, 982 SSL_DH_RSA_WITH_DES_CBC_SHA, 983 SSL_DH_RSA_WITH_3DES_EDE_CBC_SHA, 984 SSL_DH_RSA_EXPORT_WITH_DES40_CBC_SHA, 985 SSL_DHE_DSS_WITH_DES_CBC_SHA, 986 SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA, 987 SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA, 988 SSL_DHE_RSA_WITH_DES_CBC_SHA, 989 SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA, 990 SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA, 991 SSL_DH_anon_WITH_RC4_128_MD5, 992 SSL_DH_anon_WITH_DES_CBC_SHA, 993 SSL_DH_anon_WITH_3DES_EDE_CBC_SHA, 994 SSL_DH_anon_EXPORT_WITH_RC4_40_MD5, 995 SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA, 996 TLS_DH_DSS_WITH_AES_128_CBC_SHA, 997 TLS_DH_RSA_WITH_AES_128_CBC_SHA, 998 TLS_DHE_DSS_WITH_AES_128_CBC_SHA, 999 TLS_DHE_RSA_WITH_AES_128_CBC_SHA, 1000 TLS_DH_anon_WITH_AES_128_CBC_SHA, 1001 TLS_DH_DSS_WITH_AES_256_CBC_SHA, 1002 TLS_DH_RSA_WITH_AES_256_CBC_SHA, 1003 TLS_DHE_DSS_WITH_AES_256_CBC_SHA, 1004 TLS_DHE_RSA_WITH_AES_256_CBC_SHA, 1005 TLS_DH_anon_WITH_AES_256_CBC_SHA, 1006 SSL_NO_SUCH_CIPHERSUITE 1007}; 1008const SSLCipherSuite suitesDHAnon[] = { 1009 SSL_DH_anon_WITH_RC4_128_MD5, 1010 SSL_DH_anon_WITH_DES_CBC_SHA, 1011 SSL_DH_anon_WITH_3DES_EDE_CBC_SHA, 1012 SSL_DH_anon_EXPORT_WITH_RC4_40_MD5, 1013 SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA, 1014 TLS_DH_anon_WITH_AES_128_CBC_SHA, 1015 TLS_DH_anon_WITH_AES_256_CBC_SHA, 1016 SSL_NO_SUCH_CIPHERSUITE 1017}; 1018const SSLCipherSuite suitesDH_RSA[] = { 1019 SSL_DH_RSA_WITH_DES_CBC_SHA, 1020 SSL_DH_RSA_WITH_3DES_EDE_CBC_SHA, 1021 SSL_DHE_RSA_WITH_DES_CBC_SHA, 1022 SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA, 1023 SSL_DH_RSA_EXPORT_WITH_DES40_CBC_SHA, 1024 SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA, 1025 TLS_DH_RSA_WITH_AES_128_CBC_SHA, 1026 TLS_DHE_RSA_WITH_AES_128_CBC_SHA, 1027 TLS_DH_RSA_WITH_AES_256_CBC_SHA, 1028 TLS_DHE_RSA_WITH_AES_256_CBC_SHA, 1029 SSL_NO_SUCH_CIPHERSUITE 1030}; 1031const SSLCipherSuite suitesDH_DSS[] = { 1032 SSL_DH_DSS_WITH_DES_CBC_SHA, 1033 SSL_DH_DSS_WITH_3DES_EDE_CBC_SHA, 1034 SSL_DHE_DSS_WITH_DES_CBC_SHA, 1035 SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA, 1036 SSL_DH_DSS_EXPORT_WITH_DES40_CBC_SHA, 1037 SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA, 1038 TLS_DH_DSS_WITH_AES_128_CBC_SHA, 1039 TLS_DHE_DSS_WITH_AES_128_CBC_SHA, 1040 TLS_DH_DSS_WITH_AES_256_CBC_SHA, 1041 TLS_DHE_DSS_WITH_AES_256_CBC_SHA, 1042 SSL_NO_SUCH_CIPHERSUITE 1043}; 1044const SSLCipherSuite suites_SHA1[] = { 1045 SSL_RSA_WITH_RC4_128_SHA, 1046 SSL_RSA_EXPORT_WITH_DES40_CBC_SHA, 1047 SSL_RSA_WITH_IDEA_CBC_SHA, 1048 SSL_RSA_EXPORT_WITH_DES40_CBC_SHA, 1049 SSL_RSA_WITH_DES_CBC_SHA, 1050 SSL_RSA_WITH_3DES_EDE_CBC_SHA, 1051 SSL_DH_DSS_EXPORT_WITH_DES40_CBC_SHA, 1052 SSL_DH_DSS_WITH_DES_CBC_SHA, 1053 SSL_DH_DSS_WITH_3DES_EDE_CBC_SHA, 1054 SSL_DH_RSA_EXPORT_WITH_DES40_CBC_SHA, 1055 SSL_DH_RSA_WITH_DES_CBC_SHA, 1056 SSL_DH_RSA_WITH_3DES_EDE_CBC_SHA, 1057 SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA, 1058 SSL_DHE_DSS_WITH_DES_CBC_SHA, 1059 SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA, 1060 SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA, 1061 SSL_DHE_RSA_WITH_DES_CBC_SHA, 1062 SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA, 1063 SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA, 1064 SSL_DH_anon_WITH_DES_CBC_SHA, 1065 SSL_DH_anon_WITH_3DES_EDE_CBC_SHA, 1066 SSL_FORTEZZA_DMS_WITH_NULL_SHA, 1067 SSL_FORTEZZA_DMS_WITH_FORTEZZA_CBC_SHA, 1068 TLS_RSA_WITH_AES_128_CBC_SHA, 1069 TLS_DH_DSS_WITH_AES_128_CBC_SHA, 1070 TLS_DH_RSA_WITH_AES_128_CBC_SHA, 1071 TLS_DHE_DSS_WITH_AES_128_CBC_SHA, 1072 TLS_DHE_RSA_WITH_AES_128_CBC_SHA, 1073 TLS_DH_anon_WITH_AES_128_CBC_SHA, 1074 TLS_RSA_WITH_AES_256_CBC_SHA, 1075 TLS_DH_DSS_WITH_AES_256_CBC_SHA, 1076 TLS_DH_RSA_WITH_AES_256_CBC_SHA, 1077 TLS_DHE_DSS_WITH_AES_256_CBC_SHA, 1078 TLS_DHE_RSA_WITH_AES_256_CBC_SHA, 1079 TLS_DH_anon_WITH_AES_256_CBC_SHA, 1080 SSL_NO_SUCH_CIPHERSUITE 1081}; 1082const SSLCipherSuite suites_MD5[] = { 1083 SSL_RSA_EXPORT_WITH_RC4_40_MD5, 1084 SSL_RSA_WITH_RC4_128_MD5, 1085 SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5, 1086 SSL_DH_anon_EXPORT_WITH_RC4_40_MD5, 1087 SSL_DH_anon_WITH_RC4_128_MD5, 1088 SSL_NO_SUCH_CIPHERSUITE 1089}; 1090const SSLCipherSuite suites_NULL[] = { 1091 SSL_RSA_WITH_NULL_MD5, 1092 SSL_NO_SUCH_CIPHERSUITE 1093}; 1094 1095const SSLCipherSuite suites_ECDHE[] = { 1096 TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, 1097 TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, 1098 TLS_ECDHE_ECDSA_WITH_RC4_128_SHA, 1099 TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA, 1100 TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, 1101 TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, 1102 TLS_ECDHE_RSA_WITH_RC4_128_SHA, 1103 TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, 1104 SSL_NO_SUCH_CIPHERSUITE 1105}; 1106 1107const SSLCipherSuite suites_ECDH[] = { 1108 TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA, 1109 TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA, 1110 TLS_ECDH_ECDSA_WITH_RC4_128_SHA, 1111 TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA, 1112 TLS_ECDH_RSA_WITH_AES_128_CBC_SHA, 1113 TLS_ECDH_RSA_WITH_AES_256_CBC_SHA, 1114 TLS_ECDH_RSA_WITH_RC4_128_SHA, 1115 TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA, 1116 SSL_NO_SUCH_CIPHERSUITE 1117}; 1118 1119/* 1120 * Given an SSLContextRef and an array of SSLCipherSuites, terminated by 1121 * SSL_NO_SUCH_CIPHERSUITE, select those SSLCipherSuites which the library 1122 * supports and do a SSLSetEnabledCiphers() specifying those. 1123 */ 1124OSStatus sslSetEnabledCiphers( 1125 SSLContextRef ctx, 1126 const SSLCipherSuite *ciphers) 1127{ 1128 size_t numSupported; 1129 OSStatus ortn; 1130 SSLCipherSuite *supported = NULL; 1131 SSLCipherSuite *enabled = NULL; 1132 unsigned enabledDex = 0; // index into enabled 1133 unsigned supportedDex = 0; // index into supported 1134 unsigned inDex = 0; // index into ciphers 1135 1136 /* first get all the supported ciphers */ 1137 ortn = SSLGetNumberSupportedCiphers(ctx, &numSupported); 1138 if(ortn) { 1139 printSslErrStr("SSLGetNumberSupportedCiphers", ortn); 1140 return ortn; 1141 } 1142 supported = (SSLCipherSuite *)malloc(numSupported * sizeof(SSLCipherSuite)); 1143 ortn = SSLGetSupportedCiphers(ctx, supported, &numSupported); 1144 if(ortn) { 1145 printSslErrStr("SSLGetSupportedCiphers", ortn); 1146 return ortn; 1147 } 1148 1149 /* 1150 * Malloc an array we'll use for SSLGetEnabledCiphers - this will be 1151 * bigger than the number of suites we actually specify 1152 */ 1153 enabled = (SSLCipherSuite *)malloc(numSupported * sizeof(SSLCipherSuite)); 1154 1155 /* 1156 * For each valid suite in ciphers, see if it's in the list of 1157 * supported ciphers. If it is, add it to the list of ciphers to be 1158 * enabled. 1159 */ 1160 for(inDex=0; ciphers[inDex] != SSL_NO_SUCH_CIPHERSUITE; inDex++) { 1161 for(supportedDex=0; supportedDex<numSupported; supportedDex++) { 1162 if(ciphers[inDex] == supported[supportedDex]) { 1163 enabled[enabledDex++] = ciphers[inDex]; 1164 break; 1165 } 1166 } 1167 } 1168 1169 /* send it on down. */ 1170 ortn = SSLSetEnabledCiphers(ctx, enabled, enabledDex); 1171 if(ortn) { 1172 printSslErrStr("SSLSetEnabledCiphers", ortn); 1173 } 1174 free(enabled); 1175 free(supported); 1176 return ortn; 1177} 1178 1179/* 1180 * Specify a restricted set of cipherspecs. 1181 */ 1182OSStatus sslSetCipherRestrictions( 1183 SSLContextRef ctx, 1184 char cipherRestrict) 1185{ 1186 OSStatus ortn; 1187 1188 if(cipherRestrict == '\0') { 1189 return errSecSuccess; // actually should not have been called 1190 } 1191 switch(cipherRestrict) { 1192 case 'e': 1193 ortn = sslSetEnabledCiphers(ctx, suites40); 1194 break; 1195 case 'd': 1196 ortn = sslSetEnabledCiphers(ctx, suitesDES); 1197 break; 1198 case 'D': 1199 ortn = sslSetEnabledCiphers(ctx, suitesDES40); 1200 break; 1201 case '3': 1202 ortn = sslSetEnabledCiphers(ctx, suites3DES); 1203 break; 1204 case '4': 1205 ortn = sslSetEnabledCiphers(ctx, suitesRC4); 1206 break; 1207 case '$': 1208 ortn = sslSetEnabledCiphers(ctx, suitesRC4_40); 1209 break; 1210 case '2': 1211 ortn = sslSetEnabledCiphers(ctx, suitesRC2); 1212 break; 1213 case 'a': 1214 ortn = sslSetEnabledCiphers(ctx, suitesAES128); 1215 break; 1216 case 'A': 1217 ortn = sslSetEnabledCiphers(ctx, suitesAES256); 1218 break; 1219 case 'h': 1220 ortn = sslSetEnabledCiphers(ctx, suitesDH); 1221 break; 1222 case 'H': 1223 ortn = sslSetEnabledCiphers(ctx, suitesDHAnon); 1224 break; 1225 case 'r': 1226 ortn = sslSetEnabledCiphers(ctx, suitesDH_RSA); 1227 break; 1228 case 's': 1229 ortn = sslSetEnabledCiphers(ctx, suitesDH_DSS); 1230 break; 1231 case 'n': 1232 ortn = sslSetEnabledCiphers(ctx, suites_NULL); 1233 break; 1234 case 'E': 1235 ortn = sslSetEnabledCiphers(ctx, suites_ECDHE); 1236 break; 1237 case 'F': 1238 ortn = sslSetEnabledCiphers(ctx, suites_ECDH); 1239 break; 1240 default: 1241 printf("***bad cipherSpec***\n"); 1242 exit(1); 1243 } 1244 return ortn; 1245} 1246 1247#if 0 1248int sslVerifyClientCertState( 1249 const char *whichSide, // "client" or "server" 1250 SSLClientCertificateState expectState, 1251 SSLClientCertificateState gotState) 1252{ 1253 if(expectState == SSL_CLIENT_CERT_IGNORE) { 1254 /* app says "don't bother checking" */ 1255 return 0; 1256 } 1257 if(expectState == gotState) { 1258 return 0; 1259 } 1260 printf("***%s: Expected clientCertState %s; got %s\n", whichSide, 1261 sslGetClientCertStateString(expectState), 1262 sslGetClientCertStateString(gotState)); 1263 return 1; 1264} 1265 1266int sslVerifyRtn( 1267 char *whichSide, // "client" or "server" 1268 OSStatus expectRtn, 1269 OSStatus gotRtn) 1270{ 1271 if(expectRtn == gotRtn) { 1272 return 0; 1273 } 1274 printf("***%s: Expected return %s; got %s\n", whichSide, 1275 sslGetSSLErrString(expectRtn), 1276 sslGetSSLErrString(gotRtn)); 1277 return 1; 1278} 1279 1280int sslVerifyProtVers( 1281 char *whichSide, // "client" or "server" 1282 SSLProtocol expectProt, 1283 SSLProtocol gotProt) 1284{ 1285 if(expectProt == SSL_PROTOCOL_IGNORE) { 1286 /* app says "don't bopther checking" */ 1287 return 0; 1288 } 1289 if(expectProt == gotProt) { 1290 return 0; 1291 } 1292 printf("***%s: Expected return %s; got %s\n", whichSide, 1293 sslGetProtocolVersionString(expectProt), 1294 sslGetProtocolVersionString(gotProt)); 1295 return 1; 1296} 1297 1298int sslVerifyCipher( 1299 char *whichSide, // "client" or "server" 1300 SSLCipherSuite expectCipher, 1301 SSLCipherSuite gotCipher) 1302{ 1303 if(expectCipher == SSL_CIPHER_IGNORE) { 1304 /* app says "don't bopther checking" */ 1305 return 0; 1306 } 1307 if(expectCipher == gotCipher) { 1308 return 0; 1309 } 1310 printf("***%s: Expected return %s; got %s\n", whichSide, 1311 sslGetCipherSuiteString(expectCipher), 1312 sslGetCipherSuiteString(gotCipher)); 1313 return 1; 1314} 1315 1316 1317OSStatus sslSetProtocols( 1318 SSLContextRef ctx, 1319 const char *acceptedProts, 1320 SSLProtocol tryVersion) // only used if acceptedProts NULL 1321{ 1322 OSStatus ortn; 1323 1324 if(acceptedProts) { 1325 ortn = SSLSetProtocolVersionEnabled(ctx, kSSLProtocolAll, false); 1326 if(ortn) { 1327 printSslErrStr("SSLSetProtocolVersionEnabled(all off)", ortn); 1328 return ortn; 1329 } 1330 for(const char *cp = acceptedProts; *cp; cp++) { 1331 SSLProtocol prot; 1332 switch(*cp) { 1333 case '2': 1334 prot = kSSLProtocol2; 1335 break; 1336 case '3': 1337 prot = kSSLProtocol3; 1338 break; 1339 case 't': 1340 prot = kTLSProtocol1; 1341 break; 1342 default: 1343 printf("***BRRZAP! Bad acceptedProts string %s. Aborting.\n", acceptedProts); 1344 exit(1); 1345 } 1346 ortn = SSLSetProtocolVersionEnabled(ctx, prot, true); 1347 if(ortn) { 1348 printSslErrStr("SSLSetProtocolVersionEnabled", ortn); 1349 return ortn; 1350 } 1351 } 1352 } 1353 else { 1354 ortn = SSLSetProtocolVersion(ctx, tryVersion); 1355 if(ortn) { 1356 printSslErrStr("SSLSetProtocolVersion", ortn); 1357 return ortn; 1358 } 1359 } 1360 return errSecSuccess; 1361} 1362 1363void sslShowResult( 1364 const char *whichSide, // "client" or "server" 1365 SslAppTestParams *params) 1366{ 1367 printf("%s status:\n", whichSide); 1368 if(params->acceptedProts) { 1369 printf(" Allowed SSL versions : %s\n", params->acceptedProts); 1370 } 1371 else { 1372 printf(" Attempted SSL version : %s\n", 1373 sslGetProtocolVersionString(params->tryVersion)); 1374 } 1375 printf(" Result : %s\n", sslGetSSLErrString(params->ortn)); 1376 printf(" Negotiated SSL version : %s\n", 1377 sslGetProtocolVersionString(params->negVersion)); 1378 printf(" Negotiated CipherSuite : %s\n", 1379 sslGetCipherSuiteString(params->negCipher)); 1380 if(params->certState != kSSLClientCertNone) { 1381 printf(" Client Cert State : %s\n", 1382 sslGetClientCertStateString(params->certState)); 1383 } 1384} 1385#endif 1386 1387/* print a '.' every few seconds to keep UI alive while connecting */ 1388static CFAbsoluteTime lastTime = (CFAbsoluteTime)0.0; 1389#define TIME_INTERVAL 3.0 1390 1391void sslOutputDot() 1392{ 1393 CFAbsoluteTime thisTime = CFAbsoluteTimeGetCurrent(); 1394 1395 // throttle down. 1396 usleep(1000); 1397 1398 if(lastTime == 0.0) { 1399 /* avoid printing first time thru */ 1400 lastTime = thisTime; 1401 return; 1402 } 1403 if((thisTime - lastTime) >= TIME_INTERVAL) { 1404 printf("."); fflush(stdout); 1405 lastTime = thisTime; 1406 } 1407} 1408 1409#if 0 1410/* main server pthread body */ 1411static void *sslServerThread(void *arg) 1412{ 1413 SslAppTestParams *testParams = (SslAppTestParams *)arg; 1414 OSStatus status; 1415 1416 status = sslAppServe(testParams); 1417 pthread_exit((void*)status); 1418 /* NOT REACHED */ 1419 return (void *)status; 1420} 1421 1422/* 1423 * Run one session, with the server in a separate thread. 1424 * On entry, serverParams->port is the port we attempt to run on; 1425 * the server thread may overwrite that with a different port if it's 1426 * unable to open the port we specify. Whatever is left in 1427 * serverParams->port is what's used for the client side. 1428 */ 1429#define CLIENT_WAIT_SECONDS 1 1430int sslRunSession( 1431 SslAppTestParams*serverParams, 1432 SslAppTestParams *clientParams, 1433 const char *testDesc) 1434{ 1435 pthread_t serverPthread; 1436 OSStatus clientRtn; 1437 void *serverRtn; 1438 1439 if(testDesc && !clientParams->quiet) { 1440 printf("===== %s =====\n", testDesc); 1441 } 1442 1443 if(pthread_mutex_init(&serverParams->pthreadMutex, NULL)) { 1444 printf("***Error initializing mutex; aborting.\n"); 1445 return -1; 1446 } 1447 if(pthread_cond_init(&serverParams->pthreadCond, NULL)) { 1448 printf("***Error initializing pthreadCond; aborting.\n"); 1449 return -1; 1450 } 1451 serverParams->serverReady = false; // server sets true 1452 1453 int result = pthread_create(&serverPthread, NULL, 1454 sslServerThread, serverParams); 1455 if(result) { 1456 printf("***Error starting up server thread; aborting.\n"); 1457 return result; 1458 } 1459 1460 /* wait for server to set up a socket we can connect to */ 1461 if(pthread_mutex_lock(&serverParams->pthreadMutex)) { 1462 printf("***Error acquiring server lock; aborting.\n"); 1463 return -1; 1464 } 1465 while(!serverParams->serverReady) { 1466 if(pthread_cond_wait(&serverParams->pthreadCond, &serverParams->pthreadMutex)) { 1467 printf("***Error waiting server thread; aborting.\n"); 1468 return -1; 1469 } 1470 } 1471 pthread_mutex_unlock(&serverParams->pthreadMutex); 1472 pthread_cond_destroy(&serverParams->pthreadCond); 1473 pthread_mutex_destroy(&serverParams->pthreadMutex); 1474 1475 clientParams->port = serverParams->port; 1476 clientRtn = sslAppClient(clientParams); 1477 /* server doesn't shut down its socket until it sees this */ 1478 serverParams->clientDone = 1; 1479 result = pthread_join(serverPthread, &serverRtn); 1480 if(result) { 1481 printf("***pthread_join returned %d, aborting\n", result); 1482 return result; 1483 } 1484 1485 if(serverParams->verbose) { 1486 sslShowResult("server", serverParams); 1487 } 1488 if(clientParams->verbose) { 1489 sslShowResult("client", clientParams); 1490 } 1491 1492 /* verify results */ 1493 int ourRtn = 0; 1494 ourRtn += sslVerifyRtn("server", serverParams->expectRtn, serverParams->ortn); 1495 ourRtn += sslVerifyRtn("client", clientParams->expectRtn, clientParams->ortn); 1496 ourRtn += sslVerifyProtVers("server", serverParams->expectVersion, 1497 serverParams->negVersion); 1498 ourRtn += sslVerifyProtVers("client", clientParams->expectVersion, 1499 clientParams->negVersion); 1500 ourRtn += sslVerifyClientCertState("server", serverParams->expectCertState, 1501 serverParams->certState); 1502 ourRtn += sslVerifyClientCertState("client", clientParams->expectCertState, 1503 clientParams->certState); 1504 if(serverParams->ortn == errSecSuccess) { 1505 ourRtn += sslVerifyCipher("server", serverParams->expectCipher, 1506 serverParams->negCipher); 1507 } 1508 if(clientParams->ortn == errSecSuccess) { 1509 ourRtn += sslVerifyCipher("client", clientParams->expectCipher, 1510 clientParams->negCipher); 1511 } 1512 return ourRtn; 1513} 1514 1515/* 1516 * Add all of the roots in a given KC to SSL ctx's trusted anchors. 1517 */ 1518OSStatus sslAddTrustedRoots( 1519 SSLContextRef ctx, 1520 SecKeychainRef keychain, 1521 bool *foundOne) // RETURNED, true if we found 1522 // at least one root cert 1523{ 1524 OSStatus ortn; 1525 SecCertificateRef secCert; 1526 SecKeychainSearchRef srch; 1527 1528 *foundOne = false; 1529 ortn = SecKeychainSearchCreateFromAttributes(keychain, 1530 kSecCertificateItemClass, 1531 NULL, // any attrs 1532 &srch); 1533 if(ortn) { 1534 printSslErrStr("SecKeychainSearchCreateFromAttributes", ortn); 1535 return ortn; 1536 } 1537 1538 /* 1539 * Only use root certs. Not an error if we don't find any. 1540 */ 1541 do { 1542 ortn = SecKeychainSearchCopyNext(srch, 1543 (SecKeychainItemRef *)&secCert); 1544 if(ortn) { 1545 break; 1546 } 1547 1548 /* see if it's a root */ 1549 if(!isCertRoot(secCert)) { 1550 continue; 1551 } 1552 1553 /* Tell Secure Transport to trust this one. */ 1554 ortn = addTrustedSecCert(ctx, secCert, false); 1555 if(ortn) { 1556 /* fatal */ 1557 printSslErrStr("addTrustedSecCert", ortn); 1558 return ortn; 1559 } 1560 CFRelease(secCert); 1561 *foundOne = true; 1562 } while(ortn == errSecSuccess); 1563 CFRelease(srch); 1564 return errSecSuccess; 1565} 1566 1567/* 1568 * Wrapper for sslIdentPicker, with optional trusted anchor specified as a filename. 1569 */ 1570OSStatus sslIdentityPicker( 1571 SecKeychainRef kcRef, // NULL means use default list 1572 const char *trustedAnchor, // optional additional trusted anchor 1573 bool includeRoot, // true --> root is appended to outArray 1574 // false --> root not included 1575 CFArrayRef *outArray) // created and RETURNED 1576{ 1577 SecCertificateRef trustedCert = NULL; 1578 OSStatus ortn; 1579 1580 if(trustedAnchor) { 1581 ortn = sslReadAnchor(trustedAnchor, &trustedCert); 1582 if(ortn) { 1583 printf("***Error reading %s. sslIdentityPicker proceeding with no anchor.\n", 1584 trustedAnchor); 1585 trustedCert = NULL; 1586 } 1587 } 1588 ortn = sslIdentPicker(kcRef, trustedCert, includeRoot, outArray); 1589 if(trustedCert) { 1590 CFRelease(trustedCert); 1591 } 1592 return ortn; 1593} 1594 1595/* 1596 * Given a keychain name, convert it into a full path using the "SSL regression 1597 * test suite algorithm". The Sec layer by default locates root root's keychains 1598 * in different places depending on whether we're actually logged in as root 1599 * or running via e.g. cron, so we force the location of root keychains to 1600 * a hard-coded path. User keychain names we leave alone. 1601 */ 1602void sslKeychainPath( 1603 const char *kcName, 1604 char *kcPath) // allocd by caller, MAXPATHLEN 1605{ 1606 if(kcName[0] == '\0') { 1607 kcPath[0] = '\0'; 1608 } 1609 else if(geteuid() == 0) { 1610 /* root */ 1611 sprintf(kcPath, "/Library/Keychains/%s", kcName); 1612 } 1613 else { 1614 /* user, leave alone */ 1615 strcpy(kcPath, kcName); 1616 } 1617} 1618 1619/* Verify presence of required file. Returns nonzero if not found. */ 1620int sslCheckFile(const char *path) 1621{ 1622 struct stat sb; 1623 1624 if(stat(path, &sb)) { 1625 printf("***Can't find file %s.\n", path); 1626 printf(" Try running in the build directory, perhaps after running the\n" 1627 " makeLocalCert script.\n"); 1628 return 1; 1629 } 1630 return 0; 1631} 1632 1633#endif 1634 1635/* Stringify a SSL_ECDSA_NamedCurve */ 1636extern const char *sslCurveString( 1637 SSL_ECDSA_NamedCurve namedCurve) 1638{ 1639 static char unk[100]; 1640 1641 switch(namedCurve) { 1642 case SSL_Curve_None: return "Curve_None"; 1643 case SSL_Curve_secp256r1: return "secp256r1"; 1644 case SSL_Curve_secp384r1: return "secp384r1"; 1645 case SSL_Curve_secp521r1: return "secp521r1"; 1646 default: 1647 sprintf(unk, "Unknown <%d>", (int)namedCurve); 1648 return unk; 1649 } 1650} 1651