2  * Copyright (c) 2006-2008,2010-2012 Apple Inc. All Rights Reserved. 
   5 #include "sslAppUtils.h" 
  10 #include <MacErrors.h> 
  11 #include <CoreFoundation/CoreFoundation.h> 
  12 #include <Security/Security.h> 
  13 #include <Security/SecIdentityPriv.h> 
  14 #include <AssertMacros.h> 
  16 #define CFReleaseSafe(CF)       { CFTypeRef _cf = (CF); if (_cf) CFRelease(_cf); } 
  18 const char *sslGetCipherSuiteString(SSLCipherSuite cs
) 
  20         static char noSuite
[40]; 
  23                 /* TLS cipher suites, RFC 2246 */ 
  24                 case SSL_NULL_WITH_NULL_NULL
:               return "TLS_NULL_WITH_NULL_NULL"; 
  25                 case SSL_RSA_WITH_NULL_MD5
:                 return "TLS_RSA_WITH_NULL_MD5"; 
  26                 case SSL_RSA_WITH_NULL_SHA
:                 return "TLS_RSA_WITH_NULL_SHA"; 
  27                 case SSL_RSA_EXPORT_WITH_RC4_40_MD5
:        return "TLS_RSA_EXPORT_WITH_RC4_40_MD5"; 
  28                 case SSL_RSA_WITH_RC4_128_MD5
:              return "TLS_RSA_WITH_RC4_128_MD5"; 
  29                 case SSL_RSA_WITH_RC4_128_SHA
:              return "TLS_RSA_WITH_RC4_128_SHA"; 
  30                 case SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5
:    return "TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5"; 
  31                 case SSL_RSA_WITH_IDEA_CBC_SHA
:             return "TLS_RSA_WITH_IDEA_CBC_SHA"; 
  32                 case SSL_RSA_EXPORT_WITH_DES40_CBC_SHA
:     return "TLS_RSA_EXPORT_WITH_DES40_CBC_SHA"; 
  33                 case SSL_RSA_WITH_DES_CBC_SHA
:              return "TLS_RSA_WITH_DES_CBC_SHA"; 
  34                 case SSL_RSA_WITH_3DES_EDE_CBC_SHA
:         return "TLS_RSA_WITH_3DES_EDE_CBC_SHA"; 
  35                 case SSL_DH_DSS_EXPORT_WITH_DES40_CBC_SHA
:  return "TLS_DH_DSS_EXPORT_WITH_DES40_CBC_SHA"; 
  36                 case SSL_DH_DSS_WITH_DES_CBC_SHA
:           return "TLS_DH_DSS_WITH_DES_CBC_SHA"; 
  37                 case SSL_DH_DSS_WITH_3DES_EDE_CBC_SHA
:      return "TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA"; 
  38                 case SSL_DH_RSA_EXPORT_WITH_DES40_CBC_SHA
:  return "TLS_DH_RSA_EXPORT_WITH_DES40_CBC_SHA"; 
  39                 case SSL_DH_RSA_WITH_DES_CBC_SHA
:           return "TLS_DH_RSA_WITH_DES_CBC_SHA"; 
  40                 case SSL_DH_RSA_WITH_3DES_EDE_CBC_SHA
:      return "TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA"; 
  41                 case SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA
: return "TLS_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA"; 
  42                 case SSL_DHE_DSS_WITH_DES_CBC_SHA
:          return "TLS_DHE_DSS_WITH_DES_CBC_SHA"; 
  43                 case SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA
:     return "TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA"; 
  44                 case SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA
: return "TLS_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA"; 
  45                 case SSL_DHE_RSA_WITH_DES_CBC_SHA
:          return "TLS_DHE_RSA_WITH_DES_CBC_SHA"; 
  46                 case SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA
:     return "TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA"; 
  47                 case SSL_DH_anon_EXPORT_WITH_RC4_40_MD5
:    return "TLS_DH_anon_EXPORT_WITH_RC4_40_MD5"; 
  48                 case SSL_DH_anon_WITH_RC4_128_MD5
:          return "TLS_DH_anon_WITH_RC4_128_MD5"; 
  49                 case SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA
: return "TLS_DH_anon_EXPORT_WITH_DES40_CBC_SHA"; 
  50                 case SSL_DH_anon_WITH_DES_CBC_SHA
:          return "TLS_DH_anon_WITH_DES_CBC_SHA"; 
  51                 case SSL_DH_anon_WITH_3DES_EDE_CBC_SHA
:     return "TLS_DH_anon_WITH_3DES_EDE_CBC_SHA"; 
  53                 /* SSLv3 Fortezza cipher suites, from NSS */ 
  54                 case SSL_FORTEZZA_DMS_WITH_NULL_SHA
:        return "SSL_FORTEZZA_DMS_WITH_NULL_SHA"; 
  55                 case SSL_FORTEZZA_DMS_WITH_FORTEZZA_CBC_SHA
:return "SSL_FORTEZZA_DMS_WITH_FORTEZZA_CBC_SHA"; 
  57                 /* TLS addenda using AES-CBC, RFC 3268 */ 
  58                 case TLS_RSA_WITH_AES_128_CBC_SHA
:          return "TLS_RSA_WITH_AES_128_CBC_SHA"; 
  59                 case TLS_DH_DSS_WITH_AES_128_CBC_SHA
:       return "TLS_DH_DSS_WITH_AES_128_CBC_SHA"; 
  60                 case TLS_DH_RSA_WITH_AES_128_CBC_SHA
:       return "TLS_DH_RSA_WITH_AES_128_CBC_SHA"; 
  61                 case TLS_DHE_DSS_WITH_AES_128_CBC_SHA
:      return "TLS_DHE_DSS_WITH_AES_128_CBC_SHA"; 
  62                 case TLS_DHE_RSA_WITH_AES_128_CBC_SHA
:      return "TLS_DHE_RSA_WITH_AES_128_CBC_SHA"; 
  63                 case TLS_DH_anon_WITH_AES_128_CBC_SHA
:      return "TLS_DH_anon_WITH_AES_128_CBC_SHA"; 
  64                 case TLS_RSA_WITH_AES_256_CBC_SHA
:          return "TLS_RSA_WITH_AES_256_CBC_SHA"; 
  65                 case TLS_DH_DSS_WITH_AES_256_CBC_SHA
:       return "TLS_DH_DSS_WITH_AES_256_CBC_SHA"; 
  66                 case TLS_DH_RSA_WITH_AES_256_CBC_SHA
:       return "TLS_DH_RSA_WITH_AES_256_CBC_SHA"; 
  67                 case TLS_DHE_DSS_WITH_AES_256_CBC_SHA
:      return "TLS_DHE_DSS_WITH_AES_256_CBC_SHA"; 
  68                 case TLS_DHE_RSA_WITH_AES_256_CBC_SHA
:      return "TLS_DHE_RSA_WITH_AES_256_CBC_SHA"; 
  69                 case TLS_DH_anon_WITH_AES_256_CBC_SHA
:      return "TLS_DH_anon_WITH_AES_256_CBC_SHA"; 
  71                 /* ECDSA addenda, RFC 4492 */ 
  72                 case TLS_ECDH_ECDSA_WITH_NULL_SHA
:          return "TLS_ECDH_ECDSA_WITH_NULL_SHA"; 
  73                 case TLS_ECDH_ECDSA_WITH_RC4_128_SHA
:       return "TLS_ECDH_ECDSA_WITH_RC4_128_SHA"; 
  74                 case TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA
:  return "TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA"; 
  75                 case TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA
:   return "TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA"; 
  76                 case TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA
:   return "TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA"; 
  77                 case TLS_ECDHE_ECDSA_WITH_NULL_SHA
:         return "TLS_ECDHE_ECDSA_WITH_NULL_SHA"; 
  78                 case TLS_ECDHE_ECDSA_WITH_RC4_128_SHA
:      return "TLS_ECDHE_ECDSA_WITH_RC4_128_SHA"; 
  79                 case TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA
: return "TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA"; 
  80                 case TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA
:  return "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA"; 
  81                 case TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA
:  return "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA"; 
  82                 case TLS_ECDH_RSA_WITH_NULL_SHA
:            return "TLS_ECDH_RSA_WITH_NULL_SHA"; 
  83                 case TLS_ECDH_RSA_WITH_RC4_128_SHA
:         return "TLS_ECDH_RSA_WITH_RC4_128_SHA"; 
  84                 case TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA
:    return "TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA"; 
  85                 case TLS_ECDH_RSA_WITH_AES_128_CBC_SHA
:     return "TLS_ECDH_RSA_WITH_AES_128_CBC_SHA"; 
  86                 case TLS_ECDH_RSA_WITH_AES_256_CBC_SHA
:     return "TLS_ECDH_RSA_WITH_AES_256_CBC_SHA"; 
  87                 case TLS_ECDHE_RSA_WITH_NULL_SHA
:           return "TLS_ECDHE_RSA_WITH_NULL_SHA"; 
  88                 case TLS_ECDHE_RSA_WITH_RC4_128_SHA
:        return "TLS_ECDHE_RSA_WITH_RC4_128_SHA"; 
  89                 case TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA
:   return "TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA"; 
  90                 case TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA
:    return "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA"; 
  91                 case TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA
:    return "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA"; 
  92                 case TLS_ECDH_anon_WITH_NULL_SHA
:           return "TLS_ECDH_anon_WITH_NULL_SHA"; 
  93                 case TLS_ECDH_anon_WITH_RC4_128_SHA
:        return "TLS_ECDH_anon_WITH_RC4_128_SHA"; 
  94                 case TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA
:   return "TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA"; 
  95                 case TLS_ECDH_anon_WITH_AES_128_CBC_SHA
:    return "TLS_ECDH_anon_WITH_AES_128_CBC_SHA"; 
  96                 case TLS_ECDH_anon_WITH_AES_256_CBC_SHA
:    return "TLS_ECDH_anon_WITH_AES_256_CBC_SHA"; 
  98                 /* TLS 1.2 addenda, RFC 5246 */ 
  99                 case TLS_RSA_WITH_AES_128_CBC_SHA256
:       return "TLS_RSA_WITH_AES_128_CBC_SHA256"; 
 100                 case TLS_RSA_WITH_AES_256_CBC_SHA256
:       return "TLS_RSA_WITH_AES_256_CBC_SHA256"; 
 101                 case TLS_DH_DSS_WITH_AES_128_CBC_SHA256
:    return "TLS_DH_DSS_WITH_AES_128_CBC_SHA256"; 
 102                 case TLS_DH_RSA_WITH_AES_128_CBC_SHA256
:    return "TLS_DH_RSA_WITH_AES_128_CBC_SHA256"; 
 103                 case TLS_DHE_DSS_WITH_AES_128_CBC_SHA256
:   return "TLS_DHE_DSS_WITH_AES_128_CBC_SHA256"; 
 104                 case TLS_DHE_RSA_WITH_AES_128_CBC_SHA256
:   return "TLS_DHE_RSA_WITH_AES_128_CBC_SHA256"; 
 105                 case TLS_DH_DSS_WITH_AES_256_CBC_SHA256
:    return "TLS_DH_DSS_WITH_AES_256_CBC_SHA256"; 
 106                 case TLS_DH_RSA_WITH_AES_256_CBC_SHA256
:    return "TLS_DH_RSA_WITH_AES_256_CBC_SHA256"; 
 107                 case TLS_DHE_DSS_WITH_AES_256_CBC_SHA256
:   return "TLS_DHE_DSS_WITH_AES_256_CBC_SHA256"; 
 108                 case TLS_DHE_RSA_WITH_AES_256_CBC_SHA256
:   return "TLS_DHE_RSA_WITH_AES_256_CBC_SHA256"; 
 109                 case TLS_DH_anon_WITH_AES_128_CBC_SHA256
:   return "TLS_DH_anon_WITH_AES_128_CBC_SHA256"; 
 110                 case TLS_DH_anon_WITH_AES_256_CBC_SHA256
:   return "TLS_DH_anon_WITH_AES_256_CBC_SHA256"; 
 112                 /* TLS addenda using AES-GCM, RFC 5288 */ 
 113                 case TLS_RSA_WITH_AES_128_GCM_SHA256
:       return "TLS_RSA_WITH_AES_128_GCM_SHA256"; 
 114                 case TLS_RSA_WITH_AES_256_GCM_SHA384
:       return "TLS_DHE_RSA_WITH_AES_128_GCM_SHA256"; 
 115                 case TLS_DHE_RSA_WITH_AES_128_GCM_SHA256
:   return "TLS_DHE_RSA_WITH_AES_128_GCM_SHA256"; 
 116                 case TLS_DHE_RSA_WITH_AES_256_GCM_SHA384
:   return "TLS_DHE_RSA_WITH_AES_256_GCM_SHA384"; 
 117                 case TLS_DH_RSA_WITH_AES_128_GCM_SHA256
:    return "TLS_DH_RSA_WITH_AES_128_GCM_SHA256"; 
 118                 case TLS_DH_RSA_WITH_AES_256_GCM_SHA384
:    return "TLS_DH_RSA_WITH_AES_256_GCM_SHA384"; 
 119                 case TLS_DHE_DSS_WITH_AES_128_GCM_SHA256
:   return "TLS_DHE_DSS_WITH_AES_128_GCM_SHA256"; 
 120                 case TLS_DHE_DSS_WITH_AES_256_GCM_SHA384
:   return "TLS_DHE_DSS_WITH_AES_256_GCM_SHA384"; 
 121                 case TLS_DH_DSS_WITH_AES_128_GCM_SHA256
:    return "TLS_DH_DSS_WITH_AES_128_GCM_SHA256"; 
 122                 case TLS_DH_DSS_WITH_AES_256_GCM_SHA384
:    return "TLS_DH_DSS_WITH_AES_256_GCM_SHA384"; 
 123                 case TLS_DH_anon_WITH_AES_128_GCM_SHA256
:   return "TLS_DH_anon_WITH_AES_128_GCM_SHA256"; 
 124                 case TLS_DH_anon_WITH_AES_256_GCM_SHA384
:   return "TLS_DH_anon_WITH_AES_256_GCM_SHA384"; 
 126                 /* ECDSA addenda, RFC 5289 */ 
 127                 case TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256
:   return "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256"; 
 128                 case TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384
:   return "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384"; 
 129                 case TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256
:    return "TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256"; 
 130                 case TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384
:    return "TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384"; 
 131                 case TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256
:     return "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256"; 
 132                 case TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384
:     return "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384"; 
 133                 case TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256
:      return "TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256"; 
 134                 case TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384
:      return "TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384"; 
 135                 case TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
:   return "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256"; 
 136                 case TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
:   return "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384"; 
 137                 case TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256
:    return "TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256"; 
 138                 case TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384
:    return "TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384"; 
 139                 case TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
:     return "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256"; 
 140                 case TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
:     return "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384"; 
 141                 case TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256
:      return "TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256"; 
 142                 case TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384
:      return "TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384"; 
 145                  * Tags for SSL 2 cipher kinds which are not specified for SSL 3. 
 147                 case SSL_RSA_WITH_RC2_CBC_MD5
:              return "TLS_RSA_WITH_RC2_CBC_MD5"; 
 148                 case SSL_RSA_WITH_IDEA_CBC_MD5
:             return "TLS_RSA_WITH_IDEA_CBC_MD5"; 
 149                 case SSL_RSA_WITH_DES_CBC_MD5
:              return "TLS_RSA_WITH_DES_CBC_MD5"; 
 150                 case SSL_RSA_WITH_3DES_EDE_CBC_MD5
:         return "TLS_RSA_WITH_3DES_EDE_CBC_MD5"; 
 151                 case SSL_NO_SUCH_CIPHERSUITE
:               return "SSL_NO_SUCH_CIPHERSUITE"; 
 154                         sprintf(noSuite
, "Unknown (0x%04X)", (unsigned)cs
); 
 160  * Given a SSLProtocolVersion - typically from SSLGetProtocolVersion - 
 161  * return a string representation. 
 163 const char *sslGetProtocolVersionString(SSLProtocol prot
) 
 165         static char noProt
[20]; 
 168                 case kSSLProtocolUnknown
:   return "kSSLProtocolUnknown"; 
 169                 case kSSLProtocol2
:         return "kSSLProtocol2"; 
 170                 case kSSLProtocol3
:         return "kSSLProtocol3"; 
 171                 case kSSLProtocol3Only
:     return "kSSLProtocol3Only"; 
 172                 case kTLSProtocol1
:         return "kTLSProtocol1"; 
 173                 case kTLSProtocol1Only
:     return "kTLSProtocol1Only"; 
 174                 case kTLSProtocol11
:        return "kTLSProtocol11"; 
 175                 case kTLSProtocol12
:        return "kTLSProtocol12"; 
 177                         sprintf(noProt
, "Unknown (%d)", (unsigned)prot
); 
 183  * Return string representation of SecureTransport-related OSStatus. 
 185 const char *sslGetSSLErrString(OSStatus err
) 
 187         static char noErrStr
[20]; 
 190                 case noErr
:                         return "noErr"; 
 191                 case memFullErr
:                    return "memFullErr"; 
 192                 case paramErr
:                      return "paramErr"; 
 193                 case unimpErr
:                      return "unimpErr"; 
 194                 case ioErr
:                         return "ioErr"; 
 195                 case badReqErr
:                     return "badReqErr"; 
 197                 case errSSLProtocol
:                return "errSSLProtocol"; 
 198                 case errSSLNegotiation
:             return "errSSLNegotiation"; 
 199                 case errSSLFatalAlert
:              return "errSSLFatalAlert"; 
 200                 case errSSLWouldBlock
:              return "errSSLWouldBlock"; 
 201                 case errSSLSessionNotFound
:         return "errSSLSessionNotFound"; 
 202                 case errSSLClosedGraceful
:          return "errSSLClosedGraceful"; 
 203                 case errSSLClosedAbort
:             return "errSSLClosedAbort"; 
 204                 case errSSLXCertChainInvalid
:       return "errSSLXCertChainInvalid"; 
 205                 case errSSLBadCert
:                 return "errSSLBadCert"; 
 206                 case errSSLCrypto
:                  return "errSSLCrypto"; 
 207                 case errSSLInternal
:                return "errSSLInternal"; 
 208                 case errSSLModuleAttach
:            return "errSSLModuleAttach"; 
 209                 case errSSLUnknownRootCert
:         return "errSSLUnknownRootCert"; 
 210                 case errSSLNoRootCert
:              return "errSSLNoRootCert"; 
 211                 case errSSLCertExpired
:             return "errSSLCertExpired"; 
 212                 case errSSLCertNotYetValid
:         return "errSSLCertNotYetValid"; 
 213                 case errSSLClosedNoNotify
:          return "errSSLClosedNoNotify"; 
 214                 case errSSLBufferOverflow
:          return "errSSLBufferOverflow"; 
 215                 case errSSLBadCipherSuite
:          return "errSSLBadCipherSuite"; 
 216                 /* TLS/Panther addenda */ 
 217                 case errSSLPeerUnexpectedMsg
:       return "errSSLPeerUnexpectedMsg"; 
 218                 case errSSLPeerBadRecordMac
:        return "errSSLPeerBadRecordMac"; 
 219                 case errSSLPeerDecryptionFail
:      return "errSSLPeerDecryptionFail"; 
 220                 case errSSLPeerRecordOverflow
:      return "errSSLPeerRecordOverflow"; 
 221                 case errSSLPeerDecompressFail
:      return "errSSLPeerDecompressFail"; 
 222                 case errSSLPeerHandshakeFail
:       return "errSSLPeerHandshakeFail"; 
 223                 case errSSLPeerBadCert
:             return "errSSLPeerBadCert"; 
 224                 case errSSLPeerUnsupportedCert
:     return "errSSLPeerUnsupportedCert"; 
 225                 case errSSLPeerCertRevoked
:         return "errSSLPeerCertRevoked"; 
 226                 case errSSLPeerCertExpired
:         return "errSSLPeerCertExpired"; 
 227                 case errSSLPeerCertUnknown
:         return "errSSLPeerCertUnknown"; 
 228                 case errSSLIllegalParam
:            return "errSSLIllegalParam"; 
 229                 case errSSLPeerUnknownCA
:           return "errSSLPeerUnknownCA"; 
 230                 case errSSLPeerAccessDenied
:        return "errSSLPeerAccessDenied"; 
 231                 case errSSLPeerDecodeError
:         return "errSSLPeerDecodeError"; 
 232                 case errSSLPeerDecryptError
:        return "errSSLPeerDecryptError"; 
 233                 case errSSLPeerExportRestriction
:   return "errSSLPeerExportRestriction"; 
 234                 case errSSLPeerProtocolVersion
:     return "errSSLPeerProtocolVersion"; 
 235                 case errSSLPeerInsufficientSecurity
:return "errSSLPeerInsufficientSecurity"; 
 236                 case errSSLPeerInternalError
:       return "errSSLPeerInternalError"; 
 237                 case errSSLPeerUserCancelled
:       return "errSSLPeerUserCancelled"; 
 238                 case errSSLPeerNoRenegotiation
:     return "errSSLPeerNoRenegotiation"; 
 239                 case errSSLHostNameMismatch
:        return "errSSLHostNameMismatch"; 
 240                 case errSSLConnectionRefused
:       return "errSSLConnectionRefused"; 
 241                 case errSSLDecryptionFail
:          return "errSSLDecryptionFail"; 
 242                 case errSSLBadRecordMac
:            return "errSSLBadRecordMac"; 
 243                 case errSSLRecordOverflow
:          return "errSSLRecordOverflow"; 
 244                 case errSSLBadConfiguration
:        return "errSSLBadConfiguration"; 
 246                 /* some from the Sec layer */ 
 247                 case errSecNotAvailable
:            return "errSecNotAvailable"; 
 248                 case errSecDuplicateItem
:           return "errSecDuplicateItem"; 
 249                 case errSecItemNotFound
:            return "errSecItemNotFound"; 
 251                 case errSecReadOnly
:                return "errSecReadOnly"; 
 252                 case errSecAuthFailed
:              return "errSecAuthFailed"; 
 253                 case errSecNoSuchKeychain
:          return "errSecNoSuchKeychain"; 
 254                 case errSecInvalidKeychain
:         return "errSecInvalidKeychain"; 
 255                 case errSecNoSuchAttr
:              return "errSecNoSuchAttr"; 
 256                 case errSecInvalidItemRef
:          return "errSecInvalidItemRef"; 
 257                 case errSecInvalidSearchRef
:        return "errSecInvalidSearchRef"; 
 258                 case errSecNoSuchClass
:             return "errSecNoSuchClass"; 
 259                 case errSecNoDefaultKeychain
:       return "errSecNoDefaultKeychain"; 
 260                 case errSecWrongSecVersion
:         return "errSecWrongSecVersion"; 
 261                 case errSecInvalidTrustSettings
:    return "errSecInvalidTrustSettings"; 
 262                 case errSecNoTrustSettings
:         return "errSecNoTrustSettings"; 
 266                         if (err 
< (CSSM_BASE_ERROR 
+ 
 267                                  (CSSM_ERRORCODE_MODULE_EXTENT 
* 8))) 
 269                                 /* assume CSSM error */ 
 270                                 return cssmErrToStr(err
); 
 275                                 sprintf(noErrStr
, "Unknown (%d)", (unsigned)err
); 
 285         printf("*** %s: %s\n", op
, sslGetSSLErrString(err
)); 
 288 const char *sslGetClientCertStateString(SSLClientCertificateState state
) 
 290         static char noState
[20]; 
 293                 case kSSLClientCertNone
:            return "ClientCertNone"; 
 294                 case kSSLClientCertRequested
:       return "CertRequested"; 
 295                 case kSSLClientCertSent
:            return "ClientCertSent"; 
 296                 case kSSLClientCertRejected
:        return "ClientCertRejected"; 
 298                         sprintf(noState
, "Unknown (%d)", (unsigned)state
); 
 304 const char *sslGetClientAuthTypeString(SSLClientAuthenticationType authType
) 
 306         static char noType
[20]; 
 309                 case SSLClientAuthNone
:             return "None"; 
 310                 case SSLClientAuth_RSASign
:         return "RSASign"; 
 311                 case SSLClientAuth_DSSSign
:         return "DSSSign"; 
 312                 case SSLClientAuth_RSAFixedDH
:      return "RSAFixedDH"; 
 313                 case SSLClientAuth_DSS_FixedDH
:     return "DSS_FixedDH"; 
 314                 case SSLClientAuth_ECDSASign
:       return "ECDSASign"; 
 315                 case SSLClientAuth_RSAFixedECDH
:    return "RSAFixedECDH"; 
 316                 case SSLClientAuth_ECDSAFixedECDH
:  return "ECDSAFixedECDH"; 
 318                         sprintf(noType
, "Unknown (%d)", (unsigned)authType
); 
 324  * Convert a keychain name (which may be NULL) into the CFArrayRef required 
 325  * by SSLSetCertificate. This is a bare-bones example of this operation, 
 326  * since it requires and assumes that there is exactly one SecIdentity 
 327  * in the keychain - i.e., there is exactly one matching cert/private key 
 328  * pair. A real world server would probably search a keychain for a SecIdentity 
 329  * matching some specific criteria. 
 331 CFArrayRef 
getSslCerts( 
 332         const char                      *kcName
,                                // may be NULL, i.e., use default 
 334         bool                completeCertChain
, 
 335         const char                      *anchorFile
,                    // optional trusted anchor 
 336         SecKeychainRef          
*pKcRef
)                                // RETURNED 
 339         SecKeychainRef          kcRef 
= nil
; 
 344         /* pick a keychain */ 
 346                 ortn 
= SecKeychainOpen(kcName
, &kcRef
); 
 348                         printf("SecKeychainOpen returned %d.\n", (int)ortn
); 
 349                         printf("Cannot open keychain at %s. Aborting.\n", kcName
); 
 354                 /* use default keychain */ 
 355                 ortn 
= SecKeychainCopyDefault(&kcRef
); 
 357                         printf("SecKeychainCopyDefault returned %d; aborting.\n", (int)ortn
); 
 362         return sslKcRefToCertArray(kcRef
, encryptOnly
, completeCertChain
, anchorFile
); 
 364         SecCertificateRef cert 
= NULL
; 
 365         SecIdentityRef identity 
= NULL
; 
 366         CFMutableArrayRef certificates 
= NULL
, result 
= NULL
; 
 367         CFMutableDictionaryRef certQuery 
= NULL
, keyQuery 
= NULL
, keyResult 
= NULL
; 
 368         SecTrustRef trust 
= NULL
; 
 369         SecKeyRef key 
= NULL
; 
 370         CFTypeRef pkdigest 
= NULL
; 
 372         // Find the first private key in the keychain and return both its 
 373         // attributes and a ref to it. 
 374         require(keyQuery 
= CFDictionaryCreateMutable(NULL
, 0, NULL
, NULL
), errOut
); 
 375         CFDictionaryAddValue(keyQuery
, kSecClass
, kSecClassKey
); 
 376         CFDictionaryAddValue(keyQuery
, kSecAttrKeyClass
, kSecAttrKeyClassPrivate
); 
 377         CFDictionaryAddValue(keyQuery
, kSecReturnRef
, kCFBooleanTrue
); 
 378         CFDictionaryAddValue(keyQuery
, kSecReturnAttributes
, kCFBooleanTrue
); 
 379         require_noerr(SecItemCopyMatching(keyQuery
, (CFTypeRef 
*)&keyResult
), 
 381         require(key 
= (SecKeyRef
)CFDictionaryGetValue(keyResult
, kSecValueRef
), 
 383         require(pkdigest 
= CFDictionaryGetValue(keyResult
, kSecAttrApplicationLabel
), 
 386         // Find the first certificate that has the same public key hash as the 
 387         // returned private key and return it as a ref. 
 388         require(certQuery 
= CFDictionaryCreateMutable(NULL
, 0, NULL
, NULL
), errOut
); 
 389         CFDictionaryAddValue(certQuery
, kSecClass
, kSecClassCertificate
); 
 390         CFDictionaryAddValue(certQuery
, kSecAttrPublicKeyHash
, pkdigest
); 
 391         CFDictionaryAddValue(certQuery
, kSecReturnRef
, kCFBooleanTrue
); 
 392         require_noerr(SecItemCopyMatching(certQuery
, (CFTypeRef 
*)&cert
), errOut
); 
 394         // Create an identity from the key and certificate. 
 395         require(identity 
= SecIdentityCreate(NULL
, cert
, key
), errOut
); 
 397         // Build a (partial) certificate chain from cert 
 398         require(certificates 
= CFArrayCreateMutable(NULL
, 0, 
 399                 &kCFTypeArrayCallBacks
), errOut
); 
 400         CFArrayAppendValue(certificates
, cert
); 
 401         require_noerr(SecTrustCreateWithCertificates(certificates
, NULL
, &trust
), 
 403         SecTrustResultType tresult
; 
 404         require_noerr(SecTrustEvaluate(trust
, &tresult
), errOut
); 
 406         CFIndex certCount
, ix
; 
 407         // We need at least 1 certificate 
 408         require(certCount 
= SecTrustGetCertificateCount(trust
), errOut
); 
 410         // Build a result where element 0 is the identity and the other elements 
 411         // are the certs in the chain starting at the first intermediate up to the 
 412         // anchor, if we found one, or as far as we were able to build the chain 
 414         require(result 
= CFArrayCreateMutable(NULL
, certCount
, &kCFTypeArrayCallBacks
), 
 417         // We are commited to returning a result now, so do not use require below 
 418         // this line without setting result to NULL again. 
 419         CFArrayAppendValue(result
, identity
); 
 420         for (ix 
= 1; ix 
< certCount
; ++ix
) { 
 421                 CFArrayAppendValue(result
, SecTrustGetCertificateAtIndex(trust
, ix
)); 
 425         CFReleaseSafe(trust
); 
 426         CFReleaseSafe(certificates
); 
 427         CFReleaseSafe(identity
); 
 429         CFReleaseSafe(certQuery
); 
 430         CFReleaseSafe(keyResult
); 
 431         CFReleaseSafe(keyQuery
); 
 435 #else /* !TARGET_OS_IOS */ 
 436         SecIdentityRef identity 
= NULL
; 
 437         CFMutableDictionaryRef query 
= NULL
; 
 438         CFArrayRef items 
= NULL
; 
 439         require(query 
= CFDictionaryCreateMutable(NULL
, 0, NULL
, NULL
), errOut
); 
 440         CFDictionaryAddValue(query
, kSecClass
, kSecClassIdentity
); 
 441         CFDictionaryAddValue(query
, kSecReturnRef
, kCFBooleanTrue
); 
 442         require_noerr(SecItemCopyMatching(query
, (CFTypeRef 
*)&identity
), errOut
); 
 444         items 
= CFArrayCreate(kCFAllocatorDefault
, 
 445                         (const void **)&identity
, 1, &kCFTypeArrayCallBacks
); 
 448         CFReleaseSafe(identity
); 
 449         CFReleaseSafe(query
); 
 459  * Determine if specified SecCertificateRef is a self-signed cert. 
 460  * We do this by comparing the subject and issuerr names; no cryptographic 
 461  * verification is performed. 
 463  * Returns true if the cert appears to be a root. 
 465 static bool isCertRefRoot( 
 466         SecCertificateRef certRef
) 
 470         /* just search for the two attrs we want */ 
 471         UInt32 tags
[2] = {kSecSubjectItemAttr
, kSecIssuerItemAttr
}; 
 472         SecKeychainAttributeInfo attrInfo
; 
 475         attrInfo
.format 
= NULL
; 
 476         SecKeychainAttributeList 
*attrList 
= NULL
; 
 477         SecKeychainAttribute 
*attr1 
= NULL
; 
 478         SecKeychainAttribute 
*attr2 
= NULL
; 
 480         OSStatus ortn 
= SecKeychainItemCopyAttributesAndData( 
 481                 (SecKeychainItemRef
)certRef
, 
 485                 NULL
,                   // length - don't need the data 
 488                 cssmPerror("SecKeychainItemCopyAttributesAndData", ortn
); 
 489                 /* may want to be a bit more robust here, but this should 
 493         /* subsequent errors to errOut: */ 
 495         if((attrList 
== NULL
) || (attrList
->count 
!= 2)) { 
 496                 printf("***Unexpected result fetching label attr\n"); 
 500         /* rootness is just byte-for-byte compare of the two names */ 
 501         attr1 
= &attrList
->attr
[0]; 
 502         attr2 
= &attrList
->attr
[1]; 
 503         if(attr1
->length 
== attr2
->length
) { 
 504                 if(memcmp(attr1
->data
, attr2
->data
, attr1
->length
) == 0) { 
 509         SecKeychainItemFreeAttributesAndData(attrList
, NULL
); 
 517  * Given a SecIdentityRef, do our best to construct a complete, ordered, and 
 518  * verified cert chain, returning the result in a CFArrayRef. The result is 
 519  * suitable for use when calling SSLSetCertificate(). 
 521 OSStatus 
sslCompleteCertChain( 
 522         SecIdentityRef          identity
, 
 523         SecCertificateRef       trustedAnchor
,  // optional additional trusted anchor 
 524         bool                            includeRoot
,    // include the root in outArray 
 525         CFArrayRef                      
*outArray
)              // created and RETURNED 
 527         CFMutableArrayRef                       certArray
; 
 528         SecTrustRef                                     secTrust 
= NULL
; 
 529         SecPolicyRef                            policy 
= NULL
; 
 530         SecPolicySearchRef                      policySearch 
= NULL
; 
 531         SecTrustResultType                      secTrustResult
; 
 532         CSSM_TP_APPLE_EVIDENCE_INFO 
*dummyEv
;                   // not used 
 533         CFArrayRef                                      certChain 
= NULL
;   // constructed chain 
 536         certArray 
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
); 
 537         CFArrayAppendValue(certArray
, identity
); 
 540          * Case 1: identity is a root; we're done. Note that this case 
 541          * overrides the includeRoot argument. 
 543         SecCertificateRef certRef
; 
 544         OSStatus ortn 
= SecIdentityCopyCertificate(identity
, &certRef
); 
 546                 /* should never happen */ 
 547                 cssmPerror("SecIdentityCopyCertificate", ortn
); 
 550         bool isRoot 
= isCertRefRoot(certRef
); 
 552                 *outArray 
= certArray
; 
 558          * Now use SecTrust to get a complete cert chain, using all of the 
 559          * user's keychains to look for intermediate certs. 
 560          * NOTE this does NOT handle root certs which are not in the system 
 561          * root cert DB. (The above case, where the identity is a root cert, does.) 
 563         CFMutableArrayRef subjCerts 
= CFArrayCreateMutable(NULL
, 1, &kCFTypeArrayCallBacks
); 
 564         CFArraySetValueAtIndex(subjCerts
, 0, certRef
); 
 566         /* the array owns the subject cert ref now */ 
 569         /* Get a SecPolicyRef for generic X509 cert chain verification */ 
 570         ortn 
= SecPolicySearchCreate(CSSM_CERT_X_509v3
, 
 571                 &CSSMOID_APPLE_X509_BASIC
, 
 575                 cssmPerror("SecPolicySearchCreate", ortn
); 
 578         ortn 
= SecPolicySearchCopyNext(policySearch
, &policy
); 
 580                 cssmPerror("SecPolicySearchCopyNext", ortn
); 
 584         /* build a SecTrustRef for specified policy and certs */ 
 585         ortn 
= SecTrustCreateWithCertificates(subjCerts
, 
 588                 cssmPerror("SecTrustCreateWithCertificates", ortn
); 
 594                  * Tell SecTrust to trust this one in addition to the current 
 595                  * trusted system-wide anchors. 
 597                 CFMutableArrayRef newAnchors
; 
 598                 CFArrayRef currAnchors
; 
 600                 ortn 
= SecTrustCopyAnchorCertificates(&currAnchors
); 
 602                         /* should never happen */ 
 603                         cssmPerror("SecTrustCopyAnchorCertificates", ortn
); 
 606                 newAnchors 
= CFArrayCreateMutableCopy(NULL
, 
 607                         CFArrayGetCount(currAnchors
) + 1, 
 609                 CFRelease(currAnchors
); 
 610                 CFArrayAppendValue(newAnchors
, trustedAnchor
); 
 611                 ortn 
= SecTrustSetAnchorCertificates(secTrust
, newAnchors
); 
 612                 CFRelease(newAnchors
); 
 614                         cssmPerror("SecTrustSetAnchorCertificates", ortn
); 
 619         ortn 
= SecTrustEvaluate(secTrust
, &secTrustResult
); 
 621                 cssmPerror("SecTrustEvaluate", ortn
); 
 624         switch(secTrustResult
) { 
 625                 case kSecTrustResultUnspecified
: 
 626                         /* cert chain valid, no special UserTrust assignments */ 
 627                 case kSecTrustResultProceed
: 
 628                         /* cert chain valid AND user explicitly trusts this */ 
 632                          * Cert chain construction failed. 
 633                          * Just go with the single subject cert we were given. 
 635                         printf("***Warning: could not construct completed cert chain\n"); 
 640         /* get resulting constructed cert chain */ 
 641         ortn 
= SecTrustGetResult(secTrust
, &secTrustResult
, &certChain
, &dummyEv
); 
 643                 cssmPerror("SecTrustEvaluate", ortn
); 
 648          * Copy certs from constructed chain to our result array, skipping 
 649          * the leaf (which is already there, as a SecIdentityRef) and possibly 
 652         numResCerts 
= CFArrayGetCount(certChain
); 
 653         if(numResCerts 
< 2) { 
 655                  * Can't happen: if subject was a root, we'd already have returned. 
 656                  * If chain doesn't verify to a root, we'd have bailed after 
 657                  * SecTrustEvaluate(). 
 659                 printf("***sslCompleteCertChain screwup: numResCerts %d\n", 
 665                 /* skip the last (root) cert) */ 
 668         for(CFIndex dex
=1; dex
<numResCerts
; dex
++) { 
 669                 certRef 
= (SecCertificateRef
)CFArrayGetValueAtIndex(certChain
, dex
); 
 670                 CFArrayAppendValue(certArray
, certRef
); 
 678                 CFRelease(subjCerts
); 
 684                 CFRelease(policySearch
); 
 686         *outArray 
= certArray
; 
 692  * Given an open keychain, find a SecIdentityRef and munge it into 
 693  * a CFArrayRef required by SSLSetCertificate(). 
 695 CFArrayRef 
sslKcRefToCertArray( 
 696         SecKeychainRef          kcRef
, 
 698         bool                completeCertChain
, 
 699         const char                      *trustedAnchorFile
) 
 701         /* quick check to make sure the keychain exists */ 
 702         SecKeychainStatus kcStat
; 
 703         OSStatus ortn 
= SecKeychainGetStatus(kcRef
, &kcStat
); 
 705                 printSslErrStr("SecKeychainGetStatus", ortn
); 
 706                 printf("Can not open keychain. Aborting.\n"); 
 711          * Search for "any" identity matching specified key use; 
 712          * in this app, we expect there to be exactly one. 
 714         SecIdentitySearchRef srchRef 
= nil
; 
 715         ortn 
= SecIdentitySearchCreate(kcRef
, 
 716                 encryptOnly 
? CSSM_KEYUSE_DECRYPT 
: CSSM_KEYUSE_SIGN
, 
 719                 printf("SecIdentitySearchCreate returned %d.\n", (int)ortn
); 
 720                 printf("Cannot find signing key in keychain. Aborting.\n"); 
 723         SecIdentityRef identity 
= nil
; 
 724         ortn 
= SecIdentitySearchCopyNext(srchRef
, &identity
); 
 726                 printf("SecIdentitySearchCopyNext returned %d.\n", (int)ortn
); 
 727                 printf("Cannot find signing key in keychain. Aborting.\n"); 
 730         if(CFGetTypeID(identity
) != SecIdentityGetTypeID()) { 
 731                 printf("SecIdentitySearchCopyNext CFTypeID failure!\n"); 
 738         if(completeCertChain
) { 
 740                  * Place it and the other certs needed to verify it - 
 741                  * up to but not including the root - in a CFArray. 
 743                 SecCertificateRef anchorCert 
= NULL
; 
 744                 if(trustedAnchorFile
) { 
 745                         ortn 
= sslReadAnchor(trustedAnchorFile
, &anchorCert
); 
 747                                 printf("***Error reading anchor file\n"); 
 751                 ortn 
= sslCompleteCertChain(identity
, anchorCert
, false, &ca
); 
 753                         CFRelease(anchorCert
); 
 758                 /* simple case, just this one identity */ 
 759                 CFArrayRef ca 
= CFArrayCreate(NULL
, 
 760                         (const void **)&identity
, 
 764                         printf("CFArrayCreate error\n"); 
 771 OSStatus 
addTrustedSecCert( 
 773         SecCertificateRef       secCert
, 
 777         CFMutableArrayRef array
; 
 779         if(secCert 
== NULL
) { 
 780                 printf("***addTrustedSecCert screwup\n"); 
 783         array 
= CFArrayCreateMutable(kCFAllocatorDefault
, 
 784                 (CFIndex
)1, &kCFTypeArrayCallBacks
); 
 788         CFArrayAppendValue(array
, secCert
); 
 789         ortn 
= SSLSetTrustedRoots(ctx
, array
, replaceAnchors 
? true : false); 
 791                 printSslErrStr("SSLSetTrustedRoots", ortn
); 
 797 OSStatus 
sslReadAnchor( 
 798         const char                      *anchorFile
, 
 799         SecCertificateRef       
*certRef
) 
 801         SecCertificateRef secCert
; 
 802         unsigned char *certData
; 
 806         if(readFile(anchorFile
, &certData
, &certLen
)) { 
 809         dataRef 
= CFDataCreateWithBytesNoCopy(kCFAllocatorDefault
, 
 810                         (const UInt8 
*)certData
, (CFIndex
)certLen
, kCFAllocatorNull
); 
 811         secCert 
= SecCertificateCreateWithData(kCFAllocatorDefault
, dataRef
); 
 812         CFReleaseSafe(dataRef
); 
 815                 printf("***SecCertificateCreateWithData returned NULL\n"); 
 824 OSStatus 
sslAddTrustedRoot( 
 826         const char              *anchorFile
, 
 831         SecCertificateRef secCert
; 
 833         ortn 
= sslReadAnchor(anchorFile
, &secCert
); 
 835                 printf("***Error reading %s. SSLSetTrustedRoots skipped.\n", 
 839         return addTrustedSecCert(ctx
, secCert
, replaceAnchors
); 
 846 /* Per 3537606 this is no longer necessary */ 
 848  * Assume incoming identity contains a root (e.g., created by 
 849  * certtool) and add that cert to ST's trusted anchors. This 
 850  * enables ST's verify of the incoming chain to succeed without 
 851  * a kludgy "AllowAnyRoot" specification. 
 853 OSStatus 
addIdentityAsTrustedRoot( 
 855         CFArrayRef              identArray
) 
 857         CFIndex numItems 
= CFArrayGetCount(identArray
); 
 859                 printf("***addIdentityAsTrustedRoot: empty identArray\n"); 
 863         /* Root should be the last item - could be identity, could be cert */ 
 864         CFTypeRef theItem 
= CFArrayGetValueAtIndex(identArray
, numItems 
- 1); 
 865         if(CFGetTypeID(theItem
) == SecIdentityGetTypeID()) { 
 867                 SecCertificateRef certRef
; 
 868                 OSStatus ortn 
= SecIdentityCopyCertificate( 
 869                         (SecIdentityRef
)theItem
, &certRef
); 
 871                         cssmPerror("SecIdentityCopyCertificate", ortn
); 
 872                         printf("***Error gettting cert from identity\n"); 
 875                 ortn 
= addTrustedSecCert(ctx
, certRef
, false); 
 879         else if(CFGetTypeID(theItem
) == SecCertificateGetTypeID()) { 
 881                 return addTrustedSecCert(ctx
, (SecCertificateRef
)theItem
, false); 
 884                 printf("***Bogus item in identity array\n"); 
 889 OSStatus 
addIdentityAsTrustedRoot( 
 891         CFArrayRef              identArray
) 
 898  * Lists of SSLCipherSuites used in sslSetCipherRestrictions. Note that the 
 899  * SecureTransport library does not implement all of these; we only specify 
 900  * the ones it claims to support. 
 902 const SSLCipherSuite suites40
[] = { 
 903         SSL_RSA_EXPORT_WITH_RC4_40_MD5
, 
 904         SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5
, 
 905         SSL_RSA_EXPORT_WITH_DES40_CBC_SHA
, 
 906         SSL_DH_DSS_EXPORT_WITH_DES40_CBC_SHA
, 
 907         SSL_DH_RSA_EXPORT_WITH_DES40_CBC_SHA
, 
 908         SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA
, 
 909         SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA
, 
 910         SSL_DH_anon_EXPORT_WITH_RC4_40_MD5
, 
 911         SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA
, 
 912         SSL_NO_SUCH_CIPHERSUITE
 
 914 const SSLCipherSuite suitesDES
[] = { 
 915         SSL_RSA_WITH_DES_CBC_SHA
, 
 916         SSL_DH_DSS_WITH_DES_CBC_SHA
, 
 917         SSL_DH_RSA_WITH_DES_CBC_SHA
, 
 918         SSL_DHE_DSS_WITH_DES_CBC_SHA
, 
 919         SSL_DHE_RSA_WITH_DES_CBC_SHA
, 
 920         SSL_DH_anon_WITH_DES_CBC_SHA
, 
 921         SSL_RSA_WITH_DES_CBC_MD5
, 
 922         SSL_NO_SUCH_CIPHERSUITE
 
 924 const SSLCipherSuite suitesDES40
[] = { 
 925         SSL_RSA_EXPORT_WITH_DES40_CBC_SHA
, 
 926         SSL_DH_DSS_EXPORT_WITH_DES40_CBC_SHA
, 
 927         SSL_DH_RSA_EXPORT_WITH_DES40_CBC_SHA
, 
 928         SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA
, 
 929         SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA
, 
 930         SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA
, 
 931         SSL_NO_SUCH_CIPHERSUITE
 
 933 const SSLCipherSuite suites3DES
[] = { 
 934         SSL_RSA_WITH_3DES_EDE_CBC_SHA
, 
 935         SSL_DH_DSS_WITH_3DES_EDE_CBC_SHA
, 
 936         SSL_DH_RSA_WITH_3DES_EDE_CBC_SHA
, 
 937         SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA
, 
 938         SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA
, 
 939         SSL_DH_anon_WITH_3DES_EDE_CBC_SHA
, 
 940         SSL_RSA_WITH_3DES_EDE_CBC_MD5
, 
 941         SSL_NO_SUCH_CIPHERSUITE
 
 943 const SSLCipherSuite suitesRC4
[] = { 
 944         SSL_RSA_WITH_RC4_128_MD5
, 
 945         SSL_RSA_WITH_RC4_128_SHA
, 
 946         SSL_DH_anon_WITH_RC4_128_MD5
, 
 947         SSL_NO_SUCH_CIPHERSUITE
 
 949 const SSLCipherSuite suitesRC4_40
[] = { 
 950         SSL_RSA_EXPORT_WITH_RC4_40_MD5
, 
 951         SSL_DH_anon_EXPORT_WITH_RC4_40_MD5
, 
 952         SSL_NO_SUCH_CIPHERSUITE
 
 954 const SSLCipherSuite suitesRC2
[] = { 
 955         SSL_RSA_WITH_RC2_CBC_MD5
, 
 956         SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5
, 
 957         SSL_NO_SUCH_CIPHERSUITE
 
 959 const SSLCipherSuite suitesAES128
[] = { 
 960         TLS_RSA_WITH_AES_128_CBC_SHA
, 
 961         TLS_DH_DSS_WITH_AES_128_CBC_SHA
, 
 962         TLS_DH_RSA_WITH_AES_128_CBC_SHA
, 
 963         TLS_DHE_DSS_WITH_AES_128_CBC_SHA
, 
 964         TLS_DHE_RSA_WITH_AES_128_CBC_SHA
, 
 965         TLS_DH_anon_WITH_AES_128_CBC_SHA
, 
 966     SSL_NO_SUCH_CIPHERSUITE
 
 968 const SSLCipherSuite suitesAES256
[] = { 
 969         TLS_RSA_WITH_AES_256_CBC_SHA
, 
 970         TLS_DH_DSS_WITH_AES_256_CBC_SHA
, 
 971         TLS_DH_RSA_WITH_AES_256_CBC_SHA
, 
 972         TLS_DHE_DSS_WITH_AES_256_CBC_SHA
, 
 973         TLS_DHE_RSA_WITH_AES_256_CBC_SHA
, 
 974         TLS_DH_anon_WITH_AES_256_CBC_SHA
, 
 975     SSL_NO_SUCH_CIPHERSUITE
 
 977 const SSLCipherSuite suitesDH
[] = { 
 978         SSL_DH_DSS_WITH_DES_CBC_SHA
, 
 979         SSL_DH_DSS_WITH_3DES_EDE_CBC_SHA
, 
 980         SSL_DH_DSS_EXPORT_WITH_DES40_CBC_SHA
, 
 981         SSL_DH_RSA_WITH_DES_CBC_SHA
, 
 982         SSL_DH_RSA_WITH_3DES_EDE_CBC_SHA
, 
 983         SSL_DH_RSA_EXPORT_WITH_DES40_CBC_SHA
, 
 984         SSL_DHE_DSS_WITH_DES_CBC_SHA
, 
 985         SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA
, 
 986         SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA
, 
 987         SSL_DHE_RSA_WITH_DES_CBC_SHA
, 
 988         SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA
, 
 989         SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA
, 
 990         SSL_DH_anon_WITH_RC4_128_MD5
, 
 991         SSL_DH_anon_WITH_DES_CBC_SHA
, 
 992         SSL_DH_anon_WITH_3DES_EDE_CBC_SHA
, 
 993         SSL_DH_anon_EXPORT_WITH_RC4_40_MD5
, 
 994         SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA
, 
 995         TLS_DH_DSS_WITH_AES_128_CBC_SHA
, 
 996         TLS_DH_RSA_WITH_AES_128_CBC_SHA
, 
 997         TLS_DHE_DSS_WITH_AES_128_CBC_SHA
, 
 998         TLS_DHE_RSA_WITH_AES_128_CBC_SHA
, 
 999         TLS_DH_anon_WITH_AES_128_CBC_SHA
, 
1000         TLS_DH_DSS_WITH_AES_256_CBC_SHA
, 
1001         TLS_DH_RSA_WITH_AES_256_CBC_SHA
, 
1002         TLS_DHE_DSS_WITH_AES_256_CBC_SHA
, 
1003         TLS_DHE_RSA_WITH_AES_256_CBC_SHA
, 
1004         TLS_DH_anon_WITH_AES_256_CBC_SHA
, 
1005         SSL_NO_SUCH_CIPHERSUITE
 
1007 const SSLCipherSuite suitesDHAnon
[] = { 
1008         SSL_DH_anon_WITH_RC4_128_MD5
, 
1009         SSL_DH_anon_WITH_DES_CBC_SHA
, 
1010         SSL_DH_anon_WITH_3DES_EDE_CBC_SHA
, 
1011         SSL_DH_anon_EXPORT_WITH_RC4_40_MD5
, 
1012         SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA
, 
1013         TLS_DH_anon_WITH_AES_128_CBC_SHA
, 
1014         TLS_DH_anon_WITH_AES_256_CBC_SHA
, 
1015         SSL_NO_SUCH_CIPHERSUITE
 
1017 const SSLCipherSuite suitesDH_RSA
[] = { 
1018         SSL_DH_RSA_WITH_DES_CBC_SHA
, 
1019         SSL_DH_RSA_WITH_3DES_EDE_CBC_SHA
, 
1020         SSL_DHE_RSA_WITH_DES_CBC_SHA
, 
1021         SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA
, 
1022         SSL_DH_RSA_EXPORT_WITH_DES40_CBC_SHA
, 
1023         SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA
, 
1024         TLS_DH_RSA_WITH_AES_128_CBC_SHA
, 
1025         TLS_DHE_RSA_WITH_AES_128_CBC_SHA
, 
1026         TLS_DH_RSA_WITH_AES_256_CBC_SHA
, 
1027         TLS_DHE_RSA_WITH_AES_256_CBC_SHA
, 
1028         SSL_NO_SUCH_CIPHERSUITE
 
1030 const SSLCipherSuite suitesDH_DSS
[] = { 
1031         SSL_DH_DSS_WITH_DES_CBC_SHA
, 
1032         SSL_DH_DSS_WITH_3DES_EDE_CBC_SHA
, 
1033         SSL_DHE_DSS_WITH_DES_CBC_SHA
, 
1034         SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA
, 
1035         SSL_DH_DSS_EXPORT_WITH_DES40_CBC_SHA
, 
1036         SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA
, 
1037         TLS_DH_DSS_WITH_AES_128_CBC_SHA
, 
1038         TLS_DHE_DSS_WITH_AES_128_CBC_SHA
, 
1039         TLS_DH_DSS_WITH_AES_256_CBC_SHA
, 
1040         TLS_DHE_DSS_WITH_AES_256_CBC_SHA
, 
1041         SSL_NO_SUCH_CIPHERSUITE
 
1043 const SSLCipherSuite suites_SHA1
[] = { 
1044         SSL_RSA_WITH_RC4_128_SHA
, 
1045         SSL_RSA_EXPORT_WITH_DES40_CBC_SHA
, 
1046         SSL_RSA_WITH_IDEA_CBC_SHA
, 
1047         SSL_RSA_EXPORT_WITH_DES40_CBC_SHA
, 
1048         SSL_RSA_WITH_DES_CBC_SHA
, 
1049         SSL_RSA_WITH_3DES_EDE_CBC_SHA
, 
1050         SSL_DH_DSS_EXPORT_WITH_DES40_CBC_SHA
, 
1051         SSL_DH_DSS_WITH_DES_CBC_SHA
, 
1052         SSL_DH_DSS_WITH_3DES_EDE_CBC_SHA
, 
1053         SSL_DH_RSA_EXPORT_WITH_DES40_CBC_SHA
, 
1054         SSL_DH_RSA_WITH_DES_CBC_SHA
, 
1055         SSL_DH_RSA_WITH_3DES_EDE_CBC_SHA
, 
1056         SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA
, 
1057         SSL_DHE_DSS_WITH_DES_CBC_SHA
, 
1058         SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA
, 
1059         SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA
, 
1060         SSL_DHE_RSA_WITH_DES_CBC_SHA
, 
1061         SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA
, 
1062         SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA
, 
1063         SSL_DH_anon_WITH_DES_CBC_SHA
, 
1064         SSL_DH_anon_WITH_3DES_EDE_CBC_SHA
, 
1065         SSL_FORTEZZA_DMS_WITH_NULL_SHA
, 
1066         SSL_FORTEZZA_DMS_WITH_FORTEZZA_CBC_SHA
, 
1067         TLS_RSA_WITH_AES_128_CBC_SHA
, 
1068         TLS_DH_DSS_WITH_AES_128_CBC_SHA
, 
1069         TLS_DH_RSA_WITH_AES_128_CBC_SHA
, 
1070         TLS_DHE_DSS_WITH_AES_128_CBC_SHA
, 
1071         TLS_DHE_RSA_WITH_AES_128_CBC_SHA
, 
1072         TLS_DH_anon_WITH_AES_128_CBC_SHA
, 
1073         TLS_RSA_WITH_AES_256_CBC_SHA
, 
1074         TLS_DH_DSS_WITH_AES_256_CBC_SHA
, 
1075         TLS_DH_RSA_WITH_AES_256_CBC_SHA
, 
1076         TLS_DHE_DSS_WITH_AES_256_CBC_SHA
, 
1077         TLS_DHE_RSA_WITH_AES_256_CBC_SHA
, 
1078         TLS_DH_anon_WITH_AES_256_CBC_SHA
, 
1079         SSL_NO_SUCH_CIPHERSUITE
 
1081 const SSLCipherSuite suites_MD5
[] = { 
1082         SSL_RSA_EXPORT_WITH_RC4_40_MD5
, 
1083         SSL_RSA_WITH_RC4_128_MD5
, 
1084         SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5
, 
1085         SSL_DH_anon_EXPORT_WITH_RC4_40_MD5
, 
1086         SSL_DH_anon_WITH_RC4_128_MD5
, 
1087         SSL_NO_SUCH_CIPHERSUITE
 
1089 const SSLCipherSuite suites_NULL
[] = { 
1090         SSL_RSA_WITH_NULL_MD5
, 
1091         SSL_NO_SUCH_CIPHERSUITE
 
1094 const SSLCipherSuite suites_ECDHE
[] = { 
1095         TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA
, 
1096         TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA
, 
1097         TLS_ECDHE_ECDSA_WITH_RC4_128_SHA
, 
1098         TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA
, 
1099         TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA
, 
1100         TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA
, 
1101         TLS_ECDHE_RSA_WITH_RC4_128_SHA
, 
1102         TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA
, 
1103         SSL_NO_SUCH_CIPHERSUITE
 
1106 const SSLCipherSuite suites_ECDH
[] = { 
1107         TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA
, 
1108         TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA
, 
1109         TLS_ECDH_ECDSA_WITH_RC4_128_SHA
, 
1110         TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA
, 
1111         TLS_ECDH_RSA_WITH_AES_128_CBC_SHA
, 
1112         TLS_ECDH_RSA_WITH_AES_256_CBC_SHA
, 
1113         TLS_ECDH_RSA_WITH_RC4_128_SHA
, 
1114         TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA
, 
1115         SSL_NO_SUCH_CIPHERSUITE
 
1119  * Given an SSLContextRef and an array of SSLCipherSuites, terminated by 
1120  * SSL_NO_SUCH_CIPHERSUITE, select those SSLCipherSuites which the library 
1121  * supports and do a SSLSetEnabledCiphers() specifying those. 
1123 OSStatus 
sslSetEnabledCiphers( 
1125         const SSLCipherSuite 
*ciphers
) 
1127         size_t numSupported
; 
1129         SSLCipherSuite 
*supported 
= NULL
; 
1130         SSLCipherSuite 
*enabled 
= NULL
; 
1131         unsigned enabledDex 
= 0;        // index into enabled 
1132         unsigned supportedDex 
= 0;      // index into supported 
1133         unsigned inDex 
= 0;                     // index into ciphers 
1135         /* first get all the supported ciphers */ 
1136         ortn 
= SSLGetNumberSupportedCiphers(ctx
, &numSupported
); 
1138                 printSslErrStr("SSLGetNumberSupportedCiphers", ortn
); 
1141         supported 
= (SSLCipherSuite 
*)malloc(numSupported 
* sizeof(SSLCipherSuite
)); 
1142         ortn 
= SSLGetSupportedCiphers(ctx
, supported
, &numSupported
); 
1144                 printSslErrStr("SSLGetSupportedCiphers", ortn
); 
1149          * Malloc an array we'll use for SSLGetEnabledCiphers - this will  be 
1150          * bigger than the number of suites we actually specify 
1152         enabled 
= (SSLCipherSuite 
*)malloc(numSupported 
* sizeof(SSLCipherSuite
)); 
1155          * For each valid suite in ciphers, see if it's in the list of 
1156          * supported ciphers. If it is, add it to the list of ciphers to be 
1159         for(inDex
=0; ciphers
[inDex
] != SSL_NO_SUCH_CIPHERSUITE
; inDex
++) { 
1160                 for(supportedDex
=0; supportedDex
<numSupported
; supportedDex
++) { 
1161                         if(ciphers
[inDex
] == supported
[supportedDex
]) { 
1162                                 enabled
[enabledDex
++] = ciphers
[inDex
]; 
1168         /* send it on down. */ 
1169         ortn 
= SSLSetEnabledCiphers(ctx
, enabled
, enabledDex
); 
1171                 printSslErrStr("SSLSetEnabledCiphers", ortn
); 
1179  * Specify a restricted set of cipherspecs. 
1181 OSStatus 
sslSetCipherRestrictions( 
1183         char cipherRestrict
) 
1187         if(cipherRestrict 
== '\0') { 
1188                 return noErr
;           // actually should not have been called 
1190         switch(cipherRestrict
) { 
1192                         ortn 
= sslSetEnabledCiphers(ctx
, suites40
); 
1195                         ortn 
= sslSetEnabledCiphers(ctx
, suitesDES
); 
1198                         ortn 
= sslSetEnabledCiphers(ctx
, suitesDES40
); 
1201                         ortn 
= sslSetEnabledCiphers(ctx
, suites3DES
); 
1204                         ortn 
= sslSetEnabledCiphers(ctx
, suitesRC4
); 
1207                         ortn 
= sslSetEnabledCiphers(ctx
, suitesRC4_40
); 
1210                         ortn 
= sslSetEnabledCiphers(ctx
, suitesRC2
); 
1213                         ortn 
= sslSetEnabledCiphers(ctx
, suitesAES128
); 
1216                         ortn 
= sslSetEnabledCiphers(ctx
, suitesAES256
); 
1219                         ortn 
= sslSetEnabledCiphers(ctx
, suitesDH
); 
1222                         ortn 
= sslSetEnabledCiphers(ctx
, suitesDHAnon
); 
1225                         ortn 
= sslSetEnabledCiphers(ctx
, suitesDH_RSA
); 
1228                         ortn 
= sslSetEnabledCiphers(ctx
, suitesDH_DSS
); 
1231                         ortn 
= sslSetEnabledCiphers(ctx
, suites_NULL
); 
1234                         ortn 
= sslSetEnabledCiphers(ctx
, suites_ECDHE
); 
1237                         ortn 
= sslSetEnabledCiphers(ctx
, suites_ECDH
); 
1240                         printf("***bad cipherSpec***\n"); 
1247 int sslVerifyClientCertState( 
1248         const char                                      *whichSide
,             // "client" or "server" 
1249         SSLClientCertificateState       expectState
, 
1250         SSLClientCertificateState       gotState
) 
1252         if(expectState 
== SSL_CLIENT_CERT_IGNORE
) { 
1253                 /* app says "don't bother checking" */ 
1256         if(expectState 
== gotState
) { 
1259         printf("***%s: Expected clientCertState %s; got %s\n", whichSide
, 
1260                 sslGetClientCertStateString(expectState
), 
1261                 sslGetClientCertStateString(gotState
)); 
1266         char            *whichSide
,             // "client" or "server" 
1270         if(expectRtn 
== gotRtn
) { 
1273         printf("***%s: Expected return %s; got %s\n", whichSide
, 
1274                 sslGetSSLErrString(expectRtn
), 
1275                 sslGetSSLErrString(gotRtn
)); 
1279 int sslVerifyProtVers( 
1280         char            *whichSide
,             // "client" or "server" 
1281         SSLProtocol     expectProt
, 
1282         SSLProtocol     gotProt
) 
1284         if(expectProt 
== SSL_PROTOCOL_IGNORE
) { 
1285                 /* app says "don't bopther checking" */ 
1288         if(expectProt 
== gotProt
) { 
1291         printf("***%s: Expected return %s; got %s\n", whichSide
, 
1292                 sslGetProtocolVersionString(expectProt
), 
1293                 sslGetProtocolVersionString(gotProt
)); 
1297 int sslVerifyCipher( 
1298         char                    *whichSide
,             // "client" or "server" 
1299         SSLCipherSuite  expectCipher
, 
1300         SSLCipherSuite  gotCipher
) 
1302         if(expectCipher 
== SSL_CIPHER_IGNORE
) { 
1303                 /* app says "don't bopther checking" */ 
1306         if(expectCipher 
== gotCipher
) { 
1309         printf("***%s: Expected return %s; got %s\n", whichSide
, 
1310                 sslGetCipherSuiteString(expectCipher
), 
1311                 sslGetCipherSuiteString(gotCipher
)); 
1316 OSStatus 
sslSetProtocols( 
1318         const char              *acceptedProts
, 
1319         SSLProtocol             tryVersion
)                     // only used if acceptedProts NULL 
1324                 ortn 
= SSLSetProtocolVersionEnabled(ctx
, kSSLProtocolAll
, false); 
1326                         printSslErrStr("SSLSetProtocolVersionEnabled(all off)", ortn
); 
1329                 for(const char *cp 
= acceptedProts
; *cp
; cp
++) { 
1333                                         prot 
= kSSLProtocol2
; 
1336                                         prot 
= kSSLProtocol3
; 
1339                                         prot 
= kTLSProtocol1
; 
1342                                         printf("***BRRZAP! Bad acceptedProts string %s. Aborting.\n", acceptedProts
); 
1345                         ortn 
= SSLSetProtocolVersionEnabled(ctx
, prot
, true); 
1347                                 printSslErrStr("SSLSetProtocolVersionEnabled", ortn
); 
1353                 ortn 
= SSLSetProtocolVersion(ctx
, tryVersion
); 
1355                         printSslErrStr("SSLSetProtocolVersion", ortn
); 
1363         const char                      *whichSide
,             // "client" or "server" 
1364         SslAppTestParams        
*params
) 
1366         printf("%s status:\n", whichSide
); 
1367         if(params
->acceptedProts
) { 
1368                 printf("   Allowed SSL versions   : %s\n", params
->acceptedProts
); 
1371                 printf("   Attempted  SSL version : %s\n", 
1372                         sslGetProtocolVersionString(params
->tryVersion
)); 
1374         printf("   Result                 : %s\n", sslGetSSLErrString(params
->ortn
)); 
1375         printf("   Negotiated SSL version : %s\n", 
1376                 sslGetProtocolVersionString(params
->negVersion
)); 
1377         printf("   Negotiated CipherSuite : %s\n", 
1378                 sslGetCipherSuiteString(params
->negCipher
)); 
1379         if(params
->certState 
!= kSSLClientCertNone
) { 
1380                 printf("   Client Cert State      : %s\n", 
1381                         sslGetClientCertStateString(params
->certState
)); 
1386 /* print a '.' every few seconds to keep UI alive while connecting */ 
1387 static CFAbsoluteTime lastTime 
= (CFAbsoluteTime
)0.0; 
1388 #define TIME_INTERVAL           3.0 
1392         CFAbsoluteTime thisTime 
= CFAbsoluteTimeGetCurrent(); 
1394         if(lastTime 
== 0.0) { 
1395                 /* avoid printing first time thru */ 
1396                 lastTime 
= thisTime
; 
1399         if((thisTime 
- lastTime
) >= TIME_INTERVAL
) { 
1400                 printf("."); fflush(stdout
); 
1401                 lastTime 
= thisTime
; 
1406 /* main server pthread body */ 
1407 static void *sslServerThread(void *arg
) 
1409         SslAppTestParams 
*testParams 
= (SslAppTestParams 
*)arg
; 
1412         status 
= sslAppServe(testParams
); 
1413         pthread_exit((void*)status
); 
1415         return (void *)status
; 
1419  * Run one session, with the server in a separate thread. 
1420  * On entry, serverParams->port is the port we attempt to run on; 
1421  * the server thread may overwrite that with a different port if it's 
1422  * unable to open the port we specify. Whatever is left in 
1423  * serverParams->port is what's used for the client side. 
1425 #define CLIENT_WAIT_SECONDS             1 
1427         SslAppTestParams
*serverParams
, 
1428         SslAppTestParams 
*clientParams
, 
1429         const char              *testDesc
) 
1431         pthread_t serverPthread
; 
1435         if(testDesc 
&& !clientParams
->quiet
) { 
1436                 printf("===== %s =====\n", testDesc
); 
1439         if(pthread_mutex_init(&serverParams
->pthreadMutex
, NULL
)) { 
1440                 printf("***Error initializing mutex; aborting.\n"); 
1443         if(pthread_cond_init(&serverParams
->pthreadCond
, NULL
)) { 
1444                 printf("***Error initializing pthreadCond; aborting.\n"); 
1447         serverParams
->serverReady 
= false;              // server sets true 
1449         int result 
= pthread_create(&serverPthread
, NULL
, 
1450                         sslServerThread
, serverParams
); 
1452                 printf("***Error starting up server thread; aborting.\n"); 
1456         /* wait for server to set up a socket we can connect to */ 
1457         if(pthread_mutex_lock(&serverParams
->pthreadMutex
)) { 
1458                 printf("***Error acquiring server lock; aborting.\n"); 
1461         while(!serverParams
->serverReady
) { 
1462                 if(pthread_cond_wait(&serverParams
->pthreadCond
, &serverParams
->pthreadMutex
)) { 
1463                         printf("***Error waiting server thread; aborting.\n"); 
1467         pthread_mutex_unlock(&serverParams
->pthreadMutex
); 
1468         pthread_cond_destroy(&serverParams
->pthreadCond
); 
1469         pthread_mutex_destroy(&serverParams
->pthreadMutex
); 
1471         clientParams
->port 
= serverParams
->port
; 
1472         clientRtn 
= sslAppClient(clientParams
); 
1473         /* server doesn't shut down its socket until it sees this */ 
1474         serverParams
->clientDone 
= 1; 
1475         result 
= pthread_join(serverPthread
, &serverRtn
); 
1477                 printf("***pthread_join returned %d, aborting\n", result
); 
1481         if(serverParams
->verbose
) { 
1482                 sslShowResult("server", serverParams
); 
1484         if(clientParams
->verbose
) { 
1485                 sslShowResult("client", clientParams
); 
1488         /* verify results */ 
1490         ourRtn 
+= sslVerifyRtn("server", serverParams
->expectRtn
, serverParams
->ortn
); 
1491         ourRtn 
+= sslVerifyRtn("client", clientParams
->expectRtn
, clientParams
->ortn
); 
1492         ourRtn 
+= sslVerifyProtVers("server", serverParams
->expectVersion
, 
1493                 serverParams
->negVersion
); 
1494         ourRtn 
+= sslVerifyProtVers("client", clientParams
->expectVersion
, 
1495                 clientParams
->negVersion
); 
1496         ourRtn 
+= sslVerifyClientCertState("server", serverParams
->expectCertState
, 
1497                 serverParams
->certState
); 
1498         ourRtn 
+= sslVerifyClientCertState("client", clientParams
->expectCertState
, 
1499                 clientParams
->certState
); 
1500         if(serverParams
->ortn 
== noErr
) { 
1501                 ourRtn 
+= sslVerifyCipher("server", serverParams
->expectCipher
, 
1502                         serverParams
->negCipher
); 
1504         if(clientParams
->ortn 
== noErr
) { 
1505                 ourRtn 
+= sslVerifyCipher("client", clientParams
->expectCipher
, 
1506                         clientParams
->negCipher
); 
1512  * Add all of the roots in a given KC to SSL ctx's trusted anchors. 
1514 OSStatus 
sslAddTrustedRoots( 
1516         SecKeychainRef  keychain
, 
1517         bool                    *foundOne
)              // RETURNED, true if we found 
1518                                                                         //    at least one root cert 
1521         SecCertificateRef               secCert
; 
1522         SecKeychainSearchRef    srch
; 
1525         ortn 
= SecKeychainSearchCreateFromAttributes(keychain
, 
1526                 kSecCertificateItemClass
, 
1530                 printSslErrStr("SecKeychainSearchCreateFromAttributes", ortn
); 
1535          * Only use root certs. Not an error if we don't find any. 
1538                 ortn 
= SecKeychainSearchCopyNext(srch
, 
1539                         (SecKeychainItemRef 
*)&secCert
); 
1544                 /* see if it's a root */ 
1545                 if(!isCertRoot(secCert
)) { 
1549                 /* Tell Secure Transport to trust this one. */ 
1550                 ortn 
= addTrustedSecCert(ctx
, secCert
, false); 
1553                         printSslErrStr("addTrustedSecCert", ortn
); 
1558         } while(ortn 
== noErr
); 
1564  * Wrapper for sslIdentPicker, with optional trusted anchor specified as a filename. 
1566 OSStatus 
sslIdentityPicker( 
1567         SecKeychainRef          kcRef
,                  // NULL means use default list 
1568         const char                      *trustedAnchor
, // optional additional trusted anchor 
1569         bool                            includeRoot
,    // true --> root is appended to outArray 
1570                                                                                 // false --> root not included 
1571         CFArrayRef                      
*outArray
)              // created and RETURNED 
1573         SecCertificateRef trustedCert 
= NULL
; 
1577                 ortn 
= sslReadAnchor(trustedAnchor
, &trustedCert
); 
1579                         printf("***Error reading %s. sslIdentityPicker proceeding with no anchor.\n", 
1584         ortn 
= sslIdentPicker(kcRef
, trustedCert
, includeRoot
, outArray
); 
1586                 CFRelease(trustedCert
); 
1592  * Given a keychain name, convert it into a full path using the "SSL regression 
1593  * test suite algorithm". The Sec layer by default locates root root's keychains 
1594  * in different places depending on whether we're actually logged in as root 
1595  * or running via e.g. cron, so we force the location of root keychains to 
1596  * a hard-coded path. User keychain names we leave alone. 
1598 void sslKeychainPath( 
1600         char *kcPath
)                   // allocd by caller, MAXPATHLEN 
1602         if(kcName
[0] == '\0') { 
1605         else if(geteuid() == 0) { 
1607                 sprintf(kcPath
, "/Library/Keychains/%s", kcName
); 
1610                 /* user, leave alone */ 
1611                 strcpy(kcPath
, kcName
); 
1615 /* Verify presence of required file. Returns nonzero if not found. */ 
1616 int sslCheckFile(const char *path
) 
1620         if(stat(path
, &sb
)) { 
1621                 printf("***Can't find file %s.\n", path
); 
1622                 printf("   Try running in the build directory, perhaps after running the\n" 
1623                            "   makeLocalCert script.\n"); 
1631 /* Stringify a SSL_ECDSA_NamedCurve */ 
1632 extern const char *sslCurveString( 
1633         SSL_ECDSA_NamedCurve namedCurve
) 
1635         static char unk
[100]; 
1637         switch(namedCurve
) { 
1638                 case SSL_Curve_None
:      return "Curve_None"; 
1639                 case SSL_Curve_secp256r1
: return "secp256r1"; 
1640                 case SSL_Curve_secp384r1
: return "secp384r1"; 
1641                 case SSL_Curve_secp521r1
: return "secp521r1"; 
1643                         sprintf(unk
, "Unknown <%d>", (int)namedCurve
);