Como você descobriu, é possível desativar a verificação do certificado no nível do handshake SSL / TLS no Apache Httpd usando SSLVerifyCLient optional_no_ca
.
O segundo problema que você vai enfrentar com o que 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, ele pode ser autoassinado e ter vários emissores.
Ao solicitar um certificado de cliente, o servidor envia uma CertificateRequest
mensagem TLS ao cliente durante o handhsake. Esta mensagem contém a certificate_authorities
lista:
Uma lista dos nomes distintos das autoridades de certificação aceitáveis. Esses nomes distintos podem especificar um nome distinto desejado para uma autoridade de certificação raiz ou para uma autoridade de certificação subordinada; portanto, essa mensagem pode ser usada para descrever as raízes conhecidas e um espaço de autorização desejado. Se a lista certificate_authorities estiver vazia, o cliente PODE enviar qualquer certificado do ClientCertificateType apropriado, a menos que haja algum acordo externo em contrário.
Os navegadores usam isso para escolher qual certificado de cliente enviar (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 omissos e, na prática, também funcionará.)
Você tem duas opções para isso.
Se os certificados de cliente que você espera serão autoassinados, todos terão emissores diferentes. Como você não sabe o que esperar, o servidor precisará enviar uma lista vazia. Para fazer isso, use a SSLCADNRequestFile
diretiva e aponte-a para um arquivo que contenha apenas uma linha vazia (se bem me lembro, ela não funciona com um arquivo completamente vazio).
A segunda opção (menos limpa). É concordar com um DN de emissor comum a todos os certificados de cliente que você espera, independentemente de eles terem sido realmente emitidos por esse certificado de CA (ou se essa CA existe ou não). Ao fazer isso, você quebraria o modelo de PKI consideravelmente (mais).
Se você concorda com um DN do emissor como CN=Dummy CA
(por exemplo). Qualquer pessoa pode criar um certificado autoassinado usando CN=Dummy CA
como DN do Assunto (e DN do emissor), possivelmente com chaves diferentes. Embora a SSLCADNRequestFile
diretiva espere ser configurada com certificados para criar 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 a certificate_authorities
lista. Se você, como serviço, colocar um certificado autoassinado com esses nomes SSLCADNRequestFile
, isso fará com que a CertificateRequest
mensagem TLS seja usada CN=Dummy CA
na certificate_authorities
lista (estes são apenas nomes, não certs neste estágio). O cliente poderá então pegar seu próprio certificado com o DN do emissorCN=Dummy CA
, se sua assinatura pode ou não ser verificada por esse certificado (mesmas chaves) ou não, pois nenhuma verificação de assinatura está envolvida nessas etapas.
Dito isto, lembre-se de que SSLVerifyCLient optional_no_ca
, com , nenhuma verificação real do certificado é feita (suponho que você possa verificar a SSL_CLIENT_VERIFY
variável se a verificação manual for apenas uma solução de fallback para uma PKI que você configurou de qualquer maneira). Tudo o que você saberá nesse estágio é que o cliente possui a chave privada para o certificado de chave pública que ele apresentou (garantido pela CertificateVerify
mensagem TLS ): você precisará executar alguma forma de verificação se desejar que haja autenticação de alguns ordenar. (Você não pode confiar em nenhum conteúdo do certificado, que é uma ligação entre sua chave pública e os nomes / atributos que ela contém.)
Isso não funcionará bem para arquivos, mas você pode fazer isso para um aplicativo (por exemplo, PHP / CGI / ... até Java, se você passar o certificado para o servidor Java em proxy). Uma maneira básica seria ter uma lista pré-conhecida de chaves públicas, ou você poderia examinar as idéias em FOAF + SSL / WebID .