Hola Rafael,
Muchas gracias por la colaboración, la haré un poco más genérica
para que contemple todas las salidas de firma (menos XAdES que ya
lo hace) y lo añadiré al repositorio.
Gracias.
Un Saludo
Paúl.
On Friday 20 February 2009 11:28:57 Espí Botella, Rafael wrote:
> Hola.
>
>
>
> He estado trabajando en la firma PDF con validación de certificados OCSP.
> Esta funcionalidad no venía incluida en CryptoApplet. Yo he conseguido
> implementarla y me funciona correctamente, igual se podría implementar de
> alguna forma mejor. Os la paso por si os interesa a alguien.
>
>
>
> Concretamente, en la clase BouncyCastleFactory, he añadido este método:
>
>
>
> public void getConfirmation(X509Certificate signersCert,
>
> X509Certificate caCert) // TODO: remove param notaryCert
>
> throws DigiDocException {
>
> try {
>
> // create the request - sign the request if necessary
>
> OCSPReq req = createOCSPRequest(signersCert, caCert,
>
> m_bSignRequests);
>
> // debugWriteFile("req.der", req.getEncoded());
>
>
>
> if (m_logger.isDebugEnabled())
>
> m_logger.debug("REQUEST:\n"
>
> + Base64Util.encode(req.getEncoded(), 0));
>
> // send it
>
>
>
> Integer nResps = new
> Integer(ConfigManager.instance().getProperty(
>
> "DIGIDOC_OCSP_RESPONDER_COUNT"));
>
> for (int i = 1; i <= nResps; i++) {
>
> try {
>
>
>
> String ocspResponder = ConfigManager.instance()
>
> .getProperty("DIGIDOC_OCSP_RESPONDER_URL"
> + i);
>
>
>
> OCSPResp resp = sendRequest(req, ocspResponder);
>
> // debugWriteFile("resp.der", resp.getEncoded());
>
> if (m_logger.isDebugEnabled())
>
> m_logger.debug("RESPONSE:\n"
>
> + Base64Util.encode(resp.getEncoded(),
> 0));
>
> // check response status
>
> verifyRespStatus(resp);
>
>
>
> if (resp == null
>
> || resp.getStatus() !=
> || OCSPRespStatus.SUCCESSFUL)
>
> throw new DigiDocException(
>
>
> DigiDocException.ERR_OCSP_UNSUCCESSFULL,
>
> "OCSP response unsuccessfull!", null);
>
> try {
>
> // now read the info from the response
>
> BasicOCSPResp basResp = (BasicOCSPResp) resp
>
> .getResponseObject();
>
> // find real notary cert suitable for this
> response
>
>
>
> Exception exVerify = null;
>
> if (exVerify != null) {
>
> m_logger.error("OCSP verification
> error!!!",
>
> exVerify);
>
> DigiDocException.handleException(exVerify,
>
>
> DigiDocException.ERR_OCSP_VERIFY);
>
> }
>
> checkCertStatus(signersCert, basResp);
>
>
>
> } catch (DigiDocException ex) {
>
> throw ex;
>
> } catch (Exception ex) {
>
> DigiDocException.handleException(ex,
>
> DigiDocException.ERR_OCSP_PARSE);
>
> }
>
>
>
> if (m_logger.isDebugEnabled())
>
> m_logger.debug("Confirmation OK!");
>
>
>
> break;
>
> } catch (DigiDocException e) {
>
> // If it is the last unverifiable,
>
> // Throw the exception again
>
> if (i == nResps)
>
> throw e;
>
> }
>
>
>
> }
>
> } catch (DigiDocException ex) {
>
> ex.printStackTrace();
>
> throw ex;
>
> } catch (Exception ex) {
>
> DigiDocException.handleException(ex,
>
>
>
> DigiDocException.ERR_OCSP_GET_CONF);
>
> ex.printStackTrace();
>
> }
>
> return;
>
> }
>
>
>
>
>
> A continuación, pongo la llamada en el método
> PDFSignatureFactory.formatSignature() justo antes de crear el objeto
> PDFReader, tal y como os indico a continuación:
>
>
>
> public byte[] formatSignature(byte[] datos,
> X509Certificate sCer, PrivateKey pk, Provider pv) throws KeyStoreException,
> Exception
>
> {
>
>
>
>
>
> // Initialize the provider list
>
> super.initProviderList();
>
>
>
>
>
>
>
> this.pk= pk;
>
> this.pv=pv;
>
>
>
> if (OS.isWindowsUpperEqualToNT())
>
> {
>
> rq= new RegQuery();
>
> _tmp = rq.getCurrentUserPersonalFolderPath();
>
> }
>
> else
>
> _tmp = ".";
>
>
>
> chain= new Certificate[2];
>
> CertificateFactory cf =
> CertificateFactory.getInstance("X.509");
>
>
>
> // Here the certificates has to be disposed as next:
>
> // chain[0]= user_cert, chain[1]= level_n_cert,
>
> // chain[2]= level_n-1_cert, ...
>
> ClassLoader cl = PDFSignatureFactory.class.getClassLoader();
>
> //Get the CA certificate list
>
> Integer n= new Integer(prop.getProperty("PDFSIG_CA_CERTS"));
>
> Certificate cert= sCer;
>
> Certificate CACert= null;
>
>
>
> for (int i=1; i<= n; i++)
>
> {
>
> CACert=
> cf.generateCertificate(cl.getResourceAsStream(prop.getProperty("PDFSIG_CA_C
>ERT"+i)));
>
> try{
>
> cert.verify(CACert.getPublicKey());
>
> break;
>
> } catch (SignatureException e) {
>
> //The actual CACert does not match with the
>
> //signer certificate.
>
> CACert= null;
>
> }
>
> }
>
>
>
> if ( CACert == null ){
>
>
> _strerr=LabelManager.get("ERROR_CERTIFICATE_NOT_ALLOWED");
>
> return null;
>
> }
>
>
>
> chain[1]= CACert;
>
> chain[0]= cert;
>
>
>
>
>
> try
>
> {
>
>
>
> BouncyCastleNotaryFactory bcnf = new
> BouncyCastleNotaryFactory();
>
> bcnf.getConfirmation((X509Certificate) cert,
> (X509Certificate)CACert);
>
> }
>
> catch (DigiDocException e)
>
> {
>
> if ( e.getCode() == e.ERR_CERT_REVOKED ){
>
> _strerr= LabelManager.get("ERROR_DDOC_CERTREVOKED");
>
> }
>
> else if ( e.getCode() == e.ERR_CERT_EXPIRED ){
>
> _strerr= LabelManager.get("ERROR_DDOC_CERTEXPIRED");
>
> }
>
> else if ( e.getCode() == e.ERR_CA_CERT_READ ){
>
> _strerr=
> LabelManager.get("ERROR_DDOC_CERT_NOT_ALLOWED");
>
> //_strerr=
> LabelManager.get("ERROR_DDOC_CACERTREAD");
>
> }
>
> else if ( e.getCode() == e.ERR_OCSP_READ_FILE ||
> e.getCode() == e.ERR_OCSP_ISSUER_CA_NOT_FOUND ){
>
> _strerr=
> LabelManager.get("ERROR_DDOC_CERT_NOT_ALLOWED");
>
> }
>
> else{
>
> _strerr= LabelManager.get("ERROR_DDOC_CERTGENERIC");
>
> }
>
>
>
> //e.printStackTrace();
>
> return null;
>
> }
>
>
>
>
>
>
>
> /// Begin with the signature itself
>
> PdfReader reader = new PdfReader(datos);
>
> ByteArrayOutputStream sout = new ByteArrayOutputStream();
>
>
>
> PdfStamper stp = PdfStamper.createSignature(reader, sout,
> '\0', new File(_tmp), true);
>
>
>
> PdfSignatureAppearance sap = stp.getSignatureAppearance();
>
>
>
> String aux= prop.getProperty("PDFSIG_TIMESTAMPING");
>
> if (aux!=null && aux.trim().equals("true") &&
>
> prop.getProperty("PDFSIG_TSA_URL") != null){
>
>
>
> signPdfTsp(sap);
>
>
>
> } else {
>
>
>
> signPdf(sap);
>
> stp.close();
>
>
>
> }
>
>
>
>
>
> return Base64.encode(sout.toByteArray());
>
>
>
>
>
> }
_______________________________________________
CryptoApplet mailing list
[email protected]
http://llistes.uji.es/mailman/listinfo/cryptoapplet