List of usage examples for org.bouncycastle.asn1.cms SignerIdentifier SignerIdentifier
public SignerIdentifier(ASN1Primitive id)
From source file:dorkbox.util.crypto.CryptoX509.java
License:Apache License
/** * Creates a NEW signature block that contains the pkcs7 (minus content, which is the .SF file) * signature of the .SF file./*from w w w .j a va2 s . co m*/ * * It contains the hash of the data, and the verification signature. */ public static byte[] createSignature(byte[] signatureSourceData, X509CertificateHolder x509CertificateHolder, AsymmetricKeyParameter privateKey) { try { CMSTypedData content = new CMSProcessableByteArray(signatureSourceData); ASN1ObjectIdentifier contentTypeOID = new ASN1ObjectIdentifier(content.getContentType().getId()); ASN1EncodableVector digestAlgs = new ASN1EncodableVector(); ASN1EncodableVector signerInfos = new ASN1EncodableVector(); AlgorithmIdentifier sigAlgId = x509CertificateHolder.getSignatureAlgorithm(); AlgorithmIdentifier digAlgId = new DefaultDigestAlgorithmIdentifierFinder().find(sigAlgId); // use the bouncy-castle lightweight API to generate a hash of the signature source data (usually the signature file bytes) BcContentSignerBuilder contentSignerBuilder; AlgorithmIdentifier digEncryptionAlgorithm; if (privateKey instanceof ECPrivateKeyParameters) { contentSignerBuilder = new BcECDSAContentSignerBuilder(sigAlgId, digAlgId); digEncryptionAlgorithm = new AlgorithmIdentifier(DSAUtil.dsaOids[0], null); // 1.2.840.10040.4.1 // DSA hashID } else if (privateKey instanceof DSAPrivateKeyParameters) { contentSignerBuilder = new BcDSAContentSignerBuilder(sigAlgId, digAlgId); digEncryptionAlgorithm = new AlgorithmIdentifier(DSAUtil.dsaOids[0], null); // 1.2.840.10040.4.1 // DSA hashID } else if (privateKey instanceof RSAPrivateCrtKeyParameters) { contentSignerBuilder = new BcRSAContentSignerBuilder(sigAlgId, digAlgId); digEncryptionAlgorithm = new AlgorithmIdentifier(RSAUtil.rsaOids[0], null); // 1.2.840.113549.1.1.1 // RSA hashID } else { throw new RuntimeException("Invalid signature type. Only ECDSA, DSA, RSA supported."); } ContentSigner hashSigner = contentSignerBuilder.build(privateKey); OutputStream outputStream = hashSigner.getOutputStream(); outputStream.write(signatureSourceData, 0, signatureSourceData.length); outputStream.flush(); byte[] sigBytes = hashSigner.getSignature(); SignerIdentifier sigId = new SignerIdentifier( new IssuerAndSerialNumber(x509CertificateHolder.toASN1Structure())); SignerInfo inf = new SignerInfo(sigId, digAlgId, null, digEncryptionAlgorithm, new DEROctetString(sigBytes), (ASN1Set) null); digestAlgs.add(inf.getDigestAlgorithm()); signerInfos.add(inf); ASN1EncodableVector certs = new ASN1EncodableVector(); certs.add(x509CertificateHolder.toASN1Structure()); ContentInfo encInfo = new ContentInfo(contentTypeOID, null); SignedData sd = new SignedData(new DERSet(digestAlgs), encInfo, new BERSet(certs), null, new DERSet(signerInfos)); ContentInfo contentInfo = new ContentInfo(CMSObjectIdentifiers.signedData, sd); CMSSignedData cmsSignedData2 = new CMSSignedData(content, contentInfo); return cmsSignedData2.getEncoded(); } catch (Throwable t) { logger.error("Error signing data.", t); throw new RuntimeException("Error trying to sign data. " + t.getMessage()); } }
From source file:es.gob.afirma.envelopers.cades.CAdESEPESSignedAndEnvelopedData.java
License:Open Source License
/** Método que genera la firma de tipo SignedAndEnvelopedData. * @param parameters/* ww w . j a v a 2 s . c o m*/ * Parámetros necesarios para la generación de este * tipo. * @param config * Configuración del algoritmo para firmar * @param policy * Política del certificado. * @param certDest * Certificado del destino al cual va dirigido la firma. * @param dataType * Identifica el tipo del contenido a firmar. * @param keyEntry * Entrada a la clave de firma * @return Firma de tipo SignedAndEnvelopedData. * @throws java.io.IOException * Si ocurre algún problema leyendo o escribiendo los * datos * @throws java.security.cert.CertificateEncodingException * Si se produce alguna excepción con los certificados de * firma. * @throws java.security.NoSuchAlgorithmException * Si no se encuentra un algoritmo válido. */ byte[] genCADESEPESSignedAndEnvelopedData(final P7ContentSignerParameters parameters, final X509Certificate[] signerCertificateChain, final AOCipherConfig config, final AdESPolicy policy, final X509Certificate[] certDest, final String dataType, final PrivateKeyEntry keyEntry) throws IOException, CertificateEncodingException, NoSuchAlgorithmException { final SecretKey cipherKey = CAdESUtils.initEnvelopedData(config, certDest); // 1. VERSION // la version se mete en el constructor del signedAndEnvelopedData y es // 1 // 2. DIGESTALGORITM // buscamos que timo de algoritmo es y lo codificamos con su OID final String signatureAlgorithm; final String digestAlgorithm; final ASN1EncodableVector digestAlgs = new ASN1EncodableVector(); try { signatureAlgorithm = parameters.getSignatureAlgorithm(); digestAlgorithm = AOSignConstants.getDigestAlgorithmName(signatureAlgorithm); final AlgorithmIdentifier digAlgId = SigUtils.makeAlgId(AOAlgorithmID.getOID(digestAlgorithm)); digestAlgs.add(digAlgId); } catch (final Exception e) { throw new IOException("Error de codificacion: " + e, e); //$NON-NLS-1$ } // LISTA DE CERTIFICADOS: obtenemos la lista de certificados ASN1Set certificates = null; certificates = CAdESUtils.fetchCertificatesList(signerCertificateChain); // 2. RECIPIENTINFOS final Info infos = CAdESUtils.getEnvelopeInfo(parameters.getContent(), config, certDest, cipherKey); // 4. SIGNERINFO // raiz de la secuencia de SignerInfo final ASN1EncodableVector signerInfos = new ASN1EncodableVector(); final TBSCertificateStructure tbs2 = TBSCertificateStructure .getInstance(ASN1Primitive.fromByteArray(signerCertificateChain[0].getTBSCertificate())); final IssuerAndSerialNumber encSid = new IssuerAndSerialNumber(X500Name.getInstance(tbs2.getIssuer()), tbs2.getSerialNumber().getValue()); final SignerIdentifier identifier = new SignerIdentifier(encSid); // AlgorithmIdentifier final AlgorithmIdentifier digAlgId = new AlgorithmIdentifier( new ASN1ObjectIdentifier(AOAlgorithmID.getOID(digestAlgorithm)), new DERNull()); // // ATRIBUTOS final ASN1EncodableVector contextExpecific = CAdESUtils.generateSignerInfo(signerCertificateChain[0], digestAlgorithm, parameters.getContent(), policy, null); this.signedAttr2 = SigUtils.getAttributeSet(new AttributeTable(contextExpecific)); final ASN1Set signedAttr = SigUtils.getAttributeSet(new AttributeTable(contextExpecific)); // digEncryptionAlgorithm final AlgorithmIdentifier encAlgId; try { encAlgId = SigUtils.makeAlgId(AOAlgorithmID.getOID("RSA")); //$NON-NLS-1$ } catch (final Exception e) { throw new IOException("Error de codificacion: " + e, e); //$NON-NLS-1$ } final ASN1OctetString sign2; try { sign2 = firma(signatureAlgorithm, keyEntry); } catch (final AOException ex) { throw new IOException("Error en la firma electronica: " + ex, ex); //$NON-NLS-1$ } signerInfos.add(new SignerInfo(identifier, digAlgId, signedAttr, encAlgId, sign2, null // unsignedAttr )); final ASN1Set certrevlist = null; // construimos el Signed And Enveloped Data y lo devolvemos return new ContentInfo(PKCSObjectIdentifiers.signedAndEnvelopedData, new SignedAndEnvelopedData(new DERSet(infos.getRecipientInfos()), new DERSet(digestAlgs), infos.getEncInfo(), certificates, certrevlist, new DERSet(signerInfos))) .getEncoded(ASN1Encoding.DER); }
From source file:es.gob.afirma.envelopers.cades.CAdESEPESSignedAndEnvelopedData.java
License:Open Source License
/** Método que inserta remitentes en el "OriginatorInfo" de un sobre * de tipo AuthenticatedEnvelopedData./*w w w . java2s . com*/ * @return La nueva firma AuthenticatedEnvelopedData con los remitentes que * tenía (si los tuviera) con la cadena de certificados * nueva. * @throws IOException */ byte[] addOriginatorInfo(final InputStream data, final P7ContentSignerParameters parameters, final X509Certificate[] signerCertificateChain, final PrivateKeyEntry keyEntry, final AdESPolicy policy) throws IOException { // boolean isValid = false; byte[] retorno = null; // LEEMOS EL FICHERO QUE NOS INTRODUCEN final ASN1InputStream is = new ASN1InputStream(data); final ASN1Sequence dsq = (ASN1Sequence) is.readObject(); is.close(); final Enumeration<?> e = dsq.getObjects(); // Elementos que contienen los elementos OID Data final DERObjectIdentifier doi = (DERObjectIdentifier) e.nextElement(); if (doi.equals(PKCSObjectIdentifiers.signedAndEnvelopedData)) { // Contenido de Data final ASN1TaggedObject doj = (ASN1TaggedObject) e.nextElement(); final SignedAndEnvelopedData signEnv = new SignedAndEnvelopedData((ASN1Sequence) doj.getObject()); // Obtenemos los originatorInfo final ASN1EncodableVector signerInfos = new ASN1EncodableVector(); final Enumeration<?> signers = signEnv.getSignerInfos().getObjects(); while (signers.hasMoreElements()) { signerInfos.add((ASN1Sequence) signers.nextElement()); } ASN1EncodableVector signCerts = new ASN1EncodableVector(); // Si no hay certificados, se deja como esta. if (signerCertificateChain.length != 0) { // algoritmo final String signatureAlgorithm; final String digestAlgorithm; final ASN1EncodableVector digestAlgs = new ASN1EncodableVector(); signatureAlgorithm = parameters.getSignatureAlgorithm(); digestAlgorithm = AOSignConstants.getDigestAlgorithmName(signatureAlgorithm); AlgorithmIdentifier digAlgId = SigUtils.makeAlgId(AOAlgorithmID.getOID(digestAlgorithm)); digestAlgs.add(digAlgId); final TBSCertificateStructure tbs2; try { tbs2 = TBSCertificateStructure.getInstance( ASN1Primitive.fromByteArray(signerCertificateChain[0].getTBSCertificate())); } catch (final CertificateEncodingException ex) { throw new IOException("Error en la codificacion del certificado del firmante", ex); //$NON-NLS-1$ } final IssuerAndSerialNumber encSid = new IssuerAndSerialNumber( X500Name.getInstance(tbs2.getIssuer()), tbs2.getSerialNumber().getValue()); final SignerIdentifier identifier = new SignerIdentifier(encSid); // AlgorithmIdentifier digAlgId = new AlgorithmIdentifier(new ASN1ObjectIdentifier(AOAlgorithmID.getOID(digestAlgorithm)), new DERNull()); // // ATRIBUTOS final ASN1EncodableVector contextExpecific; try { contextExpecific = CAdESUtils.generateSignerInfo(signerCertificateChain[0], digestAlgorithm, parameters.getContent(), policy, null); } catch (final CertificateEncodingException ex) { throw new IOException("Error en la codificacion del certificado del firmante", ex); //$NON-NLS-1$ } catch (final NoSuchAlgorithmException ex) { throw new IOException("Error generacion del SignerInfo", ex); //$NON-NLS-1$ } this.signedAttr2 = SigUtils.getAttributeSet(new AttributeTable(contextExpecific)); final ASN1Set signedAttr = SigUtils.getAttributeSet(new AttributeTable(contextExpecific)); final ASN1Set unSignedAttr = null; // digEncryptionAlgorithm final SignerInfo nuevoSigner = CAdESUtils.signAndEnvelope(keyEntry, signatureAlgorithm, digAlgId, identifier, signedAttr, unSignedAttr, "RSA", //$NON-NLS-1$ this.signedAttr2); // introducimos el nuevo Signer signerInfos.add(nuevoSigner); // LISTA DE CERTIFICADOS: obtenemos la lista de certificados try { signCerts = CAdESUtils.loadCertificatesList(signEnv, signerCertificateChain); } catch (final CertificateEncodingException ex) { throw new IOException("Error en la codificacion de los certificados del firmante", ex); //$NON-NLS-1$ } } else { LOGGER.warning("No se ha podido obtener el certificado del nuevo firmante "); //$NON-NLS-1$ } final ASN1Set certrevlist = null; // Se crea un nuevo AuthenticatedEnvelopedData a partir de los // datos anteriores con los nuevos originantes. retorno = new ContentInfo(PKCSObjectIdentifiers.signedAndEnvelopedData, new SignedAndEnvelopedData(signEnv.getRecipientInfos(), signEnv.getDigestAlgorithms(), signEnv.getEncryptedContentInfo(), // encInfo, new DERSet(signCerts), // certificates, certrevlist, // certrevlist, new DERSet(signerInfos))).getEncoded(ASN1Encoding.DER); } return retorno; }
From source file:es.gob.afirma.envelopers.cms.CMSSignedAndEnvelopedData.java
License:Open Source License
/** Método que genera la firma de tipo SignedAndEnvelopedData. * @param parameters Parámetros necesarios para la generación de este * tipo./*ww w .j av a2 s . com*/ * @param signerCertificateChain Cadena de certificados del firmante. * @param config Configuración del algoritmo para firmar * @param certDest Certificado del destino al cual va dirigido la firma. * @param dataType Identifica el tipo del contenido a firmar. * @param keyEntry Entrada hacia la clave privada para firma. * @param atrib Conjunto de atributos firmados. * @param uatrib Conjunto de atributos no firmados. * @param keySize Tamaño de la clave AES. * @return La firma de tipo SignedAndEnvelopedData. * @throws java.io.IOException Si ocurre algún problema leyendo o escribiendo los * datos * @throws java.security.cert.CertificateEncodingException * Si se produce alguna excepción con los certificados de * firma. * @throws java.security.NoSuchAlgorithmException * Si no se soporta alguno de los algoritmos de firma o huella * digital * @throws BadPaddingException Cuando hay problemas con un relleno de datos. * @throws IllegalBlockSizeException Cuando hay problemas internos con los tamaños de bloque de cifrado. * @throws InvalidAlgorithmParameterException Si no se soporta un parámetro necesario para un algoritmo. * @throws NoSuchPaddingException Cuando no se soporta un tipo de relleno necesario. * @throws InvalidKeyException Cuando hay problemas de adecuación de la clave. * @throws SignatureException Cuando ocurren problemas en la firma PKCS#1 */ byte[] genSignedAndEnvelopedData(final P7ContentSignerParameters parameters, final X509Certificate[] signerCertificateChain, final AOCipherConfig config, final X509Certificate[] certDest, final String dataType, final PrivateKeyEntry keyEntry, final Map<String, byte[]> atrib, final Map<String, byte[]> uatrib, final Integer keySize) throws IOException, CertificateEncodingException, NoSuchAlgorithmException, InvalidKeyException, NoSuchPaddingException, InvalidAlgorithmParameterException, IllegalBlockSizeException, BadPaddingException, SignatureException { final SecretKey cipherKey = Utils.initEnvelopedData(config, keySize); // 1. VERSION // la version se mete en el constructor del signedAndEnvelopedData y es // 1 // 2. DIGESTALGORITM // buscamos que timo de algoritmo es y lo codificamos con su OID final String signatureAlgorithm = parameters.getSignatureAlgorithm(); final String digestAlgorithm = AOSignConstants.getDigestAlgorithmName(signatureAlgorithm); final AlgorithmIdentifier digAlgId = SigUtils.makeAlgId(AOAlgorithmID.getOID(digestAlgorithm)); final ASN1EncodableVector digestAlgs = new ASN1EncodableVector(); digestAlgs.add(digAlgId); // LISTA DE CERTIFICADOS: obtenemos la lista de certificados final ASN1Set certificates = Utils.fetchCertificatesList(signerCertificateChain); // Ya que el contenido puede ser grande, lo recuperamos solo una vez final byte[] content2 = parameters.getContent(); // 2. RECIPIENTINFOS final Info infos = Utils.initVariables(content2, config, certDest, cipherKey); // 4. SIGNERINFO // raiz de la secuencia de SignerInfo final ASN1EncodableVector signerInfos = new ASN1EncodableVector(); final TBSCertificateStructure tbs2 = TBSCertificateStructure .getInstance(ASN1Primitive.fromByteArray(signerCertificateChain[0].getTBSCertificate())); final IssuerAndSerialNumber encSid = new IssuerAndSerialNumber(X500Name.getInstance(tbs2.getIssuer()), tbs2.getSerialNumber().getValue()); final SignerIdentifier identifier = new SignerIdentifier(encSid); // // ATRIBUTOS final ASN1Set signedAttr = generateSignerInfo(signerCertificateChain[0], digestAlgorithm, content2, dataType, atrib); ASN1Set unSignedAttr = null; unSignedAttr = generateUnsignerInfo(uatrib); // digEncryptionAlgorithm final AlgorithmIdentifier encAlgId = SigUtils.makeAlgId(AOAlgorithmID.getOID("RSA")); //$NON-NLS-1$ final ASN1OctetString sign2 = Utils.firma(signatureAlgorithm, keyEntry, this.signedAttr2); signerInfos.add(new SignerInfo(identifier, digAlgId, signedAttr, encAlgId, sign2, unSignedAttr)); final ASN1Set certrevlist = null; // construimos el Signed And Enveloped Data y lo devolvemos return new ContentInfo(PKCSObjectIdentifiers.signedAndEnvelopedData, new SignedAndEnvelopedData(new DERSet(infos.getRecipientInfos()), new DERSet(digestAlgs), infos.getEncInfo(), certificates, certrevlist, new DERSet(signerInfos))) .getEncoded(ASN1Encoding.DER); }
From source file:es.gob.afirma.envelopers.cms.CoSignerEnveloped.java
License:Open Source License
/** Constructor de la clase. Se crea una cofirma a partir de los datos del * firmante, el archivo que se firma y del archivo que contiene las firmas. * @param parameters parámetros necesarios que contienen tanto la firma del * archivo a firmar como los datos del firmante. * @param signerCertificateChain Cadena de certificados del firmante. * @param sign Archivo que contiene las firmas. * @param dataType Identifica el tipo del contenido a firmar. * @param keyEntry Clave privada del firmante. * @param atrib Atributos firmados opcion ales. * @param uatrib Atributos no autenticados firmados opcionales. * @param messageDigest Huella digital a aplicar en la firma. * @return El archivo de firmas con la nueva firma. * @throws java.io.IOException Si ocurre algún problema leyendo o escribiendo los * datos/*w w w . j av a2 s .co m*/ * @throws java.security.NoSuchAlgorithmException Si no se soporta alguno de los algoritmos de firma o huella * digital * @throws java.security.cert.CertificateException Si se produce alguna excepción con los certificados de * firma. */ byte[] coSigner(final P7ContentSignerParameters parameters, final X509Certificate[] signerCertificateChain, final byte[] sign, final String dataType, final PrivateKeyEntry keyEntry, final Map<String, byte[]> atrib, final Map<String, byte[]> uatrib, final byte[] messageDigest) throws IOException, NoSuchAlgorithmException, CertificateException { final ASN1InputStream is = new ASN1InputStream(sign); // LEEMOS EL FICHERO QUE NOS INTRODUCEN final ASN1Sequence dsq = (ASN1Sequence) is.readObject(); is.close(); final Enumeration<?> e = dsq.getObjects(); // Elementos que contienen los elementos OID signedAndEnvelopedData e.nextElement(); // Contenido de signedAndEnvelopedData final ASN1TaggedObject doj = (ASN1TaggedObject) e.nextElement(); final ASN1Sequence contentSignedData = (ASN1Sequence) doj.getObject();// contenido // del // signedAndEnvelopedData final SignedAndEnvelopedData sd = new SignedAndEnvelopedData(contentSignedData); // 4. CERTIFICADOS // obtenemos la lista de certificados ASN1Set certificates = null; final ASN1Set certificatesSigned = sd.getCertificates(); final ASN1EncodableVector vCertsSig = new ASN1EncodableVector(); final Enumeration<?> certs = certificatesSigned.getObjects(); // COGEMOS LOS CERTIFICADOS EXISTENTES EN EL FICHERO while (certs.hasMoreElements()) { vCertsSig.add((ASN1Encodable) certs.nextElement()); } if (signerCertificateChain.length != 0) { final List<ASN1Encodable> ce = new ArrayList<ASN1Encodable>(); for (final X509Certificate element : signerCertificateChain) { ce.add(Certificate.getInstance(ASN1Primitive.fromByteArray(element.getEncoded()))); } certificates = SigUtils.fillRestCerts(ce, vCertsSig); } // buscamos que timo de algoritmo es y lo codificamos con su OID final String signatureAlgorithm = parameters.getSignatureAlgorithm(); final String digestAlgorithm = AOSignConstants.getDigestAlgorithmName(signatureAlgorithm); final AlgorithmIdentifier digAlgId = SigUtils.makeAlgId(AOAlgorithmID.getOID(digestAlgorithm)); // Identificador del firmante ISSUER AND SERIAL-NUMBER final TBSCertificateStructure tbs = TBSCertificateStructure .getInstance(ASN1Primitive.fromByteArray(signerCertificateChain[0].getTBSCertificate())); final IssuerAndSerialNumber encSid = new IssuerAndSerialNumber(X500Name.getInstance(tbs.getIssuer()), tbs.getSerialNumber().getValue()); final SignerIdentifier identifier = new SignerIdentifier(encSid); // // ATRIBUTOS // atributos firmados ASN1Set signedAttr = null; if (messageDigest == null) { signedAttr = generateSignerInfo(digestAlgorithm, parameters.getContent(), dataType, atrib); } else { signedAttr = generateSignerInfoFromHash(signerCertificateChain[0], messageDigest, dataType, atrib); } // atributos no firmados. final ASN1Set unSignedAttr = generateUnsignerInfo(uatrib); // // FIN ATRIBUTOS // digEncryptionAlgorithm final AlgorithmIdentifier encAlgId = SigUtils.makeAlgId(AOAlgorithmID.getOID("RSA")); //$NON-NLS-1$ // 5. SIGNERINFO // raiz de la secuencia de SignerInfo // Obtenemos los signerInfos del signedAndEnvelopedData final ASN1Set signerInfosSd = sd.getSignerInfos(); // introducimos los SignerInfos Existentes final ASN1EncodableVector signerInfos = new ASN1EncodableVector(); // introducimos el nuevo SignerInfo del firmante actual. for (int i = 0; i < signerInfosSd.size(); i++) { final SignerInfo si = SignerInfo.getInstance(signerInfosSd.getObjectAt(i)); signerInfos.add(si); } final ASN1OctetString sign2; try { sign2 = firma(signatureAlgorithm, keyEntry); } catch (final Exception ex) { throw new IOException("Error al generar la firma: " + ex, ex); //$NON-NLS-1$ } // Creamos los signerInfos del signedAndEnvelopedData signerInfos.add(new SignerInfo(identifier, digAlgId, signedAttr, encAlgId, sign2, unSignedAttr)); // construimos el Signed Data y lo devolvemos return new ContentInfo(PKCSObjectIdentifiers.signedAndEnvelopedData, new SignedAndEnvelopedData(sd.getRecipientInfos(), sd.getDigestAlgorithms(), sd.getEncryptedContentInfo(), certificates, null, new DERSet(signerInfos)// unsignedAttr )).getEncoded(ASN1Encoding.DER); }
From source file:es.gob.afirma.envelopers.cms.CoSignerEnveloped.java
License:Open Source License
/** Constructor de la clase. Se crea una cofirma a partir de los datos del * firmante y el archivo que se firma./*from w w w .ja va 2 s .co m*/ * @param signatureAlgorithm * Algoritmo para la firma * @param signerCertificateChain * Cadena de certificados para la construccion de los parametros * de firma. * @param sign * Archivo que contiene las firmas. * @param dataType * Identifica el tipo del contenido a firmar. * @param keyEntry * Clave privada del firmante. * @param atrib * Atributos firmados adicionales. * @param uatrib * Atributos no firmados adicionales. * @param messageDigest * Hash a aplicar en la firma. * @return El archivo de firmas con la nueva firma. * @throws java.io.IOException * Si ocurre algún problema leyendo o escribiendo los * datos * @throws java.security.NoSuchAlgorithmException * Si no se soporta alguno de los algoritmos de firma o huella * digital * @throws java.security.cert.CertificateException * Si se produce alguna excepción con los certificados de * firma. */ byte[] coSigner(final String signatureAlgorithm, final X509Certificate[] signerCertificateChain, final byte[] sign, final String dataType, final PrivateKeyEntry keyEntry, final Map<String, byte[]> atrib, final Map<String, byte[]> uatrib, final byte[] messageDigest) throws IOException, NoSuchAlgorithmException, CertificateException { final ASN1InputStream is = new ASN1InputStream(sign); // LEEMOS EL FICHERO QUE NOS INTRODUCEN ASN1Sequence dsq = null; dsq = (ASN1Sequence) is.readObject(); is.close(); final Enumeration<?> e = dsq.getObjects(); // Elementos que contienen los elementos OID signedAndEnvelopedData e.nextElement(); // Contenido de signedAndEnvelopedData final ASN1TaggedObject doj = (ASN1TaggedObject) e.nextElement(); final ASN1Sequence contentSignedData = (ASN1Sequence) doj.getObject();// contenido // del // signedAndEnvelopedData final SignedAndEnvelopedData sd = new SignedAndEnvelopedData(contentSignedData); byte[] md = messageDigest != null ? messageDigest.clone() : null; // 4. CERTIFICADOS // obtenemos la lista de certificados ASN1Set certificates = null; final ASN1Set certificatesSigned = sd.getCertificates(); final ASN1EncodableVector vCertsSig = new ASN1EncodableVector(); final Enumeration<?> certs = certificatesSigned.getObjects(); // COGEMOS LOS CERTIFICADOS EXISTENTES EN EL FICHERO while (certs.hasMoreElements()) { vCertsSig.add((ASN1Encodable) certs.nextElement()); } if (signerCertificateChain.length != 0) { final List<ASN1Encodable> ce = new ArrayList<ASN1Encodable>(); for (final X509Certificate element : signerCertificateChain) { ce.add(Certificate.getInstance(ASN1Primitive.fromByteArray(element.getEncoded()))); } certificates = SigUtils.fillRestCerts(ce, vCertsSig); } // buscamos que tipo de algoritmo es y lo codificamos con su OID final String digestAlgorithm = AOSignConstants.getDigestAlgorithmName(signatureAlgorithm); final AlgorithmIdentifier digAlgId = SigUtils.makeAlgId(AOAlgorithmID.getOID(digestAlgorithm)); // Identificador del firmante ISSUER AND SERIAL-NUMBER final TBSCertificateStructure tbs = TBSCertificateStructure .getInstance(ASN1Primitive.fromByteArray(signerCertificateChain[0].getTBSCertificate())); final IssuerAndSerialNumber encSid = new IssuerAndSerialNumber(X500Name.getInstance(tbs.getIssuer()), tbs.getSerialNumber().getValue()); final SignerIdentifier identifier = new SignerIdentifier(encSid); // // ATRIBUTOS // atributos firmados ASN1Set signedAttr = null; // atributos no firmados. final ASN1Set unSignedAttr = generateUnsignerInfo(uatrib); // // FIN ATRIBUTOS // digEncryptionAlgorithm final AlgorithmIdentifier encAlgId = SigUtils.makeAlgId(AOAlgorithmID.getOID("RSA")); //$NON-NLS-1$ // 5. SIGNERINFO // raiz de la secuencia de SignerInfo // Obtenemos los signerInfos del signedAndEnvelopedData final ASN1Set signerInfosSd = sd.getSignerInfos(); // introducimos los SignerInfos Existentes final ASN1EncodableVector signerInfos = new ASN1EncodableVector(); // introducimos el nuevo SignerInfo del firmante actual. // Secuencia: // 1.- Si cofirmamos sin datos en el mismo algoritmo de hash que la firma // original sacamos el messagedigest de la firma previa. // 2.- Si no es el mismo algoritmo, miramos si nos ha llegado un messagedigest // como parametro del metodo, que quiere decir que se ha calculado externamente // (en el fondo sera que no se ha sobreescrito el parametro, con lo que // si llego != null, seguira siendo != null) // 3.- Si no es ninguno de los dos casos, no podemos firmar for (int i = 0; i < signerInfosSd.size(); i++) { final SignerInfo si = SignerInfo.getInstance(signerInfosSd.getObjectAt(i)); final AlgorithmIdentifier algHash = si.getDigestAlgorithm(); // Solo si coninciden los algos puedo sacar el hash de dentro if (algHash.getAlgorithm().toString().equals(AOAlgorithmID.getOID(digestAlgorithm))) { final ASN1Set signedAttrib = si.getAuthenticatedAttributes(); for (int s = 0; s < signedAttrib.size(); s++) { final ASN1Sequence elemento = (ASN1Sequence) signedAttrib.getObjectAt(s); final ASN1ObjectIdentifier oids = (ASN1ObjectIdentifier) elemento.getObjectAt(0); if (CMSAttributes.messageDigest.getId().toString().equals(oids.toString())) { final DERSet derSetHash = (DERSet) elemento.getObjectAt(1); final DEROctetString derHash = (DEROctetString) derSetHash.getObjectAt(0); md = derHash.getOctets(); } } } signerInfos.add(si); } // En este caso no puedo usar un hash de fuera, ya que no me han // pasado datos ni huellas digitales, solo un fichero de firma if (md == null) { throw new IllegalStateException("No se puede crear la firma ya que no se ha encontrado un hash valido"); //$NON-NLS-1$ } signedAttr = generateSignerInfoFromHash(signerCertificateChain[0], messageDigest, dataType, atrib); final ASN1OctetString sign2; try { sign2 = firma(signatureAlgorithm, keyEntry); } catch (final Exception ex) { throw new IOException("Error al generar la firma: " + ex, ex); //$NON-NLS-1$ } // Creamos los signerInfos del signedAndEnvelopedData signerInfos.add(new SignerInfo(identifier, digAlgId, signedAttr, encAlgId, sign2, unSignedAttr// null //unsignedAttr )); // construimos el Signed Data y lo devolvemos return new ContentInfo(PKCSObjectIdentifiers.signedAndEnvelopedData, new SignedAndEnvelopedData(sd.getRecipientInfos(), sd.getDigestAlgorithms(), sd.getEncryptedContentInfo(), certificates, null, new DERSet(signerInfos)// unsignedAttr )).getEncoded(ASN1Encoding.DER); }
From source file:es.gob.afirma.envelopers.cms.CounterSignerEnveloped.java
License:Open Source License
/** Método que genera un signerInfo específico utilizando los * datos necesarios para crearlo. Se utiliza siempre que no se sabe cual es * el signerInfo que se debe firmar./*w ww . j a v a 2 s . com*/ * @param parameters * Parámetros necesarios para firmar un determinado * SignerInfo hoja. * @param cert Certificado de firma. * @param si SignerInfo del que se debe recoger la información para * realizar la contrafirma específica. * @param keyEntry Clave privada a usar para firmar * @return El signerInfo contrafirmado. * @throws java.security.NoSuchAlgorithmException Cuando el JRE no soporta algún algoritmo necesario. * @throws java.io.IOException Cuando hay errores de entrada / salida. * @throws java.security.cert.CertificateException Cuando hay problemas relacionados con los certificados X.509. * @throws SignatureException Cuando ocurren problemas en la firma PKCS#1. * @throws InvalidKeyException Cuando hay problemas de adecuación de la clave. */ private SignerInfo unsignedAtributte(final P7ContentSignerParameters parameters, final X509Certificate cert, final SignerInfo si, final PrivateKeyEntry keyEntry) throws NoSuchAlgorithmException, IOException, CertificateException, InvalidKeyException, SignatureException { // // UNAUTHENTICATEDATTRIBUTES ASN1Set unsignedAttr = null; ASN1Set signedAttr = null; // buscamos que timo de algoritmo es y lo codificamos con su OID final String signatureAlgorithm = parameters.getSignatureAlgorithm(); final String digestAlgorithm = AOSignConstants.getDigestAlgorithmName(signatureAlgorithm); final AlgorithmIdentifier digAlgId = SigUtils.makeAlgId(AOAlgorithmID.getOID(digestAlgorithm)); // ATRIBUTOS FINALES signedAttr = generateSignerInfo(cert, digestAlgorithm, si.getEncryptedDigest().getOctets()); unsignedAttr = generateUnsignerInfo(); // 5. SIGNERINFO // raiz de la secuencia de SignerInfo final TBSCertificateStructure tbs = TBSCertificateStructure .getInstance(ASN1Primitive.fromByteArray(cert.getTBSCertificate())); final IssuerAndSerialNumber encSid = new IssuerAndSerialNumber(X500Name.getInstance(tbs.getIssuer()), tbs.getSerialNumber().getValue()); final SignerIdentifier identifier = new SignerIdentifier(encSid); // // FIN ATRIBUTOS // digEncryptionAlgorithm final AlgorithmIdentifier encAlgId = SigUtils.makeAlgId(AOAlgorithmID.getOID("RSA")); //$NON-NLS-1$ // Firma del SignerInfo final ASN1OctetString sign2 = firma(signatureAlgorithm, keyEntry); return new SignerInfo(identifier, digAlgId, signedAttr, encAlgId, sign2, unsignedAttr); }
From source file:es.gob.afirma.signers.cades.CAdESTriPhaseSigner.java
License:Open Source License
/** Realiza una firma CAdES completa. * @param digestAlgorithmName Algoritmo de huella digital * @param content Datos a firmar (usar <code>null</code> si no se desean añadir a la firma) * @param signerCertificateChain Cadena de certificados del firmante * @param signature Firma PKCS#1 v1.5 de los atributos firmados * @param signedAttributes Atributos firmados (prefirma) * @return Firma CAdES completa/*w w w .j ava 2s. c om*/ * @throws AOException Cuando se produce cualquier error durante el proceso. */ public static byte[] postSign(final String digestAlgorithmName, final byte[] content, final X509Certificate[] signerCertificateChain, final byte[] signature, final byte[] signedAttributes) throws AOException { if (signerCertificateChain == null || signerCertificateChain.length == 0) { throw new IllegalArgumentException("La cadena de certificados debe contener al menos una entrada"); //$NON-NLS-1$ } final TBSCertificateStructure tbsCertificateStructure; try { tbsCertificateStructure = TBSCertificateStructure .getInstance(ASN1Primitive.fromByteArray(signerCertificateChain[0].getTBSCertificate())); } catch (final Exception e) { throw new AOException("No se ha podido crear la estructura de certificados", e); //$NON-NLS-1$ } final SignerIdentifier signerIdentifier = new SignerIdentifier( new IssuerAndSerialNumber(X500Name.getInstance(tbsCertificateStructure.getIssuer()), tbsCertificateStructure.getSerialNumber().getValue())); // Algoritmo de huella digital final AlgorithmIdentifier digestAlgorithmOID; try { digestAlgorithmOID = SigUtils.makeAlgId(AOAlgorithmID.getOID(digestAlgorithmName)); } catch (final Exception e) { throw new AOException("Error obteniendo el OID en ASN.1 del algoritmo de huella digital", e); //$NON-NLS-1$ } // EncryptionAlgorithm final AlgorithmIdentifier keyAlgorithmIdentifier; try { keyAlgorithmIdentifier = SigUtils.makeAlgId(AOAlgorithmID.getOID("RSA")); //$NON-NLS-1$ } catch (final Exception e) { throw new AOException("Error al codificar el algoritmo de cifrado", e); //$NON-NLS-1$ } // Firma PKCS#1 codificada final ASN1OctetString encodedPKCS1Signature = new DEROctetString(signature); // Atributos firmados final ASN1Set asn1SignedAttributes; try { asn1SignedAttributes = (ASN1Set) ASN1Primitive.fromByteArray(signedAttributes); } catch (final IOException e) { throw new AOException("Error en la inclusion de la recuperacion de los SignedAttibutes", e); //$NON-NLS-1$ } // SignerInfo final ASN1EncodableVector signerInfo = new ASN1EncodableVector(); signerInfo.add(new SignerInfo(signerIdentifier, digestAlgorithmOID, asn1SignedAttributes, keyAlgorithmIdentifier, encodedPKCS1Signature, null)); // ContentInfo final ContentInfo contentInfo; if (content != null) { final ByteArrayOutputStream baos = new ByteArrayOutputStream(); final CMSProcessable msg = new CMSProcessableByteArray(content); try { msg.write(baos); } catch (final Exception e) { throw new AOException("Error en la escritura del contenido implicito en el ContentInfo", e); //$NON-NLS-1$ } contentInfo = new ContentInfo(new ASN1ObjectIdentifier(PKCSObjectIdentifiers.data.getId()), new BEROctetString(baos.toByteArray())); } else { contentInfo = new ContentInfo(new ASN1ObjectIdentifier(PKCSObjectIdentifiers.data.getId()), null); } // Certificados final List<ASN1Encodable> ce = new ArrayList<ASN1Encodable>(); for (final X509Certificate cert : signerCertificateChain) { try { ce.add(Certificate.getInstance(ASN1Primitive.fromByteArray(cert.getEncoded()))); } catch (final Exception e) { Logger.getLogger("es.gob.afirma").severe( //$NON-NLS-1$ "Error insertando el certificado '" + AOUtil.getCN(cert) + "' en la cadena de confianza"); //$NON-NLS-1$ //$NON-NLS-2$ } } final ASN1Set certificates = SigUtils.createBerSetFromList(ce); // Algoritmos de huella digital final ASN1EncodableVector digestAlgorithms = new ASN1EncodableVector(); digestAlgorithms.add(digestAlgorithmOID); try { return new ContentInfo(PKCSObjectIdentifiers.signedData, new SignedData(new DERSet(digestAlgorithms), contentInfo, certificates, null, new DERSet(signerInfo))).getEncoded(ASN1Encoding.DER); } catch (final IOException e) { throw new AOException("Error creando el ContentInfo de CAdES: " + e, e); //$NON-NLS-1$ } }
From source file:es.gob.afirma.signers.cms.CoSigner.java
License:Open Source License
/** Constructor de la clase. Se crea una cofirma a partir de los datos del * firmante, el archivo que se firma y del archivo que contiene las firmas. * @param parameters parámetros necesarios que contienen tanto la firma del * archivo a firmar como los datos del firmante. * @param sign Archivo que contiene las firmas. * @param omitContent Si se omite el contenido o no, es decir,si se hace de forma * Explícita o Implícita. * @param dataType Identifica el tipo del contenido a firmar. * @param key Clave privada del firmante. * @param certChain Cadena de certificados del firmante * @param atrib Atributos firmados opcionales. * @param uatrib Atributos no autenticados firmados opcionales. * @param messageDigest Hash a aplicar en la firma. * @return El archivo de firmas con la nueva firma. * @throws java.io.IOException Si ocurre algún problema leyendo o escribiendo los datos * @throws java.security.NoSuchAlgorithmException * Si no se soporta alguno de los algoritmos de firma o huella digital * @throws java.security.cert.CertificateException Si se produce alguna excepción con * los certificados de firma. */ byte[] coSigner(final P7ContentSignerParameters parameters, final byte[] sign, final boolean omitContent, final String dataType, final PrivateKey key, final java.security.cert.Certificate[] certChain, final Map<String, byte[]> atrib, final Map<String, byte[]> uatrib, final byte[] messageDigest) throws IOException, NoSuchAlgorithmException, CertificateException { // LEEMOS EL FICHERO QUE NOS INTRODUCEN final ASN1InputStream is = new ASN1InputStream(sign); final ASN1Sequence dsq = (ASN1Sequence) is.readObject(); is.close();/*from w w w . j a v a2s. c om*/ final Enumeration<?> e = dsq.getObjects(); // Elementos que contienen los elementos OID SignedData e.nextElement(); // Contenido de SignedData final ASN1TaggedObject doj = (ASN1TaggedObject) e.nextElement(); final ASN1Sequence contentSignedData = (ASN1Sequence) doj.getObject();// contenido // del // SignedData final SignedData sd = SignedData.getInstance(contentSignedData); // 3. CONTENTINFO // si se introduce el contenido o no ContentInfo encInfo = null; final ASN1ObjectIdentifier contentTypeOID = new ASN1ObjectIdentifier(dataType); // Ya que el contenido puede ser grande, lo recuperamos solo una vez byte[] content2 = null; if (!omitContent) { final ByteArrayOutputStream bOut = new ByteArrayOutputStream(); content2 = parameters.getContent(); final CMSProcessable msg = new CMSProcessableByteArray(content2); try { msg.write(bOut); } catch (final Exception ex) { throw new IOException("Error en la escritura del procesable CMS: " + ex, ex); //$NON-NLS-1$ } encInfo = new ContentInfo(contentTypeOID, new BEROctetString(bOut.toByteArray())); } else { encInfo = new ContentInfo(contentTypeOID, null); } // 4. CERTIFICADOS // obtenemos la lista de certificados ASN1Set certificates = null; final ASN1Set certificatesSigned = sd.getCertificates(); final ASN1EncodableVector vCertsSig = new ASN1EncodableVector(); final Enumeration<?> certs = certificatesSigned.getObjects(); // COGEMOS LOS CERTIFICADOS EXISTENTES EN EL FICHERO while (certs.hasMoreElements()) { vCertsSig.add((ASN1Encodable) certs.nextElement()); } if (certChain.length != 0) { final List<ASN1Encodable> ce = new ArrayList<ASN1Encodable>(); for (final java.security.cert.Certificate element : certChain) { ce.add(Certificate.getInstance(ASN1Primitive.fromByteArray(element.getEncoded()))); } certificates = SigUtils.fillRestCerts(ce, vCertsSig); } // buscamos que timo de algoritmo es y lo codificamos con su OID final String signatureAlgorithm = parameters.getSignatureAlgorithm(); final String digestAlgorithm = AOSignConstants.getDigestAlgorithmName(signatureAlgorithm); final AlgorithmIdentifier digAlgId = SigUtils.makeAlgId(AOAlgorithmID.getOID(digestAlgorithm)); // Identificador del firmante ISSUER AND SERIAL-NUMBER final TBSCertificateStructure tbs = TBSCertificateStructure .getInstance(ASN1Primitive.fromByteArray(((X509Certificate) certChain[0]).getTBSCertificate())); final IssuerAndSerialNumber encSid = new IssuerAndSerialNumber(X500Name.getInstance(tbs.getIssuer()), tbs.getSerialNumber().getValue()); final SignerIdentifier identifier = new SignerIdentifier(encSid); // // ATRIBUTOS // atributos firmados ASN1Set signedAttr = null; if (messageDigest == null) { signedAttr = generateSignerInfo(digestAlgorithm, content2 != null ? content2 : parameters.getContent(), dataType, atrib); } else { signedAttr = generateSignerInfoFromHash((X509Certificate) certChain[0], messageDigest, dataType, atrib); } // atributos no firmados. final ASN1Set unSignedAttr = generateUnsignerInfo(uatrib); // // FIN ATRIBUTOS // digEncryptionAlgorithm final AlgorithmIdentifier encAlgId = SigUtils.makeAlgId(AOAlgorithmID.getOID("RSA")); //$NON-NLS-1$ // 5. SIGNERINFO // raiz de la secuencia de SignerInfo // Obtenemos los signerInfos del SignedData final ASN1Set signerInfosSd = sd.getSignerInfos(); // introducimos los SignerInfos Existentes final ASN1EncodableVector signerInfos = new ASN1EncodableVector(); // introducimos el nuevo SignerInfo del firmante actual. for (int i = 0; i < signerInfosSd.size(); i++) { final SignerInfo si = SignerInfo.getInstance(signerInfosSd.getObjectAt(i)); signerInfos.add(si); } final ASN1OctetString sign2; try { sign2 = firma(signatureAlgorithm, key); } catch (final Exception ex) { throw new IOException("Error al generar la firma: " + ex, ex); //$NON-NLS-1$ } // Creamos los signerInfos del SignedData signerInfos.add(new SignerInfo(identifier, digAlgId, signedAttr, encAlgId, sign2, unSignedAttr// null //unsignedAttr )); // construimos el Signed Data y lo devolvemos return new ContentInfo(PKCSObjectIdentifiers.signedData, new SignedData(sd.getDigestAlgorithms(), encInfo, certificates, null, new DERSet(signerInfos)// unsignedAttr )).getEncoded(ASN1Encoding.DER); }
From source file:es.gob.afirma.signers.cms.CoSigner.java
License:Open Source License
/** Constructor de la clase. Se crea una cofirma a partir de los datos del * firmante y el archivo que se firma./*from www . j a v a 2 s. c o m*/ * @param signatureAlgorithm Algoritmo para la firma * @param signerCertificateChain Cadena de certificados para la construccion de los parametros * de firma. * @param sign Archivo que contiene las firmas. * @param dataType Identifica el tipo del contenido a firmar. * @param key Clave privada del firmante. * @param atrib Atributos firmados adicionales. * @param uatrib Atributos no firmados adicionales. * @param digest Hash a aplicar en la firma. * @return El archivo de firmas con la nueva firma. * @throws java.io.IOException Si ocurre algún problema leyendo o escribiendo los datos * @throws java.security.NoSuchAlgorithmException Si no se soporta alguno de los algoritmos de * firma o huella digital * @throws java.security.cert.CertificateException Si se produce alguna excepción con * los certificados de firma. * @throws ContainsNoDataException Cuando la firma no contiene los datos * ni fue generada con el mismo algoritmo de firma. */ byte[] coSigner(final String signatureAlgorithm, final X509Certificate[] signerCertificateChain, final byte[] sign, final String dataType, final PrivateKey key, final Map<String, byte[]> atrib, final Map<String, byte[]> uatrib, final byte[] digest) throws IOException, NoSuchAlgorithmException, CertificateException, ContainsNoDataException { byte[] messageDigest = digest != null ? digest.clone() : null; // LEEMOS EL FICHERO QUE NOS INTRODUCEN final ASN1InputStream is = new ASN1InputStream(sign); final ASN1Sequence dsq = (ASN1Sequence) is.readObject(); is.close(); final Enumeration<?> e = dsq.getObjects(); // Elementos que contienen los elementos OID SignedData e.nextElement(); // Contenido de SignedData final ASN1TaggedObject doj = (ASN1TaggedObject) e.nextElement(); final ASN1Sequence contentSignedData = (ASN1Sequence) doj.getObject(); // Contenido del SignedData final SignedData sd = SignedData.getInstance(contentSignedData); // 3. CONTENTINFO // si se introduce el contenido o no final ContentInfo encInfo = sd.getEncapContentInfo(); final DEROctetString contenido = (DEROctetString) encInfo.getContent(); byte[] contenidoDatos = null; if (contenido != null) { contenidoDatos = AOUtil.getDataFromInputStream(contenido.getOctetStream()); } // 4. CERTIFICADOS // obtenemos la lista de certificados ASN1Set certificates = null; final ASN1Set certificatesSigned = sd.getCertificates(); final ASN1EncodableVector vCertsSig = new ASN1EncodableVector(); final Enumeration<?> certs = certificatesSigned.getObjects(); // COGEMOS LOS CERTIFICADOS EXISTENTES EN EL FICHERO while (certs.hasMoreElements()) { vCertsSig.add((ASN1Encodable) certs.nextElement()); } if (signerCertificateChain.length != 0) { final List<ASN1Encodable> ce = new ArrayList<ASN1Encodable>(); for (final X509Certificate element : signerCertificateChain) { ce.add(Certificate.getInstance(ASN1Primitive.fromByteArray(element.getEncoded()))); } certificates = SigUtils.fillRestCerts(ce, vCertsSig); } // buscamos que tipo de algoritmo es y lo codificamos con su OID final String digestAlgorithm = AOSignConstants.getDigestAlgorithmName(signatureAlgorithm); final AlgorithmIdentifier digAlgId = SigUtils.makeAlgId(AOAlgorithmID.getOID(digestAlgorithm)); // Identificador del firmante ISSUER AND SERIAL-NUMBER final TBSCertificateStructure tbs = TBSCertificateStructure .getInstance(ASN1Primitive.fromByteArray(signerCertificateChain[0].getTBSCertificate())); final IssuerAndSerialNumber encSid = new IssuerAndSerialNumber(X500Name.getInstance(tbs.getIssuer()), tbs.getSerialNumber().getValue()); final SignerIdentifier identifier = new SignerIdentifier(encSid); // // ATRIBUTOS // atributos firmados ASN1Set signedAttr = null; // atributos no firmados. final ASN1Set unSignedAttr = generateUnsignerInfo(uatrib); // // FIN ATRIBUTOS // digEncryptionAlgorithm final AlgorithmIdentifier encAlgId = SigUtils.makeAlgId(AOAlgorithmID.getOID("RSA")); //$NON-NLS-1$ // 5. SIGNERINFO // raiz de la secuencia de SignerInfo // Obtenemos los signerInfos del SignedData final ASN1Set signerInfosSd = sd.getSignerInfos(); // introducimos los SignerInfos Existentes final ASN1EncodableVector signerInfos = new ASN1EncodableVector(); // introducimos el nuevo SignerInfo del firmante actual. // Secuencia: // 1.- Si cofirmamos sin datos en el mismo algoritmo de hash que la // firma // original sacamos el messagedigest de la firma previa. // 2.- Si no es el mismo algoritmo, miramos si nos ha llegado un // messagedigest // como parametro del metodo, que quiere decir que se ha calculado // externamente // (en el fondo sera que no se ha sobreescrito el parametro, con lo que // si llego // != null, seguira siendo != null) // 3.- Si no es ninguno de los dos casos, no podemos firmar for (int i = 0; i < signerInfosSd.size(); i++) { final SignerInfo si = SignerInfo.getInstance(signerInfosSd.getObjectAt(i)); final AlgorithmIdentifier algHash = si.getDigestAlgorithm(); // Solo si coninciden los algos puedo sacar el hash de dentro if (algHash.getAlgorithm().toString().equals(AOAlgorithmID.getOID(digestAlgorithm))) { final ASN1Set signedAttrib = si.getAuthenticatedAttributes(); for (int s = 0; s < signedAttrib.size(); s++) { final ASN1Sequence elemento = (ASN1Sequence) signedAttrib.getObjectAt(s); final ASN1ObjectIdentifier oids = (ASN1ObjectIdentifier) elemento.getObjectAt(0); if (CMSAttributes.messageDigest.getId().toString().equals(oids.toString())) { final DERSet derSetHash = (DERSet) elemento.getObjectAt(1); final DEROctetString derHash = (DEROctetString) derSetHash.getObjectAt(0); messageDigest = derHash.getOctets(); } } } signerInfos.add(si); } // atributos firmados if (contenidoDatos != null) { signedAttr = generateSignerInfo(digestAlgorithm, contenidoDatos, dataType, atrib); } else if (messageDigest != null) { signedAttr = generateSignerInfoFromHash(signerCertificateChain[0], messageDigest, dataType, atrib); } else { // En este caso no puedo usar un hash de fuera, ya que no me han // pasado datos ni // huellas digitales, solo un fichero de firma throw new ContainsNoDataException( "No se puede crear la cofirma ya que no se han encontrado ni los datos firmados ni una huella digital compatible con el algoritmo de firma"); //$NON-NLS-1$ } final ASN1OctetString sign2; try { sign2 = firma(signatureAlgorithm, key); } catch (final Exception ex) { throw new IOException("Error al generar la firma: " + ex, ex); //$NON-NLS-1$ } // Creamos los signerInfos del SignedData signerInfos.add(new SignerInfo(identifier, digAlgId, signedAttr, encAlgId, sign2, unSignedAttr// null //unsignedAttr )); // construimos el Signed Data y lo devolvemos return new ContentInfo(PKCSObjectIdentifiers.signedData, new SignedData(sd.getDigestAlgorithms(), encInfo, certificates, null, new DERSet(signerInfos)// unsignedAttr )).getEncoded(ASN1Encoding.DER); }