En una aplicación Java 1.7 que se ejecuta en Windows 7, intento hacer un SSL bidireccional con un servidor (un token de tarjeta inteligente proporciona certificados de mi cliente a través de openSC). El cliente verifica que el certificado del servidor está bien, pero el cliente no responde a la solicitud de certificado del servidor. Creo que es porque el cliente no puede hacer una cadena desde mi certificado a una de las solicitadas por el servidor (incluso si existe una cadena).Mi cliente SSL (Java) no está enviando un certificado de vuelta al servidor en el protocolo de enlace SSL bidireccional
Aquí está la depuración de SSL de solicitud de certificado del servidor y el cliente respuesta vacía:
*** 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
***
Mi certificado de cliente es el siguiente:
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]
Via-herramienta clave, también instalado en el truststore (archivo java cacerts), cuál debería ser el vínculo entre el emisor de mi cert, DOD CA-30, y lo que el servidor está solicitando, DoD Root CA 2.
De depuración de 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
Entonces la pregunta es, ¿por qué el cliente no puede hacer la cadena de certificados para la respuesta? Aquí está el código correspondiente:
// 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());
...
Y el error que consigo de vuelta es que el servidor devuelve un 403. Lo más probable porque el cliente no envió un certificado de cliente.
Gracias por indicarme directamente al cliente que no utiliza el depósito de confianza para encontrar la cadena de certificados completa. Como el certificado proviene de una SmartCard, es difícil o imposible modificar el certificado. Me las arreglé para evitarlo de otra manera, que detallo a continuación como la respuesta, provista para que cualquier otra persona en la misma situación pueda tener una respuesta. – PaulP