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