3

I am using Alamofire in my IOS Application and has implemented SSL Pinning. I have kept the certificate locally in .der format. The issue is the certificate when getting expired, I have to do an App release with new certificate.

Code Snippet used:

struct Certificates {
    fileprivate static let sslCertificate: SecCertificate? = Certificates.certificate(filename: (Bundle.main.infoDictionary?["SSL_CERTIFICATE"] as? String))

private static func certificate(filename: String?) -> SecCertificate? {
    guard let filePath = Bundle.main.path(forResource: filename, ofType: "der"), let data = try? Data(contentsOf: URL(fileURLWithPath: filePath)), let certificate = SecCertificateCreateWithData(nil, data as CFData) else{
        return nil
    }
    return certificate
}


final class APIClient {
    
    // MARK: - Host To Evaluate
    private static var hostToEvaluate: String {
        guard let urlString = Bundle.main.infoDictionary?["API_BASE_URL_ENDPOINT"] as? String, let hostURL = URL(string: urlString), let host = hostURL.host else{
            return ""
        }
        return host
    }
    
    // MARK: - Evaluators
    private static var evaluators: Dictionary<String,ServerTrustEvaluating> {
        guard let sslCertificate = Certificates.sslCertificate else{
            return [hostToEvaluate : DisabledTrustEvaluator()]
        }
        return [hostToEvaluate : PinnedCertificatesTrustEvaluator(certificates: [sslCertificate])]
    }
    
    // MARK: - Session
    private static let session = Session(
        serverTrustManager: ServerTrustManager(evaluators: evaluators)
    )
}

Can I keep 2 certificates and do a check to evaluate existing certificate and if it fails pick up the new certificate.

Have checked few documentations and forums, but did not find anything relevant.

Thanks,

Abin

1 Answers1

4

Yes. By default PublicKeysTrustEvaluator and PinnedCertificatesTrustEvaluator will pick up all certificates that are in the application bundle, if you don't pass anything for keys and certificates parameters in the initializer respectively. The evaluation will pass if one of the bundled certificates are matching.

Your code will look something like this:

// MARK: - Evaluators

private static var evaluators: Dictionary<String, ServerTrustEvaluating> = [
    hostToEvaluate: PinnedCertificatesTrustEvaluator()
]

// MARK: - Session

private static let session = Session(
    serverTrustManager: ServerTrustManager(evaluators: evaluators)
)

Just make sure that both certificates are in the application bundle. (add them to your target)

gcharita
  • 7,729
  • 3
  • 20
  • 37