List of usage examples for com.lowagie.text.pdf PdfPKCS7 getSubjectFields
public static X509Name getSubjectFields(X509Certificate cert)
From source file:SignPdf.java
License:Open Source License
/** * Add a signature and a cryptographic timestamp to a pdf document. See www.ietf.org/rfc/rfc3161.txt. Proves that this * pdf had the current content at the current point in time. * * @param originalPdf/*from w w w. j a v a2s. co m*/ * @param targetPdf * @param pk * @param certChain * @param revoked * @param tsaAddress * address of a rfc 3161 compatible timestamp server * @param reason * reason for the signature * @param location * location of signing * @param contact * emailaddress of the person who is signing * @throws IOException * @throws DocumentException * @throws SignatureException */ public static void signAndTimestamp(final InputStream originalPdf, final OutputStream targetPdf, final PrivateKey pk, final X509Certificate[] certChain, final CRL[] revoked, final String tsaAddress, final String reason, final String location, final String contact) throws IOException, DocumentException, SignatureException { // only an estimate, depends on the certificates returned by the TSA final int timestampSize = 4400; Security.addProvider(new BouncyCastleProvider()); final PdfReader reader = new PdfReader(originalPdf); final PdfStamper stamper = PdfStamper.createSignature(reader, targetPdf, '\0'); final PdfSignatureAppearance sap = stamper.getSignatureAppearance(); // comment next lines to have an invisible signature Rectangle cropBox = reader.getCropBox(1); float width = 50; float height = 50; Rectangle rectangle = new Rectangle(cropBox.getRight(width) - 20, cropBox.getTop(height) - 20, cropBox.getRight() - 20, cropBox.getTop() - 20); sap.setVisibleSignature(rectangle, 1, null); //sap.setVisibleSignature(new Rectangle(450, 650, 500, 700), 1, null); sap.setLayer2Text(""); final PdfSigGenericPKCS sig = new PdfSigGenericPKCS.PPKMS("BC"); final HashMap<PdfName, Integer> exclusionSizes = new HashMap<PdfName, Integer>(); // some informational fields sig.setReason(reason); sig.setLocation(location); sig.setContact(contact); sig.setName(PdfPKCS7.getSubjectFields(certChain[0]).getField("CN")); sig.setDate(new PdfDate(Calendar.getInstance())); // signing stuff final byte[] digest = new byte[256]; final byte[] rsaData = new byte[20]; sig.setExternalDigest(digest, rsaData, "RSA"); sig.setSignInfo(pk, certChain, revoked); final PdfString contents = (PdfString) sig.get(PdfName.CONTENTS); // *2 to get hex size, +2 for delimiters PdfLiteral contentsLit = new PdfLiteral((contents.toString().length() + timestampSize) * 2 + 2); exclusionSizes.put(PdfName.CONTENTS, new Integer(contentsLit.getPosLength())); sig.put(PdfName.CONTENTS, contentsLit); // certification; will display dialog or blue bar in Acrobat Reader sap.setCertificationLevel(PdfSignatureAppearance.CERTIFIED_NO_CHANGES_ALLOWED); // process all the information set above sap.setCryptoDictionary(sig); sap.preClose(exclusionSizes); // calculate digest (hash) try { final MessageDigest messageDigest = MessageDigest.getInstance("SHA1"); final byte[] buf = new byte[8192]; int n; final InputStream inp = sap.getRangeStream(); while ((n = inp.read(buf)) != -1) { messageDigest.update(buf, 0, n); } final byte[] hash = messageDigest.digest(); // make signature (SHA1 the hash, prepend algorithm ID, pad, and encrypt with RSA) final Signature sign = Signature.getInstance("SHA1withRSA"); sign.initSign(pk); sign.update(hash); final byte[] signature = sign.sign(); // prepare the location of the signature in the target PDF contentsLit = (PdfLiteral) sig.get(PdfName.CONTENTS); final byte[] outc = new byte[(contentsLit.getPosLength() - 2) / 2]; final PdfPKCS7 pkcs7 = sig.getSigner(); pkcs7.setExternalDigest(signature, hash, "RSA"); final PdfDictionary dic = new PdfDictionary(); byte[] ssig = pkcs7.getEncodedPKCS7(); try { // try to retrieve cryptographic timestamp from configured tsa server ssig = pkcs7.getEncodedPKCS7(null, null, new TSAClientBouncyCastle(tsaAddress), null); } catch (final RuntimeException e) { log.error("Could not retrieve timestamp from server.", e); } System.arraycopy(ssig, 0, outc, 0, ssig.length); // add the timestamped signature dic.put(PdfName.CONTENTS, new PdfString(outc).setHexWriting(true)); // finish up sap.close(dic); } catch (final InvalidKeyException e) { throw new RuntimeException("Internal implementation error! No such signature type.", e); } catch (final NoSuchAlgorithmException e) { throw new RuntimeException("Internal implementation error! No such algorithm type.", e); } }
From source file:de.thorstenberger.examServer.pdf.signature.SignPdf.java
License:Open Source License
/** * Add a signature and a cryptographic timestamp to a pdf document. See www.ietf.org/rfc/rfc3161.txt. Proves that this * pdf had the current content at the current point in time. * * @param originalPdf//from w ww .ja v a2 s. c o m * @param targetPdf * @param pk * @param certChain * @param revoked * @param tsaAddress * address of a rfc 3161 compatible timestamp server * @param reason * reason for the signature * @param location * location of signing * @param contact * emailaddress of the person who is signing * @throws IOException * @throws DocumentException * @throws SignatureException */ public static void signAndTimestamp(final InputStream originalPdf, final OutputStream targetPdf, final PrivateKey pk, final X509Certificate[] certChain, final CRL[] revoked, final String tsaAddress, final String reason, final String location, final String contact) throws IOException, DocumentException, SignatureException { // only an estimate, depends on the certificates returned by the TSA final int timestampSize = 4400; Security.addProvider(new BouncyCastleProvider()); final PdfReader reader = new PdfReader(originalPdf); final PdfStamper stamper = PdfStamper.createSignature(reader, targetPdf, '\0'); final PdfSignatureAppearance sap = stamper.getSignatureAppearance(); // comment next lines to have an invisible signature sap.setVisibleSignature(new Rectangle(450, 650, 500, 700), 1, null); sap.setLayer2Text(""); final PdfSigGenericPKCS sig = new PdfSigGenericPKCS.PPKMS("BC"); final HashMap<PdfName, Integer> exclusionSizes = new HashMap<PdfName, Integer>(); // some informational fields sig.setReason(reason); sig.setLocation(location); sig.setContact(contact); sig.setName(PdfPKCS7.getSubjectFields(certChain[0]).getField("CN")); sig.setDate(new PdfDate(Calendar.getInstance())); // signing stuff final byte[] digest = new byte[256]; final byte[] rsaData = new byte[20]; sig.setExternalDigest(digest, rsaData, "RSA"); sig.setSignInfo(pk, certChain, revoked); final PdfString contents = (PdfString) sig.get(PdfName.CONTENTS); // *2 to get hex size, +2 for delimiters PdfLiteral contentsLit = new PdfLiteral((contents.toString().length() + timestampSize) * 2 + 2); exclusionSizes.put(PdfName.CONTENTS, new Integer(contentsLit.getPosLength())); sig.put(PdfName.CONTENTS, contentsLit); // certification; will display dialog or blue bar in Acrobat Reader sap.setCertificationLevel(PdfSignatureAppearance.CERTIFIED_NO_CHANGES_ALLOWED); // process all the information set above sap.setCryptoDictionary(sig); sap.preClose(exclusionSizes); // calculate digest (hash) try { final MessageDigest messageDigest = MessageDigest.getInstance("SHA1"); final byte[] buf = new byte[8192]; int n; final InputStream inp = sap.getRangeStream(); while ((n = inp.read(buf)) != -1) { messageDigest.update(buf, 0, n); } final byte[] hash = messageDigest.digest(); // make signature (SHA1 the hash, prepend algorithm ID, pad, and encrypt with RSA) final Signature sign = Signature.getInstance("SHA1withRSA"); sign.initSign(pk); sign.update(hash); final byte[] signature = sign.sign(); // prepare the location of the signature in the target PDF contentsLit = (PdfLiteral) sig.get(PdfName.CONTENTS); final byte[] outc = new byte[(contentsLit.getPosLength() - 2) / 2]; final PdfPKCS7 pkcs7 = sig.getSigner(); pkcs7.setExternalDigest(signature, hash, "RSA"); final PdfDictionary dic = new PdfDictionary(); byte[] ssig = pkcs7.getEncodedPKCS7(); try { // try to retrieve cryptographic timestamp from configured tsa server ssig = pkcs7.getEncodedPKCS7(null, null, new TSAClientBouncyCastle(tsaAddress), null); } catch (final RuntimeException e) { log.error("Could not retrieve timestamp from server.", e); } System.arraycopy(ssig, 0, outc, 0, ssig.length); // add the timestamped signature dic.put(PdfName.CONTENTS, new PdfString(outc).setHexWriting(true)); // finish up sap.close(dic); } catch (final InvalidKeyException e) { throw new RuntimeException("Internal implementation error! No such signature type.", e); } catch (final NoSuchAlgorithmException e) { throw new RuntimeException("Internal implementation error! No such algorithm type.", e); } }
From source file:es.gob.afirma.signers.pades.PAdESSigner.java
License:Open Source License
@SuppressWarnings("boxing") static byte[] signPDF(final PrivateKey key, final java.security.cert.Certificate[] certChain, final byte[] inPDF, final Properties extraParams, final String algorithm) throws IOException, AOException, DocumentException, NoSuchAlgorithmException, CertificateException { // ********************************************************************************************************************* // **************** LECTURA PARAMETROS ADICIONALES ********************************************************************* // ********************************************************************************************************************* // Imagen de la rubrica final Image rubric = getRubricImage(extraParams.getProperty("signatureRubricImage")); //$NON-NLS-1$ // Usar hora y fecha del sistema final boolean useSystemDateTime = Boolean .parseBoolean(extraParams.getProperty("applySystemDate", Boolean.TRUE.toString())); //$NON-NLS-1$ // Motivo de la firma final String reason = extraParams.getProperty("signReason"); //$NON-NLS-1$ // Nombre del campo de firma preexistente en el PDF a usar final String signatureField = extraParams.getProperty("signatureField"); //$NON-NLS-1$ // Lugar de realizacion de la firma final String signatureProductionCity = extraParams.getProperty("signatureProductionCity"); //$NON-NLS-1$ // Datos de contacto (correo electronico) del firmante final String signerContact = extraParams.getProperty("signerContact"); //$NON-NLS-1$ // Pagina donde situar la firma visible int page = LAST_PAGE; try {/* w ww .jav a2s . c o m*/ page = Integer.parseInt(extraParams.getProperty("signaturePage")); //$NON-NLS-1$ } catch (final Exception e) { /* Se deja la pagina tal y como esta */ } // Nombre del subfiltro de firma en el diccionario PDF final String signatureSubFilter = extraParams.getProperty("signatureSubFilter"); //$NON-NLS-1$ // ****************** // ** Adjuntos ****** // Contenido a adjuntar (en Base64) final String b64Attachment = extraParams.getProperty("attach"); //$NON-NLS-1$ // Nombre que se pondra al fichero adjunto en el PDF final String attachmentFileName = extraParams.getProperty("attachFileName"); //$NON-NLS-1$ // Descripcion del adjunto final String attachmentDescription = extraParams.getProperty("attachDescription"); //$NON-NLS-1$ // ** Fin Adjuntos ** // ****************** // Nivel de certificacion del PDF int certificationLevel; try { certificationLevel = extraParams.getProperty("certificationLevel") != null ? //$NON-NLS-1$ Integer.parseInt(extraParams.getProperty("certificationLevel")) : //$NON-NLS-1$ -1; } catch (final Exception e) { certificationLevel = UNDEFINED; } // ***************************** // **** Texto firma visible **** // Texto en capa 4 final String layer4Text = extraParams.getProperty("layer4Text"); //$NON-NLS-1$ // Texto en capa 2 final String layer2Text = extraParams.getProperty("layer2Text"); //$NON-NLS-1$ // Tipo de letra en capa 2 int layer2FontFamily; try { layer2FontFamily = extraParams.getProperty("layer2FontFamily") != null ? //$NON-NLS-1$ Integer.parseInt(extraParams.getProperty("layer2FontFamily")) : //$NON-NLS-1$ -1; } catch (final Exception e) { layer2FontFamily = UNDEFINED; } // Tamano del tipo de letra en capa 2 int layer2FontSize; try { layer2FontSize = extraParams.getProperty("layer2FontSize") != null ? //$NON-NLS-1$ Integer.parseInt(extraParams.getProperty("layer2FontSize")) : //$NON-NLS-1$ -1; } catch (final Exception e) { layer2FontSize = UNDEFINED; } // Estilo del tipo de letra en capa 2 int layer2FontStyle; try { layer2FontStyle = extraParams.getProperty("layer2FontStyle") != null ? //$NON-NLS-1$ Integer.parseInt(extraParams.getProperty("layer2FontStyle")) : //$NON-NLS-1$ -1; } catch (final Exception e) { layer2FontStyle = UNDEFINED; } // Color del tipo de letra en capa 2 final String layer2FontColor = extraParams.getProperty("layer2FontColor"); //$NON-NLS-1$ // ** Fin texto firma visible ** // ***************************** // Contrasena del propietario del PDF String ownerPassword = extraParams.getProperty("ownerPassword"); //$NON-NLS-1$ // Contrasena del usuario del PDF final String userPassword = extraParams.getProperty("userPassword"); //$NON-NLS-1$ // ********************************************************************************************************************* // **************** FIN LECTURA PARAMETROS ADICIONALES ***************************************************************** // ********************************************************************************************************************* PdfReader pdfReader; try { if (ownerPassword != null) { pdfReader = new PdfReader(inPDF, ownerPassword.getBytes()); } else if (userPassword != null) { pdfReader = new PdfReader(inPDF, userPassword.getBytes()); } else { pdfReader = new PdfReader(inPDF); } } catch (final BadPasswordException e) { // Comprobamos que el signer esta en modo interactivo, y si no lo // esta no pedimos contrasena por dialogo, principalmente para no interrumpir un firmado por lotes // desatendido if (Boolean.TRUE.toString().equalsIgnoreCase(extraParams.getProperty("headLess"))) { //$NON-NLS-1$ throw new BadPdfPasswordException(e); } // La contrasena que nos han proporcionada no es buena o no nos // proporcionaron ninguna ownerPassword = new String(AOUIFactory.getPassword( ownerPassword == null ? PDFMessages.getString("AOPDFSigner.0") //$NON-NLS-1$ : PDFMessages.getString("AOPDFSigner.1"), //$NON-NLS-1$ null)); try { pdfReader = new PdfReader(inPDF, ownerPassword.getBytes()); } catch (final BadPasswordException e2) { throw new BadPdfPasswordException(e2); } } catch (final IOException e) { throw new InvalidPdfException(e); } if (pdfReader.getCertificationLevel() == PdfSignatureAppearance.CERTIFIED_NO_CHANGES_ALLOWED && !Boolean.parseBoolean(extraParams.getProperty("allowSigningCertifiedPdfs"))) { //$NON-NLS-1$ // Si no permitimos dialogos graficos o directamente hemos indicado que no permitimos firmar PDF certificados lanzamos // una excepcion if (Boolean.parseBoolean(extraParams.getProperty("headLess")) //$NON-NLS-1$ || "false".equalsIgnoreCase(extraParams.getProperty("allowSigningCertifiedPdfs"))) { //$NON-NLS-1$ //$NON-NLS-2$ throw new PdfIsCertifiedException(); } // En otro caso, perguntamos al usuario if (AOUIFactory.NO_OPTION == AOUIFactory.showConfirmDialog(null, PDFMessages.getString("AOPDFSigner.8"), //$NON-NLS-1$ PDFMessages.getString("AOPDFSigner.9"), //$NON-NLS-1$ AOUIFactory.YES_NO_OPTION, AOUIFactory.WARNING_MESSAGE)) { throw new AOCancelledOperationException( "El usuario no ha permitido la firma de un PDF certificado"); //$NON-NLS-1$ } } // Los derechos van firmados por Adobe, y como desde iText se invalidan // es mejor quitarlos pdfReader.removeUsageRights(); final ByteArrayOutputStream baos = new ByteArrayOutputStream(); // Activar el atributo de "agregar firma" (cuarto parametro del metodo // "PdfStamper.createSignature") hace que se cree una nueva revision del // documento y evita que las firmas previas queden invalidadas. Sin embargo, este // exige que el PDF no incorpore ningun error, asi que lo mantendremos desactivado // para la primera firma y activado para las subsiguientes. Un error incorporado // en un PDF erroneo puede quedar subsanado en su version firmada, haciendo // posible incorporar nuevas firmas agregando revisiones del documento. final PdfStamper stp; try { stp = PdfStamper.createSignature(pdfReader, // PDF de entrada baos, // Salida '\0', // Mantener version null, // No crear temporal pdfReader.getAcroFields().getSignatureNames().size() > 0 // Si hay mas firmas, creo una revision ); } catch (final BadPasswordException e) { throw new PdfIsPasswordProtectedException(e); } // Aplicamos todos los atributos de firma final PdfSignatureAppearance sap = stp.getSignatureAppearance(); stp.setFullCompression(); sap.setAcro6Layers(true); // PAdES parte 3 seccion 4.7 - Habilitacion para LTV stp.getWriter().addDeveloperExtension(new PdfDeveloperExtension(new PdfName("ESIC"), //$NON-NLS-1$ PdfWriter.PDF_VERSION_1_7, 1)); // Adjuntos if (b64Attachment != null && attachmentFileName != null) { byte[] attachment = null; try { attachment = Base64.decode(b64Attachment); } catch (final IOException e) { LOGGER.warning("Se ha indicado un adjunto, pero no estaba en formato Base64, se ignorara : " + e); //$NON-NLS-1$ } if (attachment != null) { stp.getWriter().addFileAttachment(attachmentDescription, attachment, null, attachmentFileName); } } // iText antiguo sap.setRender(PdfSignatureAppearance.SignatureRenderDescription); // En iText nuevo seria "sap.setRenderingMode(PdfSignatureAppearance.RenderingMode.NAME_AND_DESCRIPTION);" // Razon de firma if (reason != null) { sap.setReason(reason); } // Establecer fecha local del equipo if (useSystemDateTime) { sap.setSignDate(new GregorianCalendar()); } // Gestion de los cifrados if (pdfReader.isEncrypted() && (ownerPassword != null || userPassword != null)) { if (Boolean.TRUE.toString().equalsIgnoreCase(extraParams.getProperty("avoidEncryptingSignedPdfs"))) { //$NON-NLS-1$ LOGGER.info( "Aunque el PDF original estaba encriptado no se encriptara el PDF firmado (se establecio el indicativo 'avoidEncryptingSignedPdfs')" //$NON-NLS-1$ ); } else { LOGGER.info("El PDF original estaba encriptado, se intentara encriptar tambien el PDF firmado" //$NON-NLS-1$ ); try { stp.setEncryption(ownerPassword != null ? ownerPassword.getBytes() : null, userPassword != null ? userPassword.getBytes() : null, pdfReader.getPermissions(), pdfReader.getCryptoMode()); } catch (final DocumentException de) { LOGGER.warning("No se ha podido cifrar el PDF destino, se escribira sin contrasena: " + de //$NON-NLS-1$ ); } } } // Pagina en donde se imprime la firma if (page == LAST_PAGE) { page = pdfReader.getNumberOfPages(); } // Posicion de la firma final Rectangle signaturePositionOnPage = getSignaturePositionOnPage(extraParams); if (signaturePositionOnPage != null && signatureField == null) { sap.setVisibleSignature(signaturePositionOnPage, page, null); } else if (signatureField != null) { sap.setVisibleSignature(signatureField); } // Localizacion en donde se produce la firma if (signatureProductionCity != null) { sap.setLocation(signatureProductionCity); } // Contacto del firmante if (signerContact != null) { sap.setContact(signerContact); } // Rubrica de la firma if (rubric != null) { sap.setImage(rubric); sap.setLayer2Text(""); //$NON-NLS-1$ sap.setLayer4Text(""); //$NON-NLS-1$ } // ************************** // ** Texto en las capas **** // ************************** // Capa 2 if (layer2Text != null) { sap.setLayer2Text(layer2Text); final int layer2FontColorR; final int layer2FontColorG; final int layer2FontColorB; if ("black".equalsIgnoreCase(layer2FontColor)) { //$NON-NLS-1$ layer2FontColorR = 0; layer2FontColorG = 0; layer2FontColorB = 0; } else if ("white".equalsIgnoreCase(layer2FontColor)) { //$NON-NLS-1$ layer2FontColorR = 255; layer2FontColorG = 255; layer2FontColorB = 255; } else if ("lightGray".equalsIgnoreCase(layer2FontColor)) { //$NON-NLS-1$ layer2FontColorR = 192; layer2FontColorG = 192; layer2FontColorB = 192; } else if ("gray".equalsIgnoreCase(layer2FontColor)) { //$NON-NLS-1$ layer2FontColorR = 128; layer2FontColorG = 128; layer2FontColorB = 128; } else if ("darkGray".equalsIgnoreCase(layer2FontColor)) { //$NON-NLS-1$ layer2FontColorR = 64; layer2FontColorG = 64; layer2FontColorB = 64; } else if ("red".equalsIgnoreCase(layer2FontColor)) { //$NON-NLS-1$ layer2FontColorR = 255; layer2FontColorG = 0; layer2FontColorB = 0; } else if ("pink".equalsIgnoreCase(layer2FontColor)) { //$NON-NLS-1$ layer2FontColorR = 255; layer2FontColorG = 175; layer2FontColorB = 175; } else if (layer2FontColor == null) { layer2FontColorR = 0; layer2FontColorG = 0; layer2FontColorB = 0; } else { LOGGER.warning("No se soporta el color '" + layer2FontColor //$NON-NLS-1$ + "' para el texto de la capa 4, se usara negro"); //$NON-NLS-1$ layer2FontColorR = 0; layer2FontColorG = 0; layer2FontColorB = 0; } com.lowagie.text.Font font; try { Class<?> colorClass; if (Platform.getOS() == OS.ANDROID) { colorClass = Class.forName("harmony.java.awt.Color"); //$NON-NLS-1$ } else { colorClass = Class.forName("java.awt.Color"); //$NON-NLS-1$ } final Object color = colorClass.getConstructor(Integer.TYPE, Integer.TYPE, Integer.TYPE) .newInstance(layer2FontColorR, layer2FontColorG, layer2FontColorB); font = com.lowagie.text.Font.class .getConstructor(Integer.TYPE, Integer.TYPE, Integer.TYPE, colorClass).newInstance( // Family (COURIER = 0, HELVETICA = 1, TIMES_ROMAN = 2, SYMBOL = 3, ZAPFDINGBATS = 4) layer2FontFamily == UNDEFINED ? COURIER : layer2FontFamily, // Size (DEFAULTSIZE = 12) layer2FontSize == UNDEFINED ? DEFAULT_LAYER_2_FONT_SIZE : layer2FontSize, // Style (NORMAL = 0, BOLD = 1, ITALIC = 2, BOLDITALIC = 3, UNDERLINE = 4, STRIKETHRU = 8) layer2FontStyle == UNDEFINED ? com.lowagie.text.Font.NORMAL : layer2FontStyle, // Color color); } catch (Exception e) { font = new com.lowagie.text.Font( // Family (COURIER = 0, HELVETICA = 1, TIMES_ROMAN = 2, SYMBOL = 3, ZAPFDINGBATS = 4) layer2FontFamily == UNDEFINED ? COURIER : layer2FontFamily, // Size (DEFAULTSIZE = 12) layer2FontSize == UNDEFINED ? DEFAULT_LAYER_2_FONT_SIZE : layer2FontSize, // Style (NORMAL = 0, BOLD = 1, ITALIC = 2, BOLDITALIC = 3, UNDERLINE = 4, STRIKETHRU = 8) layer2FontStyle == UNDEFINED ? com.lowagie.text.Font.NORMAL : layer2FontStyle, // Color null); } sap.setLayer2Font(font); } // Capa 4 if (layer4Text != null) { sap.setLayer4Text(layer4Text); } // *************************** // ** Fin texto en las capas * // *************************** sap.setCrypto(null, certChain, null, null); final PdfSignature dic = new PdfSignature(PdfName.ADOBE_PPKLITE, signatureSubFilter != null && !"".equals(signatureSubFilter) ? new PdfName(signatureSubFilter) //$NON-NLS-1$ : PdfName.ADBE_PKCS7_DETACHED); // Fecha de firma if (sap.getSignDate() != null) { dic.setDate(new PdfDate(sap.getSignDate())); } dic.setName(PdfPKCS7.getSubjectFields((X509Certificate) certChain[0]).getField("CN")); //$NON-NLS-1$ if (sap.getReason() != null) { dic.setReason(sap.getReason()); } // Lugar de la firma if (sap.getLocation() != null) { dic.setLocation(sap.getLocation()); } // Contacto del firmante if (sap.getContact() != null) { dic.setContact(sap.getContact()); } sap.setCryptoDictionary(dic); // Certificacion del PDF (NOT_CERTIFIED = 0, CERTIFIED_NO_CHANGES_ALLOWED = 1, // CERTIFIED_FORM_FILLING = 2, CERTIFIED_FORM_FILLING_AND_ANNOTATIONS = 3) if (certificationLevel != -1) { sap.setCertificationLevel(certificationLevel); } // Reservamos el espacio necesario en el PDF para insertar la firma final HashMap<PdfName, Integer> exc = new HashMap<PdfName, Integer>(); exc.put(PdfName.CONTENTS, Integer.valueOf(CSIZE * 2 + 2)); sap.preClose(exc); // ******************************************************************************** // **************** CALCULO DEL SIGNED DATA *************************************** // ******************************************************************************** // La norma PAdES establece que si el algoritmo de huella digital es SHA1 debe usarse SigningCertificateV2, y en cualquier // otro caso deberia usarse SigningCertificateV2 boolean signingCertificateV2; if (extraParams.containsKey("signingCertificateV2")) { //$NON-NLS-1$ signingCertificateV2 = Boolean.parseBoolean(extraParams.getProperty("signingCertificateV2")); //$NON-NLS-1$ } else { signingCertificateV2 = !"SHA1".equals(AOSignConstants.getDigestAlgorithmName(algorithm)); //$NON-NLS-1$ } byte[] completeCAdESSignature = GenCAdESEPESSignedData.generateSignedData( new P7ContentSignerParameters(inPDF, algorithm), true, // omitContent new AdESPolicy(extraParams), signingCertificateV2, key, certChain, MessageDigest.getInstance(AOSignConstants.getDigestAlgorithmName(algorithm)) .digest(AOUtil.getDataFromInputStream(sap.getRangeStream())), AOSignConstants.getDigestAlgorithmName(algorithm), true, // Modo PAdES PDF_OID, extraParams.getProperty("contentDescription") != null //$NON-NLS-1$ ? extraParams.getProperty("contentDescription") //$NON-NLS-1$ : PDF_DESC); //***************** SELLO DE TIEMPO **************** final String tsa = extraParams.getProperty("tsaURL"); //$NON-NLS-1$ URI tsaURL; if (tsa != null) { try { tsaURL = new URI(tsa); } catch (final Exception e) { LOGGER.warning("Se ha indicado una URL de TSA invalida (" + tsa //$NON-NLS-1$ + "), no se anadira sello de tiempo: " + e); //$NON-NLS-1$ tsaURL = null; } if (tsaURL != null) { final String tsaPolicy = extraParams.getProperty("tsaPolicy"); //$NON-NLS-1$ if (tsaPolicy == null) { LOGGER.warning( "Se ha indicado una URL de TSA pero no una politica, no se anadira sello de tiempo"); //$NON-NLS-1$ } else { final String tsaHashAlgorithm = extraParams.getProperty("tsaHashAlgorithm"); //$NON-NLS-1$ completeCAdESSignature = new CMSTimestamper( !Boolean.FALSE.toString().equalsIgnoreCase(extraParams.getProperty("tsaRequireCert")), //$NON-NLS-1$ tsaPolicy, tsaURL, extraParams.getProperty("tsaUsr"), //$NON-NLS-1$ extraParams.getProperty("tsaPwd"), //$NON-NLS-1$ extraParams.getProperty("tsaExtensionOid") != null //$NON-NLS-1$ && extraParams.getProperty("tsaExtensionValueBase64") != null ? //$NON-NLS-1$ new TsaRequestExtension[] { new TsaRequestExtension( extraParams.getProperty("tsaExtensionOid"), //$NON-NLS-1$ Boolean.getBoolean(extraParams .getProperty("tsaExtensionCritical", "false")), //$NON-NLS-1$ //$NON-NLS-2$ Base64.decode( extraParams.getProperty("tsaExtensionValueBase64")) //$NON-NLS-1$ ) } : null).addTimestamp(completeCAdESSignature, AOAlgorithmID.getOID(AOSignConstants.getDigestAlgorithmName( tsaHashAlgorithm != null ? tsaHashAlgorithm : "SHA1"))); //$NON-NLS-1$ } } } //************** FIN SELLO DE TIEMPO **************** // ******************************************************************************** // *************** FIN CALCULO DEL SIGNED DATA ************************************ // ******************************************************************************** final byte[] outc = new byte[CSIZE]; if (outc.length < completeCAdESSignature.length) { throw new AOException("La firma generada tiene un tamano (" + completeCAdESSignature.length //$NON-NLS-1$ + ") mayor que el permitido (" + outc.length + ")" //$NON-NLS-1$ //$NON-NLS-2$ ); } final PdfDictionary dic2 = new PdfDictionary(); System.arraycopy(completeCAdESSignature, 0, outc, 0, completeCAdESSignature.length); dic2.put(PdfName.CONTENTS, new PdfString(outc).setHexWriting(true)); sap.close(dic2); return baos.toByteArray(); }
From source file:es.gob.afirma.signers.pades.PdfSessionManager.java
License:Open Source License
/** Obtiene los datos PDF relevantes en cuanto a las firmas electrónicas, consistentes en los datos * a ser firmados con CAdES o PKCS#7 y los metadatos necesarios para su correcta inserción en el PDF. * @param inPDF Documento PDF que se desea firmar * @param certChain Cadena de certificados del firmante * @param signTime Hora de la firma/*w w w . j a v a2 s . co m*/ * @param extraParams Parámetros adicionales de la firma * @return Datos PDF relevantes en cuanto a las firmas electrónicas * @throws AOException En caso de que ocurra cualquier otro tipo de error * @throws IOException En caso de errores de entrada / salida * @throws DocumentException Si ocurren errores en la estampaciín de la firma PDF */ public static PdfTriPhaseSession getSessionData(final byte[] inPDF, final Certificate[] certChain, final Calendar signTime, final Properties extraParams) throws AOException, IOException, DocumentException { // ********************************************************************************************************************* // **************** LECTURA PARAMETROS ADICIONALES ********************************************************************* // ********************************************************************************************************************* // Forzar la creacion de revisiones incluso en PDF no firmados final boolean alwaysCreateRevision = Boolean .parseBoolean(extraParams.getProperty("alwaysCreateRevision", "true")); //$NON-NLS-1$ //$NON-NLS-2$ // Imagen de la rubrica final Image rubric = PdfPreProcessor.getImage(extraParams.getProperty("signatureRubricImage")); //$NON-NLS-1$ // Motivo de la firma final String reason = extraParams.getProperty("signReason"); //$NON-NLS-1$ // Nombre del campo de firma preexistente en el PDF a usar final String signatureField = extraParams.getProperty("signatureField"); //$NON-NLS-1$ // Lugar de realizacion de la firma final String signatureProductionCity = extraParams.getProperty("signatureProductionCity"); //$NON-NLS-1$ // Datos de contacto (correo electronico) del firmante final String signerContact = extraParams.getProperty("signerContact"); //$NON-NLS-1$ // Pagina donde situar la firma visible int page = LAST_PAGE; try { page = Integer.parseInt(extraParams.getProperty("signaturePage")); //$NON-NLS-1$ } catch (final Exception e) { /* Se deja la pagina tal y como esta */ } // Nombre del subfiltro de firma en el diccionario PDF final String signatureSubFilter = extraParams.getProperty("signatureSubFilter"); //$NON-NLS-1$ // Nivel de certificacion del PDF int certificationLevel; try { certificationLevel = extraParams.getProperty("certificationLevel") != null ? //$NON-NLS-1$ Integer.parseInt(extraParams.getProperty("certificationLevel")) : //$NON-NLS-1$ -1; } catch (final Exception e) { certificationLevel = UNDEFINED; } // ***************************** // **** Texto firma visible **** // Texto en capa 4 final String layer4Text = extraParams.getProperty("layer4Text"); //$NON-NLS-1$ // Texto en capa 2 final String layer2Text = extraParams.getProperty("layer2Text"); //$NON-NLS-1$ // Tipo de letra en capa 2 int layer2FontFamily; try { layer2FontFamily = extraParams.getProperty("layer2FontFamily") != null ? //$NON-NLS-1$ Integer.parseInt(extraParams.getProperty("layer2FontFamily")) : //$NON-NLS-1$ -1; } catch (final Exception e) { layer2FontFamily = UNDEFINED; } // Tamano del tipo de letra en capa 2 int layer2FontSize; try { layer2FontSize = extraParams.getProperty("layer2FontSize") != null ? //$NON-NLS-1$ Integer.parseInt(extraParams.getProperty("layer2FontSize")) : //$NON-NLS-1$ -1; } catch (final Exception e) { layer2FontSize = UNDEFINED; } // Estilo del tipo de letra en capa 2 int layer2FontStyle; try { layer2FontStyle = extraParams.getProperty("layer2FontStyle") != null ? //$NON-NLS-1$ Integer.parseInt(extraParams.getProperty("layer2FontStyle")) : //$NON-NLS-1$ -1; } catch (final Exception e) { layer2FontStyle = UNDEFINED; } // Color del tipo de letra en capa 2 final String layer2FontColor = extraParams.getProperty("layer2FontColor"); //$NON-NLS-1$ // ** Fin texto firma visible ** // ***************************** // ********************************************************************************************************************* // **************** FIN LECTURA PARAMETROS ADICIONALES ***************************************************************** // ********************************************************************************************************************* final PdfReader pdfReader = PdfUtil.getPdfReader(inPDF, extraParams, Boolean.getBoolean(extraParams.getProperty("headLess")) //$NON-NLS-1$ ); //PdfUtil.checkPdfCertification(pdfReader.getCertificationLevel(), extraParams); //PdfUtil.checkUnregisteredSignatures(pdfReader, extraParams); // Los derechos van firmados por Adobe, y como desde iText se invalidan // es mejor quitarlos pdfReader.removeUsageRights(); final ByteArrayOutputStream baos = new ByteArrayOutputStream(); // Activar el atributo de "agregar firma" (quinto parametro del metodo // "PdfStamper.createSignature") hace que se cree una nueva revision del // documento y evita que las firmas previas queden invalidadas. // Sin embargo, este procedimiento no funciona cuando los PDF contienen informacion // despues de la ultima marca %%EOF, aspecto no permitido en PDF 1.7 (ISO 32000-1:2008) // pero si en PDF 1.3 (Adobe) y que se da con frecuencia en PDF generados con bibliotetcas // de software libre como QPDF. // // Especificacion PDF 1.3 // 3.4.4, "File Trailer" // Acrobat viewers require only that the %%EOF marker appear somewhere within // the last 1024 bytes of the file. // // Especificacion PDF 1.7 // 7.5.5. File Trailer // The trailer of a PDF file enables a conforming reader to quickly find the // cross-reference table and certain special objects. Conforming readers should read a // PDF file from its end. The last line of the file shall contain only the end-of-file // marker, %%EOF. // // Para aceptar al menos en algunos casos PDF 1.3 (son aun muy frecuentes, especialmente // en archivos, lo mantendremos desactivado para la primera firma y activado para las // subsiguientes. // // No obstante, el integrador puede siempre forzar la creacion de revisiones mediante // el parametro "alwaysCreateRevision". final PdfStamper stp; try { stp = PdfStamper.createSignature( // PDF de entrada pdfReader, // Salida baos, // Mantener version '\0', // No crear temporal null, // Si hay mas firmas o asi me lo indican, creo una revision alwaysCreateRevision || pdfReader.getAcroFields().getSignatureNames().size() > 0, // Momento de la firma signTime); } catch (final BadPasswordException e) { // Comprobamos que el signer esta en modo interactivo, y si no lo // esta no pedimos contrasena por dialogo, principalmente para no interrumpir un firmado por lotes // desatendido if (Boolean.getBoolean(extraParams.getProperty("headLess"))) { //$NON-NLS-1$ throw new BadPdfPasswordException(e); } // La contrasena que nos han proporcionada no es buena o no nos // proporcionaron ninguna final String userPwd = new String(AOUIFactory.getPassword( extraParams.getProperty("userPassword") == null ? CommonPdfMessages.getString("AOPDFSigner.0") //$NON-NLS-1$//$NON-NLS-2$ : CommonPdfMessages.getString("AOPDFSigner.1"), //$NON-NLS-1$ null)); if ("".equals(userPwd)) { //$NON-NLS-1$ throw new AOCancelledOperationException("Entrada de contrasena de PDF cancelada por el usuario", e //$NON-NLS-1$ ); } extraParams.put("userPassword", userPwd); //$NON-NLS-1$ return getSessionData(inPDF, certChain, signTime, extraParams); } // Aplicamos todos los atributos de firma final PdfSignatureAppearance sap = stp.getSignatureAppearance(); stp.setFullCompression(); sap.setAcro6Layers(true); PdfUtil.enableLtv(stp); // Adjuntos PdfPreProcessor.attachFile(extraParams, stp); // Imagenes PdfPreProcessor.addImage(extraParams, stp); // Establecemos el render segun iText antiguo, varia en versiones modernas sap.setRender(PdfSignatureAppearance.SignatureRenderDescription); // Razon de firma if (reason != null) { sap.setReason(reason); } sap.setSignDate(signTime); // Gestion de los cifrados PdfUtil.managePdfEncryption(stp, pdfReader, extraParams); // Pagina en donde se imprime la firma if (page == LAST_PAGE) { page = pdfReader.getNumberOfPages(); } // Posicion de la firma final Rectangle signaturePositionOnPage = getSignaturePositionOnPage(extraParams); if (signaturePositionOnPage != null && signatureField == null) { sap.setVisibleSignature(signaturePositionOnPage, page, null); } else if (signatureField != null) { sap.setVisibleSignature(signatureField); } // Localizacion en donde se produce la firma if (signatureProductionCity != null) { sap.setLocation(signatureProductionCity); } // Contacto del firmante if (signerContact != null) { sap.setContact(signerContact); } // Rubrica de la firma if (rubric != null) { sap.setImage(rubric); sap.setLayer2Text(""); //$NON-NLS-1$ sap.setLayer4Text(""); //$NON-NLS-1$ } // ************************** // ** Texto en las capas **** // ************************** // Capa 2 if (layer2Text != null) { sap.setLayer2Text(layer2Text); final int layer2FontColorR; final int layer2FontColorG; final int layer2FontColorB; if ("black".equalsIgnoreCase(layer2FontColor)) { //$NON-NLS-1$ layer2FontColorR = 0; layer2FontColorG = 0; layer2FontColorB = 0; } else if ("white".equalsIgnoreCase(layer2FontColor)) { //$NON-NLS-1$ layer2FontColorR = 255; layer2FontColorG = 255; layer2FontColorB = 255; } else if ("lightGray".equalsIgnoreCase(layer2FontColor)) { //$NON-NLS-1$ layer2FontColorR = 192; layer2FontColorG = 192; layer2FontColorB = 192; } else if ("gray".equalsIgnoreCase(layer2FontColor)) { //$NON-NLS-1$ layer2FontColorR = 128; layer2FontColorG = 128; layer2FontColorB = 128; } else if ("darkGray".equalsIgnoreCase(layer2FontColor)) { //$NON-NLS-1$ layer2FontColorR = 64; layer2FontColorG = 64; layer2FontColorB = 64; } else if ("red".equalsIgnoreCase(layer2FontColor)) { //$NON-NLS-1$ layer2FontColorR = 255; layer2FontColorG = 0; layer2FontColorB = 0; } else if ("pink".equalsIgnoreCase(layer2FontColor)) { //$NON-NLS-1$ layer2FontColorR = 255; layer2FontColorG = 175; layer2FontColorB = 175; } else if (layer2FontColor == null) { layer2FontColorR = 0; layer2FontColorG = 0; layer2FontColorB = 0; } else { LOGGER.warning("No se soporta el color '" + layer2FontColor //$NON-NLS-1$ + "' para el texto de la capa 4, se usara negro"); //$NON-NLS-1$ layer2FontColorR = 0; layer2FontColorG = 0; layer2FontColorB = 0; } com.lowagie.text.Font font; try { Class<?> colorClass; if (Platform.getOS() == OS.ANDROID) { colorClass = Class.forName("harmony.java.awt.Color"); //$NON-NLS-1$ } else { colorClass = Class.forName("java.awt.Color"); //$NON-NLS-1$ } final Object color = colorClass.getConstructor(Integer.TYPE, Integer.TYPE, Integer.TYPE) .newInstance(Integer.valueOf(layer2FontColorR), Integer.valueOf(layer2FontColorG), Integer.valueOf(layer2FontColorB)); font = com.lowagie.text.Font.class .getConstructor(Integer.TYPE, Float.TYPE, Integer.TYPE, colorClass).newInstance( // Family (COURIER = 0, HELVETICA = 1, TIMES_ROMAN = 2, SYMBOL = 3, ZAPFDINGBATS = 4) Integer.valueOf(layer2FontFamily == UNDEFINED ? COURIER : layer2FontFamily), // Size (DEFAULTSIZE = 12) Float.valueOf( layer2FontSize == UNDEFINED ? DEFAULT_LAYER_2_FONT_SIZE : layer2FontSize), // Style (NORMAL = 0, BOLD = 1, ITALIC = 2, BOLDITALIC = 3, UNDERLINE = 4, STRIKETHRU = 8) Integer.valueOf(layer2FontStyle == UNDEFINED ? com.lowagie.text.Font.NORMAL : layer2FontStyle), // Color color); } catch (final Exception e) { font = new com.lowagie.text.Font( // Family (COURIER = 0, HELVETICA = 1, TIMES_ROMAN = 2, SYMBOL = 3, ZAPFDINGBATS = 4) layer2FontFamily == UNDEFINED ? COURIER : layer2FontFamily, // Size (DEFAULTSIZE = 12) layer2FontSize == UNDEFINED ? DEFAULT_LAYER_2_FONT_SIZE : layer2FontSize, // Style (NORMAL = 0, BOLD = 1, ITALIC = 2, BOLDITALIC = 3, UNDERLINE = 4, STRIKETHRU = 8) layer2FontStyle == UNDEFINED ? com.lowagie.text.Font.NORMAL : layer2FontStyle, // Color null); } sap.setLayer2Font(font); } // Capa 4 if (layer4Text != null) { sap.setLayer4Text(layer4Text); } // *************************** // ** Fin texto en las capas * // *************************** sap.setCrypto(null, certChain, null, null); final PdfSignature dic = new PdfSignature(PdfName.ADOBE_PPKLITE, signatureSubFilter != null && !"".equals(signatureSubFilter) ? new PdfName(signatureSubFilter) //$NON-NLS-1$ : PdfName.ADBE_PKCS7_DETACHED); // Fecha de firma if (sap.getSignDate() != null) { dic.setDate(new PdfDate(sap.getSignDate())); } dic.setName(PdfPKCS7.getSubjectFields((X509Certificate) certChain[0]).getField("CN")); //$NON-NLS-1$ if (sap.getReason() != null) { dic.setReason(sap.getReason()); } // Lugar de la firma if (sap.getLocation() != null) { dic.setLocation(sap.getLocation()); } // Contacto del firmante if (sap.getContact() != null) { dic.setContact(sap.getContact()); } sap.setCryptoDictionary(dic); // Certificacion del PDF (NOT_CERTIFIED = 0, CERTIFIED_NO_CHANGES_ALLOWED = 1, // CERTIFIED_FORM_FILLING = 2, CERTIFIED_FORM_FILLING_AND_ANNOTATIONS = 3) if (certificationLevel != -1) { sap.setCertificationLevel(certificationLevel); } // Reservamos el espacio necesario en el PDF para insertar la firma final HashMap<PdfName, Integer> exc = new HashMap<PdfName, Integer>(); exc.put(PdfName.CONTENTS, Integer.valueOf(CSIZE * 2 + 2)); sap.preClose(exc, signTime); final PdfObject pdfObject = ((com.lowagie.text.pdf.PdfStamperImp) stp.getWriter()).getFileID(); return new PdfTriPhaseSession(sap, baos, new String(pdfObject.getBytes())); }
From source file:eu.europa.ec.markt.dss.validation.pades.PDFDocumentValidator.java
License:Open Source License
@Override protected SignatureLevelLTV verifyLevelLTV(AdvancedSignature signature, Date referenceTime, ValidationContext ctx) {// w w w . ja va 2s .c om try { PAdESSignature pades = (PAdESSignature) signature; LOG.info("Starting LTV validation of signature: " + pades.getPdfPkcs7().getSignName() + " / " + PdfPKCS7.getSubjectFields(pades.getPdfPkcs7().getSigningCertificate())); PdfDictionary catalog = pades.getOuterCatalog(); if (catalog == null) { catalog = pades.getPdfReader().getCatalog(); } PdfDictionary dss = catalog.getAsDict(new PdfName("DSS")); if (dss == null) { LOG.info("No DSS dictionary!"); return new SignatureLevelLTV(new Result(ResultStatus.INVALID, "no.dss.dictionary"), null, null); } LOG.info("DSS dictionary found"); PdfName sigType = pades.getSignatureDictionary().getAsName(PdfName.TYPE); // PdfName subfilter = pades.getSignatureDictionary().getAsName(PdfName.SUBFILTER); TimestampVerificationResult docTimestampCheck = null; boolean dssCertsVerificationResult = everyCertificateValueAreThere(ctx, pades.getExtendedCertificateSource().getCertificates(), pades.getSigningCertificate()); boolean dssRevocationVerificationResult = true; dssRevocationVerificationResult &= everyCRLValueOrRefAreThere(ctx, pades.getCRLs()); dssRevocationVerificationResult &= everyOCSPValueOrRefAreThere(ctx, pades.getOCSPs()); boolean vriVerificationresult = true; if (sigType != null) { if (sigType.equals(new PdfName("Sig"))) { // Standard signature PdfDictionary vri = dss.getAsDict(new PdfName("VRI")); if (vri == null) { LOG.info("No VRI dictionary, this is optional but required by Adobe Acrobat"); return new SignatureLevelLTV(new Result(ResultStatus.INVALID, "no.vri.dictionary"), null, null); } // Verify the VRI MessageDigest _md = MessageDigest.getInstance("SHA1"); String hexHash = Hex .encodeHexString( _md.digest(pades.getSignatureDictionary().get(PdfName.CONTENTS).getBytes())) .toUpperCase(); } else if (sigType.equals(new PdfName("DocTimeStamp"))) { } else { throw new RuntimeException("Unknown signature dictionary type"); } } Result levelReached = null; if (dssCertsVerificationResult && dssRevocationVerificationResult) { levelReached = new Result(ResultStatus.VALID, null); } else { levelReached = new Result(); if (!dssCertsVerificationResult) { levelReached.setStatus(ResultStatus.INVALID, "dss.certs.verification.result.error"); } else if (!dssRevocationVerificationResult) { levelReached.setStatus(ResultStatus.INVALID, "dss.revocation.verification.result.error"); } else if (!vriVerificationresult) { levelReached.setStatus(ResultStatus.INVALID, "vri.verification.result.error"); } } return new SignatureLevelLTV(levelReached, new Result((dssCertsVerificationResult) ? ResultStatus.VALID : ResultStatus.INVALID, null), new Result((dssRevocationVerificationResult) ? ResultStatus.VALID : ResultStatus.INVALID, null)); } catch (NoSuchAlgorithmException e) { throw new RuntimeException(e); } }
From source file:net.sf.jsignpdf.SignerLogic.java
License:Mozilla Public License
/** * Signs a single file./*from w ww. ja v a2s .co m*/ * * @return true when signing is finished succesfully, false otherwise */ public boolean signFile() { final String outFile = options.getOutFileX(); if (!validateInOutFiles(options.getInFile(), outFile)) { LOGGER.info(RES.get("console.skippingSigning")); return false; } boolean finished = false; Throwable tmpException = null; FileOutputStream fout = null; try { SSLInitializer.init(options); final PrivateKeyInfo pkInfo = KeyStoreUtils.getPkInfo(options); final PrivateKey key = pkInfo.getKey(); final Certificate[] chain = pkInfo.getChain(); if (ArrayUtils.isEmpty(chain)) { // the certificate was not found LOGGER.info(RES.get("console.certificateChainEmpty")); return false; } LOGGER.info(RES.get("console.createPdfReader", options.getInFile())); PdfReader reader; try { reader = new PdfReader(options.getInFile(), options.getPdfOwnerPwdStrX().getBytes()); } catch (Exception e) { try { reader = new PdfReader(options.getInFile(), new byte[0]); } catch (Exception e2) { // try to read without password reader = new PdfReader(options.getInFile()); } } LOGGER.info(RES.get("console.createOutPdf", outFile)); fout = new FileOutputStream(outFile); final HashAlgorithm hashAlgorithm = options.getHashAlgorithmX(); LOGGER.info(RES.get("console.createSignature")); char tmpPdfVersion = '\0'; // default version - the same as input if (reader.getPdfVersion() < hashAlgorithm.getPdfVersion()) { // this covers also problems with visible signatures (embedded // fonts) in PDF 1.2, because the minimal version // for hash algorithms is 1.3 (for SHA1) if (options.isAppendX()) { // if we are in append mode and version should be updated // then return false (not possible) LOGGER.info(RES.get("console.updateVersionNotPossibleInAppendMode")); return false; } tmpPdfVersion = hashAlgorithm.getPdfVersion(); LOGGER.info(RES.get("console.updateVersion", new String[] { String.valueOf(reader.getPdfVersion()), String.valueOf(tmpPdfVersion) })); } final PdfStamper stp = PdfStamper.createSignature(reader, fout, tmpPdfVersion, null, options.isAppendX()); if (!options.isAppendX()) { // we are not in append mode, let's remove existing signatures // (otherwise we're getting to troubles) final AcroFields acroFields = stp.getAcroFields(); @SuppressWarnings("unchecked") final List<String> sigNames = acroFields.getSignatureNames(); for (String sigName : sigNames) { acroFields.removeField(sigName); } } if (options.isAdvanced() && options.getPdfEncryption() != PDFEncryption.NONE) { LOGGER.info(RES.get("console.setEncryption")); final int tmpRight = options.getRightPrinting().getRight() | (options.isRightCopy() ? PdfWriter.ALLOW_COPY : 0) | (options.isRightAssembly() ? PdfWriter.ALLOW_ASSEMBLY : 0) | (options.isRightFillIn() ? PdfWriter.ALLOW_FILL_IN : 0) | (options.isRightScreanReaders() ? PdfWriter.ALLOW_SCREENREADERS : 0) | (options.isRightModifyAnnotations() ? PdfWriter.ALLOW_MODIFY_ANNOTATIONS : 0) | (options.isRightModifyContents() ? PdfWriter.ALLOW_MODIFY_CONTENTS : 0); switch (options.getPdfEncryption()) { case PASSWORD: stp.setEncryption(true, options.getPdfUserPwdStr(), options.getPdfOwnerPwdStrX(), tmpRight); break; case CERTIFICATE: final X509Certificate encCert = KeyStoreUtils .loadCertificate(options.getPdfEncryptionCertFile()); if (encCert == null) { LOGGER.error(RES.get("console.pdfEncError.wrongCertificateFile", StringUtils.defaultString(options.getPdfEncryptionCertFile()))); return false; } if (!KeyStoreUtils.isEncryptionSupported(encCert)) { LOGGER.error(RES.get("console.pdfEncError.cantUseCertificate", encCert.getSubjectDN().getName())); return false; } stp.setEncryption(new Certificate[] { encCert }, new int[] { tmpRight }, PdfWriter.ENCRYPTION_AES_128); break; default: LOGGER.error(RES.get("console.unsupportedEncryptionType")); return false; } } final PdfSignatureAppearance sap = stp.getSignatureAppearance(); sap.setCrypto(key, chain, null, PdfSignatureAppearance.WINCER_SIGNED); final String reason = options.getReason(); if (StringUtils.isNotEmpty(reason)) { LOGGER.info(RES.get("console.setReason", reason)); sap.setReason(reason); } final String location = options.getLocation(); if (StringUtils.isNotEmpty(location)) { LOGGER.info(RES.get("console.setLocation", location)); sap.setLocation(location); } final String contact = options.getContact(); if (StringUtils.isNotEmpty(contact)) { LOGGER.info(RES.get("console.setContact", contact)); sap.setContact(contact); } LOGGER.info(RES.get("console.setCertificationLevel")); sap.setCertificationLevel(options.getCertLevelX().getLevel()); if (options.isVisible()) { // visible signature is enabled LOGGER.info(RES.get("console.configureVisible")); LOGGER.info(RES.get("console.setAcro6Layers", Boolean.toString(options.isAcro6Layers()))); sap.setAcro6Layers(options.isAcro6Layers()); final String tmpImgPath = options.getImgPath(); if (tmpImgPath != null) { LOGGER.info(RES.get("console.createImage", tmpImgPath)); final Image img = Image.getInstance(tmpImgPath); LOGGER.info(RES.get("console.setSignatureGraphic")); sap.setSignatureGraphic(img); } final String tmpBgImgPath = options.getBgImgPath(); if (tmpBgImgPath != null) { LOGGER.info(RES.get("console.createImage", tmpBgImgPath)); final Image img = Image.getInstance(tmpBgImgPath); LOGGER.info(RES.get("console.setImage")); sap.setImage(img); } LOGGER.info(RES.get("console.setImageScale")); sap.setImageScale(options.getBgImgScale()); LOGGER.info(RES.get("console.setL2Text")); final String signer = PdfPKCS7.getSubjectFields((X509Certificate) chain[0]).getField("CN"); final String timestamp = new SimpleDateFormat("yyyy.MM.dd HH:mm:ss z") .format(sap.getSignDate().getTime()); if (options.getL2Text() != null) { final Map<String, String> replacements = new HashMap<String, String>(); replacements.put(L2TEXT_PLACEHOLDER_SIGNER, StringUtils.defaultString(signer)); replacements.put(L2TEXT_PLACEHOLDER_TIMESTAMP, timestamp); replacements.put(L2TEXT_PLACEHOLDER_LOCATION, StringUtils.defaultString(location)); replacements.put(L2TEXT_PLACEHOLDER_REASON, StringUtils.defaultString(reason)); replacements.put(L2TEXT_PLACEHOLDER_CONTACT, StringUtils.defaultString(contact)); final String l2text = StrSubstitutor.replace(options.getL2Text(), replacements); sap.setLayer2Text(l2text); } else { final StringBuilder buf = new StringBuilder(); buf.append(RES.get("default.l2text.signedBy")).append(" ").append(signer).append('\n'); buf.append(RES.get("default.l2text.date")).append(" ").append(timestamp); if (StringUtils.isNotEmpty(reason)) buf.append('\n').append(RES.get("default.l2text.reason")).append(" ").append(reason); if (StringUtils.isNotEmpty(location)) buf.append('\n').append(RES.get("default.l2text.location")).append(" ").append(location); sap.setLayer2Text(buf.toString()); } if (FontUtils.getL2BaseFont() != null) { sap.setLayer2Font(new Font(FontUtils.getL2BaseFont(), options.getL2TextFontSize())); } LOGGER.info(RES.get("console.setL4Text")); sap.setLayer4Text(options.getL4Text()); LOGGER.info(RES.get("console.setRender")); RenderMode renderMode = options.getRenderMode(); if (renderMode == RenderMode.GRAPHIC_AND_DESCRIPTION && sap.getSignatureGraphic() == null) { LOGGER.warn( "Render mode of visible signature is set to GRAPHIC_AND_DESCRIPTION, but no image is loaded. Fallback to DESCRIPTION_ONLY."); LOGGER.info(RES.get("console.renderModeFallback")); renderMode = RenderMode.DESCRIPTION_ONLY; } sap.setRender(renderMode.getRender()); LOGGER.info(RES.get("console.setVisibleSignature")); int page = options.getPage(); if (page < 1 || page > reader.getNumberOfPages()) { page = reader.getNumberOfPages(); } sap.setVisibleSignature(new Rectangle(options.getPositionLLX(), options.getPositionLLY(), options.getPositionURX(), options.getPositionURY()), page, null); } LOGGER.info(RES.get("console.processing")); final PdfSignature dic = new PdfSignature(PdfName.ADOBE_PPKLITE, new PdfName("adbe.pkcs7.detached")); if (!StringUtils.isEmpty(reason)) { dic.setReason(sap.getReason()); } if (!StringUtils.isEmpty(location)) { dic.setLocation(sap.getLocation()); } if (!StringUtils.isEmpty(contact)) { dic.setContact(sap.getContact()); } dic.setDate(new PdfDate(sap.getSignDate())); sap.setCryptoDictionary(dic); final Proxy tmpProxy = options.createProxy(); final CRLInfo crlInfo = new CRLInfo(options, chain); // CRLs are stored twice in PDF c.f. // PdfPKCS7.getAuthenticatedAttributeBytes final int contentEstimated = (int) (Constants.DEFVAL_SIG_SIZE + 2L * crlInfo.getByteCount()); final Map<PdfName, Integer> exc = new HashMap<PdfName, Integer>(); exc.put(PdfName.CONTENTS, new Integer(contentEstimated * 2 + 2)); sap.preClose(exc); PdfPKCS7 sgn = new PdfPKCS7(key, chain, crlInfo.getCrls(), hashAlgorithm.getAlgorithmName(), null, false); InputStream data = sap.getRangeStream(); final MessageDigest messageDigest = MessageDigest.getInstance(hashAlgorithm.getAlgorithmName()); byte buf[] = new byte[8192]; int n; while ((n = data.read(buf)) > 0) { messageDigest.update(buf, 0, n); } byte hash[] = messageDigest.digest(); Calendar cal = Calendar.getInstance(); byte[] ocsp = null; if (options.isOcspEnabledX() && chain.length >= 2) { LOGGER.info(RES.get("console.getOCSPURL")); String url = PdfPKCS7.getOCSPURL((X509Certificate) chain[0]); if (StringUtils.isEmpty(url)) { // get from options LOGGER.info(RES.get("console.noOCSPURL")); url = options.getOcspServerUrl(); } if (!StringUtils.isEmpty(url)) { LOGGER.info(RES.get("console.readingOCSP", url)); final OcspClientBouncyCastle ocspClient = new OcspClientBouncyCastle((X509Certificate) chain[0], (X509Certificate) chain[1], url); ocspClient.setProxy(tmpProxy); ocsp = ocspClient.getEncoded(); } } byte sh[] = sgn.getAuthenticatedAttributeBytes(hash, cal, ocsp); sgn.update(sh, 0, sh.length); TSAClientBouncyCastle tsc = null; if (options.isTimestampX() && !StringUtils.isEmpty(options.getTsaUrl())) { LOGGER.info(RES.get("console.creatingTsaClient")); if (options.getTsaServerAuthn() == ServerAuthentication.PASSWORD) { tsc = new TSAClientBouncyCastle(options.getTsaUrl(), StringUtils.defaultString(options.getTsaUser()), StringUtils.defaultString(options.getTsaPasswd())); } else { tsc = new TSAClientBouncyCastle(options.getTsaUrl()); } final String tsaHashAlg = options.getTsaHashAlgWithFallback(); LOGGER.info(RES.get("console.settingTsaHashAlg", tsaHashAlg)); tsc.setHashAlgorithm(tsaHashAlg); tsc.setProxy(tmpProxy); final String policyOid = options.getTsaPolicy(); if (StringUtils.isNotEmpty(policyOid)) { LOGGER.info(RES.get("console.settingTsaPolicy", policyOid)); tsc.setPolicy(policyOid); } } byte[] encodedSig = sgn.getEncodedPKCS7(hash, cal, tsc, ocsp); if (contentEstimated + 2 < encodedSig.length) { System.err.println( "SigSize - contentEstimated=" + contentEstimated + ", sigLen=" + encodedSig.length); throw new Exception("Not enough space"); } byte[] paddedSig = new byte[contentEstimated]; System.arraycopy(encodedSig, 0, paddedSig, 0, encodedSig.length); PdfDictionary dic2 = new PdfDictionary(); dic2.put(PdfName.CONTENTS, new PdfString(paddedSig).setHexWriting(true)); LOGGER.info(RES.get("console.closeStream")); sap.close(dic2); fout.close(); fout = null; finished = true; } catch (Exception e) { LOGGER.error(RES.get("console.exception"), e); } catch (OutOfMemoryError e) { LOGGER.fatal(RES.get("console.memoryError"), e); } finally { if (fout != null) { try { fout.close(); } catch (Exception e) { e.printStackTrace(); } } LOGGER.info(RES.get("console.finished." + (finished ? "ok" : "error"))); options.fireSignerFinishedEvent(tmpException); } return finished; }
From source file:net.sf.jsignpdf.verify.VerifierLogic.java
License:Mozilla Public License
/** * Verifies signature(s) in PDF document. * // ww w . j a v a 2 s .c o m * @param tmpReader * PdfReader for given PDF * @return */ @SuppressWarnings("unchecked") private VerificationResult verify(final PdfReader tmpReader) { final VerificationResult tmpResult = new VerificationResult(); try { final AcroFields tmpAcroFields = tmpReader.getAcroFields(); final List<String> tmpNames = tmpAcroFields.getSignatureNames(); tmpResult.setTotalRevisions(tmpAcroFields.getTotalRevisions()); final int lastSignatureIdx = tmpNames.size() - 1; if (lastSignatureIdx < 0) { // there is no signature tmpResult.setWithoutSignature(); } for (int i = lastSignatureIdx; i >= 0; i--) { final String name = tmpNames.get(i); final SignatureVerification tmpVerif = new SignatureVerification(name); tmpVerif.setLastSignature(i == lastSignatureIdx); tmpVerif.setWholeDocument(tmpAcroFields.signatureCoversWholeDocument(name)); tmpVerif.setRevision(tmpAcroFields.getRevision(name)); final PdfPKCS7 pk = tmpAcroFields.verifySignature(name); final TimeStampToken tst = pk.getTimeStampToken(); tmpVerif.setTsTokenPresent(tst != null); tmpVerif.setTsTokenValidationResult(validateTimeStampToken(tst)); tmpVerif.setDate(pk.getTimeStampDate() != null ? pk.getTimeStampDate() : pk.getSignDate()); tmpVerif.setLocation(pk.getLocation()); tmpVerif.setReason(pk.getReason()); tmpVerif.setSignName(pk.getSignName()); final Certificate pkc[] = pk.getCertificates(); final X509Name tmpX509Name = PdfPKCS7.getSubjectFields(pk.getSigningCertificate()); tmpVerif.setSubject(tmpX509Name.toString()); tmpVerif.setModified(!pk.verify()); tmpVerif.setOcspPresent(pk.getOcsp() != null); tmpVerif.setOcspValid(pk.isRevocationValid()); tmpVerif.setCrlPresent(pk.getCRLs() != null && pk.getCRLs().size() > 0); tmpVerif.setFails(PdfPKCS7.verifyCertificates(pkc, kall, pk.getCRLs(), tmpVerif.getDate())); tmpVerif.setSigningCertificate(pk.getSigningCertificate()); // generate CertPath List<Certificate> certList = Arrays.asList(pkc); CertificateFactory cf = CertificateFactory.getInstance("X.509"); CertPath cp = cf.generateCertPath(certList); tmpVerif.setCertPath(cp); // to save time - check OCSP in certificate only if document's OCSP is not present and valid if (!tmpVerif.isOcspValid()) { // try to get OCSP url from signing certificate String url = PdfPKCS7.getOCSPURL((X509Certificate) pk.getSigningCertificate()); tmpVerif.setOcspInCertPresent(url != null); if (url != null) { // OCSP url is found in signing certificate - verify certificate with that url tmpVerif.setOcspInCertValid(validateCertificateOCSP(pk.getSignCertificateChain(), url)); } } String certificateAlias = kall.getCertificateAlias(pk.getSigningCertificate()); if (certificateAlias != null) { // this means that signing certificate is directly trusted String verifyCertificate = PdfPKCS7.verifyCertificate(pk.getSigningCertificate(), pk.getCRLs(), tmpVerif.getDate()); if (verifyCertificate == null) { // this means that signing certificate is valid tmpVerif.setSignCertTrustedAndValid(true); } } final InputStream revision = tmpAcroFields.extractRevision(name); try { final PdfReader revisionReader = new PdfReader(revision); tmpVerif.setCertLevelCode(revisionReader.getCertificationLevel()); } finally { if (revision != null) { revision.close(); } } tmpResult.addVerification(tmpVerif); if (failFast && tmpVerif.containsError()) { return tmpResult; } } } catch (Exception e) { tmpResult.setException(e); } return tmpResult; }
From source file:org.opensignature.opensignpdf.PDFSigner.java
License:Open Source License
/** * Allow you to sign a PDF File with a PKCS11 session opened. * /*from w ww.j a va 2 s.co m*/ * @param mySign * @param session * @param pdfFiles * @param suffix * @param reason * @param signatureVisibility * @param cal * @throws OpenSignatureException * @throws TokenException * @throws IOException * @throws CertificateException * @throws OpenSignatureException * @throws KeyStoreException * @throws UnrecoverableKeyException * @throws NoSuchAlgorithmException * @throws FileNotFoundException * @throws DocumentException * @throws NoSuchAlgorithmException * @throws ExceptionConverter */ public void signPDFwithKS(KeyStore ks, String alias, String pwd, File[] pdfFiles, String suffix, String reason, boolean signatureVisibility, Calendar cal) throws OpenSignatureException, KeyStoreException, NoSuchAlgorithmException, UnrecoverableKeyException { if (pdfFiles == null || ks == null) { throw new OpenSignatureException("Invalid parameters."); } // -- System's date by default if (cal == null) { cal = Calendar.getInstance(); } logger.info("[signPDFwithKS.in]:: " + Arrays.asList(new Object[] { "<ks>", alias, Arrays.asList(pdfFiles), suffix, reason, Boolean.valueOf(signatureVisibility) })); if (alias == null) { Enumeration aliases = ks.aliases(); while (aliases.hasMoreElements()) { String alTmp = (String) aliases.nextElement(); logger.debug("[signPDFwithKS]:: alTmp: " + alTmp); X509Certificate x509certificate = (X509Certificate) ks.getCertificate(alTmp); boolean[] keyUsage = x509certificate.getKeyUsage(); if (keyUsage != null && (keyUsage[1] || keyUsage[0])) { alias = alTmp; break; } } } logger.debug("\n\n[signPDFwithKS]:: alias: " + alias + "\n\n"); PrivateKey key = (PrivateKey) ks.getKey(alias, pwd.toCharArray()); Certificate[] certs = ks.getCertificateChain(alias); for (int i = 0; i < pdfFiles.length; i++) { logger.info("[signPDFwithKS]:: Signing the file: " + pdfFiles[i].getAbsolutePath()); try { // -- Check the access to the PDF if (!pdfFiles[i].exists() || !pdfFiles[i].canRead()) { throw new FileNotFoundException( "The file '" + pdfFiles[i].getAbsolutePath() + "' doesn't exist."); } byte signatureBytes[] = new byte[128]; // -- Creating the OutputStream overwritting the file if it exists // previously File fOut = FileUtils.addSuffix(pdfFiles[i], suffix, true); FileOutputStream fos = new FileOutputStream(fOut); BufferedOutputStream bos = new BufferedOutputStream(fos); // -- Creating the reader PdfReader reader = createPDFReader(pdfFiles[i]); PdfStamperOSP stamper; if ("countersigner".equals(typeSignatureSelected)) { stamper = PdfStamperOSP.createSignature(reader, bos, '\0', null, true); } else { stamper = PdfStamperOSP.createSignature(reader, bos, '\0'); } PdfSignatureAppearanceOSP sap = stamper.getSignatureAppearance(); sap.setCrypto(null, certs, null, PdfSignatureAppearance.WINCER_SIGNED); sap.setReason(reason); if (signatureVisibility) { if ("countersigner".equals(typeSignatureSelected)) { sap.setCertified(0); sap.setVisibleSignature(fieldName); } else { sap.setCertified(2); if (!"".equals(fieldName)) { sap.setVisibleSignature(fieldName); } else { sap.setVisibleSignature(new com.lowagie.text.Rectangle(llx, lly, urx, ury), 1, null); } } } sap.setExternalDigest(new byte[128], new byte[20], "RSA"); PdfDictionary dic = new PdfDictionary(); dic.put(PdfName.FT, PdfName.SIG); dic.put(PdfName.FILTER, new PdfName("Adobe.PPKLite")); dic.put(PdfName.SUBFILTER, new PdfName("adbe.pkcs7.detached")); if (cal != null) { dic.put(PdfName.M, new PdfDate(cal)); } else { dic.put(PdfName.M, new PdfNull()); } dic.put(PdfName.NAME, new PdfString(PdfPKCS7.getSubjectFields((X509Certificate) certs[0]).getField("CN"))); dic.put(PdfName.REASON, new PdfString(reason)); sap.setCryptoDictionary(dic); HashMap exc = new HashMap(); exc.put(PdfName.CONTENTS, new Integer(0x5002)); sap.preClose(exc); byte[] content = IOUtils.streamToByteArray(sap.getRangeStream()); //SHA256, alias CMSSignedDataGenerator.DIGEST_SHA256, // alias NISTObjectIdentifiers.id_sha256.getId(), // alias "2.16.840.1.101.3.4.2.1" byte[] hash = MessageDigest.getInstance("2.16.840.1.101.3.4.2.1", "BC").digest(content); // costruzione degli authenticated attributes ASN1EncodableVector signedAttributes = buildSignedAttributes(hash, cal); byte[] bytesForSecondHash = IOUtils.toByteArray(new DERSet(signedAttributes)); // -- Signature generated with the private key of the KS Signature signature = Signature.getInstance("SHA256withRSA"); signature.initSign(key); signature.update(bytesForSecondHash); signatureBytes = signature.sign(); byte[] encodedPkcs7 = null; try { // Create the set of Hash algorithms DERConstructedSet digestAlgorithms = new DERConstructedSet(); // Creo manualmente la sequenza di digest algos ASN1EncodableVector algos = new ASN1EncodableVector(); //algos.add(new DERObjectIdentifier("1.3.14.3.2.26")); // SHA1 //SHA-256 algos.add(new DERObjectIdentifier("2.16.840.1.101.3.4.2.1")); algos.add(new DERNull()); digestAlgorithms.addObject(new DERSequence(algos)); // Create the contentInfo. ASN1EncodableVector ev = new ASN1EncodableVector(); ev.add(new DERObjectIdentifier("1.2.840.113549.1.7.1")); // PKCS7SignedData DERSequence contentinfo = new DERSequence(ev); // Get all the certificates // ASN1EncodableVector v = new ASN1EncodableVector(); for (int c = 0; c < certs.length; c++) { ASN1InputStream tempstream = new ASN1InputStream( new ByteArrayInputStream(certs[c].getEncoded())); v.add(tempstream.readObject()); } DERSet dercertificates = new DERSet(v); // Create signerinfo structure. // ASN1EncodableVector signerinfo = new ASN1EncodableVector(); // Add the signerInfo version // signerinfo.add(new DERInteger(1)); v = new ASN1EncodableVector(); v.add(CertUtil.getIssuer((X509Certificate) certs[0])); v.add(new DERInteger(((X509Certificate) certs[0]).getSerialNumber())); signerinfo.add(new DERSequence(v)); // Add the digestAlgorithm v = new ASN1EncodableVector(); //v.add(new DERObjectIdentifier("1.3.14.3.2.26")); // SHA1 //SHA-256 v.add(new DERObjectIdentifier("1.2.840.113549.1.7.1")); v.add(new DERNull()); signerinfo.add(new DERSequence(v)); // add the authenticated attribute if present signerinfo.add(new DERTaggedObject(false, 0, new DERSet(signedAttributes))); // Add the digestEncryptionAlgorithm v = new ASN1EncodableVector(); v.add(new DERObjectIdentifier("1.2.840.113549.1.1.1"));// RSA v.add(new DERNull()); signerinfo.add(new DERSequence(v)); // Add the encrypted digest signerinfo.add(new DEROctetString(signatureBytes)); // Add unsigned attributes (timestamp) if (serverTimestamp != null && !"".equals(serverTimestamp.toString())) { byte[] timestampHash = MessageDigest.getInstance("SHA-256").digest(signatureBytes); ASN1EncodableVector unsignedAttributes = buildUnsignedAttributes(timestampHash, serverTimestamp, usernameTimestamp, passwordTimestamp); if (unsignedAttributes != null) { signerinfo.add(new DERTaggedObject(false, 1, new DERSet(unsignedAttributes))); } } // Finally build the body out of all the components above ASN1EncodableVector body = new ASN1EncodableVector(); body.add(new DERInteger(1)); // pkcs7 version, always 1 body.add(digestAlgorithms); body.add(contentinfo); body.add(new DERTaggedObject(false, 0, dercertificates)); // Only allow one signerInfo body.add(new DERSet(new DERSequence(signerinfo))); // Now we have the body, wrap it in it's PKCS7Signed shell // and return it // ASN1EncodableVector whole = new ASN1EncodableVector(); whole.add(new DERObjectIdentifier("1.2.840.113549.1.7.2"));// PKCS7_SIGNED_DATA whole.add(new DERTaggedObject(0, new DERSequence(body))); encodedPkcs7 = IOUtils.toByteArray(new DERSequence(whole)); } catch (Exception e) { throw new ExceptionConverter(e); } PdfDictionary dic2 = new PdfDictionary(); byte out[] = new byte[0x5000 / 2]; System.arraycopy(encodedPkcs7, 0, out, 0, encodedPkcs7.length); dic2.put(PdfName.CONTENTS, new PdfString(out).setHexWriting(true)); sap.close(dic2); bos.close(); fos.close(); } catch (Exception e) { logger.warn("[signPDFwithKS]:: ", e); } } logger.info("[signPDFwithKS.out]:: "); }
From source file:org.opensignature.opensignpdf.PDFSigner.java
License:Open Source License
/** * @param mySign/*from w w w .j av a 2 s. c o m*/ * @param session * @param reason * @param signCertKeyObject * @param certs * @param stamper * @throws IOException * @throws DocumentException * @throws NoSuchAlgorithmException * @throws TokenException * @throws ExceptionConverter * @throws NoSuchProviderException */ private void createSignatureAppearance(MyPkcs11 mySign, Session session, String reason, Key signCertKeyObject, X509Certificate[] certs, PdfStamperOSP stamper, boolean signatureVisible, Calendar cal) throws IOException, DocumentException, NoSuchAlgorithmException, TokenException, ExceptionConverter, NoSuchProviderException { logger.info("[createSignatureAppearance.in]:: "); byte[] signatureBytes = new byte[128]; PdfSignatureAppearanceOSP sap = stamper.getSignatureAppearance(); sap.setCrypto(null, certs, null, PdfSignatureAppearance.WINCER_SIGNED); sap.setReason(reason); if (signatureVisible) { if ("countersigner".equals(typeSignatureSelected)) { sap.setCertified(0); sap.setVisibleSignature(fieldName); } else { sap.setCertified(0); if ((fieldName != null) && (!"".equals(fieldName))) { sap.setVisibleSignature(fieldName); } else { sap.setVisibleSignature(new com.lowagie.text.Rectangle(llx, lly, urx, ury), 1, null); } } } //aggiunta di grafico per la firma if ("true".equals(graphicSignSelected)) { sap.setSignatureGraphic(Image.getInstance(fileImgfirma)); sap.setRender(2); } else { sap.setRender(0); } sap.setExternalDigest(new byte[128], new byte[20], "RSA"); PdfDictionary dic = new PdfDictionary(); dic.put(PdfName.FT, PdfName.SIG); dic.put(PdfName.FILTER, new PdfName("Adobe.PPKLite")); dic.put(PdfName.SUBFILTER, new PdfName("adbe.pkcs7.detached")); if (cal != null) { dic.put(PdfName.M, new PdfDate(cal)); } else { dic.put(PdfName.M, new PdfNull()); } dic.put(PdfName.NAME, new PdfString(PdfPKCS7.getSubjectFields((X509Certificate) certs[0]).getField("CN"))); dic.put(PdfName.REASON, new PdfString(reason)); sap.setCryptoDictionary(dic); HashMap exc = new HashMap(); exc.put(PdfName.CONTENTS, new Integer(0x5002)); sap.preClose(exc); byte[] content = IOUtils.streamToByteArray(sap.getRangeStream()); byte[] hash = MessageDigest.getInstance("2.16.840.1.101.3.4.2.1", "BC").digest(content); // costruzione degli authenticated attributes ASN1EncodableVector signedAttributes = buildSignedAttributes(hash, cal); byte[] bytesForSecondHash = IOUtils.toByteArray(new DERSet(signedAttributes)); byte[] secondHash = MessageDigest.getInstance("2.16.840.1.101.3.4.2.1").digest(bytesForSecondHash); // -- Generatting the signature signatureBytes = mySign.sign(session, secondHash, signCertKeyObject); byte[] encodedPkcs7 = null; try { // Create the set of Hash algorithms DERConstructedSet digestAlgorithms = new DERConstructedSet(); // Creo manualmente la sequenza di digest algos ASN1EncodableVector algos = new ASN1EncodableVector(); //algos.add(new DERObjectIdentifier("1.3.14.3.2.26")); // SHA1 //SHA256 algos.add(new DERObjectIdentifier("2.16.840.1.101.3.4.2.1")); algos.add(new DERNull()); digestAlgorithms.addObject(new DERSequence(algos)); // Create the contentInfo. ASN1EncodableVector ev = new ASN1EncodableVector(); ev.add(new DERObjectIdentifier("1.2.840.113549.1.7.1")); // PKCS7SignedData DERSequence contentinfo = new DERSequence(ev); // Get all the certificates // ASN1EncodableVector v = new ASN1EncodableVector(); for (int c = 0; c < certs.length; c++) { ASN1InputStream tempstream = new ASN1InputStream(new ByteArrayInputStream(certs[c].getEncoded())); v.add(tempstream.readObject()); } DERSet dercertificates = new DERSet(v); // Create signerinfo structure. // ASN1EncodableVector signerinfo = new ASN1EncodableVector(); // Add the signerInfo version // signerinfo.add(new DERInteger(1)); v = new ASN1EncodableVector(); v.add(CertUtil.getIssuer(certs[0])); v.add(new DERInteger(certs[0].getSerialNumber())); signerinfo.add(new DERSequence(v)); // Add the digestAlgorithm v = new ASN1EncodableVector(); //v.add(new DERObjectIdentifier("1.3.14.3.2.26")); // SHA1 //SHA-256 v.add(new DERObjectIdentifier("2.16.840.1.101.3.4.2.1")); v.add(new DERNull()); signerinfo.add(new DERSequence(v)); // add the authenticated attribute if present signerinfo.add(new DERTaggedObject(false, 0, new DERSet(signedAttributes))); // Add the digestEncryptionAlgorithm v = new ASN1EncodableVector(); v.add(new DERObjectIdentifier("1.2.840.113549.1.1.1"));// RSA v.add(new DERNull()); signerinfo.add(new DERSequence(v)); // Add the encrypted digest signerinfo.add(new DEROctetString(signatureBytes)); // Add unsigned attributes (timestamp) if (serverTimestamp != null && !"".equals(serverTimestamp.toString())) { byte[] timestampHash = MessageDigest.getInstance("2.16.840.1.101.3.4.2.1", "BC") .digest(signatureBytes); ASN1EncodableVector unsignedAttributes = buildUnsignedAttributes(timestampHash, serverTimestamp, usernameTimestamp, passwordTimestamp); if (unsignedAttributes != null) { signerinfo.add(new DERTaggedObject(false, 1, new DERSet(unsignedAttributes))); } } // Finally build the body out of all the components above ASN1EncodableVector body = new ASN1EncodableVector(); body.add(new DERInteger(1)); // pkcs7 version, always 1 body.add(digestAlgorithms); body.add(contentinfo); body.add(new DERTaggedObject(false, 0, dercertificates)); // Only allow one signerInfo body.add(new DERSet(new DERSequence(signerinfo))); // Now we have the body, wrap it in it's PKCS7Signed shell // and return it // ASN1EncodableVector whole = new ASN1EncodableVector(); whole.add(new DERObjectIdentifier("1.2.840.113549.1.7.2"));// PKCS7_SIGNED_DATA whole.add(new DERTaggedObject(0, new DERSequence(body))); encodedPkcs7 = IOUtils.toByteArray(new DERSequence(whole)); } catch (Exception e) { throw new ExceptionConverter(e); } PdfDictionary dic2 = new PdfDictionary(); byte out[] = new byte[0x5000 / 2]; System.arraycopy(encodedPkcs7, 0, out, 0, encodedPkcs7.length); dic2.put(PdfName.CONTENTS, new PdfString(out).setHexWriting(true)); sap.close(dic2); logger.info("[createSignatureAppearance.retorna]:: "); }