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