Wie funktioniert CRL und OSCP Checking unter iOS?

9

Ich kann CRLs unter iOS nicht zum Laufen bringen. Ich habe zwei Testfälle erstellt. Ich habe ein gültiges Zertifikat, das von einer Zertifizierungsstelle ausgestellt wurde. Ich habe ein anderes gültiges Zertifikat, das von einer Zertifizierungsstelle ausgestellt wurde, aber die Zertifizierungsstelle hat dieses Zertifikat zu ihrer CRL hinzugefügt.

Ich habe dann eine Sperrrichtlinie eingerichtet, die die CRL-Prüfung aktiviert und deren Erfolg voraussetzt.

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
}

Ich gehe davon aus, dass das Zertifikat in der CRL nicht vertrauenswürdig ist und dem sauberen Zertifikat vertraut wird.

In Anbetracht der obigen Konfiguration schlagen beide als nicht vertrauenswürdig fehl. Wenn ich die kSecRevocationRequirePositiveResponseFlagge entferne , sind beide erfolgreich. Ich habe all die verschiedenen Permutationen ausprobiert, nur OSCP oder nur CRL zu verwenden, und nichts funktioniert so, wie ich es erwarten würde.

Apples Dokumentation für SecPolicyCreateRevocationStaaten:

Es ist normalerweise nicht erforderlich, eine Sperrrichtlinie selbst zu erstellen, es sei denn, Sie möchten das Standardsystemverhalten überschreiben, z. B. um eine bestimmte Methode zu erzwingen oder die Sperrprüfung vollständig zu deaktivieren.

Wenn Sie nur die SecPolicyCreateBasicX509Richtlinie verwenden, können beide erfolgreich sein (wenn das zweite Zertifikat fehlschlagen sollte). Ist es also das Standardverhalten von Apple, überhaupt keine CRL-Prüfung durchzuführen?

Ich habe CharlesProxy an mein Gerät angeschlossen und den Code mehrmals ausgeführt, während ich den gesamten Netzwerkverkehr abgehört habe. Es gehen nie ausgehende Anforderungen an die CRL. Dies erklärt, warum alle fehlschlagen, wenn das RequirePositiveResponseFlag aktiviert ist.

Ich habe auch versucht, mit a direkt vom Gerät zur CRL zu navigieren URLRequest, und konnte die CRL-Daten ohne Probleme auf dem Gerät abrufen.

Wird die CRL-Prüfung über die Apple Security Library nicht unterstützt? Wenn ja, hat jemand die Konfiguration herausgefunden, damit sie richtig reagiert? Ich gehe davon aus, welche hochsicheren mobilen Anwendungen für die CRL-Validierung verwendet werden. Ich gehe davon aus, dass mobile Hochsicherheitsanwendungen, die im Finanzviertel oder in anderen sensiblen Bereichen eingesetzt werden, diese Versorgungslücke nicht zulassen.

UPDATE Zum Vergleich habe ichcertutil -f -urlfetch -verify MYCERT.cercertutil ausgeführt und Fiddler an die Boxangehängt,in der der Befehl ausgeführt wird. Ich erhalte die erwarteten Ergebnisse, die iOS mir nicht liefert, und ich sehe eine ausgehende Anfrage an die CRL über HTTP über Fiddler.

Ich habe ein Kopfgeld geschaffen, um mehr Interesse daran zu wecken. Ich hoffe, jemand hat mehr Details darüber, was oben falsch gemacht wurde oder warum dies unter iOS nicht funktioniert.

Unome
quelle

Antworten:

7

Auf Apple-Plattformen überprüfen Clients weder die Zertifikatsperrliste (Certificate Revocation List, CRL) von Zertifizierungsstellen, noch verwenden sie standardmäßig OCSP.

Apple-Plattformen unterstützen jedoch das OCSP-Heften und bieten alternativ einen Mechanismus, den sie als Revocation Enhancement bezeichnen, der tatsächlich zu einem OCSP-Aufruf führen kann (siehe Details unten).

OCSP-Heften

Zunächst eine Erklärung der OCSP-Heftung:

Das OCSP-Heften (Online Certificate Status Protocol) , das früher als TLS Certificate Status Request- Erweiterung bezeichnet wurde, ist ein Standard zum Überprüfen des Sperrstatus von digitalen X.509-Zertifikaten. 1 Der Präsentator eines Zertifikats kann die Ressourcenkosten tragen, die mit der Bereitstellung von OCSP-Antworten (Online Certificate Status Protocol) verbunden sind, indem eine von der Zertifizierungsstelle signierte OCSP-Antwort mit Zeitstempel an den ersten TLS-Handshake angehängt ("geheftet") wird, wodurch die Notwendigkeit entfällt Kunden können sich an die Zertifizierungsstelle wenden, um sowohl die Sicherheit als auch die Leistung zu verbessern.

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

Unterschiede zwischen OCSP- und OCSP-Heftung

Wenn ein Client in einem herkömmlichen OCSP-Ablauf eine Verbindung zu einem Server herstellt und das Zertifikat abruft, prüft er, ob das empfangene Zertifikat widerrufen wurde, indem er eine Anforderung an die Zertifizierungsstelle sendet. Dies hat einige Nachteile, zum Beispiel ist eine zusätzliche Netzwerkverbindung erforderlich, die Informationen sind unverschlüsselt und stellen daher ein Datenschutzproblem dar.

Durch OCSP-Heften fordert der Server von der Zertifizierungsstelle signierte Sperrinformationen an und fügt diese dem TLS-Handshake hinzu.

Dies bedeutet auch, dass bei Verwendung der OCSP-Heftung keine OCSP-Anforderung von iOS an einen CA-Server angezeigt wird.

Nachteile der OCSP-Heftung

Der Server, zu dem Sie eine Verbindung herstellen, muss das OCSP-Heften unterstützen. Dies schützt auch nicht vor böswilligen Servern.

Dies sind die Hauptgründe, warum Apple eine Widerrufsverbesserung anbietet.

Apples Widerrufsverbesserung

So funktioniert das:

  • Einträge für Zertifikatstransparenzprotokolle werden von Apple gesammelt
  • Mit diesen Informationen sammelt Apple Informationen zu Widerrufen von den Zertifizierungsstellen
  • Diese aggregierten Informationen werden dann automatisch regelmäßig allen Apple-Clients zur Verfügung gestellt
  • Basierend auf diesen Informationen führt eine iOS-App beim Versuch, mit einem widerrufenen Zertifikat eine Verbindung zum Server herzustellen, eine zusätzliche Überprüfung über OCSP durch.

Anforderung

Die einzige Voraussetzung für eine App, die dies unterstützt, ist, dass das verwendete Serverzertifikat einem Zertifikatstransparenzprotokoll hinzugefügt wird. Normalerweise macht eine Zertifizierungsstelle dies bereits, aber Sie sollten überprüfen, ob sich das Domänenzertifikat in den aktiven Transparenzprotokollen für öffentliche Zertifikate befindet, z. B. über den folgenden Link: https://transparencyreport.google.com/https/certificates

WWDC 2017, Sitzung 701

Es gibt eine ausgezeichnete WWDC-Sitzung, in der dieses Thema und Apples Motive ausführlich erläutert werden: WWDC 2017, Sitzung 701: https://developer.apple.com/videos/play/wwdc2017/701/

Gegen Minute 12:10 erklärt ein Apple-Ingenieur das gesamte Widerrufsthema im Detail. Gegen 15:30 Uhr erklärt sie, dass für normales OCSP zusätzliche APIs erforderlich wären.

Test der OCSP-Heftung unter iOS

Für einen Test benötigen wir einen Server, der OCSP-Heften unterstützt und ein widerrufenes Zertifikat verwendet: https://revoked.grc.com (diesen Server in dieser Serverfehlerantwort gefunden: https://serverfault.com/a/645066 )

Dann können wir versuchen, eine Verbindung von iOS mit einem kleinen Testprogramm herzustellen, das versucht, die HTML-Antwort herunterzuladen und an die Konsole auszugeben.

Basierend auf den Informationen aus der oben erwähnten WWDC-Sitzung sollte der Verbindungsversuch fehlschlagen.

...
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()
}

Wenn wir die obige Routine im iOS-Simulator ausführen, können wir mit Wireshark prüfen, ob eine von der Zertifizierungsstelle signierte OCSP-Antwort mit Zeitstempel an den TLS-Handshake geheftet ist.

Mit nslookup revoked.grc.combekommen wir die IP-Adresse des Servers und können in Wireshark mit filtern ip.addr==4.79.142.205.

Auf dem Screenshot sieht man, dass das Zertifikat den Status hat revoked.

Wireshark

Wenn Sie also einen Blick in die Xcodes-Konsole werfen, sehen Sie die folgende Ausgabe:

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 bricht den Versuch ab, eine Verbindung zum Server mit einem TLS-Fehler herzustellen.

Test revoked.badssl.com

revoked.badssl.com unterstützt kein OCSP-Heften.

Wenn wir uns die Zertifikatdetails von https://revoked.badssl.com ansehen , können wir Folgendes herausfinden:

Wenn man die CRL-Datei (2,5 MB) herunterlädt und a ausgibt

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

man kann sehen, dass dieses Zertifikat über CRL widerrufen wird.

Interessanterweise erkennen weder Safari noch Chrome oder iOS diesen widerrufenen Status. Nur Mozilla Firefox zeigt eine Fehlermeldung an ( Peer-Zertifikat wurde widerrufen. Fehlercode: SEC_ERROR_REVOKED_CERTIFICATE ).

Der Grund könnte sein, dass das Zertifikat erst vor wenigen Tagen erneuert wurde und daher noch nicht in alle lokalen Widerrufslisten von Browsern und Betriebssystemen Eingang gefunden hat.

Stephan Schlecht
quelle
Tolle Informationen hier. Danke für die nachdenkliche Antwort. Während ich mich weiter mit diesem Thema befasst habe, habe ich das gleiche wie Sie gesehen. Die CRL-Unterstützung wird von den wichtigsten Browsern / Betriebssystemen eingestellt, und das OCSP-Heften scheint der neue empfohlene Sicherheitsmechanismus zu sein. Im WWDC-Video erklärt der Apple-Vertreter: "Leider überprüfen unsere Plattformen derzeit NICHT standardmäßig den Widerruf." Was ich durch meine Experimente herausgefunden habe, ist, dass es nicht nur nicht standardmäßig unterstützt wird, sondern überhaupt nicht unterstützt wird (selbst wenn Sie die Einstellungen erzwingen) @Stephan Schlecht
Unome