Skip to content

Instantly share code, notes, and snippets.

@mstyura
Created March 11, 2022 11:16
Show Gist options
  • Save mstyura/566a053f7535948b5a3e6bfedfe6e56b to your computer and use it in GitHub Desktop.
Save mstyura/566a053f7535948b5a3e6bfedfe6e56b to your computer and use it in GitHub Desktop.
WebRTC custom SSL certificate verifier.
//
// RTCSSLCertificateVerifier.swift
//
import Foundation
import WebRTC
import Security
final class CertificateVerifier: NSObject, RTCSSLCertificateVerifier {
private let policies: [SecPolicy] = {
var policies = [SecPolicyCreateBasicX509()]
if let revocationPolicy = SecPolicyCreateRevocation(kSecRevocationUseAnyAvailableMethod | kSecRevocationRequirePositiveResponse) {
policies.append(revocationPolicy)
}
return policies
}()
func verify(_ certificate: Data) -> Bool {
certificate.withUnsafeBytes { bytes in
guard let memory = bytes.bindMemory(to: UInt8.self).baseAddress else {
print("Unable to bind memory")
return false
}
guard let data = CFDataCreateWithBytesNoCopy(nil, memory, certificate.count, kCFAllocatorNull) else {
print("Unable to copy certificate data")
return false
}
guard let certificate = SecCertificateCreateWithData(kCFAllocatorDefault, data) else {
print("Unable to create certificate from DER data")
return false
}
var status: OSStatus
var trust: SecTrust?
status = SecTrustCreateWithCertificates([certificate] as CFArray, policies as CFArray, &trust)
guard status == errSecSuccess else {
print("Unable to create trust: \(status)")
return false
}
guard let trust = trust else {
print("Created trust is empty")
return false
}
status = SecTrustSetNetworkFetchAllowed(trust, true)
guard status == errSecSuccess else {
print("Unable to update trust to allow network fetch: \(status)")
return false
}
var error: CFError?
guard SecTrustEvaluateWithError(trust, &error) else {
print("Untrusted certificate: \(unwrapping: error)")
return false
}
return true
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment