0001    //
0002    //  HTTPSecurity.swift
0003    //  SwiftHTTP
0004    //
0005    //  Created by Dalton Cherry on 5/16/15.
0006    //  Copyright (c) 2015 Vluxe. All rights reserved.
0007    //
0008    
0009    import Foundation
0010    import Security
0011    
0012    public class SSLCert
HTTPSecurity.swift:56
        var collect = Array<SSLCert>()
HTTPSecurity.swift:59
                collect.append(SSLCert(data: d))
HTTPSecurity.swift:73
    public init(certs: [SSLCert], usePublicKeys: Bool) {
{ 0013 var certData
HTTPSecurity.swift:24
        self.certData = data
HTTPSecurity.swift:80
                    if let data = cert.certData where cert.key == nil  {
HTTPSecurity.swift:93
                if let d = cert.certData {
: NSData? 0014 var key
HTTPSecurity.swift:35
        self.key = key
HTTPSecurity.swift:80
                    if let data = cert.certData where cert.key == nil  {
HTTPSecurity.swift:81
                        cert.key = self.extractPublicKey(data)
HTTPSecurity.swift:83
                    if let k = cert.key {
: SecKeyRef? 0015 0016 /** 0017 Designated init for certificates 0018 0019 - parameter data: is the binary data of the certificate 0020 0021 - returns: a representation security object to be used with 0022 */ 0023 public init
HTTPSecurity.swift:59
                collect.append(SSLCert(data: d))
(data: NSData) { 0024 self.certData = data 0025 } 0026 0027 /** 0028 Designated init for public keys 0029 0030 - parameter key: is the public key to be used 0031 0032 - returns: a representation security object to be used with 0033 */ 0034 public init(key: SecKeyRef) { 0035 self.key = key 0036 } 0037 } 0038 0039 public class HTTPSecurity
Operation.swift:108
    var security: HTTPSecurity?
Operation.swift:141
    public var security: HTTPSecurity? {
Operation.swift:412
    public class func globalSecurity(security: HTTPSecurity?) {
Operation.swift:455
    var security: HTTPSecurity?
{ 0040 public var validatedDN
HTTPSecurity.swift:121
        if self.validatedDN {
= true //should the domain name be validated? 0041 0042 var isReady
HTTPSecurity.swift:88
                self.isReady = true
HTTPSecurity.swift:98
            self.isReady = true
HTTPSecurity.swift:113
        while(!self.isReady) {
= false //is the key processing done? 0043 var certificates
HTTPSecurity.swift:97
            self.certificates = collect
HTTPSecurity.swift:143
        } else if let certs = self.certificates {
: [NSData]? //the certificates 0044 var pubKeys
HTTPSecurity.swift:87
                self.pubKeys = collect
HTTPSecurity.swift:128
            if let keys = self.pubKeys {
: [SecKeyRef]? //the public keys 0045 var usePublicKeys
HTTPSecurity.swift:74
        self.usePublicKeys = usePublicKeys
HTTPSecurity.swift:76
        if self.usePublicKeys {
HTTPSecurity.swift:127
        if self.usePublicKeys {
= false //use public keys or certificate validation? 0046 0047 /** 0048 Use certs from main app bundle 0049 0050 - parameter usePublicKeys: is to specific if the publicKeys or certificates should be used for SSL pinning validation 0051 0052 - returns: a representation security object to be used with 0053 */ 0054 public convenience init(usePublicKeys: Bool = false) { 0055 let paths = NSBundle.mainBundle().pathsForResourcesOfType("cer", inDirectory: ".") 0056 var collect = Array<SSLCert>() 0057 for path in paths { 0058 if let d = NSData(contentsOfFile: path as String) { 0059 collect.append(SSLCert(data: d)) 0060 } 0061 } 0062 self.init(certs:collect, usePublicKeys: usePublicKeys) 0063 } 0064 0065 /** 0066 Designated init 0067 0068 - parameter keys: is the certificates or public keys to use 0069 - parameter usePublicKeys: is to specific if the publicKeys or certificates should be used for SSL pinning validation 0070 0071 - returns: a representation security object to be used with 0072 */ 0073 public init
HTTPSecurity.swift:62
        self.init(certs:collect, usePublicKeys: usePublicKeys)
(certs: [SSLCert], usePublicKeys: Bool) { 0074 self.usePublicKeys = usePublicKeys 0075 0076 if self.usePublicKeys { 0077 dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0), { 0078 var collect = Array<SecKeyRef>() 0079 for cert in certs { 0080 if let data = cert.certData where cert.key == nil { 0081 cert.key = self.extractPublicKey(data) 0082 } 0083 if let k = cert.key { 0084 collect.append(k) 0085 } 0086 } 0087 self.pubKeys = collect 0088 self.isReady = true 0089 }) 0090 } else { 0091 var collect = Array<NSData>() 0092 for cert in certs { 0093 if let d = cert.certData { 0094 collect.append(d) 0095 } 0096 } 0097 self.certificates = collect 0098 self.isReady = true 0099 } 0100 } 0101 0102 /** 0103 Valid the trust and domain name. 0104 0105 - parameter trust: is the serverTrust to validate 0106 - parameter domain: is the CN domain to validate 0107 0108 - returns: if the key was successfully validated 0109 */ 0110 public func isValid
Operation.swift:531
                if sec.isValid(trust, domain: space.host) {
(trust: SecTrustRef, domain: String?) -> Bool { 0111 0112 var tries = 0 0113 while(!self.isReady) { 0114 usleep(1000) 0115 tries += 1 0116 if tries > 5 { 0117 return false //doesn't appear it is going to ever be ready... 0118 } 0119 } 0120 var policy: SecPolicyRef 0121 if self.validatedDN { 0122 policy = SecPolicyCreateSSL(true, domain) 0123 } else { 0124 policy = SecPolicyCreateBasicX509() 0125 } 0126 SecTrustSetPolicies(trust,policy) 0127 if self.usePublicKeys { 0128 if let keys = self.pubKeys { 0129 var trustedCount = 0 0130 let serverPubKeys = publicKeyChainForTrust(trust) 0131 for serverKey in serverPubKeys as [AnyObject] { 0132 for key in keys as [AnyObject] { 0133 if serverKey.isEqual(key) { 0134 trustedCount++ 0135 break 0136 } 0137 } 0138 } 0139 if trustedCount == serverPubKeys.count { 0140 return true 0141 } 0142 } 0143 } else if let certs = self.certificates { 0144 let serverCerts = certificateChainForTrust(trust) 0145 var collect = Array<SecCertificate>() 0146 for cert in certs { 0147 collect.append(SecCertificateCreateWithData(nil,cert)!) 0148 } 0149 SecTrustSetAnchorCertificates(trust,collect) 0150 var result: SecTrustResultType = 0 0151 SecTrustEvaluate(trust,&result) 0152 let r = Int(result) 0153 if r == kSecTrustResultUnspecified || r == kSecTrustResultProceed { 0154 var trustedCount = 0 0155 for serverCert in serverCerts { 0156 for cert in certs { 0157 if cert == serverCert { 0158 trustedCount++ 0159 break 0160 } 0161 } 0162 } 0163 if trustedCount == serverCerts.count { 0164 return true 0165 } 0166 } 0167 } 0168 return false 0169 } 0170 0171 /** 0172 Get the public key from a certificate data 0173 0174 - parameter data: is the certificate to pull the public key from 0175 0176 - returns: a public key 0177 */ 0178 func extractPublicKey
HTTPSecurity.swift:81
                        cert.key = self.extractPublicKey(data)
(data: NSData) -> SecKeyRef? { 0179 let possibleCert = SecCertificateCreateWithData(nil,data) 0180 if let cert = possibleCert { 0181 return extractPublicKeyFromCert(cert, policy: SecPolicyCreateBasicX509()) 0182 } 0183 return nil 0184 } 0185 0186 /** 0187 Get the public key from a certificate 0188 0189 - parameter data: is the certificate to pull the public key from 0190 0191 - returns: a public key 0192 */ 0193 func extractPublicKeyFromCert
HTTPSecurity.swift:181
            return extractPublicKeyFromCert(cert, policy: SecPolicyCreateBasicX509())
HTTPSecurity.swift:232
            if let key = extractPublicKeyFromCert(cert!, policy: policy) {
(cert: SecCertificate, policy: SecPolicy) -> SecKeyRef? { 0194 var possibleTrust: SecTrust? 0195 SecTrustCreateWithCertificates(cert, policy, &possibleTrust) 0196 if let trust = possibleTrust { 0197 var result: SecTrustResultType = 0 0198 SecTrustEvaluate(trust, &result) 0199 return SecTrustCopyPublicKey(trust) 0200 } 0201 return nil 0202 } 0203 0204 /** 0205 Get the certificate chain for the trust 0206 0207 - parameter trust: is the trust to lookup the certificate chain for 0208 0209 - returns: the certificate chain for the trust 0210 */ 0211 func certificateChainForTrust
HTTPSecurity.swift:144
            let serverCerts = certificateChainForTrust(trust)
(trust: SecTrustRef) -> Array<NSData> { 0212 var collect = Array<NSData>() 0213 for var i = 0; i < SecTrustGetCertificateCount(trust); i++ { 0214 let cert = SecTrustGetCertificateAtIndex(trust,i) 0215 collect.append(SecCertificateCopyData(cert!)) 0216 } 0217 return collect 0218 } 0219 0220 /** 0221 Get the public key chain for the trust 0222 0223 - parameter trust: is the trust to lookup the certificate chain and extract the public keys 0224 0225 - returns: the public keys from the certifcate chain for the trust 0226 */ 0227 func publicKeyChainForTrust
HTTPSecurity.swift:130
                let serverPubKeys = publicKeyChainForTrust(trust)
(trust: SecTrustRef) -> Array<SecKeyRef> { 0228 var collect = Array<SecKeyRef>() 0229 let policy = SecPolicyCreateBasicX509() 0230 for var i = 0; i < SecTrustGetCertificateCount(trust); i++ { 0231 let cert = SecTrustGetCertificateAtIndex(trust,i) 0232 if let key = extractPublicKeyFromCert(cert!, policy: policy) { 0233 collect.append(key) 0234 } 0235 } 0236 return collect 0237 } 0238 0239 0240 }