2 #include "sslAppUtils.h" 
   3 #include "sslThreading.h" 
   4 #include "identPicker.h" 
   5 #include <utilLib/fileIo.h> 
   6 #include <utilLib/common.h> 
  10 #include <sys/types.h> 
  12 #include <CoreServices/../Frameworks/CarbonCore.framework/Headers/MacErrors.h> 
  13 #include <Security/AuthSession.h>               // for Sec errors  
  14 #include <CoreFoundation/CFDate.h> 
  16 /* Set true when PR-3074739 is merged to TOT */ 
  17 #define NEW_SSL_ERRS_3074739            1 
  19 const char *sslGetCipherSuiteString(SSLCipherSuite cs
) 
  21         static char noSuite
[40]; 
  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"; 
 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"; 
 172                         sprintf(noSuite
, "Unknown (%d)", (unsigned)cs
); 
 178  * Given a SSLProtocolVersion - typically from SSLGetProtocolVersion - 
 179  * return a string representation. 
 181 const char *sslGetProtocolVersionString(SSLProtocol prot
) 
 183         static char noProt
[20]; 
 186                 case kSSLProtocolUnknown
: 
 187                         return "kSSLProtocolUnknown"; 
 189                         return "kSSLProtocol2"; 
 191                         return "kSSLProtocol3"; 
 192                 case kSSLProtocol3Only
: 
 193                         return "kSSLProtocol3Only"; 
 195                         return "kTLSProtocol1"; 
 196                 case kTLSProtocol1Only
: 
 197                         return "kTLSProtocol1Only"; 
 199                         sprintf(noProt
, "Unknown (%d)", (unsigned)prot
); 
 205  * Return string representation of SecureTransport-related OSStatus. 
 207 const char *sslGetSSLErrString(OSStatus err
) 
 209         static char noErrStr
[20]; 
 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"; 
 241                         return "errSSLBadCert";  
 243                         return "errSSLCrypto"; 
 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"; 
 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"; 
 343                         if(err 
< (CSSM_BASE_ERROR 
+  
 344                                  (CSSM_ERRORCODE_MODULE_EXTENT 
* 8))) { 
 345                                 /* assume CSSM error */ 
 346                                 return cssmErrToStr(err
); 
 349                                 sprintf(noErrStr
, "Unknown (%d)", (unsigned)err
); 
 359         printf("*** %s: %s\n", op
, sslGetSSLErrString(err
)); 
 362 const char *sslGetClientCertStateString(SSLClientCertificateState state
) 
 364         static char noState
[20]; 
 367                 case kSSLClientCertNone
: 
 368                         return "ClientCertNone"; 
 369                 case kSSLClientCertRequested
: 
 370                         return "CertRequested"; 
 371                 case kSSLClientCertSent
: 
 372                         return "ClientCertSent"; 
 373                 case kSSLClientCertRejected
: 
 374                         return "ClientCertRejected"; 
 376                         sprintf(noState
, "Unknown (%d)", (unsigned)state
); 
 382 const char *sslGetClientAuthTypeString(SSLClientAuthenticationType authType
) 
 384         static char noType
[20]; 
 387                 case SSLClientAuthNone
: 
 389                 case SSLClientAuth_RSASign
: 
 391                 case SSLClientAuth_DSSSign
: 
 393                 case SSLClientAuth_RSAFixedDH
: 
 395                 case SSLClientAuth_DSS_FixedDH
: 
 396                         return "DSS_FixedDH"; 
 397                 case SSLClientAuth_ECDSASign
: 
 399                 case SSLClientAuth_RSAFixedECDH
: 
 400                         return "RSAFixedECDH"; 
 401                 case SSLClientAuth_ECDSAFixedECDH
: 
 402                         return "ECDSAFixedECDH"; 
 404                         sprintf(noType
, "Unknown (%d)", (unsigned)authType
); 
 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.  
 417 CFArrayRef 
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 
 424         SecKeychainRef          kcRef 
= nil
; 
 429         /* pick a keychain */ 
 431                 ortn 
= SecKeychainOpen(kcName
, &kcRef
); 
 433                         printf("SecKeychainOpen returned %d.\n", (int)ortn
); 
 434                         printf("Cannot open keychain at %s. Aborting.\n", kcName
); 
 439                 /* use default keychain */ 
 440                 ortn 
= SecKeychainCopyDefault(&kcRef
); 
 442                         printf("SecKeychainCopyDefault returned %d; aborting.\n", (int)ortn
); 
 447         return sslKcRefToCertArray(kcRef
, encryptOnly
, completeCertChain
,  
 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. 
 457  * Returns true if the cert appears to be a root.  
 459 static bool isCertRefRoot( 
 460         SecCertificateRef certRef
) 
 462         /* just search for the two attrs we want */ 
 463         UInt32 tags
[2] = {kSecSubjectItemAttr
, kSecIssuerItemAttr
}; 
 464         SecKeychainAttributeInfo attrInfo
; 
 467         attrInfo
.format 
= NULL
; 
 468         SecKeychainAttributeList 
*attrList 
= NULL
; 
 469         SecKeychainAttribute 
*attr1 
= NULL
; 
 470         SecKeychainAttribute 
*attr2 
= NULL
; 
 473         OSStatus ortn 
= SecKeychainItemCopyAttributesAndData( 
 474                 (SecKeychainItemRef
)certRef
,  
 478                 NULL
,                   // length - don't need the data 
 481                 cssmPerror("SecKeychainItemCopyAttributesAndData", ortn
); 
 482                 /* may want to be a bit more robust here, but this should 
 486         /* subsequent errors to errOut: */ 
 488         if((attrList 
== NULL
) || (attrList
->count 
!= 2)) { 
 489                 printf("***Unexpected result fetching label attr\n"); 
 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) { 
 502         SecKeychainItemFreeAttributesAndData(attrList
, NULL
); 
 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(). 
 512 OSStatus 
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 
 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 
 528         certArray 
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
); 
 529         CFArrayAppendValue(certArray
, identity
); 
 532          * Case 1: identity is a root; we're done. Note that this case 
 533          * overrides the includeRoot argument. 
 535         SecCertificateRef certRef
; 
 536         OSStatus ortn 
= SecIdentityCopyCertificate(identity
, &certRef
); 
 538                 /* should never happen */ 
 539                 cssmPerror("SecIdentityCopyCertificate", ortn
); 
 542         bool isRoot 
= isCertRefRoot(certRef
); 
 544                 *outArray 
= certArray
; 
 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.) 
 555         CFMutableArrayRef subjCerts 
= CFArrayCreateMutable(NULL
, 1, &kCFTypeArrayCallBacks
); 
 556         CFArraySetValueAtIndex(subjCerts
, 0, certRef
); 
 558         /* the array owns the subject cert ref now */ 
 561         /* Get a SecPolicyRef for SSL cert chain verification */ 
 562         ortn 
= SecPolicySearchCreate(CSSM_CERT_X_509v3
, 
 563                 vfyPolicy 
? vfyPolicy 
: &CSSMOID_APPLE_TP_SSL
, 
 567                 cssmPerror("SecPolicySearchCreate", ortn
); 
 570         ortn 
= SecPolicySearchCopyNext(policySearch
, &policy
); 
 572                 cssmPerror("SecPolicySearchCopyNext", ortn
); 
 576         /* build a SecTrustRef for specified policy and certs */ 
 577         ortn 
= SecTrustCreateWithCertificates(subjCerts
, 
 580                 cssmPerror("SecTrustCreateWithCertificates", ortn
); 
 586                  * Tell SecTrust to trust this one in addition to the current 
 587                  * trusted system-wide anchors. 
 589                 CFMutableArrayRef newAnchors
; 
 590                 CFArrayRef currAnchors
; 
 592                 ortn 
= SecTrustCopyAnchorCertificates(&currAnchors
); 
 594                         /* should never happen */ 
 595                         cssmPerror("SecTrustCopyAnchorCertificates", ortn
); 
 598                 newAnchors 
= CFArrayCreateMutableCopy(NULL
, 
 599                         CFArrayGetCount(currAnchors
) + 1, 
 601                 CFRelease(currAnchors
); 
 602                 CFArrayAppendValue(newAnchors
, trustedAnchor
); 
 603                 ortn 
= SecTrustSetAnchorCertificates(secTrust
, newAnchors
); 
 604                 CFRelease(newAnchors
); 
 606                         cssmPerror("SecTrustSetAnchorCertificates", ortn
); 
 611         ortn 
= SecTrustEvaluate(secTrust
, &secTrustResult
); 
 613                 cssmPerror("SecTrustEvaluate", ortn
); 
 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 */ 
 624                          * Cert chain construction failed.  
 625                          * Just go with the single subject cert we were given. 
 627                         printf("***Warning: could not construct completed cert chain\n"); 
 632         /* get resulting constructed cert chain */ 
 633         ortn 
= SecTrustGetResult(secTrust
, &secTrustResult
, &certChain
, &dummyEv
); 
 635                 cssmPerror("SecTrustEvaluate", ortn
); 
 640          * Copy certs from constructed chain to our result array, skipping  
 641          * the leaf (which is already there, as a SecIdentityRef) and possibly 
 644         numResCerts 
= CFArrayGetCount(certChain
); 
 645         if(numResCerts 
< 2) { 
 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(). 
 651                 printf("***sslCompleteCertChain screwup: numResCerts %d\n",  
 657                 /* skip the last (root) cert) */ 
 660         for(CFIndex dex
=1; dex
<numResCerts
; dex
++) { 
 661                 certRef 
= (SecCertificateRef
)CFArrayGetValueAtIndex(certChain
, dex
); 
 662                 CFArrayAppendValue(certArray
, certRef
); 
 670                 CFRelease(subjCerts
); 
 676                 CFRelease(policySearch
); 
 678         *outArray 
= certArray
; 
 684  * Given an open keychain, find a SecIdentityRef and munge it into 
 685  * a CFArrayRef required by SSLSetCertificate(). 
 687 CFArrayRef 
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
) 
 694         /* quick check to make sure the keychain exists */ 
 695         SecKeychainStatus kcStat
; 
 696         OSStatus ortn 
= SecKeychainGetStatus(kcRef
, &kcStat
); 
 698                 printSslErrStr("SecKeychainGetStatus", ortn
); 
 699                 printf("Can not open keychain. Aborting.\n"); 
 704          * Search for "any" identity matching specified key use;  
 705          * in this app, we expect there to be exactly one.  
 707         SecIdentitySearchRef srchRef 
= nil
; 
 708         ortn 
= SecIdentitySearchCreate(kcRef
,  
 709                 encryptOnly 
? CSSM_KEYUSE_DECRYPT 
: CSSM_KEYUSE_SIGN
, 
 712                 printf("SecIdentitySearchCreate returned %d.\n", (int)ortn
); 
 713                 printf("Cannot find signing key in keychain. Aborting.\n"); 
 716         SecIdentityRef identity 
= nil
; 
 717         ortn 
= SecIdentitySearchCopyNext(srchRef
, &identity
); 
 719                 printf("SecIdentitySearchCopyNext returned %d.\n", (int)ortn
); 
 720                 printf("Cannot find signing key in keychain. Aborting.\n"); 
 723         if(CFGetTypeID(identity
) != SecIdentityGetTypeID()) { 
 724                 printf("SecIdentitySearchCopyNext CFTypeID failure!\n"); 
 731         if(completeCertChain
) { 
 733                  * Place it and the other certs needed to verify it - 
 734                  * up to but not including the root - in a CFArray. 
 736                 SecCertificateRef anchorCert 
= NULL
; 
 737                 if(trustedAnchorFile
) { 
 738                         ortn 
= sslReadAnchor(trustedAnchorFile
, &anchorCert
); 
 740                                 printf("***Error reading anchor file\n"); 
 744                 ortn 
= sslCompleteCertChain(identity
, anchorCert
, false, vfyPolicy
, &ca
); 
 746                         CFRelease(anchorCert
); 
 751                 /* simple case, just this one identity */ 
 752                 CFArrayRef ca 
= CFArrayCreate(NULL
, 
 753                         (const void **)&identity
, 
 757                         printf("CFArrayCreate error\n"); 
 763 OSStatus 
addTrustedSecCert( 
 765         SecCertificateRef       secCert
,  
 766         CSSM_BOOL                       replaceAnchors
) 
 769         CFMutableArrayRef array
; 
 771         if(secCert 
== NULL
) { 
 772                 printf("***addTrustedSecCert screwup\n"); 
 775         array 
= CFArrayCreateMutable(kCFAllocatorDefault
, 
 776                 (CFIndex
)1, &kCFTypeArrayCallBacks
); 
 780         CFArrayAppendValue(array
, secCert
); 
 781         ortn 
= SSLSetTrustedRoots(ctx
, array
, replaceAnchors 
? true : false); 
 783                 printSslErrStr("SSLSetTrustedRoots", ortn
); 
 789 OSStatus 
sslReadAnchor( 
 790         const char                      *anchorFile
, 
 791         SecCertificateRef       
*certRef
) 
 794         SecCertificateRef secCert
; 
 795         unsigned char *certData
; 
 800         rtn 
= cspReadFile(anchorFile
, &certData
, &certLen
); 
 802                 printf("cspReadFile(%s) returned %d\n", anchorFile
, rtn
); 
 805         cert
.Data 
= certData
; 
 806         cert
.Length 
= certLen
; 
 807         ortn 
= SecCertificateCreateFromData(&cert
, 
 809                         CSSM_CERT_ENCODING_DER
, 
 813                 printf("***SecCertificateCreateFromData returned %d\n", (int)ortn
); 
 820 OSStatus 
sslAddTrustedRoot( 
 822         const char              *anchorFile
,  
 823         CSSM_BOOL               replaceAnchors
) 
 826         SecCertificateRef secCert
; 
 828         ortn 
= sslReadAnchor(anchorFile
, &secCert
); 
 830                 printf("***Error (%ld) reading %s. SSLSetTrustedRoots skipped.\n", 
 831                         (long)ortn
, anchorFile
); 
 834         return addTrustedSecCert(ctx
, secCert
, replaceAnchors
); 
 838 /* Per 3537606 this is no longer necessary */ 
 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. 
 845 OSStatus 
addIdentityAsTrustedRoot( 
 847         CFArrayRef              identArray
) 
 849         CFIndex numItems 
= CFArrayGetCount(identArray
); 
 851                 printf("***addIdentityAsTrustedRoot: empty identArray\n"); 
 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()) { 
 859                 SecCertificateRef certRef
; 
 860                 OSStatus ortn 
= SecIdentityCopyCertificate( 
 861                         (SecIdentityRef
)theItem
, &certRef
); 
 863                         cssmPerror("SecIdentityCopyCertificate", ortn
); 
 864                         printf("***Error gettting cert from identity\n"); 
 867                 ortn 
= addTrustedSecCert(ctx
, certRef
, CSSM_FALSE
); 
 871         else if(CFGetTypeID(theItem
) == SecCertificateGetTypeID()) { 
 873                 return addTrustedSecCert(ctx
, (SecCertificateRef
)theItem
, CSSM_FALSE
); 
 876                 printf("***Bogus item in identity array\n"); 
 881 OSStatus 
addIdentityAsTrustedRoot( 
 883         CFArrayRef              identArray
) 
 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. 
 894 const 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
 
 906 const 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
 
 916 const 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
 
 925 const 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
 
 935 const 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
 
 941 const 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
 
 946 const SSLCipherSuite suitesRC2
[] = { 
 947         SSL_RSA_WITH_RC2_CBC_MD5
, 
 948         SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5
, 
 949         SSL_NO_SUCH_CIPHERSUITE
 
 951 const 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
 
 959 const 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
 
 967 const 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
 
 997 const 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
 
1007 const 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
 
1020 const 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
 
1033 const 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
 
1071 const 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
 
1079 const SSLCipherSuite suites_NULL
[] = { 
1080         SSL_RSA_WITH_NULL_MD5
, 
1081         SSL_NO_SUCH_CIPHERSUITE
 
1084 const 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
 
1096 const 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
 
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.  
1114 OSStatus 
sslSetEnabledCiphers( 
1116         const SSLCipherSuite 
*ciphers
) 
1118         size_t numSupported
; 
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 
1126         /* first get all the supported ciphers */ 
1127         ortn 
= SSLGetNumberSupportedCiphers(ctx
, &numSupported
); 
1129                 printSslErrStr("SSLGetNumberSupportedCiphers", ortn
); 
1132         supported 
= (SSLCipherSuite 
*)malloc(numSupported 
* sizeof(SSLCipherSuite
)); 
1133         ortn 
= SSLGetSupportedCiphers(ctx
, supported
, &numSupported
); 
1135                 printSslErrStr("SSLGetSupportedCiphers", ortn
); 
1140          * Malloc an array we'll use for SSLGetEnabledCiphers - this will  be 
1141          * bigger than the number of suites we actually specify  
1143         enabled 
= (SSLCipherSuite 
*)malloc(numSupported 
* sizeof(SSLCipherSuite
)); 
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 
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
]; 
1159         /* send it on down. */ 
1160         ortn 
= SSLSetEnabledCiphers(ctx
, enabled
, enabledDex
); 
1162                 printSslErrStr("SSLSetEnabledCiphers", ortn
); 
1170  * Specify a restricted set of cipherspecs. 
1172 OSStatus 
sslSetCipherRestrictions( 
1174         char cipherRestrict
) 
1178         if(cipherRestrict 
== '\0') { 
1179                 return noErr
;           // actually should not have been called  
1181         switch(cipherRestrict
) { 
1183                         ortn 
= sslSetEnabledCiphers(ctx
, suites40
); 
1186                         ortn 
= sslSetEnabledCiphers(ctx
, suitesDES
); 
1189                         ortn 
= sslSetEnabledCiphers(ctx
, suitesDES40
); 
1192                         ortn 
= sslSetEnabledCiphers(ctx
, suites3DES
); 
1195                         ortn 
= sslSetEnabledCiphers(ctx
, suitesRC4
); 
1198                         ortn 
= sslSetEnabledCiphers(ctx
, suitesRC4_40
); 
1201                         ortn 
= sslSetEnabledCiphers(ctx
, suitesRC2
); 
1204                         ortn 
= sslSetEnabledCiphers(ctx
, suitesAES128
); 
1207                         ortn 
= sslSetEnabledCiphers(ctx
, suitesAES256
); 
1210                         ortn 
= sslSetEnabledCiphers(ctx
, suitesDH
); 
1213                         ortn 
= sslSetEnabledCiphers(ctx
, suitesDHAnon
); 
1216                         ortn 
= sslSetEnabledCiphers(ctx
, suitesDH_RSA
); 
1219                         ortn 
= sslSetEnabledCiphers(ctx
, suitesDH_DSS
); 
1222                         ortn 
= sslSetEnabledCiphers(ctx
, suites_NULL
); 
1225                         ortn 
= sslSetEnabledCiphers(ctx
, suites_ECDHE
); 
1228                         ortn 
= sslSetEnabledCiphers(ctx
, suites_ECDH
); 
1231                         printf("***bad cipherSpec***\n"); 
1237 int sslVerifyClientCertState( 
1238         const char                                      *whichSide
,             // "client" or "server" 
1239         SSLClientCertificateState       expectState
, 
1240         SSLClientCertificateState       gotState
) 
1242         if(expectState 
== SSL_CLIENT_CERT_IGNORE
) { 
1243                 /* app says "don't bother checking" */ 
1246         if(expectState 
== gotState
) { 
1249         printf("***%s: Expected clientCertState %s; got %s\n", whichSide
, 
1250                 sslGetClientCertStateString(expectState
), 
1251                 sslGetClientCertStateString(gotState
)); 
1256         const char      *whichSide
,             // "client" or "server" 
1260         if(expectRtn 
== gotRtn
) { 
1263         printf("***%s: Expected return %s; got %s\n", whichSide
, 
1264                 sslGetSSLErrString(expectRtn
), 
1265                 sslGetSSLErrString(gotRtn
)); 
1269 int sslVerifyProtVers( 
1270         const char      *whichSide
,             // "client" or "server" 
1271         SSLProtocol     expectProt
, 
1272         SSLProtocol     gotProt
)                 
1274         if(expectProt 
== SSL_PROTOCOL_IGNORE
) { 
1275                 /* app says "don't bopther checking" */ 
1278         if(expectProt 
== gotProt
) { 
1281         printf("***%s: Expected return %s; got %s\n", whichSide
, 
1282                 sslGetProtocolVersionString(expectProt
), 
1283                 sslGetProtocolVersionString(gotProt
)); 
1287 int sslVerifyCipher( 
1288         const char              *whichSide
,             // "client" or "server" 
1289         SSLCipherSuite  expectCipher
, 
1290         SSLCipherSuite  gotCipher
)               
1292         if(expectCipher 
== SSL_CIPHER_IGNORE
) { 
1293                 /* app says "don't bopther checking" */ 
1296         if(expectCipher 
== gotCipher
) { 
1299         printf("***%s: Expected return %s; got %s\n", whichSide
, 
1300                 sslGetCipherSuiteString(expectCipher
), 
1301                 sslGetCipherSuiteString(gotCipher
)); 
1306 OSStatus 
sslSetProtocols( 
1308         const char              *acceptedProts
, 
1309         SSLProtocol             tryVersion
)                     // only used if acceptedProts NULL 
1314                 ortn 
= SSLSetProtocolVersionEnabled(ctx
, kSSLProtocolAll
, false); 
1316                         printSslErrStr("SSLSetProtocolVersionEnabled(all off)", ortn
); 
1319                 for(const char *cp 
= acceptedProts
; *cp
; cp
++) { 
1323                                         prot 
= kSSLProtocol2
; 
1326                                         prot 
= kSSLProtocol3
; 
1329                                         prot 
= kTLSProtocol1
; 
1332                                         printf("***BRRZAP! Bad acceptedProts string %s. Aborting.\n", acceptedProts
); 
1335                         ortn 
= SSLSetProtocolVersionEnabled(ctx
, prot
, true); 
1337                                 printSslErrStr("SSLSetProtocolVersionEnabled", ortn
); 
1343                 ortn 
= SSLSetProtocolVersion(ctx
, tryVersion
); 
1345                         printSslErrStr("SSLSetProtocolVersion", ortn
); 
1353         const char                      *whichSide
,             // "client" or "server" 
1354         SslAppTestParams        
*params
) 
1356         printf("%s status:\n", whichSide
); 
1357         if(params
->acceptedProts
) { 
1358                 printf("   Allowed SSL versions   : %s\n", params
->acceptedProts
); 
1361                 printf("   Attempted  SSL version : %s\n",  
1362                         sslGetProtocolVersionString(params
->tryVersion
)); 
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
)); 
1375 /* print a '.' every few seconds to keep UI alive while connecting */ 
1376 static CFAbsoluteTime lastTime 
= (CFAbsoluteTime
)0.0; 
1377 #define TIME_INTERVAL           3.0 
1381         CFAbsoluteTime thisTime 
= CFAbsoluteTimeGetCurrent(); 
1383         if(lastTime 
== 0.0) { 
1384                 /* avoid printing first time thru */ 
1385                 lastTime 
= thisTime
; 
1388         if((thisTime 
- lastTime
) >= TIME_INTERVAL
) { 
1389                 printf("."); fflush(stdout
); 
1390                 lastTime 
= thisTime
; 
1394 /* main server pthread body */ 
1395 static void *sslServerThread(void *arg
) 
1397         SslAppTestParams 
*testParams 
= (SslAppTestParams 
*)arg
; 
1400         status 
= sslAppServe(testParams
); 
1401         pthread_exit((void*)status
); 
1403         return (void *)status
; 
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.  
1413 #define CLIENT_WAIT_SECONDS             1 
1415         SslAppTestParams
*serverParams
, 
1416         SslAppTestParams 
*clientParams
, 
1417         const char              *testDesc
) 
1419         pthread_t serverPthread
; 
1423         if(testDesc 
&& !clientParams
->quiet
) { 
1424                 printf("===== %s =====\n", testDesc
); 
1428          * Workaround for Radar 4619502: resolve references to Security.framework  
1429          * here, in main thread, before we fork off the server thread. 
1431         SecKeychainRef defaultKc 
= NULL
; 
1432         SecKeychainCopyDefault(&defaultKc
); 
1433         /* end workaround */ 
1435         if(pthread_mutex_init(&serverParams
->pthreadMutex
, NULL
)) { 
1436                 printf("***Error initializing mutex; aborting.\n"); 
1439         if(pthread_cond_init(&serverParams
->pthreadCond
, NULL
)) { 
1440                 printf("***Error initializing pthreadCond; aborting.\n"); 
1443         serverParams
->serverReady 
= false;              // server sets true 
1445         int result 
= pthread_create(&serverPthread
, NULL
,  
1446                         sslServerThread
, serverParams
); 
1448                 printf("***Error starting up server thread; aborting.\n"); 
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"); 
1457         while(!serverParams
->serverReady
) { 
1458                 if(pthread_cond_wait(&serverParams
->pthreadCond
, &serverParams
->pthreadMutex
)) { 
1459                         printf("***Error waiting server thread; aborting.\n"); 
1463         pthread_mutex_unlock(&serverParams
->pthreadMutex
); 
1464         pthread_cond_destroy(&serverParams
->pthreadCond
); 
1465         pthread_mutex_destroy(&serverParams
->pthreadMutex
); 
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
); 
1473                 printf("***pthread_join returned %d, aborting\n", result
); 
1477         if(serverParams
->verbose
) { 
1478                 sslShowResult("server", serverParams
); 
1480         if(clientParams
->verbose
) { 
1481                 sslShowResult("client", clientParams
); 
1484         /* verify results */ 
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
); 
1500         if(clientParams
->ortn 
== noErr
) { 
1501                 ourRtn 
+= sslVerifyCipher("client", clientParams
->expectCipher
,  
1502                         clientParams
->negCipher
); 
1506                 /* for workaround for Radar 4619502 */ 
1507                 CFRelease(defaultKc
); 
1513  * Add all of the roots in a given KC to SSL ctx's trusted anchors. 
1515 OSStatus 
sslAddTrustedRoots( 
1517         SecKeychainRef  keychain
, 
1518         bool                    *foundOne
)              // RETURNED, true if we found  
1519                                                                         //    at least one root cert 
1522         SecCertificateRef               secCert
; 
1523         SecKeychainSearchRef    srch
; 
1526         ortn 
= SecKeychainSearchCreateFromAttributes(keychain
, 
1527                 kSecCertificateItemClass
, 
1531                 printSslErrStr("SecKeychainSearchCreateFromAttributes", ortn
); 
1536          * Only use root certs. Not an error if we don't find any. 
1539                 ortn 
= SecKeychainSearchCopyNext(srch
,  
1540                         (SecKeychainItemRef 
*)&secCert
); 
1545                 /* see if it's a root */ 
1546                 if(!isCertRefRoot(secCert
)) { 
1550                 /* Tell Secure Transport to trust this one. */ 
1551                 ortn 
= addTrustedSecCert(ctx
, secCert
, false); 
1554                         printSslErrStr("addTrustedSecCert", ortn
); 
1559         } while(ortn 
== noErr
); 
1565  * Wrapper for sslIdentPicker, with optional trusted anchor specified as a filename. 
1567 OSStatus 
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 
1575         SecCertificateRef trustedCert 
= NULL
; 
1579                 ortn 
= sslReadAnchor(trustedAnchor
, &trustedCert
); 
1581                         printf("***Error reading %s. sslIdentityPicker proceeding with no anchor.\n", 
1586         ortn 
= sslIdentPicker(kcRef
, trustedCert
, includeRoot
, vfyPolicy
, outArray
); 
1588                 CFRelease(trustedCert
); 
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  
1602 void sslKeychainPath( 
1604         char *kcPath
)                   // allocd by caller, MAXPATHLEN 
1606         if(kcName
[0] == '\0') { 
1609         else if(geteuid() == 0) { 
1611                 const char *buildDir 
= getenv("LOCAL_BUILD_DIR"); 
1612                 if(buildDir 
== NULL
) { 
1615                 sprintf(kcPath
, "%s/Library/Keychains/%s", buildDir
, kcName
); 
1618                 /* user, leave alone */ 
1619                 strcpy(kcPath
, kcName
); 
1623 /* Verify presence of required file. Returns nonzero if not found. */ 
1624 int sslCheckFile(const char *path
) 
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"); 
1637 /* Stringify a SSL_ECDSA_NamedCurve */ 
1638 extern const char *sslCurveString( 
1639         SSL_ECDSA_NamedCurve namedCurve
) 
1641         static char unk
[100]; 
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"; 
1649                         sprintf(unk
, "Unknown <%d>", (int)namedCurve
);