I am migrating my app to use Alamofire 5.0.2, in the past version it uses Alamofire 4.x and the certificate pinning is working fine.
Then I migrated Alamofire and its certificate pinning configuration with these changes:
//Usage example of the function `defaultSessionManager`
class ViewController: UIViewController {
let sessionManager = defaultSessionManager(defaultRequestInterceptor())
//...
}
private func defaultSessionManager(_ requestInterceptor: RequestInterceptor?) -> Alamofire.Session {
let evaluators: [String: ServerTrustEvaluating] = [
"https://myapp.com": PinnedCertificatesTrustEvaluator(certificates: pinnedCertificates()),
]
let configuration: URLSessionConfiguration = URLSessionConfiguration.af.default
configuration.timeoutIntervalForRequest = 10 // seconds
configuration.timeoutIntervalForResource = 10 // seconds
return Alamofire.Session(
configuration: configuration,
interceptor: requestInterceptor,
serverTrustManager: ServerTrustManager(evaluators: evaluators))
}
func pinnedCertificates() -> [SecCertificate] {
var certificates: [SecCertificate] = []
let directoryContents: [URL] = //...
let certificateName: String = "app.cer" // Replaced for the demo
let pinnedCertificateURL: URL? = directoryContents.first { (url: URL) in url.lastPathComponent == certificateName }
if let pinnedCertificateURL: URL = pinnedCertificateURL {
do {
let pinnedCertificateData: CFData = try Data(contentsOf: pinnedCertificateURL) as CFData
if let pinnedCertificate: SecCertificate = SecCertificateCreateWithData(nil, pinnedCertificateData) {
certificates.append(pinnedCertificate)
}
} catch {
//...
}
}
return certificates
}
With the solution above, I am getting the error:
MyApp[374:21470] Task <DDC8F9FD-81A3-EBA4-8AA2-D7C99DD3E63B>.<1> HTTP load failed, 0/0 bytes (error code: -999 [1:89])
If I remove the line serverTrustManager: ServerTrustManager(evaluators: evaluators))
, Alamofire works but without certificate pinning.
Any idea how to solve this and what I am doing wrong?
Thank you.
The String
in your evaluator mapping should only be the host, not a full url:
let evaluators: [String: ServerTrustEvaluating] = [
"myapp.com": PinnedCertificatesTrustEvaluator(certificates: pinnedCertificates()),
]
Also, you need to make sure the host exactly matches the domains you're making requests against.
Additionally, Alamofire will automatically find certificates in your bundle so you may not need to find it yourself.