maia_modificado/.svn/pristine/fa/faa45b3cb353876d4a996dd7b71...

585 lines
25 KiB
Plaintext
Executable File

package com.fp.firma.common;
import java.io.ByteArrayOutputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.security.GeneralSecurityException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.Security;
import java.security.cert.Certificate;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Enumeration;
import java.util.List;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import com.fp.firma.dto.TfirmDatosFirmante;
import com.fp.firma.keystore.KeyStoreProvider;
import com.fp.firma.keystore.LinuxKeyStoreProvider;
import com.fp.firma.keystore.WindowsJDK6KeyStoreProvider;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Font;
import com.itextpdf.text.Rectangle;
import com.itextpdf.text.pdf.AcroFields;
import com.itextpdf.text.pdf.PdfReader;
import com.itextpdf.text.pdf.PdfSignatureAppearance;
import com.itextpdf.text.pdf.PdfStamper;
import com.itextpdf.text.pdf.security.BouncyCastleDigest;
import com.itextpdf.text.pdf.security.CertificateInfo;
import com.itextpdf.text.pdf.security.CertificateInfo.X500Name;
import com.itextpdf.text.pdf.security.DigestAlgorithms;
import com.itextpdf.text.pdf.security.ExternalDigest;
import com.itextpdf.text.pdf.security.ExternalSignature;
import com.itextpdf.text.pdf.security.MakeSignature;
import com.itextpdf.text.pdf.security.MakeSignature.CryptoStandard;
import com.itextpdf.text.pdf.security.OcspClient;
import com.itextpdf.text.pdf.security.OcspClientBouncyCastle;
import com.itextpdf.text.pdf.security.PrivateKeySignature;
import com.itextpdf.text.pdf.security.TSAClient;
//import javax.persistence.NoResultException;
//import javax.persistence.Query;
/**
* Clase que contiene métodos utilitarios para manejar certificados
*
* @author dcruz
*
*/
public class CertificateUtils {
/*
* CONSTANTES DESIGNADAS SEGUN LA NUEVA ESTRUCTURA DEL BCE
*/
// OIDs de Campos del Certificado:
public static final String OID_CEDULA_PASAPORTE = FirmMessages.getString("oid.cedula_pasaporte");
public static final String OID_NOMBRES = FirmMessages.getString("oid.nombres_persona");
public static final String OID_APELLIDO_1 = FirmMessages.getString("oid.apellido_persona1");
public static final String OID_APELLIDO_2 = FirmMessages.getString("oid.apellido_persona2");
public static final String OID_CARGO = FirmMessages.getString("oid.cargo");
public static final String OID_INSTITUCION = FirmMessages.getString("oid.institucion");
public static final String OID_DIRECCION = FirmMessages.getString("oid.direccion");
public static final String OID_TELEFONO = FirmMessages.getString("oid.telefono");
public static final String OID_CIUDAD = FirmMessages.getString("oid.ciudad");
public static final String OID_RAZON_SOCIAL = FirmMessages.getString("oid.razon_social");
public static final String OID_RUC = FirmMessages.getString("oid.ruc");
public static final String X509 = "X.509";
static {
BouncyCastleProvider provider = new BouncyCastleProvider();
Security.addProvider(provider);
}
/**
* Retorna el certificado del usuario contenido en la firma
*
* @param store el store en el que se va a buscar los certificados
* @param aliases los alias que estan dentro del keystore
* @return el {@link java.security.Certificate}
* @throws KeyStoreException
*/
public synchronized static Certificate obtainCertificateInAlias(KeyStore store, Enumeration<String> aliases) throws KeyStoreException {
Certificate certs[] = null;
synchronized (aliases) {
int i = 0;
while (aliases.hasMoreElements()) {
String alias = aliases.nextElement();
System.out.println("Se imprime los alias: " + i + " " + alias);
certs = store.getCertificateChain(alias);
for (int j = 0; j < certs.length; j++) {
X509Certificate certificate = (X509Certificate) certs[j];
boolean[] usages = certificate.getKeyUsage();
System.out.println("Certificado en primera posicion usado: " + j + " " + usages[0]);
if (usages[0]) {
return certificate;
}
}
i++;
}
}
return null;
}
/**
* Se devuelve todos los datos de la firma del usuario en base al certificado enviado
*
* @param certificate el certificado enviado
* @return Los datos del certificado de dicho usuario
*/
public static TfirmDatosFirmante obtainDataForCertificate(Certificate certificate) {
X509Certificate signedCertificate = (X509Certificate) certificate;
TfirmDatosFirmante datosFirmante = new TfirmDatosFirmante();
if (signedCertificate.getExtensionValue(OID_CEDULA_PASAPORTE) != null) {
datosFirmante.setIdentificacion(new String(signedCertificate.getExtensionValue(OID_CEDULA_PASAPORTE)).trim());
}
if (signedCertificate.getExtensionValue(OID_NOMBRES) != null) {
datosFirmante.setNombre(new String(signedCertificate.getExtensionValue(OID_NOMBRES)).trim());
}
if (signedCertificate.getExtensionValue(OID_APELLIDO_1) != null) {
datosFirmante.setApellido1(new String(signedCertificate.getExtensionValue(OID_APELLIDO_1)).trim());
if (signedCertificate.getExtensionValue(OID_APELLIDO_2) != null) {
datosFirmante.setApellido2(new String(signedCertificate.getExtensionValue(OID_APELLIDO_2)).trim());
} else {
datosFirmante.setApellido2("");
}
}
if (signedCertificate.getExtensionValue(OID_TELEFONO) != null) {
datosFirmante.setTelefono(new String(signedCertificate.getExtensionValue(OID_TELEFONO)).trim());
}
if (signedCertificate.getExtensionValue(OID_CARGO) != null) {
datosFirmante.setCargo(new String(signedCertificate.getExtensionValue(OID_CARGO)).trim());
}
if (signedCertificate.getExtensionValue(OID_CIUDAD) != null) {
datosFirmante.setCiudad(new String(signedCertificate.getExtensionValue(OID_CIUDAD)).trim());
}
if (signedCertificate.getExtensionValue(OID_DIRECCION) != null) {
datosFirmante.setDireccion(new String(signedCertificate.getExtensionValue(OID_DIRECCION)).trim());
}
if (signedCertificate.getExtensionValue(OID_INSTITUCION) != null) {
datosFirmante.setInstitucion(new String(signedCertificate.getExtensionValue(OID_INSTITUCION)).trim());
}
if (signedCertificate.getExtensionValue(OID_RAZON_SOCIAL) != null) {
datosFirmante.setInstitucion(new String(signedCertificate.getExtensionValue(OID_RAZON_SOCIAL)).trim());
}
if (signedCertificate.getExtensionValue(OID_RUC) != null) {
datosFirmante.setRuc(new String(signedCertificate.getExtensionValue(OID_RUC)).trim());
}
datosFirmante.setFechaInicioVigencia(signedCertificate.getNotBefore());
datosFirmante.setFechaVigencia(signedCertificate.getNotAfter());
return datosFirmante;
}
/**
* Valida que el certificado del usuario sea un certificado valido contra el servicio OCSP del proveedor
*
* @param certificateUser
* @throws FileNotFoundException
* @throws CertificateException
*/
public static void validateOcsCertificate(Certificate certificateUser) throws FileNotFoundException, CertificateException {
System.out.println(((X509Certificate) certificateUser).getIssuerDN().getName());
CertificateFactory cf = CertificateFactory.getInstance(X509);
InputStream subordStream = new FileInputStream(FirmMessages.getString("dir.ruta.base.repositorio") + "/"
+ FirmMessages.getString("nombre.certificado.subordinado"));
X509Certificate subordCertificate = (X509Certificate) cf.generateCertificate(subordStream);
check((X509Certificate) certificateUser, subordCertificate);
}
/**
* Valida que los certificados enviados sean validos por la entidad certificadora
*
* @param issuerCert certificado del usuario
* @param x509Cert certificado que firmo el certificado expedido
*/
public static void check(X509Certificate issuerCert, X509Certificate x509Cert) {
// try {
//
// BigInteger serialNumber = issuerCert.getSerialNumber();
// X509CertificateHolder holder;
//
// try {
// holder = new X509CertificateHolder(x509Cert.getEncoded());
// } catch (IOException e) {
// throw new RuntimeException(e);
// }
//
// CertificateID id = new CertificateID(new JcaDigestCalculatorProviderBuilder().setProvider(BouncyCastleProvider.PROVIDER_NAME).build()
// .get(CertificateID.HASH_SHA1), holder, serialNumber);
//
// OCSPReqBuilder ocspGen = new OCSPReqBuilder();
// ocspGen.addRequest(id);
// OCSPReq ocspReq = ocspGen.build();
//
// // Ir al OCSP
// String ocspUrl = CertificateUtil.getOCSPURL(issuerCert);
//
// if (ocspUrl == null) {
// System.out.println("URL de OCSP is null");
// return;
// }
//
// URL url;
//
// try {
// url = new URL(ocspUrl);
// } catch (MalformedURLException e) {
// throw new RuntimeException(e);
// }
//
// HttpURLConnection con;
// OCSPResp ocspResponse;
// DataOutputStream dataOut = null;
// try {
// con = (HttpURLConnection) url.openConnection();
//
// con.setRequestProperty("Content-Type", "application/ocsp-request");
// con.setRequestProperty("Accept", "application/ocsp-response");
// con.setDoOutput(true);
//
// OutputStream out = con.getOutputStream();
// dataOut = new DataOutputStream(new BufferedOutputStream(out));
// dataOut.write(ocspReq.getEncoded());
//
// System.out.println("Estado de respuesta de la peticion=" + con.getResponseCode());
//
// /*
// * Se parsea la respuesta y se obtiene el estado del certificado retornado por el OCSP
// */
// InputStream in = (InputStream) con.getContent();
// byte[] resp = read(in); // Read the reponse
// ocspResponse = new OCSPResp(resp);
// } catch (IOException e) {
// throw new FirmasException("ERROR AL ESTABLECER CONEXI\u00d3N AL SERVICIO: "+url);
// } finally{
// if(dataOut != null){
// try {
// dataOut.flush();
// dataOut.close();
// } catch (IOException e) {}
// }
// }
//
// int status = ocspResponse.getStatus();
// System.out.println("status=" + status);
//
// BasicOCSPResp basicResponse = (BasicOCSPResp) ocspResponse.getResponseObject();
//
// if (basicResponse != null) {
// SingleResp[] responses = basicResponse.getResponses();
// SingleResp response = responses[0];
// CertificateStatus certStatus = (CertificateStatus) response.getCertStatus();
//
// if (certStatus instanceof RevokedStatus) {
// System.out.println("REVOKED");
// RevokedStatus revokedStatus = (RevokedStatus) certStatus;
// System.out.println("Reason: " + revokedStatus.getRevocationReason());
// System.out.println("Date: " + revokedStatus.getRevocationTime());
//
// throw new FirmasException("ERROR, CERTIFICADO REVOCADO POR "+revokedStatus.getRevocationReason()+" CON FECHA "+ revokedStatus.getRevocationTime());
// }
// }
// } catch (OCSPException e) {
// throw new RuntimeException(e);
// } catch (CertificateEncodingException e) {
// throw new RuntimeException(e);
// }
}
/**
* Devuelve los nombres de firmas de un documento PDF
*
* @param docStream el documento a verificar
* @return un lista de nombres de firmas
*/
public static List<String> obtainNameSigns(InputStream docStream) {
try {
PdfReader docPdf = new PdfReader(docStream);
AcroFields af = docPdf.getAcroFields();
return af.getSignatureNames();
} catch (IOException e) {
System.err.println("Error al obtener los nombres del documentoss");
return null;
} finally{
}
}
/**
* M&eacute;todo para firmar documentos
* @param fileSrc
* @param usuario
* @param password
* @param compania
* @param reason
* @param location
* @param rectangle
* @param numPage
* @param nameSign
* @return
* @throws Exception
*/
public static byte[] sign(InputStream fileSrc, String usuario, String password, Integer compania, String reason, String location,
Rectangle rectangle, int numPage, String nameSign, String pathCertificate) throws Exception {
String path = pathCertificate;
FileInputStream ceritificateInputStream = new FileInputStream(path);
return sign(fileSrc, ceritificateInputStream, password, reason, location, false, true, rectangle, numPage, nameSign, null);
}
/**
* Metodo para firmar documentos
* @param fileSrc
* @param usuario
* @param password
* @param compania
* @param reason
* @param location
* @param rectangle
* @param numPage
* @param nameSign
* @return
* @throws Exception
*/
public static byte[] sign(InputStream fileSrc, String usuario, String password, Integer compania, String reason, String location,
Rectangle rectangle, int numPage, String nameSign) throws Exception {
String path = "";
FileInputStream ceritificateInputStream = new FileInputStream(path);
return sign(fileSrc, ceritificateInputStream, password, reason, location, false, true, rectangle, numPage, nameSign, null);
}
/**
* M&eacute;todo que firma un documento en base los par&aacute;metros indicados
*
* @param fileSrc archivo origen
* @param fileCert archivo firma en formato digital si no es null el firmado es con archivo caso contrario es token
* @param password contrasena
* @param reason raz&oacute;n o motivo de la firma.
* @param location localizaci&oacute;n coemtario adicional de la firma.
* @param withTS tiene TS estamapado de tiempo.
* @param withOCSP tiene OCSP verificacion de la firma por el la entidad certificadora BCE.
* @param rectangle lugar localizaci&acute;n firma
* @param numPage n&uacute;mero pagina
* @param nameSign nombre firma
* @param tipoFirma es el tipo de token que se usar&aacute;(Token que tipo?)
* @return el documento firmado
*/
public static byte[] sign(InputStream fileSrc, InputStream fileCert, String password, String reason, String location, boolean withTS,
boolean withOCSP, Rectangle rectangle, int numPage, String nameSign, String tipoFirma) {
OutputStream outputStream = null;
System.out.println("Ingreso a firmar");
try {
PdfReader pdfReader = new PdfReader(fileSrc);
outputStream = new ByteArrayOutputStream(512);
PdfStamper stamper = PdfStamper.createSignature(pdfReader, outputStream, '\0');
PdfSignatureAppearance appearance = stamper.getSignatureAppearance();
KeyStore store;
String alias;
// PrivateKey privateKey = null;
ExternalSignature signature = null;
if(fileCert != null){
store = KeyStore.getInstance("PKCS12");
store.load(fileCert, password.toCharArray());
alias = store.aliases().nextElement();
signature = new PrivateKeySignature((PrivateKey) store.getKey(alias, password.toCharArray()), DigestAlgorithms.SHA256,
"SunRsaSign");
} else{//firma por token
KeyStoreProvider provider = getKeyStoreProvider(tipoFirma);
store = provider.getKeystore(password.toCharArray());
alias = store.aliases().nextElement();
// privateKey = (PrivateKey) store.getKey(alias, null);
signature = new PrivateKeySignature((PrivateKey) store.getKey(alias, null), DigestAlgorithms.SHA1,
null);
}
// appearance.setCrypto(privateKey, store.getCertificateChain(alias), null, null);
appearance.setLayer2Text(generateSignText(store.getCertificateChain(alias), reason, location));
appearance.setLayer2Font(new Font(Font.FontFamily.UNDEFINED, 8F));
appearance.setVisibleSignature(rectangle, numPage, nameSign);
TSAClient tsc = null;
if (withTS) {
}
OcspClient ocsp = null;
if (withOCSP) {
ocsp = new OcspClientBouncyCastle();
}
// stamper.close();
ExternalDigest externalDigest = new BouncyCastleDigest();
MakeSignature.signDetached(appearance, externalDigest, signature, store.getCertificateChain(alias), null, ocsp, tsc, 15000,
CryptoStandard.CADES);
return ((ByteArrayOutputStream) outputStream).toByteArray();
} catch (IOException e) {
throw new RuntimeException(e);
} catch (DocumentException e) {
throw new RuntimeException(e);
} catch (KeyStoreException e) {
throw new RuntimeException(e);
} catch (NoSuchAlgorithmException e) {
throw new RuntimeException(e);
} catch (CertificateException e) {
throw new RuntimeException(e);
} catch (GeneralSecurityException e) {
throw new RuntimeException(e);
} catch (FirmasException e) {
throw new RuntimeException(FirmMessages.getString("FIR-0006"));
} catch (Throwable e) {
throw new RuntimeException(e);
} finally{
try {
if(fileCert != null){
fileCert.close();
}
} catch (IOException e) {}
try {
fileSrc.close();
} catch (IOException e) {}
try {
if(outputStream != null){
outputStream.close();
}
} catch (IOException e) {}
}
}
/**
* Arma documento el texto a mostrar de la plantilla
* @param chains certificados
* @param reason raz&oacute;n
* @param location lugar
* @return una layout de la firma
*/
private static String generateSignText(Certificate[] chains, String reason, String location){
StringBuffer textLayout = new StringBuffer("Firmado digitalmente por: ");
String name = null;
X500Name x500name = CertificateInfo.getSubjectFields((X509Certificate)chains[0]);
if (x500name != null) {
name = x500name.getField("CN");
if (name == null)
name = x500name.getField("E");
}
if(name == null){
name = "";
}
textLayout.append(name).append("\n");
if(reason != null){
textLayout.append("Raz\u00f3n: ").append(reason).append("\n");
}
if(location != null){
textLayout.append("Lugar: ").append(location).append("\n");
}
SimpleDateFormat format = new SimpleDateFormat("dd/MM/yyyy HH:mm:ss");
textLayout.append("Fecha: ").append(format.format(new Date(System.currentTimeMillis())));
return textLayout.toString();
}
/**
* Retorna el keystore del token especificado
* @param tipoToken
* @return
* @throws KeyStoreException
*/
private static KeyStoreProvider getKeyStoreProvider(String tipoToken) {
String osName = System.getProperty("os.name");
KeyStoreProvider provider = null;
if(tipoToken == null){
return provider;
}
if (osName.toUpperCase().indexOf("WINDOWS") == 0) {
provider = new WindowsJDK6KeyStoreProvider();
if (tipoToken.equals("2")) {
provider = new WindowsJDK6KeyStoreProvider(); // trabaja con librerias sera para eToken
}else if (tipoToken.equals("1")) {
provider = new WindowsJDK6KeyStoreProvider(); // trabaja con librerias sera para iKey
}else if (tipoToken.equals("3")) {
provider = new WindowsJDK6KeyStoreProvider(); // trabaja con librerias sera para iKey
}
} else {
provider = new LinuxKeyStoreProvider();
}
return provider;
}
private static byte[] read(InputStream in) throws IOException {
ByteArrayOutputStream bos = new ByteArrayOutputStream();
int next = in.read();
while (next > -1) {
bos.write(next);
next = in.read();
}
bos.flush();
return bos.toByteArray();
}
/**
* Entrega el path en el que se encuentra el certificado digital.
*
* @param cusuario Codigo de usuario.
* @param ccompania Codigo de compania.
* @return String
* @throws Exception
*/
// private static String getPath(String cusuario, Integer ccompania) throws Exception {
// TfirmCertificado tfirmcertificado = getTfirmCertificado(cusuario);
// TgeneParametersKey tgeneParametersKey = new TgeneParametersKey("PATH_CERTIFICADO_BCE", ccompania);
// TgeneParameters tgeneParameters = TgeneParameters.find(PersistenceHelper.getEntityManager(), tgeneParametersKey);
// String path = tgeneParameters.getTextvalue() + "/" + tfirmcertificado.getPk().getIdcertificado();
// return path;
// }
/**
* Sentencia que entrega la defincion vigente de un certificado digital para un usuario.
*/
// private static final String JPQL = "from TfirmCertificado where t.codigousuario = :cusuario";
/**
* Entrega defincion de certificados digitales vigente.
*
* @param cusuario Codigo de usuario.
* @return TfirmCertificado.
* @throws Exception
*/
// private static TfirmCertificado getTfirmCertificado(String cusuario) throws Exception {
// TfirmCertificado tfirmCertificado = null;
// Query qry = PersistenceHelper.getEntityManager().createQuery(JPQL);
// qry.setParameter("cusuario", cusuario);
// try {
// tfirmCertificado = (TfirmCertificado) qry.getSingleResult();
// } catch (NoResultException e) {
// throw new FirmasException("FIR-0001", "PARAMETROS DEL CERTIFICADO DIGITAL NO DEFINIDO PARA EL USUARIO: {0}", cusuario);
// }
// return tfirmCertificado;
// }
/*
public static boolean validatePassword(InputStream fileSrc, String usuario, String password, Integer compania, String reason, String location,
Rectangle rectangle, int numPage, String nameSign) throws Exception {
String path = getPath(usuario, compania);
FileInputStream ceritificateInputStream = new FileInputStream(path);
return pass(fileSrc, ceritificateInputStream, password, reason, location, false, true, rectangle, numPage, nameSign);
}
private static boolean pass(InputStream fileSrc, InputStream fileCert, String password, String reason, String location, boolean withTS,
boolean withOCSP, Rectangle rectangle, int numPage, String nameSign) {
try {
PdfReader pdfReader = new PdfReader(fileSrc);
OutputStream outputStream = new ByteArrayOutputStream(512);
PdfStamper stamper = PdfStamper.createSignature(pdfReader, outputStream, '\0');
PdfSignatureAppearance appearance = stamper.getSignatureAppearance();
KeyStore store = KeyStore.getInstance("PKCS12");
store.load(fileCert, password.toCharArray());
String alias = store.aliases().nextElement();
ExternalSignature signature = new PrivateKeySignature((PrivateKey) store.getKey(alias, password.toCharArray()), DigestAlgorithms.SHA256,
"SunRsaSign");
return true;
} catch (Exception e) {
return false;
}
}
*/
}