Quiero obtener datos de un servidor que acepte solo la autenticación del cliente mediante una tarjeta inteligente y los guarde en mi servidor. Dado que son muchos datos, quiero crear una conexión entre mi servidor y este servidor de terceros, pero necesito el certificado del usuario en la tarjeta inteligente. Es imposible para mí extraer la clave privada de la tarjeta inteligente, por supuesto, así que no sé si esto es posible o no.
He habilitado en mi servidor Apache la autenticación del cliente de esta manera:
SSLVerifyClient require
SSLVerifyDepth 4
SSLProtocol +TLSv1.1 +TLSv1.2
SSLOptions +ExportCertData +StdEnvVars
SSLCACertificateFile /usr/share/ca-certificates/ca-bundle.crt
Después de que el usuario inserte el PIN, con mi script PHP puedo obtener el certificado de esta manera:
$_SERVER["SSL_CLIENT_CERT"];
Finalmente, trato de usar este certificado para firmar la solicitud a través de php cURL de esta manera:
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => "https://ext.processotelematico.giustizia.it/pda/pycons/GLMV/JPW_SICID",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_SSL_VERIFYPEER => true,
CURLOPT_SSLCERT => $certificate,
CURLOPT_POSTFIELDS => "<soapenv:Envelope xmlns:soapenv='http://schemas.xmlsoap.org/soap/envelope/'>\r\n <soapenv:Header>\r\n <ws:InvocationDomain name=\"JPW\" role=\"AVV\" group=\"9876\" soapenv:mustUnderstand=\"1\" soapenv:actor=\"http://schemas.xmlsoap.org/soap/actor/next\" xmlns:ws=\"http://www.netserv.it/anag/security\" />\r\n </soapenv:Header>\r\n <soapenv:Body>\r\n <sicc:execute xmlns:sicc=\"urn:CONS-ANONIMA-SICC-BE\">\r\n <sicc:name>RicercaRuoloGenerale</sicc:name>\r\n <sicc:valueSet>\r\n <sicc:value name='idUfficio' type='string'>9876</sicc:value>\r\n <sicc:value name='numero' type='integer'>1</sicc:value>\r\n <sicc:value name='anno' type='string'>2017</sicc:value>\r\n </sicc:valueSet>\r\n <sicc:orderBy>\r\n <sicc:entry mode='asc' property='IDFASCICOLO' />\r\n </sicc:orderBy>\r\n </sicc:execute>\r\n </soapenv:Body>\r\n</soapenv:Envelope>",
CURLOPT_HTTPHEADER => array(
"cache-control: no-cache",
"content-type: text/xml",
"x-wasp-user: user-id"
),
));
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}
Pero recibo este error: "no se puede establecer el archivo de clave privada:". Entonces, supongo que solo tengo la parte pública del certificado. ¿Hay algo que pueda hacer para iniciar sesión de forma remota? ¿O es imposible? Sé que debo usar el código del lado del cliente, como Java Applet, pero, como he dicho, hay muchos datos y quiero evitar descargarlos en el cliente y cargarlos nuevamente en mi servidor.
ACTUALIZACIÓN: Solo para aclarar el caso de uso:
-
El segundo servidor es un servidor de gobierno. El ministerio proporciona datos de los ciudadanos después del inicio de sesión. No puedo cambiar nada en este servidor, obviamente.
-
El gobierno libera las tarjetas inteligentes para la autenticación, a través de Autoridades de Certificación Confiables. Tengo en mi servidor los certificados de CA, por lo que la CA no es un problema (supongo)
-
Mi aplicación web debe descargar, administrar y representar los datos de los ciudadanos de una manera mejor que el servidor original