Nas plataformas da Apple, os clientes não verificam a lista de revogação de certificados (CRL) das CAs, nem usam o OCSP por padrão.
As plataformas da Apple, no entanto, oferecem suporte ao grampeamento OCSP e, alternativamente, fornecem um mecanismo que eles chamam de aprimoramento de revogação, que poderia realmente levar a uma chamada OCSP, veja os detalhes abaixo.
Grampeamento OCSP
Primeiro, uma explicação do grampeamento OCSP:
O grampeamento do Online Certificate Status Protocol (OCSP) , formalmente conhecido como extensão TLS Certificate Status Request , é um padrão para verificar o status de revogação dos certificados digitais X.509. 1 Ele permite que o apresentador de um certificado arque com o custo do recurso envolvido no fornecimento de respostas do Protocolo de status do certificado on-line (OCSP) anexando ("grampeando") uma resposta OCSP com carimbo de data e hora assinada pela CA no handshake TLS inicial, eliminando a necessidade para que os clientes entrem em contato com a CA, com o objetivo de melhorar a segurança e o desempenho.
consulte https://en.wikipedia.org/wiki/OCSP_stapling
Diferenças entre o OCSP e o grampeamento OCSP
Se um cliente se conectar a um servidor em um fluxo OCSP tradicional e recuperar o certificado, ele verificará se o certificado recebido foi revogado fazendo uma solicitação à CA. Isso tem algumas desvantagens, por exemplo, é necessária uma conexão de rede adicional, as informações não são criptografadas e, portanto, representam um problema de privacidade de dados.
Por meio do grampeamento OCSP, o servidor solicita informações de revogação assinadas da CA e as adiciona ao handshake TLS.
Isso também significa que, ao usar o grampeamento OCSP, você não vê uma solicitação OCSP do iOS para um servidor da CA.
Desvantagens do grampeamento OCSP
O servidor ao qual você está se conectando deve suportar o grampeamento OCSP. Isso também não protege contra servidores maliciosos.
Essa é a principal razão pela qual a Apple está fornecendo um aprimoramento de revogação.
Aprimoramento de revogação da Apple
Veja como funciona:
- registros de transparência de certificados são coletados pela Apple
- com essas informações, a Apple reúne informações sobre revogações das autoridades de certificação
- essas informações agregadas são automaticamente disponibilizadas a todos os clientes da Apple regularmente
- com base nessas informações, quando um aplicativo iOS tenta se conectar ao servidor com um certificado revogado, ele executa uma verificação adicional via OCSP.
Requerimento
O único requisito para um aplicativo suportar isso é que o certificado do servidor usado seja adicionado a um log de transparência do certificado. Normalmente, uma CA já faz isso, mas você deve verificar se o certificado de domínio está nos registros de transparência ativos de certificados públicos, por exemplo, usando o seguinte link: https://transparencyreport.google.com/https/certificates
WWDC 2017, sessão 701
Há uma excelente sessão da WWDC na qual este tópico e os motivos da Apple são explicados em detalhes: WWDC 2017, sessão 701: https://developer.apple.com/videos/play/wwdc2017/701/
Por volta das 12h10, um engenheiro da Apple explica todo o tópico da revogação em detalhes. Por volta das 15:30, ela explica que o OCSP normal exigiria o uso de APIs adicionais.
Teste de grampeamento OCSP no iOS
Para um teste, precisamos de um servidor que suporte o grampeamento OCSP e use um certificado revogado: https://revoked.grc.com
(encontrou este servidor nesta resposta de falha do servidor: https://serverfault.com/a/645066 )
Em seguida, podemos tentar conectar-se a partir do iOS com um pequeno programa de teste que tenta baixar a resposta HTML e enviá-la para o console.
Com base nas informações da sessão WWDC mencionada acima, a tentativa de conexão deve falhar.
...
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()
}
Se executarmos a rotina acima no iOS Simulator, poderemos usar o Wireshark para verificar se uma resposta OCSP com registro de data e hora assinada pela CA é grampeada para o handshake TLS.
Com nslookup revoked.grc.com
obtemos o endereço IP do servidor e podemos filtrar no Wireshark com ip.addr==4.79.142.205
.
Na captura de tela, é possível ver que o certificado possui o status revoked
.
Então, olhando para o console Xcodes, podemos ver a seguinte saída:
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}
O iOS interrompe a tentativa de conectar-se ao servidor com um erro TLS.
Teste revoked.badssl.com
revoked.badssl.com não suporta grampeamento OCSP.
Se dermos uma olhada nos detalhes do certificado em https://revoked.badssl.com , podemos descobrir:
Se você baixar o arquivo .crl (2,5 MB) e emitir um
openssl crl -inform DER -text -in ssca-sha2-g6.crl | grep 0371B58A86F6CE9C3ECB7BF42F9208FC
pode-se ver que este certificado é revogado via CRL.
Curiosamente, nem o Safari, nem o Chrome, nem o iOS reconhecem esse status revogado. Somente o Mozilla Firefox exibe uma mensagem de erro ( o certificado do parceiro foi revogado. Código do erro: SEC_ERROR_REVOKED_CERTIFICATE ).
O motivo pode ser que o certificado foi renovado há apenas alguns dias e, portanto, ainda não foi encontrado em todas as listas locais de revogação de navegadores e sistemas operacionais.