Meu cliente SSL (Java) não está enviando um certificado de volta ao servidor em handshake SSL bidirecional
Em um aplicativo Java 1.7 em execução no Windows 7, estou tentando fazer SSL bidirecional com um servidor (um token de smartcard está fornecendo certificações do meu cliente via openSC). O certificado do servidor está sendo verificado pelo cliente, mas o cliente não responde à solicitação de certificado do servidor. Eu acredito que é porque o cliente não é capaz de fazer uma cadeia do meu certificado para um dos pedidos pelo servidor (mesmo que tal cadeia exista).
Aqui está a depuração SSL da Solicitação de Certificado do servidor e a resposta vazia dos clientes:
*** CertificateRequest
Cert Types: RSA, DSS, ECDSA
Cert Authorities:
<CN=c4isuite-SDNI-DC02-CA, DC=c4isuite, DC=local>
<CN=DoD Root CA 2, OU=PKI, OU=DoD, O=U.S. Government, C=US>
...
*** ServerHelloDone
*** Certificate chain
***
Meu certificado de cliente é o seguinte:
found key for : Certificate for PIV Authentication
chain [0] = [
[
Version: V3
Subject: CN=<...>, OU=CONTRACTOR, OU=PKI, OU=DoD, O=U.S. Government, C=US
Signature Algorithm: SHA1withRSA, OID = 1.2.840.113549.1.1.5
Key: Sun RSA public key, 2048 bits
Issuer: CN=DOD CA-30, OU=PKI, OU=DoD, O=U.S. Government, C=US
SerialNumber: [ 05bf13]
Através da ferramenta-chave, eu também instalei no armazenamento confiável (arquivo java cacerts), qual deve ser o link entre o emissor do meu cert, DOD CA-30 e o que o servidor está solicitando, DoD Root CA 2.
De depuração SSL:
adding as trusted cert:
Subject: CN=DOD CA-30, OU=PKI, OU=DoD, O=U.S. Government, C=US
Issuer: CN=DoD Root CA 2, OU=PKI, OU=DoD, O=U.S. Government, C=US
Algorithm: RSA; Serial number: 0x1b5
Valid from Thu Sep 08 10:59:24 CDT 2011 until Fri Sep 08 10:59:24 CDT 2017
adding as trusted cert:
Subject: CN=DoD Root CA 2, OU=PKI, OU=DoD, O=U.S. Government, C=US
Issuer: CN=DoD Root CA 2, OU=PKI, OU=DoD, O=U.S. Government, C=US
Algorithm: RSA; Serial number: 0x5
Valid from Mon Dec 13 09:00:10 CST 2004 until Wed Dec 05 09:00:10 CST 2029
Então a questão é: por que o cliente não pode fazer a cadeia de certificados para a resposta? Aqui está o código relevante:
// Create the keyStore from the SmartCard certs
Provider provider = new sun.security.pkcs11.SunPKCS11(configName);
Security.addProvider(provider);
keyStore = KeyStore.getInstance("PKCS11", "SunPKCS11-SCR3310test");
char[] pin = PIN.toCharArray();
keyStore.load(null, pin);
// Init the trustmanager
TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
tmf.init(trustStore);
// Create the client key manager
LOG.info("Installing keystore with pin");
KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance("SunX509");
keyManagerFactory.init(clientKeyStore, clientKeyPassword.toCharArray());
sslContext.init(keyManagerFactory.getKeyManagers(), tmf.getTrustManagers(), null);
// Init SSL context
SSLSocketFactory socketFactory = sslContext.getSocketFactory();
URL url = new URL(urlString);
URLConnection connection = url.openConnection();
if (connection instanceof HttpsURLConnection) {
LOG.info("Connection is HTTPS");
((HttpsURLConnection) connection).setSSLSocketFactory(socketFactory);
}
// Send the request.
connection.connect();
InputStreamReader in = new InputStreamReader((InputStream) connection.getContent());
...
E o erro que recebo é que o servidor retorna um 403. Muito provavelmente porque o cliente não enviou um certificado de cliente.