739 lines
29 KiB
Plaintext
Executable File
739 lines
29 KiB
Plaintext
Executable File
package com.fp.firmas.rules.common;
|
|
|
|
import java.io.BufferedOutputStream;
|
|
import java.io.ByteArrayOutputStream;
|
|
import java.io.DataOutputStream;
|
|
import java.io.FileInputStream;
|
|
import java.io.FileNotFoundException;
|
|
import java.io.IOException;
|
|
import java.io.InputStream;
|
|
import java.io.OutputStream;
|
|
import java.math.BigInteger;
|
|
import java.net.HttpURLConnection;
|
|
import java.net.MalformedURLException;
|
|
import java.net.URL;
|
|
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.UnrecoverableKeyException;
|
|
import java.security.cert.Certificate;
|
|
import java.security.cert.CertificateEncodingException;
|
|
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 javax.persistence.NoResultException;
|
|
import javax.persistence.Query;
|
|
|
|
import org.bouncycastle.cert.X509CertificateHolder;
|
|
import org.bouncycastle.cert.ocsp.BasicOCSPResp;
|
|
import org.bouncycastle.cert.ocsp.CertificateID;
|
|
import org.bouncycastle.cert.ocsp.CertificateStatus;
|
|
import org.bouncycastle.cert.ocsp.OCSPException;
|
|
import org.bouncycastle.cert.ocsp.OCSPReq;
|
|
import org.bouncycastle.cert.ocsp.OCSPReqBuilder;
|
|
import org.bouncycastle.cert.ocsp.OCSPResp;
|
|
import org.bouncycastle.cert.ocsp.RevokedStatus;
|
|
import org.bouncycastle.cert.ocsp.SingleResp;
|
|
import org.bouncycastle.jce.provider.BouncyCastleProvider;
|
|
import org.bouncycastle.operator.OperatorCreationException;
|
|
import org.bouncycastle.operator.jcajce.JcaDigestCalculatorProviderBuilder;
|
|
|
|
import com.fp.base.persistence.TfirmDatosFirmante;
|
|
import com.fp.common.logger.APPLogger;
|
|
import com.fp.firmas.rules.common.enumerator.SignType;
|
|
import com.fp.firmas.rules.common.exception.FirmasException;
|
|
import com.fp.firmas.rules.common.resources.FirmMessages;
|
|
import com.fp.persistence.commondb.PersistenceHelper;
|
|
import com.fp.persistence.pfirmas.param.TfirmCertificado;
|
|
import com.fp.persistence.pgeneral.gene.TgeneParameters;
|
|
import com.fp.persistence.pgeneral.gene.TgeneParametersKey;
|
|
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.parser.PdfReaderContentParser;
|
|
import com.itextpdf.text.pdf.parser.Vector;
|
|
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.CertificateUtil;
|
|
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;
|
|
|
|
/**
|
|
* Clase que contiene metodos 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, FirmasException{
|
|
// 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);
|
|
try{
|
|
subordStream.close();
|
|
}catch(Exception e){}
|
|
}
|
|
|
|
/**
|
|
* 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) throws FirmasException{
|
|
|
|
OutputStream out = null;
|
|
DataOutputStream dataOut =null;
|
|
InputStream in =null;
|
|
|
|
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) {
|
|
APPLogger.getLogger().error("URL de OCSP is null");
|
|
return;
|
|
}
|
|
|
|
URL url;
|
|
|
|
try {
|
|
url = new URL(ocspUrl);
|
|
} catch (MalformedURLException e) {
|
|
throw new RuntimeException(e);
|
|
}
|
|
|
|
HttpURLConnection con;
|
|
OCSPResp ocspResponse;
|
|
|
|
|
|
try {
|
|
con = (HttpURLConnection) url.openConnection();
|
|
|
|
con.setRequestProperty("Content-Type", "application/ocsp-request");
|
|
con.setRequestProperty("Accept", "application/ocsp-response");
|
|
con.setDoOutput(true);
|
|
out = con.getOutputStream();
|
|
dataOut = new DataOutputStream(new BufferedOutputStream(out));
|
|
|
|
dataOut.write(ocspReq.getEncoded());
|
|
|
|
APPLogger.getLogger().info("Estado de respuesta de la peticion=" + con.getResponseCode());
|
|
|
|
/*
|
|
* Se parsea la respuesta y se obtiene el estado del certificado retornado por el OCSP
|
|
*/
|
|
in = (InputStream) con.getContent();
|
|
byte[] resp = read(in); // Read the reponse
|
|
ocspResponse = new OCSPResp(resp);
|
|
|
|
|
|
} catch (IOException e) {
|
|
throw new FirmasException("FIR-0001", "ERROR AL ESTABLECER CONEXI\u00d3N AL SERVICIO: {0}", url);
|
|
}
|
|
|
|
int status = ocspResponse.getStatus();
|
|
APPLogger.getLogger().info("status=" + status);
|
|
|
|
BasicOCSPResp basicResponse = (BasicOCSPResp) ocspResponse.getResponseObject();
|
|
|
|
if (basicResponse != null) {
|
|
SingleResp[] responses = basicResponse.getResponses();
|
|
SingleResp response = responses[0];
|
|
CertificateStatus certStatus = response.getCertStatus();
|
|
|
|
if (certStatus instanceof RevokedStatus) {
|
|
APPLogger.getLogger().error("REVOKED");
|
|
RevokedStatus revokedStatus = (RevokedStatus) certStatus;
|
|
APPLogger.getLogger().error("Reason: " + revokedStatus.getRevocationReason());
|
|
APPLogger.getLogger().error("Date: " + revokedStatus.getRevocationTime());
|
|
|
|
throw new FirmasException("FIR-0002", "ERROR, CERTIFICADO REVOCADO POR {0} CON FECHA {1}", revokedStatus.getRevocationReason(),
|
|
revokedStatus.getRevocationTime());
|
|
}
|
|
}
|
|
} catch (OCSPException e) {
|
|
throw new RuntimeException(e);
|
|
} catch (CertificateEncodingException e) {
|
|
throw new RuntimeException(e);
|
|
} catch (OperatorCreationException e) {
|
|
throw new RuntimeException(e);
|
|
}
|
|
finally{
|
|
try {
|
|
dataOut.close();
|
|
if(in!=null) {
|
|
in.close();
|
|
}
|
|
out.close();
|
|
} catch (IOException 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) {
|
|
PdfReader docPdf = null;
|
|
try {
|
|
docPdf = new PdfReader(docStream);
|
|
AcroFields af = docPdf.getAcroFields();
|
|
return af.getSignatureNames();
|
|
} catch (IOException e) {
|
|
APPLogger.getLogger().error("Error al obtener los nombres del documentoss");
|
|
return null;
|
|
} finally {
|
|
if(docPdf != null){
|
|
docPdf.close();
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 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, String pathCertificate) throws Exception {
|
|
String path = pathCertificate;
|
|
FileInputStream ceritificateInputStream = new FileInputStream(path);
|
|
return sign(fileSrc, ceritificateInputStream, password, reason, location, false, true, rectangle, numPage, nameSign);
|
|
}
|
|
|
|
/**
|
|
* 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 = getPath(usuario, compania);
|
|
FileInputStream ceritificateInputStream = new FileInputStream(path);
|
|
return sign(fileSrc, ceritificateInputStream, password, reason, location, false, true, rectangle, numPage, nameSign);
|
|
}
|
|
|
|
/**
|
|
* Método que firma un documento en base los parámetros indicados
|
|
*
|
|
* @param fileSrc archivo origen
|
|
* @param fileCert archivo destino
|
|
* @param password contrasena
|
|
* @param reason razón o motivo de la firma.
|
|
* @param location localizació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´n firma
|
|
* @param numPage número pagina
|
|
* @param nameSign nombre firma
|
|
* @return el documento firmado
|
|
*/
|
|
private static byte[] sign(InputStream fileSrc, InputStream fileCert, String password, String reason, String location, boolean withTS,
|
|
boolean withOCSP, Rectangle rectangle, int numPage, String nameSign) {
|
|
OutputStream outputStream =null;
|
|
PdfStamper stamper = null;
|
|
try {
|
|
PdfReader pdfReader = new PdfReader(fileSrc);
|
|
PDFRendererListener listener = new PDFRendererListener();
|
|
Integer numberPage = pdfReader.getNumberOfPages();
|
|
PdfReaderContentParser parser =new PdfReaderContentParser(pdfReader);
|
|
parser.processContent(numberPage, listener);
|
|
List<Vector> listaI = listener.getListaImagenes();
|
|
float llx = listaI.get(3).get(1);//50;
|
|
float lly = listaI.get(3).get(1);//210;
|
|
float urx = llx+250;//305;
|
|
float ury = lly+60;//277;
|
|
rectangle = new Rectangle(llx, lly, urx, ury);
|
|
|
|
|
|
outputStream = new ByteArrayOutputStream(512);
|
|
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");
|
|
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();
|
|
}
|
|
|
|
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) {
|
|
APPLogger.getLogger().error(e);
|
|
e.printStackTrace();
|
|
} catch (DocumentException e) {
|
|
APPLogger.getLogger().error(e);
|
|
e.printStackTrace();
|
|
} catch (KeyStoreException e) {
|
|
APPLogger.getLogger().error(e);
|
|
e.printStackTrace();
|
|
} catch (NoSuchAlgorithmException e) {
|
|
APPLogger.getLogger().error(e);
|
|
e.printStackTrace();
|
|
} catch (CertificateException e) {
|
|
APPLogger.getLogger().error(e);
|
|
e.printStackTrace();
|
|
} catch (UnrecoverableKeyException e) {
|
|
APPLogger.getLogger().error(e);
|
|
e.printStackTrace();
|
|
} catch (GeneralSecurityException e) {
|
|
APPLogger.getLogger().error(e);
|
|
e.printStackTrace();
|
|
}
|
|
finally{
|
|
try{
|
|
fileCert.close();
|
|
fileSrc.close();
|
|
try {
|
|
stamper.close();
|
|
} catch (Exception e2) {
|
|
}
|
|
|
|
if(outputStream!=null) {
|
|
outputStream.close();
|
|
}
|
|
}
|
|
catch (IOException e){
|
|
APPLogger.getLogger().error(e);
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
|
|
public static byte[] sign(InputStream fileSrc, String usuario, String password, String reason, String location,
|
|
String nameSign, String pathCertificate, SignType signType) throws Exception {
|
|
String path = pathCertificate;
|
|
FileInputStream certificateInputStream = null;
|
|
try{
|
|
certificateInputStream = new FileInputStream(path);
|
|
return positionSign(fileSrc, certificateInputStream, password, reason, location, false, true, nameSign,signType);
|
|
}finally{
|
|
if(certificateInputStream !=null){
|
|
certificateInputStream.close();
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
/**
|
|
* Método que firma un documento en base los parámetros indicados
|
|
* @param fileSrc
|
|
* @param fileCert
|
|
* @param password
|
|
* @param reason
|
|
* @param location
|
|
* @param withTS
|
|
* @param withOCSP
|
|
* @param nameSign
|
|
* @param signType
|
|
* @return
|
|
*/
|
|
private static byte[] positionSign(InputStream fileSrc, InputStream fileCert, String password, String reason, String location, boolean withTS,
|
|
boolean withOCSP, String nameSign, SignType signType) {
|
|
OutputStream outputStream =null;
|
|
PdfStamper stamper = null;
|
|
try {
|
|
PdfReader pdfReader = new PdfReader(fileSrc);
|
|
PDFRendererListener listener = new PDFRendererListener();
|
|
Integer numPage = pdfReader.getNumberOfPages();
|
|
PdfReaderContentParser parser =new PdfReaderContentParser(pdfReader);
|
|
parser.processContent(numPage, listener);
|
|
List<Vector> listaI = listener.getListaImagenes();
|
|
float llx = listaI.get(listaI.size()-signType.getIndice()).get(0);
|
|
float lly = listaI.get(listaI.size()-signType.getIndice()).get(1);
|
|
float urx = llx+250;//305;
|
|
float ury = lly+60;//277;
|
|
Rectangle rectangle = new Rectangle(llx, lly, urx, ury);
|
|
outputStream = new ByteArrayOutputStream(512);
|
|
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");
|
|
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();
|
|
}
|
|
|
|
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) {
|
|
APPLogger.getLogger().error(e);
|
|
e.printStackTrace();
|
|
} catch (DocumentException e) {
|
|
APPLogger.getLogger().error(e);
|
|
e.printStackTrace();
|
|
} catch (KeyStoreException e) {
|
|
APPLogger.getLogger().error(e);
|
|
e.printStackTrace();
|
|
} catch (NoSuchAlgorithmException e) {
|
|
APPLogger.getLogger().error(e);
|
|
e.printStackTrace();
|
|
} catch (CertificateException e) {
|
|
APPLogger.getLogger().error(e);
|
|
e.printStackTrace();
|
|
} catch (UnrecoverableKeyException e) {
|
|
APPLogger.getLogger().error(e);
|
|
e.printStackTrace();
|
|
} catch (GeneralSecurityException e) {
|
|
APPLogger.getLogger().error(e);
|
|
e.printStackTrace();
|
|
}
|
|
finally{
|
|
try{
|
|
fileCert.close();
|
|
fileSrc.close();
|
|
try {
|
|
stamper.close();
|
|
} catch (Exception e2) {
|
|
}
|
|
|
|
if(outputStream!=null) {
|
|
outputStream.close();
|
|
}
|
|
}
|
|
catch (IOException e){
|
|
APPLogger.getLogger().error(e);
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
|
|
/**
|
|
* Arma documento el texto a mostrar de la plantilla
|
|
* @param chains certificados
|
|
* @param reason razó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();
|
|
}
|
|
|
|
private static byte[] read(InputStream in) throws IOException {
|
|
ByteArrayOutputStream bos = null;
|
|
try {
|
|
bos = new ByteArrayOutputStream();
|
|
int next = in.read();
|
|
while (next > -1) {
|
|
bos.write(next);
|
|
next = in.read();
|
|
}
|
|
bos.flush();
|
|
|
|
return bos.toByteArray();
|
|
} finally {
|
|
if(in != null){
|
|
in.close();
|
|
}
|
|
if(bos != null){
|
|
bos.close();
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
/**
|
|
* 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;
|
|
}
|
|
|
|
/**
|
|
* Método para validar el password ingresado
|
|
* @param path
|
|
* @param usuario
|
|
* @param password
|
|
* @param compania
|
|
* @return
|
|
* @throws Exception
|
|
*/
|
|
public static boolean validatePassword(String path, String usuario,
|
|
String password, Integer compania) {
|
|
FileInputStream certificateInputStream =null;
|
|
try {
|
|
certificateInputStream = new FileInputStream(path);
|
|
KeyStore ks = KeyStore.getInstance("PKCS12");
|
|
ks.load(certificateInputStream, password.toCharArray());
|
|
return true;
|
|
} catch (Exception e) {
|
|
return false;
|
|
}finally{
|
|
try {
|
|
if(certificateInputStream!=null)
|
|
{
|
|
certificateInputStream.close();
|
|
}
|
|
} catch (IOException e) {}
|
|
}
|
|
|
|
}
|
|
|
|
}
|