İOS'ta çalışmak için CRL ve OSCP Denetimi nasıl edinilir?


9

İOS'ta CRL'leri çalıştıramıyorum. İki test vakası oluşturdum. CA tarafından verilen geçerli bir sertifikam var. Geçerli, CA tarafından verilen başka bir sertifika var, ancak CA bu sertifikayı CRL'ye ekledi.

Daha sonra CRL denetimini etkinleştiren ve başarılı olmasını gerektiren bir iptal ilkesi ayarladım.

func crlValidationTest(trustedCert: SecCertificate, certToVerify: SecCertificate) -> Bool {

    let basicPolicy = SecPolicyCreateBasicX509()

    let crlPolicy = SecPolicyCreateRevocation(kSecRevocationOCSPMethod | kSecRevocationCRLMethod | kSecRevocationRequirePositiveResponse)!

    var trust: SecTrust?

    SecTrustCreateWithCertificates(NSArray(object: certToVerify), NSArray(objects: basicPolicy, crlPolicy), &trust)
    SecTrustSetAnchorCertificates(trust!, NSArray(object: trustedCert))
    SecTrustSetNetworkFetchAllowed(trust!, true)

    var trustResult = SecTrustResultType.invalid

    guard SecTrustEvaluate(trust!, &trustResult) == errSecSuccess else {
        return false
    }

    return trustResult == SecTrustResultType.proceed || trustResult == SecTrustResultType.unspecified
}

Beklentim, CRL üzerindeki sertifikaya güvenilmeyecek ve temiz olan sertifikaya güvenilecek.

Yukarıdaki yapılandırma göz önüne alındığında, her ikisi de güvenilmez olarak başarısız olur. kSecRevocationRequirePositiveResponseBayrağı kaldırırsam , ikisi de başarılı olur. Ben sadece OSCP veya sadece CRL kullanarak tüm farklı permütasyonları denedim ve hiçbir şey beklediğim gibi çalışmıyor.

Eyaletler için elma belgeleriSecPolicyCreateRevocation :

Örneğin, belirli bir yöntemi zorlamak veya iptal denetimini tamamen devre dışı bırakmak istemiyorsanız, varsayılan sistem davranışını geçersiz kılmak istemiyorsanız genellikle bir iptal ilkesi oluşturmanız gerekmez.

Yalnızca SecPolicyCreateBasicX509ilkeyi kullanmak her ikisinin de başarılı olmasına izin verir (ikinci sertifika başarısız olduğunda), Apple'ın varsayılan davranışı CRL denetimi yapmamak mıdır?

Ben ekli CharlesProxy cihazıma ve tüm ağ trafiği dinlerken kodu birden çok kez koştu ve hiçbir giden istekleri zaman hiç tüm başarısız açıklıyor CRL gidin RequirePositiveResponsebayrağı kontrol edilir.

Ayrıca URLRequest, a kullanarak doğrudan cihazdan CRL'ye gitmeyi denedim ve herhangi bir sorun olmadan cihazdaki CRL verilerini alabildim.

Apple Güvenlik kitaplığı aracılığıyla CRL denetimi desteklenmiyor mu? Öyleyse, yapılandırmanın doğru yanıt vermesini isteyen var mı? CRL doğrulaması yapmak için kullanılan alternatifler, finans bölgesinde veya diğer hassas alanlarda uğraşan yüksek güvenlikli mobil uygulamaların bu kapsam boşluğuna izin vermeyeceğini varsayıyorum.

GÜNCELLEME Karşılaştırma için,certutil -f -urlfetch -verify MYCERT.cercertutil kullanarakkoştumve Fiddler'ı komutu çalıştıran kutuya ekledim . İOS'un bana vermemesi beklenen sonuçları alıyorum ve kemancı aracılığıyla HTTP aracılığıyla CRL'ye giden bir istek görüyorum.

Buna biraz daha ilgi çekmek için bir ödül yarattım. Birisinin yukarıda neyin yanlış yapıldığına veya bunun neden iOS'ta çalışmadığına ilişkin daha fazla ayrıntıya sahip olmasını umuyorum.

Yanıtlar:


7

Apple platformlarında, istemciler CA'ların Sertifika İptal Listesi'ni (CRL) denetlemez veya varsayılan olarak OCSP kullanmazlar.

Bununla birlikte, Apple platformları OCSP zımbalamayı destekliyor ve alternatif olarak, gerçekten bir OCSP çağrısına yol açabilecek İptal Geliştirme adını verdikleri bir mekanizma sağlıyorlar, aşağıdaki ayrıntılara bakın.

OCSP Zımbalama

İlk önce OCSP zımbalamanın açıklaması:

Çevrimiçi Sertifika Durum Protokolü (OCSP) zımbalama resmen olarak bilinen TLS Sertifika Durum İsteği uzantısı X.509 dijital sertifikaların iptal durumunu denetlemek için bir standarttır. 1 Sertifika sahibinin, ilk TLS anlaşmasına CA tarafından imzalanmış zaman damgalı bir OCSP yanıtı ekleyerek ("zımbalama") Çevrimiçi Sertifika Durum Protokolü (OCSP) yanıtlarının sağlanmasında yer alan kaynak maliyetini karşılayabilmesini sağlar. hem güvenliği hem de performansı artırmak amacıyla müşterilerin CA ile iletişim kurması için.

bkz. https://en.wikipedia.org/wiki/OCSP_stapling

OCSP ve OCSP Zımbalama arasındaki farklar

İstemci geleneksel bir OCSP akışındaki bir sunucuya bağlanır ve sertifikayı alırsa, CA'ya bir istekte bulunarak alınan sertifikanın iptal edilip edilmediğini denetler. Bunun bazı dezavantajları vardır, örneğin ek bir ağ bağlantısı gereklidir, bilgiler şifrelenmez ve bu nedenle veri gizliliği sorununu temsil eder.

OCSP zımbalama yoluyla, sunucu CA'dan imzalı bir iptal bilgisi ister ve bunu TLS el sıkışmasına ekler.

Bu, OCSP zımbalama kullanırken iOS'tan bir CA sunucusuna OCSP isteği görmediğiniz anlamına da gelir.

OCSP Zımbalamasının Dezavantajları

Bağlandığınız sunucunun OCSP zımbalamasını desteklemesi gerekir. Bu ayrıca kötü amaçlı sunuculara karşı da koruma sağlamaz.

Apple'ın bir İptal İyileştirmesi sunmasının ana nedenleri budur.

Apple'ın İptal Geliştirme

Şöyle çalışır:

  • Sertifika şeffaflığı günlükleri girişleri Apple tarafından toplanır
  • Bu bilgi ile Apple CA'lardan gelen iptaller hakkında bilgi toplar
  • bu toplu bilgiler daha sonra otomatik olarak tüm Apple istemcilerine düzenli olarak sunulur
  • bu bilgilere dayanarak, bir iOS uygulaması iptal edilmiş bir sertifika ile sunucuya bağlanmaya çalıştığında, OCSP aracılığıyla ek bir kontrol gerçekleştirir.

gereklilik

Bir uygulamanın bunu desteklemesi için tek gereksinim, kullanılan sunucu sertifikasının bir sertifika şeffaflığı günlüğüne eklenmesidir. Normalde bir CA zaten bunu yapar, ancak etki alanı sertifikasının genel sertifikalar için etkin saydamlık günlüklerinde olup olmadığını, örneğin aşağıdaki bağlantıyı kullanarak kontrol etmelisiniz: https://transparencyreport.google.com/https/certificates

WWDC 2017, oturum 701

Bu konunun ve Apple'ın motiflerinin ayrıntılı olarak açıklandığı mükemmel bir WWDC oturumu var: WWDC 2017, oturum 701: https://developer.apple.com/videos/play/wwdc2017/701/

Bir Apple mühendisi saat 12:10 civarında tüm iptal konusunu ayrıntılı olarak açıklıyor. 15:30 civarında normal OCSP'nin ek API kullanımını gerektireceğini açıklar.

İOS'ta OCSP Zımbalama Testi

Bir test için OCSP zımbalamayı destekleyen ve iptal edilmiş bir sertifika kullanan bir sunucuya ihtiyacımız var: https://revoked.grc.com (bu sunucuyu bu sunucuda buldufaç yanıt: https://serverfault.com/a/645066 )

Ardından, iOS'tan HTML yanıtını indirmeye ve konsola çıktı vermeye çalışan küçük bir test programıyla bağlanmayı deneyebiliriz.

Yukarıda belirtilen WWDC oturumundaki bilgilere dayanarak, bağlantı girişimi başarısız olmalıdır.

...
let session = URLSession(configuration: .default)
...

func onDownloadAction() {
    let url = URL(string: "https://revoked.grc.com")!
    self.download(from: url) { (result, error) in
        if let result = result {
            print("result: " + result)
        } else {
            print("download failed")
            if let error = error {
                print("error: \(error)")
            }
        }
    }
}


func download(from url: URL, completion: @escaping(String?, Error?)->Void) {
    let dataTask = self.session.dataTask(with: url) { data, response, error in
        guard let data = data else {
            if let error = error {
                completion(nil, error)
                return
            }
            completion(nil, NSError(domain: "DownloadFailure", code: 0, userInfo:nil))
            return
        }

        guard let response = response as? HTTPURLResponse else {
            completion(nil, NSError(domain: "ResponseFailure", code: 0, userInfo:nil))
            return
        }
        print("http status: \(response.statusCode)")
        let res = String(bytes: data, encoding: .utf8)
        completion(res, nil)
    }
    dataTask.resume()
}

İOS Simülatöründe yukarıdaki rutini yürütürsek, CA tarafından imzalanan zaman damgalı OCSP yanıtının TLS el sıkışmasına zımbalanıp zımbalanmadığını kontrol etmek için Wireshark'ı kullanabiliriz.

İle nslookup revoked.grc.combiz sunucusunun IP adresini almak ve birlikte Wireshark filtreleme yapabilirsiniz ip.addr==4.79.142.205.

Ekran görüntüsünde sertifikanın durumu olduğunu görebilirsiniz revoked.

wireshark

Yani Xcodes konsoluna bir göz atarak aşağıdaki çıktıyı görebilirsiniz:

2019-10-12 21:32:25.734382+0200 OCSPTests[6701:156558] ATS failed system trust
2019-10-12 21:32:25.734526+0200 OCSPTests[6701:156558] Connection 1: system TLS Trust evaluation failed(-9802)
2019-10-12 21:32:25.734701+0200 OCSPTests[6701:156558] Connection 1: TLS Trust encountered error 3:-9802
2019-10-12 21:32:25.734787+0200 OCSPTests[6701:156558] Connection 1: encountered error(3:-9802)
2019-10-12 21:32:25.737672+0200 OCSPTests[6701:156558] Task <12408947-689F-4537-9642-C8F95E86CA62>.<1> HTTP load failed, 0/0 bytes (error code: -1200 [3:-9802])
download failed
error: Error Domain=NSURLErrorDomain Code=-1200 "An SSL error has occurred and a secure connection to the server cannot be made." UserInfo={NSURLErrorFailingURLPeerTrustErrorKey=<SecTrustRef: 0x6000037f8510>, NSLocalizedRecoverySuggestion=Would you like to connect to the server anyway?, _kCFStreamErrorDomainKey=3, _kCFStreamErrorCodeKey=-9802, NSErrorPeerCertificateChainKey=(
    "<cert(0x7fda78828200) s: revoked.grc.com i: DigiCert SHA2 Secure Server CA>",
    "<cert(0x7fda7882b200) s: DigiCert SHA2 Secure Server CA i: DigiCert Global Root CA>"
), NSUnderlyingError=0x600000be9170 {Error Domain=kCFErrorDomainCFNetwork Code=-1200 "(null)" UserInfo={_kCFStreamPropertySSLClientCertificateState=0, kCFStreamPropertySSLPeerTrust=<SecTrustRef: 0x6000037f8510>, _kCFNetworkCFStreamSSLErrorOriginalValue=-9802, _kCFStreamErrorDomainKey=3, _kCFStreamErrorCodeKey=-9802, kCFStreamPropertySSLPeerCertificates=(
    "<cert(0x7fda78828200) s: revoked.grc.com i: DigiCert SHA2 Secure Server CA>",
    "<cert(0x7fda7882b200) s: DigiCert SHA2 Secure Server CA i: DigiCert Global Root CA>"
)}}, NSLocalizedDescription=An SSL error has occurred and a secure connection to the server cannot be made., NSErrorFailingURLKey=https://revoked.grc.com/, NSErrorFailingURLStringKey=https://revoked.grc.com/, NSErrorClientCertificateStateKey=0}

iOS, sunucuya TLS hatasıyla bağlanma girişimini iptal eder.

Test revoked.badssl.com

revoked.badssl.com OCSP zımbalamayı desteklemez.

Biz belgesi detaylara bir göz atacak olursak https://revoked.badssl.com , biz öğrenebilirsiniz:

Biri .crl dosyasını (2.5MB) indirir ve bir

openssl crl -inform DER -text -in ssca-sha2-g6.crl | grep 0371B58A86F6CE9C3ECB7BF42F9208FC

bu sertifikanın CRL ile iptal edildiğini görebilirsiniz.

İlginç bir şekilde, ne Safari ne de Chrome veya iOS bu iptal edilmiş durumu tanımıyor. Yalnızca Mozilla Firefox bir hata mesajı görüntüler ( Eş Sertifikası iptal edildi. Hata kodu: SEC_ERROR_REVOKED_CERTIFICATE ).

Bunun nedeni, sertifikanın yalnızca birkaç gün önce yenilenmiş olması ve bu nedenle tarayıcı ve işletim sistemlerinin tüm yerel iptal listelerine henüz girmemiş olması olabilir.


Burada harika bilgiler var. Düşünceli cevap için teşekkürler. Sizinle aynı şekilde gördüğüm bu konuyu araştırmaya devam ederken, CRL desteği büyük tarayıcılar / işletim sistemleri tarafından bırakılıyor ve OCSP zımbalama önerilen yeni güvenlik mekanizması gibi görünüyor. WWDC videosunda Apple temsilcisi şunları söylüyor: "Ne yazık ki platformlarımız şu anda varsayılan olarak iptal işlemini kontrol ETMİYOR". Deneylerim aracılığıyla bulduğum şey, varsayılan olarak desteklenmediği, aynı zamanda hiç desteklenmediği (ayarları zorlansanız bile) @Stephan Schlecht
Unome
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.