Como você descobriu, é possível desativar a verificação de certificado no nível de handshake SSL / TLS no Apache Httpd usando SSLVerifyCLient optional_no_ca
.
O segundo problema que você vai enfrentar com o que você está tentando fazer é fazer com que o cliente envie o certificado. Como o seu certificado não se destina a estar dentro de uma PKI, eles podem ser auto-assinados e ter vários emissores.
Ao solicitar um certificado de cliente, o servidor envia uma % mensagem% TLS para o cliente durante o handhsake. Esta mensagem contém a lista CertificateRequest
:
A list of the distinguished names of acceptable certificate authorities. These distinguished names may specify a desired distinguished name for a root CA or for a subordinate CA; thus, this message can be used to describe both known roots and a desired authorization space. If the certificate_authorities list is empty then the client MAY send any certificate of the appropriate ClientCertificateType, unless there is some external arrangement to the contrary.
Os navegadores usam isso para escolher qual certificado de cliente deve ser enviado (se houver).
(Observe que a parte sobre a lista vazia está apenas na especificação do TLS 1.1 em diante. O SSL 3.0 e o TLS 1.0 são silenciosos sobre isso e, na prática, ele também funcionará.)
Você tem duas opções para isso.
-
Se os certificados do cliente que você espera serão autoassinados, todos eles terão emissores diferentes. Como você não sabe o que esperar, o servidor precisará enviar uma lista vazia. Para fazer isso, use a
certificate_authorities
diretiva e aponte-a para um arquivo que contenha apenas uma linha vazia (se bem me lembro, não funciona com um arquivo completamente vazio). -
A segunda opção (menos limpa). É concordar com um DN do Emissor comum a todos os certificados de cliente que você espera, independentemente de terem ou não sido emitidos por esse certificado de autoridade de certificação (ou se essa CA existe ou não). Ao fazer isso, você estaria quebrando o modelo PKI consideravelmente (mais).
Se você concordar com um DN do Emissor, como
SSLCADNRequestFile
(por exemplo). Qualquer pessoa pode criar um certificado auto-assinado usandoCN=Dummy CA
como Assunto DN (e DN do Emissor), possivelmente com chaves diferentes. Embora a diretivaCN=Dummy CA
espere ser configurada com certificados para construir a lista, eles não são usados para verificar o certificado do cliente, é apenas uma maneira complicada (mas natural no contexto das outras diretivas) de configurar oSSLCADNRequestFile
list. Se você, como um serviço, colocar um certificado autoassinado com esses nomes emcertificate_authorities
, isso fará com que a mensagemSSLCADNRequestFile
TLS useCertificateRequest
na listaCN=Dummy CA
(esses são apenas nomes, não certs neste palco). O cliente poderá então obter seu próprio certificado com o Emissor DNcertificate_authorities
, independentemente de sua assinatura poder ou não ser verificada por esse certificado (mesmas chaves) ou não, já que nenhuma verificação de assinatura está envolvida nessas etapas.
CN=Dummy CA
, nenhuma verificação de certificado real é feita (suponho que você poderia verificar a variável SSLVerifyCLient optional_no_ca
se sua verificação manual é apenas uma solução alternativa para uma PKI que você configurou).
Tudo o que você saberá nesse estágio é que o cliente tem a chave privada para o certificado de chave pública que ele apresentou (garantido pela mensagem TLS SSL_CLIENT_VERIFY
): você precisará executar alguma forma de verificação se quiser que haja autenticação de algum tipo. (Você não pode confiar em nenhum conteúdo do certificado, isto é, qualquer ligação entre sua chave pública e os nomes / atributos que contém.)
Isso não funciona bem para arquivos, mas você pode fazer isso para um aplicativo (por exemplo, PHP / CGI / ... mesmo Java, se passar o certificado para o servidor Java com proxy). Uma forma básica seria ter uma lista pré-conhecida de chaves públicas, ou você poderia ver as ideias em FOAF + SSL / WebID .