X-Git-Url: https://git.saurik.com/apple/security.git/blobdiff_plain/ce3c8656732c924baf7e88df75eab50891bdc471..fa7225c82381bac4432a6edf16f53b5370238d85:/OSX/libsecurity_ssl/sslViewer/sslAppUtils.cpp diff --git a/OSX/libsecurity_ssl/sslViewer/sslAppUtils.cpp b/OSX/libsecurity_ssl/sslViewer/sslAppUtils.cpp deleted file mode 100644 index e3ba62d1..00000000 --- a/OSX/libsecurity_ssl/sslViewer/sslAppUtils.cpp +++ /dev/null @@ -1,1592 +0,0 @@ -/* - * Copyright (c) 2006-2008,2010-2014 Apple Inc. All Rights Reserved. - */ - -#include "sslAppUtils.h" -#include "fileIo.h" -#include -#include -#include -#include - -#include -#include -#include -#include - -#define CFReleaseSafe(CF) { CFTypeRef _cf = (CF); if (_cf) CFRelease(_cf); } - -const char *sslGetCipherSuiteString(SSLCipherSuite cs) -{ - static char noSuite[40]; - - switch (cs) { - /* TLS cipher suites, RFC 2246 */ - case SSL_NULL_WITH_NULL_NULL: return "TLS_NULL_WITH_NULL_NULL"; - case SSL_RSA_WITH_NULL_MD5: return "TLS_RSA_WITH_NULL_MD5"; - case SSL_RSA_WITH_NULL_SHA: return "TLS_RSA_WITH_NULL_SHA"; - case SSL_RSA_EXPORT_WITH_RC4_40_MD5: return "TLS_RSA_EXPORT_WITH_RC4_40_MD5"; - case SSL_RSA_WITH_RC4_128_MD5: return "TLS_RSA_WITH_RC4_128_MD5"; - case SSL_RSA_WITH_RC4_128_SHA: return "TLS_RSA_WITH_RC4_128_SHA"; - case SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5: return "TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5"; - case SSL_RSA_WITH_IDEA_CBC_SHA: return "TLS_RSA_WITH_IDEA_CBC_SHA"; - case SSL_RSA_EXPORT_WITH_DES40_CBC_SHA: return "TLS_RSA_EXPORT_WITH_DES40_CBC_SHA"; - case SSL_RSA_WITH_DES_CBC_SHA: return "TLS_RSA_WITH_DES_CBC_SHA"; - case SSL_RSA_WITH_3DES_EDE_CBC_SHA: return "TLS_RSA_WITH_3DES_EDE_CBC_SHA"; - case SSL_DH_DSS_EXPORT_WITH_DES40_CBC_SHA: return "TLS_DH_DSS_EXPORT_WITH_DES40_CBC_SHA"; - case SSL_DH_DSS_WITH_DES_CBC_SHA: return "TLS_DH_DSS_WITH_DES_CBC_SHA"; - case SSL_DH_DSS_WITH_3DES_EDE_CBC_SHA: return "TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA"; - case SSL_DH_RSA_EXPORT_WITH_DES40_CBC_SHA: return "TLS_DH_RSA_EXPORT_WITH_DES40_CBC_SHA"; - case SSL_DH_RSA_WITH_DES_CBC_SHA: return "TLS_DH_RSA_WITH_DES_CBC_SHA"; - case SSL_DH_RSA_WITH_3DES_EDE_CBC_SHA: return "TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA"; - case SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA: return "TLS_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA"; - case SSL_DHE_DSS_WITH_DES_CBC_SHA: return "TLS_DHE_DSS_WITH_DES_CBC_SHA"; - case SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA: return "TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA"; - case SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA: return "TLS_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA"; - case SSL_DHE_RSA_WITH_DES_CBC_SHA: return "TLS_DHE_RSA_WITH_DES_CBC_SHA"; - case SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA: return "TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA"; - case SSL_DH_anon_EXPORT_WITH_RC4_40_MD5: return "TLS_DH_anon_EXPORT_WITH_RC4_40_MD5"; - case SSL_DH_anon_WITH_RC4_128_MD5: return "TLS_DH_anon_WITH_RC4_128_MD5"; - case SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA: return "TLS_DH_anon_EXPORT_WITH_DES40_CBC_SHA"; - case SSL_DH_anon_WITH_DES_CBC_SHA: return "TLS_DH_anon_WITH_DES_CBC_SHA"; - case SSL_DH_anon_WITH_3DES_EDE_CBC_SHA: return "TLS_DH_anon_WITH_3DES_EDE_CBC_SHA"; - - /* SSLv3 Fortezza cipher suites, from NSS */ - case SSL_FORTEZZA_DMS_WITH_NULL_SHA: return "SSL_FORTEZZA_DMS_WITH_NULL_SHA"; - case SSL_FORTEZZA_DMS_WITH_FORTEZZA_CBC_SHA:return "SSL_FORTEZZA_DMS_WITH_FORTEZZA_CBC_SHA"; - - /* TLS addenda using AES-CBC, RFC 3268 */ - case TLS_RSA_WITH_AES_128_CBC_SHA: return "TLS_RSA_WITH_AES_128_CBC_SHA"; - case TLS_DH_DSS_WITH_AES_128_CBC_SHA: return "TLS_DH_DSS_WITH_AES_128_CBC_SHA"; - case TLS_DH_RSA_WITH_AES_128_CBC_SHA: return "TLS_DH_RSA_WITH_AES_128_CBC_SHA"; - case TLS_DHE_DSS_WITH_AES_128_CBC_SHA: return "TLS_DHE_DSS_WITH_AES_128_CBC_SHA"; - case TLS_DHE_RSA_WITH_AES_128_CBC_SHA: return "TLS_DHE_RSA_WITH_AES_128_CBC_SHA"; - case TLS_DH_anon_WITH_AES_128_CBC_SHA: return "TLS_DH_anon_WITH_AES_128_CBC_SHA"; - case TLS_RSA_WITH_AES_256_CBC_SHA: return "TLS_RSA_WITH_AES_256_CBC_SHA"; - case TLS_DH_DSS_WITH_AES_256_CBC_SHA: return "TLS_DH_DSS_WITH_AES_256_CBC_SHA"; - case TLS_DH_RSA_WITH_AES_256_CBC_SHA: return "TLS_DH_RSA_WITH_AES_256_CBC_SHA"; - case TLS_DHE_DSS_WITH_AES_256_CBC_SHA: return "TLS_DHE_DSS_WITH_AES_256_CBC_SHA"; - case TLS_DHE_RSA_WITH_AES_256_CBC_SHA: return "TLS_DHE_RSA_WITH_AES_256_CBC_SHA"; - case TLS_DH_anon_WITH_AES_256_CBC_SHA: return "TLS_DH_anon_WITH_AES_256_CBC_SHA"; - - /* ECDSA addenda, RFC 4492 */ - case TLS_ECDH_ECDSA_WITH_NULL_SHA: return "TLS_ECDH_ECDSA_WITH_NULL_SHA"; - case TLS_ECDH_ECDSA_WITH_RC4_128_SHA: return "TLS_ECDH_ECDSA_WITH_RC4_128_SHA"; - case TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA: return "TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA"; - case TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA: return "TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA"; - case TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA: return "TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA"; - case TLS_ECDHE_ECDSA_WITH_NULL_SHA: return "TLS_ECDHE_ECDSA_WITH_NULL_SHA"; - case TLS_ECDHE_ECDSA_WITH_RC4_128_SHA: return "TLS_ECDHE_ECDSA_WITH_RC4_128_SHA"; - case TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA: return "TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA"; - case TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA: return "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA"; - case TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA: return "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA"; - case TLS_ECDH_RSA_WITH_NULL_SHA: return "TLS_ECDH_RSA_WITH_NULL_SHA"; - case TLS_ECDH_RSA_WITH_RC4_128_SHA: return "TLS_ECDH_RSA_WITH_RC4_128_SHA"; - case TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA: return "TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA"; - case TLS_ECDH_RSA_WITH_AES_128_CBC_SHA: return "TLS_ECDH_RSA_WITH_AES_128_CBC_SHA"; - case TLS_ECDH_RSA_WITH_AES_256_CBC_SHA: return "TLS_ECDH_RSA_WITH_AES_256_CBC_SHA"; - case TLS_ECDHE_RSA_WITH_NULL_SHA: return "TLS_ECDHE_RSA_WITH_NULL_SHA"; - case TLS_ECDHE_RSA_WITH_RC4_128_SHA: return "TLS_ECDHE_RSA_WITH_RC4_128_SHA"; - case TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA: return "TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA"; - case TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA: return "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA"; - case TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA: return "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA"; - case TLS_ECDH_anon_WITH_NULL_SHA: return "TLS_ECDH_anon_WITH_NULL_SHA"; - case TLS_ECDH_anon_WITH_RC4_128_SHA: return "TLS_ECDH_anon_WITH_RC4_128_SHA"; - case TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA: return "TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA"; - case TLS_ECDH_anon_WITH_AES_128_CBC_SHA: return "TLS_ECDH_anon_WITH_AES_128_CBC_SHA"; - case TLS_ECDH_anon_WITH_AES_256_CBC_SHA: return "TLS_ECDH_anon_WITH_AES_256_CBC_SHA"; - - /* TLS 1.2 addenda, RFC 5246 */ - case TLS_RSA_WITH_AES_128_CBC_SHA256: return "TLS_RSA_WITH_AES_128_CBC_SHA256"; - case TLS_RSA_WITH_AES_256_CBC_SHA256: return "TLS_RSA_WITH_AES_256_CBC_SHA256"; - case TLS_DH_DSS_WITH_AES_128_CBC_SHA256: return "TLS_DH_DSS_WITH_AES_128_CBC_SHA256"; - case TLS_DH_RSA_WITH_AES_128_CBC_SHA256: return "TLS_DH_RSA_WITH_AES_128_CBC_SHA256"; - case TLS_DHE_DSS_WITH_AES_128_CBC_SHA256: return "TLS_DHE_DSS_WITH_AES_128_CBC_SHA256"; - case TLS_DHE_RSA_WITH_AES_128_CBC_SHA256: return "TLS_DHE_RSA_WITH_AES_128_CBC_SHA256"; - case TLS_DH_DSS_WITH_AES_256_CBC_SHA256: return "TLS_DH_DSS_WITH_AES_256_CBC_SHA256"; - case TLS_DH_RSA_WITH_AES_256_CBC_SHA256: return "TLS_DH_RSA_WITH_AES_256_CBC_SHA256"; - case TLS_DHE_DSS_WITH_AES_256_CBC_SHA256: return "TLS_DHE_DSS_WITH_AES_256_CBC_SHA256"; - case TLS_DHE_RSA_WITH_AES_256_CBC_SHA256: return "TLS_DHE_RSA_WITH_AES_256_CBC_SHA256"; - case TLS_DH_anon_WITH_AES_128_CBC_SHA256: return "TLS_DH_anon_WITH_AES_128_CBC_SHA256"; - case TLS_DH_anon_WITH_AES_256_CBC_SHA256: return "TLS_DH_anon_WITH_AES_256_CBC_SHA256"; - - /* TLS addenda using AES-GCM, RFC 5288 */ - case TLS_RSA_WITH_AES_128_GCM_SHA256: return "TLS_RSA_WITH_AES_128_GCM_SHA256"; - case TLS_RSA_WITH_AES_256_GCM_SHA384: return "TLS_DHE_RSA_WITH_AES_128_GCM_SHA256"; - case TLS_DHE_RSA_WITH_AES_128_GCM_SHA256: return "TLS_DHE_RSA_WITH_AES_128_GCM_SHA256"; - case TLS_DHE_RSA_WITH_AES_256_GCM_SHA384: return "TLS_DHE_RSA_WITH_AES_256_GCM_SHA384"; - case TLS_DH_RSA_WITH_AES_128_GCM_SHA256: return "TLS_DH_RSA_WITH_AES_128_GCM_SHA256"; - case TLS_DH_RSA_WITH_AES_256_GCM_SHA384: return "TLS_DH_RSA_WITH_AES_256_GCM_SHA384"; - case TLS_DHE_DSS_WITH_AES_128_GCM_SHA256: return "TLS_DHE_DSS_WITH_AES_128_GCM_SHA256"; - case TLS_DHE_DSS_WITH_AES_256_GCM_SHA384: return "TLS_DHE_DSS_WITH_AES_256_GCM_SHA384"; - case TLS_DH_DSS_WITH_AES_128_GCM_SHA256: return "TLS_DH_DSS_WITH_AES_128_GCM_SHA256"; - case TLS_DH_DSS_WITH_AES_256_GCM_SHA384: return "TLS_DH_DSS_WITH_AES_256_GCM_SHA384"; - case TLS_DH_anon_WITH_AES_128_GCM_SHA256: return "TLS_DH_anon_WITH_AES_128_GCM_SHA256"; - case TLS_DH_anon_WITH_AES_256_GCM_SHA384: return "TLS_DH_anon_WITH_AES_256_GCM_SHA384"; - - /* ECDSA addenda, RFC 5289 */ - case TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256: return "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256"; - case TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384: return "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384"; - case TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256: return "TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256"; - case TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384: return "TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384"; - case TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256: return "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256"; - case TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384: return "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384"; - case TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256: return "TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256"; - case TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384: return "TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384"; - case TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256: return "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256"; - case TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384: return "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384"; - case TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256: return "TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256"; - case TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384: return "TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384"; - case TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256: return "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256"; - case TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384: return "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384"; - case TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256: return "TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256"; - case TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384: return "TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384"; - - /* - * Tags for SSL 2 cipher kinds which are not specified for SSL 3. - */ - case SSL_RSA_WITH_RC2_CBC_MD5: return "TLS_RSA_WITH_RC2_CBC_MD5"; - case SSL_RSA_WITH_IDEA_CBC_MD5: return "TLS_RSA_WITH_IDEA_CBC_MD5"; - case SSL_RSA_WITH_DES_CBC_MD5: return "TLS_RSA_WITH_DES_CBC_MD5"; - case SSL_RSA_WITH_3DES_EDE_CBC_MD5: return "TLS_RSA_WITH_3DES_EDE_CBC_MD5"; - case SSL_NO_SUCH_CIPHERSUITE: return "SSL_NO_SUCH_CIPHERSUITE"; - - default: - snprintf(noSuite, sizeof(noSuite), "Unknown ciphersuite 0x%04x", (unsigned)cs); - return noSuite; - } -} - -/* - * Given a SSLProtocolVersion - typically from SSLGetProtocolVersion - - * return a string representation. - */ -const char *sslGetProtocolVersionString(SSLProtocol prot) -{ - static char noProt[20]; - - switch(prot) { - case kSSLProtocolUnknown: return "kSSLProtocolUnknown"; - case kSSLProtocol2: return "kSSLProtocol2"; - case kSSLProtocol3: return "kSSLProtocol3"; - case kSSLProtocol3Only: return "kSSLProtocol3Only"; - case kTLSProtocol1: return "kTLSProtocol1"; - case kTLSProtocol1Only: return "kTLSProtocol1Only"; - case kTLSProtocol11: return "kTLSProtocol11"; - case kTLSProtocol12: return "kTLSProtocol12"; - default: - sprintf(noProt, "Unknown (%d)", (unsigned)prot); - return noProt; - } -} - -/* - * Return string representation of SecureTransport-related OSStatus. - */ -const char *sslGetSSLErrString(OSStatus err) -{ - static char errSecSuccessStr[20]; - - switch(err) { - case errSecSuccess: return "errSecSuccess"; - case errSecAllocate: return "errSecAllocate"; - case errSecParam: return "errSecParam"; - case errSecUnimplemented: return "errSecUnimplemented"; - case errSecIO: return "errSecIO"; - case errSecBadReq: return "errSecBadReq"; - /* SSL errors */ - case errSSLProtocol: return "errSSLProtocol"; - case errSSLNegotiation: return "errSSLNegotiation"; - case errSSLFatalAlert: return "errSSLFatalAlert"; - case errSSLWouldBlock: return "errSSLWouldBlock"; - case errSSLSessionNotFound: return "errSSLSessionNotFound"; - case errSSLClosedGraceful: return "errSSLClosedGraceful"; - case errSSLClosedAbort: return "errSSLClosedAbort"; - case errSSLXCertChainInvalid: return "errSSLXCertChainInvalid"; - case errSSLBadCert: return "errSSLBadCert"; - case errSSLCrypto: return "errSSLCrypto"; - case errSSLInternal: return "errSSLInternal"; - case errSSLModuleAttach: return "errSSLModuleAttach"; - case errSSLUnknownRootCert: return "errSSLUnknownRootCert"; - case errSSLNoRootCert: return "errSSLNoRootCert"; - case errSSLCertExpired: return "errSSLCertExpired"; - case errSSLCertNotYetValid: return "errSSLCertNotYetValid"; - case errSSLClosedNoNotify: return "errSSLClosedNoNotify"; - case errSSLBufferOverflow: return "errSSLBufferOverflow"; - case errSSLBadCipherSuite: return "errSSLBadCipherSuite"; - /* TLS/Panther addenda */ - case errSSLPeerUnexpectedMsg: return "errSSLPeerUnexpectedMsg"; - case errSSLPeerBadRecordMac: return "errSSLPeerBadRecordMac"; - case errSSLPeerDecryptionFail: return "errSSLPeerDecryptionFail"; - case errSSLPeerRecordOverflow: return "errSSLPeerRecordOverflow"; - case errSSLPeerDecompressFail: return "errSSLPeerDecompressFail"; - case errSSLPeerHandshakeFail: return "errSSLPeerHandshakeFail"; - case errSSLPeerBadCert: return "errSSLPeerBadCert"; - case errSSLPeerUnsupportedCert: return "errSSLPeerUnsupportedCert"; - case errSSLPeerCertRevoked: return "errSSLPeerCertRevoked"; - case errSSLPeerCertExpired: return "errSSLPeerCertExpired"; - case errSSLPeerCertUnknown: return "errSSLPeerCertUnknown"; - case errSSLIllegalParam: return "errSSLIllegalParam"; - case errSSLPeerUnknownCA: return "errSSLPeerUnknownCA"; - case errSSLPeerAccessDenied: return "errSSLPeerAccessDenied"; - case errSSLPeerDecodeError: return "errSSLPeerDecodeError"; - case errSSLPeerDecryptError: return "errSSLPeerDecryptError"; - case errSSLPeerExportRestriction: return "errSSLPeerExportRestriction"; - case errSSLPeerProtocolVersion: return "errSSLPeerProtocolVersion"; - case errSSLPeerInsufficientSecurity:return "errSSLPeerInsufficientSecurity"; - case errSSLPeerInternalError: return "errSSLPeerInternalError"; - case errSSLPeerUserCancelled: return "errSSLPeerUserCancelled"; - case errSSLPeerNoRenegotiation: return "errSSLPeerNoRenegotiation"; - case errSSLHostNameMismatch: return "errSSLHostNameMismatch"; - case errSSLConnectionRefused: return "errSSLConnectionRefused"; - case errSSLDecryptionFail: return "errSSLDecryptionFail"; - case errSSLBadRecordMac: return "errSSLBadRecordMac"; - case errSSLRecordOverflow: return "errSSLRecordOverflow"; - case errSSLBadConfiguration: return "errSSLBadConfiguration"; - - /* some from the Sec layer */ - case errSecNotAvailable: return "errSecNotAvailable"; - case errSecDuplicateItem: return "errSecDuplicateItem"; - case errSecItemNotFound: return "errSecItemNotFound"; -#if !TARGET_OS_IPHONE - case errSecReadOnly: return "errSecReadOnly"; - case errSecAuthFailed: return "errSecAuthFailed"; - case errSecNoSuchKeychain: return "errSecNoSuchKeychain"; - case errSecInvalidKeychain: return "errSecInvalidKeychain"; - case errSecNoSuchAttr: return "errSecNoSuchAttr"; - case errSecInvalidItemRef: return "errSecInvalidItemRef"; - case errSecInvalidSearchRef: return "errSecInvalidSearchRef"; - case errSecNoSuchClass: return "errSecNoSuchClass"; - case errSecNoDefaultKeychain: return "errSecNoDefaultKeychain"; - case errSecWrongSecVersion: return "errSecWrongSecVersion"; - case errSecInvalidTrustSettings: return "errSecInvalidTrustSettings"; - case errSecNoTrustSettings: return "errSecNoTrustSettings"; -#endif - default: -#if 0 - if (err < (CSSM_BASE_ERROR + - (CSSM_ERRORCODE_MODULE_EXTENT * 8))) - { - /* assume CSSM error */ - return cssmErrToStr(err); - } - else -#endif - { - sprintf(errSecSuccessStr, "Unknown (%d)", (unsigned)err); - return errSecSuccessStr; - } - } -} - -void printSslErrStr( - const char *op, - OSStatus err) -{ - printf("*** %s: %s\n", op, sslGetSSLErrString(err)); -} - -const char *sslGetClientCertStateString(SSLClientCertificateState state) -{ - static char noState[20]; - - switch(state) { - case kSSLClientCertNone: return "ClientCertNone"; - case kSSLClientCertRequested: return "CertRequested"; - case kSSLClientCertSent: return "ClientCertSent"; - case kSSLClientCertRejected: return "ClientCertRejected"; - default: - sprintf(noState, "Unknown (%d)", (unsigned)state); - return noState; - } - -} - -const char *sslGetClientAuthTypeString(SSLClientAuthenticationType authType) -{ - static char noType[20]; - - switch(authType) { - case SSLClientAuthNone: return "None"; - case SSLClientAuth_RSASign: return "RSASign"; - case SSLClientAuth_DSSSign: return "DSSSign"; - case SSLClientAuth_RSAFixedDH: return "RSAFixedDH"; - case SSLClientAuth_DSS_FixedDH: return "DSS_FixedDH"; - case SSLClientAuth_ECDSASign: return "ECDSASign"; - case SSLClientAuth_RSAFixedECDH: return "RSAFixedECDH"; - case SSLClientAuth_ECDSAFixedECDH: return "ECDSAFixedECDH"; - default: - sprintf(noType, "Unknown (%d)", (unsigned)authType); - return noType; - } -} - -/* - * Convert a keychain name (which may be NULL) into the CFArrayRef required - * by SSLSetCertificate. This is a bare-bones example of this operation, - * since it requires and assumes that there is exactly one SecIdentity - * in the keychain - i.e., there is exactly one matching cert/private key - * pair. A real world server would probably search a keychain for a SecIdentity - * matching some specific criteria. - */ -CFArrayRef getSslCerts( - const char *kcName, // may be NULL, i.e., use default - bool encryptOnly, - bool completeCertChain, - const char *anchorFile, // optional trusted anchor - SecKeychainRef *pKcRef) // RETURNED -{ -#if 0 - SecKeychainRef kcRef = nil; - OSStatus ortn; - - *pKcRef = nil; - - /* pick a keychain */ - if(kcName) { - ortn = SecKeychainOpen(kcName, &kcRef); - if(ortn) { - printf("SecKeychainOpen returned %d.\n", (int)ortn); - printf("Cannot open keychain at %s. Aborting.\n", kcName); - return NULL; - } - } - else { - /* use default keychain */ - ortn = SecKeychainCopyDefault(&kcRef); - if(ortn) { - printf("SecKeychainCopyDefault returned %d; aborting.\n", (int)ortn); - return nil; - } - } - *pKcRef = kcRef; - return sslKcRefToCertArray(kcRef, encryptOnly, completeCertChain, anchorFile); -#elif TARGET_OS_IOS - SecCertificateRef cert = NULL; - SecIdentityRef identity = NULL; - CFMutableArrayRef certificates = NULL, result = NULL; - CFMutableDictionaryRef certQuery = NULL, keyQuery = NULL, keyResult = NULL; - SecTrustRef trust = NULL; - SecKeyRef key = NULL; - CFTypeRef pkdigest = NULL; - - // Find the first private key in the keychain and return both its - // attributes and a ref to it. - require(keyQuery = CFDictionaryCreateMutable(NULL, 0, NULL, NULL), errOut); - CFDictionaryAddValue(keyQuery, kSecClass, kSecClassKey); - CFDictionaryAddValue(keyQuery, kSecAttrKeyClass, kSecAttrKeyClassPrivate); - CFDictionaryAddValue(keyQuery, kSecReturnRef, kCFBooleanTrue); - CFDictionaryAddValue(keyQuery, kSecReturnAttributes, kCFBooleanTrue); - require_noerr(SecItemCopyMatching(keyQuery, (CFTypeRef *)&keyResult), - errOut); - require(key = (SecKeyRef)CFDictionaryGetValue(keyResult, kSecValueRef), - errOut); - require(pkdigest = CFDictionaryGetValue(keyResult, kSecAttrApplicationLabel), - errOut); - - // Find the first certificate that has the same public key hash as the - // returned private key and return it as a ref. - require(certQuery = CFDictionaryCreateMutable(NULL, 0, NULL, NULL), errOut); - CFDictionaryAddValue(certQuery, kSecClass, kSecClassCertificate); - CFDictionaryAddValue(certQuery, kSecAttrPublicKeyHash, pkdigest); - CFDictionaryAddValue(certQuery, kSecReturnRef, kCFBooleanTrue); - require_noerr(SecItemCopyMatching(certQuery, (CFTypeRef *)&cert), errOut); - - // Create an identity from the key and certificate. - require(identity = SecIdentityCreate(NULL, cert, key), errOut); - - // Build a (partial) certificate chain from cert - require(certificates = CFArrayCreateMutable(NULL, 0, - &kCFTypeArrayCallBacks), errOut); - CFArrayAppendValue(certificates, cert); - require_noerr(SecTrustCreateWithCertificates(certificates, NULL, &trust), - errOut); - SecTrustResultType tresult; - require_noerr(SecTrustEvaluate(trust, &tresult), errOut); - - CFIndex certCount, ix; - // We need at least 1 certificate - require(certCount = SecTrustGetCertificateCount(trust), errOut); - - // Build a result where element 0 is the identity and the other elements - // are the certs in the chain starting at the first intermediate up to the - // anchor, if we found one, or as far as we were able to build the chain - // if not. - require(result = CFArrayCreateMutable(NULL, certCount, &kCFTypeArrayCallBacks), - errOut); - - // We are commited to returning a result now, so do not use require below - // this line without setting result to NULL again. - CFArrayAppendValue(result, identity); - for (ix = 1; ix < certCount; ++ix) { - CFArrayAppendValue(result, SecTrustGetCertificateAtIndex(trust, ix)); - } - -errOut: - CFReleaseSafe(trust); - CFReleaseSafe(certificates); - CFReleaseSafe(identity); - CFReleaseSafe(cert); - CFReleaseSafe(certQuery); - CFReleaseSafe(keyResult); - CFReleaseSafe(keyQuery); - - return result; - -#else /* !TARGET_OS_IOS */ - SecIdentityRef identity = NULL; - CFMutableDictionaryRef query = NULL; - CFArrayRef items = NULL; - require(query = CFDictionaryCreateMutable(NULL, 0, NULL, NULL), errOut); - CFDictionaryAddValue(query, kSecClass, kSecClassIdentity); - CFDictionaryAddValue(query, kSecReturnRef, kCFBooleanTrue); - require_noerr(SecItemCopyMatching(query, (CFTypeRef *)&identity), errOut); - - items = CFArrayCreate(kCFAllocatorDefault, - (const void **)&identity, 1, &kCFTypeArrayCallBacks); - -errOut: - CFReleaseSafe(identity); - CFReleaseSafe(query); - - return items; - -#endif - -} - -#if 0 -/* - * Determine if specified SecCertificateRef is a self-signed cert. - * We do this by comparing the subject and issuerr names; no cryptographic - * verification is performed. - * - * Returns true if the cert appears to be a root. - */ -static bool isCertRefRoot( - SecCertificateRef certRef) -{ - bool brtn = false; -#if 0 - /* just search for the two attrs we want */ - UInt32 tags[2] = {kSecSubjectItemAttr, kSecIssuerItemAttr}; - SecKeychainAttributeInfo attrInfo; - attrInfo.count = 2; - attrInfo.tag = tags; - attrInfo.format = NULL; - SecKeychainAttributeList *attrList = NULL; - SecKeychainAttribute *attr1 = NULL; - SecKeychainAttribute *attr2 = NULL; - - OSStatus ortn = SecKeychainItemCopyAttributesAndData( - (SecKeychainItemRef)certRef, - &attrInfo, - NULL, // itemClass - &attrList, - NULL, // length - don't need the data - NULL); // outData - if(ortn) { - cssmPerror("SecKeychainItemCopyAttributesAndData", ortn); - /* may want to be a bit more robust here, but this should - * never happen */ - return false; - } - /* subsequent errors to errOut: */ - - if((attrList == NULL) || (attrList->count != 2)) { - printf("***Unexpected result fetching label attr\n"); - goto errOut; - } - - /* rootness is just byte-for-byte compare of the two names */ - attr1 = &attrList->attr[0]; - attr2 = &attrList->attr[1]; - if(attr1->length == attr2->length) { - if(memcmp(attr1->data, attr2->data, attr1->length) == 0) { - brtn = true; - } - } -errOut: - SecKeychainItemFreeAttributesAndData(attrList, NULL); -#endif - return brtn; -} -#endif - -#if 0 -/* - * Given a SecIdentityRef, do our best to construct a complete, ordered, and - * verified cert chain, returning the result in a CFArrayRef. The result is - * suitable for use when calling SSLSetCertificate(). - */ -OSStatus sslCompleteCertChain( - SecIdentityRef identity, - SecCertificateRef trustedAnchor, // optional additional trusted anchor - bool includeRoot, // include the root in outArray - CFArrayRef *outArray) // created and RETURNED -{ - CFMutableArrayRef certArray; - SecTrustRef secTrust = NULL; - SecPolicyRef policy = NULL; - SecPolicySearchRef policySearch = NULL; - SecTrustResultType secTrustResult; - CSSM_TP_APPLE_EVIDENCE_INFO *dummyEv; // not used - CFArrayRef certChain = NULL; // constructed chain - CFIndex numResCerts; - - certArray = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks); - CFArrayAppendValue(certArray, identity); - - /* - * Case 1: identity is a root; we're done. Note that this case - * overrides the includeRoot argument. - */ - SecCertificateRef certRef; - OSStatus ortn = SecIdentityCopyCertificate(identity, &certRef); - if(ortn) { - /* should never happen */ - cssmPerror("SecIdentityCopyCertificate", ortn); - return ortn; - } - bool isRoot = isCertRefRoot(certRef); - if(isRoot) { - *outArray = certArray; - CFRelease(certRef); - return errSecSuccess; - } - - /* - * Now use SecTrust to get a complete cert chain, using all of the - * user's keychains to look for intermediate certs. - * NOTE this does NOT handle root certs which are not in the system - * root cert DB. (The above case, where the identity is a root cert, does.) - */ - CFMutableArrayRef subjCerts = CFArrayCreateMutable(NULL, 1, &kCFTypeArrayCallBacks); - CFArraySetValueAtIndex(subjCerts, 0, certRef); - - /* the array owns the subject cert ref now */ - CFRelease(certRef); - - /* Get a SecPolicyRef for generic X509 cert chain verification */ - ortn = SecPolicySearchCreate(CSSM_CERT_X_509v3, - &CSSMOID_APPLE_X509_BASIC, - NULL, // value - &policySearch); - if(ortn) { - cssmPerror("SecPolicySearchCreate", ortn); - goto errOut; - } - ortn = SecPolicySearchCopyNext(policySearch, &policy); - if(ortn) { - cssmPerror("SecPolicySearchCopyNext", ortn); - goto errOut; - } - - /* build a SecTrustRef for specified policy and certs */ - ortn = SecTrustCreateWithCertificates(subjCerts, - policy, &secTrust); - if(ortn) { - cssmPerror("SecTrustCreateWithCertificates", ortn); - goto errOut; - } - - if(trustedAnchor) { - /* - * Tell SecTrust to trust this one in addition to the current - * trusted system-wide anchors. - */ - CFMutableArrayRef newAnchors; - CFArrayRef currAnchors; - - ortn = SecTrustCopyAnchorCertificates(&currAnchors); - if(ortn) { - /* should never happen */ - cssmPerror("SecTrustCopyAnchorCertificates", ortn); - goto errOut; - } - newAnchors = CFArrayCreateMutableCopy(NULL, - CFArrayGetCount(currAnchors) + 1, - currAnchors); - CFRelease(currAnchors); - CFArrayAppendValue(newAnchors, trustedAnchor); - ortn = SecTrustSetAnchorCertificates(secTrust, newAnchors); - CFRelease(newAnchors); - if(ortn) { - cssmPerror("SecTrustSetAnchorCertificates", ortn); - goto errOut; - } - } - /* evaluate: GO */ - ortn = SecTrustEvaluate(secTrust, &secTrustResult); - if(ortn) { - cssmPerror("SecTrustEvaluate", ortn); - goto errOut; - } - switch(secTrustResult) { - case kSecTrustResultUnspecified: - /* cert chain valid, no special UserTrust assignments */ - case kSecTrustResultProceed: - /* cert chain valid AND user explicitly trusts this */ - break; - default: - /* - * Cert chain construction failed. - * Just go with the single subject cert we were given. - */ - printf("***Warning: could not construct completed cert chain\n"); - ortn = errSecSuccess; - goto errOut; - } - - /* get resulting constructed cert chain */ - ortn = SecTrustGetResult(secTrust, &secTrustResult, &certChain, &dummyEv); - if(ortn) { - cssmPerror("SecTrustEvaluate", ortn); - goto errOut; - } - - /* - * Copy certs from constructed chain to our result array, skipping - * the leaf (which is already there, as a SecIdentityRef) and possibly - * a root. - */ - numResCerts = CFArrayGetCount(certChain); - if(numResCerts < 2) { - /* - * Can't happen: if subject was a root, we'd already have returned. - * If chain doesn't verify to a root, we'd have bailed after - * SecTrustEvaluate(). - */ - printf("***sslCompleteCertChain screwup: numResCerts %d\n", - (int)numResCerts); - ortn = errSecSuccess; - goto errOut; - } - if(!includeRoot) { - /* skip the last (root) cert) */ - numResCerts--; - } - for(CFIndex dex=1; dexacceptedProts) { - printf(" Allowed SSL versions : %s\n", params->acceptedProts); - } - else { - printf(" Attempted SSL version : %s\n", - sslGetProtocolVersionString(params->tryVersion)); - } - printf(" Result : %s\n", sslGetSSLErrString(params->ortn)); - printf(" Negotiated SSL version : %s\n", - sslGetProtocolVersionString(params->negVersion)); - printf(" Negotiated CipherSuite : %s\n", - sslGetCipherSuiteString(params->negCipher)); - if(params->certState != kSSLClientCertNone) { - printf(" Client Cert State : %s\n", - sslGetClientCertStateString(params->certState)); - } -} -#endif - -/* print a '.' every few seconds to keep UI alive while connecting */ -static CFAbsoluteTime lastTime = (CFAbsoluteTime)0.0; -#define TIME_INTERVAL 3.0 - -void sslOutputDot() -{ - CFAbsoluteTime thisTime = CFAbsoluteTimeGetCurrent(); - - // throttle down. - usleep(1000); - - if(lastTime == 0.0) { - /* avoid printing first time thru */ - lastTime = thisTime; - return; - } - if((thisTime - lastTime) >= TIME_INTERVAL) { - printf("."); fflush(stdout); - lastTime = thisTime; - } -} - -#if 0 -/* main server pthread body */ -static void *sslServerThread(void *arg) -{ - SslAppTestParams *testParams = (SslAppTestParams *)arg; - OSStatus status; - - status = sslAppServe(testParams); - pthread_exit((void*)status); - /* NOT REACHED */ - return (void *)status; -} - -/* - * Run one session, with the server in a separate thread. - * On entry, serverParams->port is the port we attempt to run on; - * the server thread may overwrite that with a different port if it's - * unable to open the port we specify. Whatever is left in - * serverParams->port is what's used for the client side. - */ -#define CLIENT_WAIT_SECONDS 1 -int sslRunSession( - SslAppTestParams*serverParams, - SslAppTestParams *clientParams, - const char *testDesc) -{ - pthread_t serverPthread; - OSStatus clientRtn; - void *serverRtn; - - if(testDesc && !clientParams->quiet) { - printf("===== %s =====\n", testDesc); - } - - if(pthread_mutex_init(&serverParams->pthreadMutex, NULL)) { - printf("***Error initializing mutex; aborting.\n"); - return -1; - } - if(pthread_cond_init(&serverParams->pthreadCond, NULL)) { - printf("***Error initializing pthreadCond; aborting.\n"); - return -1; - } - serverParams->serverReady = false; // server sets true - - int result = pthread_create(&serverPthread, NULL, - sslServerThread, serverParams); - if(result) { - printf("***Error starting up server thread; aborting.\n"); - return result; - } - - /* wait for server to set up a socket we can connect to */ - if(pthread_mutex_lock(&serverParams->pthreadMutex)) { - printf("***Error acquiring server lock; aborting.\n"); - return -1; - } - while(!serverParams->serverReady) { - if(pthread_cond_wait(&serverParams->pthreadCond, &serverParams->pthreadMutex)) { - printf("***Error waiting server thread; aborting.\n"); - return -1; - } - } - pthread_mutex_unlock(&serverParams->pthreadMutex); - pthread_cond_destroy(&serverParams->pthreadCond); - pthread_mutex_destroy(&serverParams->pthreadMutex); - - clientParams->port = serverParams->port; - clientRtn = sslAppClient(clientParams); - /* server doesn't shut down its socket until it sees this */ - serverParams->clientDone = 1; - result = pthread_join(serverPthread, &serverRtn); - if(result) { - printf("***pthread_join returned %d, aborting\n", result); - return result; - } - - if(serverParams->verbose) { - sslShowResult("server", serverParams); - } - if(clientParams->verbose) { - sslShowResult("client", clientParams); - } - - /* verify results */ - int ourRtn = 0; - ourRtn += sslVerifyRtn("server", serverParams->expectRtn, serverParams->ortn); - ourRtn += sslVerifyRtn("client", clientParams->expectRtn, clientParams->ortn); - ourRtn += sslVerifyProtVers("server", serverParams->expectVersion, - serverParams->negVersion); - ourRtn += sslVerifyProtVers("client", clientParams->expectVersion, - clientParams->negVersion); - ourRtn += sslVerifyClientCertState("server", serverParams->expectCertState, - serverParams->certState); - ourRtn += sslVerifyClientCertState("client", clientParams->expectCertState, - clientParams->certState); - if(serverParams->ortn == errSecSuccess) { - ourRtn += sslVerifyCipher("server", serverParams->expectCipher, - serverParams->negCipher); - } - if(clientParams->ortn == errSecSuccess) { - ourRtn += sslVerifyCipher("client", clientParams->expectCipher, - clientParams->negCipher); - } - return ourRtn; -} - -/* - * Add all of the roots in a given KC to SSL ctx's trusted anchors. - */ -OSStatus sslAddTrustedRoots( - SSLContextRef ctx, - SecKeychainRef keychain, - bool *foundOne) // RETURNED, true if we found - // at least one root cert -{ - OSStatus ortn; - SecCertificateRef secCert; - SecKeychainSearchRef srch; - - *foundOne = false; - ortn = SecKeychainSearchCreateFromAttributes(keychain, - kSecCertificateItemClass, - NULL, // any attrs - &srch); - if(ortn) { - printSslErrStr("SecKeychainSearchCreateFromAttributes", ortn); - return ortn; - } - - /* - * Only use root certs. Not an error if we don't find any. - */ - do { - ortn = SecKeychainSearchCopyNext(srch, - (SecKeychainItemRef *)&secCert); - if(ortn) { - break; - } - - /* see if it's a root */ - if(!isCertRoot(secCert)) { - continue; - } - - /* Tell Secure Transport to trust this one. */ - ortn = addTrustedSecCert(ctx, secCert, false); - if(ortn) { - /* fatal */ - printSslErrStr("addTrustedSecCert", ortn); - return ortn; - } - CFRelease(secCert); - *foundOne = true; - } while(ortn == errSecSuccess); - CFRelease(srch); - return errSecSuccess; -} - -/* - * Wrapper for sslIdentPicker, with optional trusted anchor specified as a filename. - */ -OSStatus sslIdentityPicker( - SecKeychainRef kcRef, // NULL means use default list - const char *trustedAnchor, // optional additional trusted anchor - bool includeRoot, // true --> root is appended to outArray - // false --> root not included - CFArrayRef *outArray) // created and RETURNED -{ - SecCertificateRef trustedCert = NULL; - OSStatus ortn; - - if(trustedAnchor) { - ortn = sslReadAnchor(trustedAnchor, &trustedCert); - if(ortn) { - printf("***Error reading %s. sslIdentityPicker proceeding with no anchor.\n", - trustedAnchor); - trustedCert = NULL; - } - } - ortn = sslIdentPicker(kcRef, trustedCert, includeRoot, outArray); - if(trustedCert) { - CFRelease(trustedCert); - } - return ortn; -} - -/* - * Given a keychain name, convert it into a full path using the "SSL regression - * test suite algorithm". The Sec layer by default locates root root's keychains - * in different places depending on whether we're actually logged in as root - * or running via e.g. cron, so we force the location of root keychains to - * a hard-coded path. User keychain names we leave alone. - */ -void sslKeychainPath( - const char *kcName, - char *kcPath) // allocd by caller, MAXPATHLEN -{ - if(kcName[0] == '\0') { - kcPath[0] = '\0'; - } - else if(geteuid() == 0) { - /* root */ - sprintf(kcPath, "/Library/Keychains/%s", kcName); - } - else { - /* user, leave alone */ - strcpy(kcPath, kcName); - } -} - -/* Verify presence of required file. Returns nonzero if not found. */ -int sslCheckFile(const char *path) -{ - struct stat sb; - - if(stat(path, &sb)) { - printf("***Can't find file %s.\n", path); - printf(" Try running in the build directory, perhaps after running the\n" - " makeLocalCert script.\n"); - return 1; - } - return 0; -} - -#endif - -/* Stringify a SSL_ECDSA_NamedCurve */ -extern const char *sslCurveString( - SSL_ECDSA_NamedCurve namedCurve) -{ - static char unk[100]; - - switch(namedCurve) { - case SSL_Curve_None: return "Curve_None"; - case SSL_Curve_secp256r1: return "secp256r1"; - case SSL_Curve_secp384r1: return "secp384r1"; - case SSL_Curve_secp521r1: return "secp521r1"; - default: - sprintf(unk, "Unknown <%d>", (int)namedCurve); - return unk; - } -}