Example usage for org.bouncycastle.asn1.pkcs PKCSObjectIdentifiers signedData

List of usage examples for org.bouncycastle.asn1.pkcs PKCSObjectIdentifiers signedData

Introduction

In this page you can find the example usage for org.bouncycastle.asn1.pkcs PKCSObjectIdentifiers signedData.

Prototype

ASN1ObjectIdentifier signedData

To view the source code for org.bouncycastle.asn1.pkcs PKCSObjectIdentifiers signedData.

Click Source Link

Document

PKCS#7: 1.2.840.113549.1.7.2

Usage

From source file:es.gob.afirma.signers.cms.ValidateCMSSignedData.java

License:Open Source License

/** Método que verifica que es una firma de tipo "Signed data"
 * @param data//from  w  w w  . j  ava2  s .  c  o  m
 *        Datos CMS.
 * @return si es de este tipo.
 * @throws IOException Si ocurren errores durante la lectura de los datos */
public static boolean isCMSSignedData(final byte[] data) throws IOException {
    new BCChecker().checkBouncyCastle();
    boolean isValid = true;
    ASN1InputStream is = null;
    try {
        is = new ASN1InputStream(data);
        final ASN1Sequence dsq = (ASN1Sequence) is.readObject();
        final Enumeration<?> e = dsq.getObjects();
        // Elementos que contienen los elementos OID Data
        final ASN1ObjectIdentifier doi = (ASN1ObjectIdentifier) e.nextElement();
        if (!doi.equals(PKCSObjectIdentifiers.signedData)) {
            isValid = false;
        } else {
            // Contenido de SignedData
            final ASN1TaggedObject doj = (ASN1TaggedObject) e.nextElement();
            final ASN1Sequence datos = (ASN1Sequence) doj.getObject();
            final SignedData sd = SignedData.getInstance(datos);
            final ASN1Set signerInfosSd = sd.getSignerInfos();

            for (int i = 0; isValid && i < signerInfosSd.size(); i++) {
                final SignerInfo si = SignerInfo.getInstance(signerInfosSd.getObjectAt(i));
                isValid = verifySignerInfo(si);
            }
        }
    } catch (final Exception ex) {
        isValid = false;
    } finally {
        if (is != null) {
            is.close();
        }
    }
    return isValid;
}

From source file:es.gob.afirma.signers.multi.cades.CAdESCoSigner.java

License:Open Source License

/** Se crea una cofirma a partir de los datos del firmante, el archivo
 * que se firma y el archivo que contiene las firmas.
 * @param parameters/*from   w w  w . ja  v  a 2  s.  c o m*/
 *        Par&aacute;metros necesarios que contienen tanto la firma del
 *        archivo a firmar como los datos del firmante.
 * @param signature
 *        Archivo que contiene las firmas.
 * @param omitContent
 *        Si se omite el contenido o no, es decir,si se hace de forma
 *        Expl&iacute;cita o Impl&iacute;cita.
 * @param policy Pol&iacute;tica de firma
 * @param signingCertificateV2
 *        <code>true</code> si se desea usar la versi&oacute;n 2 del
 *        atributo <i>Signing Certificate</i> <code>false</code> para
 *        usar la versi&oacute;n 1
 * @param key Clave privada usada para firmar.
 * @param certChain Cadena de certificados del firmante.
 * @param messageDigest
 *        Hash espec&iacute;fico para una firma.
 * @param contentType Tipo de contenido definido por su OID.
 * @param contentDescription Descripci&oacute;n textual del tipo de contenido firmado.
 * @param ctis Indicaciones sobre los tipos de compromisos adquiridos con la firma.
 * @param csm Metadatos sobre el firmante
 * @return El archivo de firmas con la nueva firma.
 * @throws IOException Si ocurre alg&uacute;n problema leyendo o escribiendo los datos
 * @throws NoSuchAlgorithmException Si no se soporta alguno de los algoritmos de firma o huella
 *                                  digital
 * @throws CertificateException Si se produce alguna excepci&oacute;n con los certificados de
 *                              firma.*/
byte[] coSigner(final P7ContentSignerParameters parameters, final byte[] signature, final boolean omitContent,
        final AdESPolicy policy, final boolean signingCertificateV2, final PrivateKey key,
        final java.security.cert.Certificate[] certChain, final byte[] messageDigest, final String contentType,
        final String contentDescription, final List<CommitmentTypeIndicationBean> ctis,
        final CAdESSignerMetadata csm) throws IOException, NoSuchAlgorithmException, CertificateException {
    // LEEMOS EL FICHERO QUE NOS INTRODUCEN
    final ASN1InputStream is = new ASN1InputStream(signature);
    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
    ContentInfo encInfo = null;
    final ASN1ObjectIdentifier contentTypeOID = new ASN1ObjectIdentifier(PKCSObjectIdentifiers.data.getId());

    // Ya que el contenido puede ser grande, lo recuperamos solo una vez porque se clona
    // al recuperarlo
    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 CMSException 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 tipo 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(AOSignConstants.getDigestAlgorithmName(signatureAlgorithm)));

    // 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

    ASN1Set signedAttr = null;
    if (messageDigest == null) {
        final ASN1EncodableVector contextExpecific = CAdESUtils.generateSignerInfo(certChain[0],
                digestAlgorithm, content2 != null ? content2 : parameters.getContent(), policy,
                signingCertificateV2, null, new Date(), false, contentType, contentDescription, ctis, csm);
        this.signedAttr2 = SigUtils.getAttributeSet(new AttributeTable(contextExpecific));
        signedAttr = SigUtils.getAttributeSet(new AttributeTable(contextExpecific));
    } else {
        final ASN1EncodableVector contextExpecific = CAdESUtils.generateSignerInfo(certChain[0],
                digestAlgorithm, null, policy, signingCertificateV2, messageDigest, new Date(), false,
                contentType, contentDescription, ctis, csm);
        this.signedAttr2 = SigUtils.getAttributeSet(new AttributeTable(contextExpecific));
        signedAttr = SigUtils.getAttributeSet(new AttributeTable(contextExpecific));
    }

    // 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++) {
        signerInfos.add(SignerInfo.getInstance(signerInfosSd.getObjectAt(i)));
    }

    final ASN1OctetString sign2;
    try {
        sign2 = firma(signatureAlgorithm, key, certChain);
    } catch (final AOException ex) {
        throw new IOException("Error al realizar la firma: " + ex, ex); //$NON-NLS-1$
    }

    // Creamos los signerInfos del SignedData
    signerInfos.add(new SignerInfo(identifier, digAlgId, signedAttr, encAlgId, sign2, null));

    // construimos el Signed Data y lo devolvemos
    return new ContentInfo(PKCSObjectIdentifiers.signedData,
            new SignedData(sd.getDigestAlgorithms(), encInfo, certificates, null, // CRLS no usado
                    new DERSet(signerInfos)// unsignedAttr
            )).getEncoded(ASN1Encoding.DER);
}

From source file:es.gob.afirma.signers.multi.cades.CAdESCoSigner.java

License:Open Source License

/** Constructor de la clase. Se crea una cofirma a partir de los datos del
 * firmante y del archivo que contiene las firmas.
 * @param signatureAlgorithm Algoritmo para la firma
 * @param signerCertificateChain Cadena de certificados para la construccion de los parametros de firma.
 * @param signature Archivo que contiene las firmas.
 * @param policy Pol&iacute;tica de firma
 * @param signingCertificateV2//from  w  w w  . j a va  2s  .  c om
 *        <code>true</code> si se desea usar la versi&oacute;n 2 del
 *        atributo <i>Signing Certificate</i> <code>false</code> para
 *        usar la versi&oacute;n 1
 * @param key Clave privada usada para firmar.
 * @param certChain Cadena de certificados del firmante.
 * @param md Huella digital espec&iacute;fica para una firma.
 * @param contentType Tipo de contenido definido por su OID.
 * @param contentDescription Descripci&oacute;n textual del tipo de contenido firmado.
 * @param ctis Indicaciones sobre los tipos de compromisos adquiridos con la firma.
 * @param csm Metadatos sobre el firmante
 * @return El archivo de firmas con la nueva firma.
 * @throws java.io.IOException Si ocurre alg&uacute;n problema leyendo o escribiendo los datos
 * @throws NoSuchAlgorithmException Si no se soporta alguno de los algoritmos de firma o huella digital
 * @throws CertificateException Si se produce alguna excepci&oacute;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 InputStream signature, final AdESPolicy policy, final boolean signingCertificateV2,
        final PrivateKey key, final java.security.cert.Certificate[] certChain, final byte[] md,
        final String contentType, final String contentDescription,
        final List<CommitmentTypeIndicationBean> ctis, final CAdESSignerMetadata csm)
        throws IOException, NoSuchAlgorithmException, CertificateException, ContainsNoDataException {
    // LEEMOS EL FICHERO QUE NOS INTRODUCEN
    final ASN1InputStream is = new ASN1InputStream(signature);
    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 timo 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);

    // 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.

    byte[] messageDigest = md != null ? md.clone() : null;

    for (int i = 0; i < signerInfosSd.size(); i++) {
        final SignerInfo si = SignerInfo.getInstance(signerInfosSd.getObjectAt(i));
        final AlgorithmIdentifier algHash = si.getDigestAlgorithm();
        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().equals(oids.toString())) {
                    final DERSet derSetHash = (DERSet) elemento.getObjectAt(1);
                    final DEROctetString derHash = (DEROctetString) derSetHash.getObjectAt(0);
                    messageDigest = derHash.getOctets();
                }
            }
        }

        signerInfos.add(si);
    }

    // // ATRIBUTOS

    ASN1Set signedAttr;
    // atributos firmados
    if (contenidoDatos != null) {
        final ASN1EncodableVector contextExpecific = CAdESUtils.generateSignerInfo(signerCertificateChain[0],
                digestAlgorithm, contenidoDatos, policy, signingCertificateV2, null, // MessageDigest
                new Date(), false, contentType, contentDescription, ctis, csm);
        this.signedAttr2 = SigUtils.getAttributeSet(new AttributeTable(contextExpecific));
        signedAttr = SigUtils.getAttributeSet(new AttributeTable(contextExpecific));
    } else if (messageDigest != null) {
        final ASN1EncodableVector contextExpecific = CAdESUtils.generateSignerInfo(signerCertificateChain[0],
                digestAlgorithm, null, policy, signingCertificateV2, messageDigest, new Date(), false,
                contentType, contentDescription, ctis, csm);
        this.signedAttr2 = SigUtils.getAttributeSet(new AttributeTable(contextExpecific));
        signedAttr = SigUtils.getAttributeSet(new AttributeTable(contextExpecific));
    } else {
        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, certChain);
    } catch (final AOException ex) {
        throw new IOException("Error al realizar la firma: " + ex, ex); //$NON-NLS-1$
    }

    // Creamos los signerInfos del SignedData
    signerInfos.add(new SignerInfo(identifier, digAlgId, signedAttr, encAlgId, sign2, null // unsignedAttr
    ));

    // construimos el Signed Data y lo devolvemos
    return new ContentInfo(PKCSObjectIdentifiers.signedData,
            new SignedData(sd.getDigestAlgorithms(), encInfo, certificates, null, // CRLS no usado
                    new DERSet(signerInfos)// unsignedAttr
            )).getEncoded(ASN1Encoding.DER);

}

From source file:es.gob.afirma.signers.multi.cades.CAdESCounterSigner.java

License:Open Source License

/** Crea una contrafirma a partir de los datos
 * del firmante, el archivo que se firma y del archivo que contiene las
 * firmas.<br>/*from   w w w  .j  a v a  2 s  .c o m*/
 * @param parameters
 *        par&aacute;metros necesarios que contienen tanto la firma del
 *        archivo a firmar como los datos del firmante.
 * @param data
 *        Archivo que contiene las firmas.
 * @param targetType
 *        Lo que se quiere firmar. Puede ser el &aacute;rbol completo,
 *        las hojas, un nodo determinado o unos determinados firmantes.
 * @param targets
 *        Nodos objetivos a firmar.
 * @param key Clave privada a usar para firmar.
 * @param certChain Cadena de certificados del firmante.
 * @param policy Pol&iacute;tica de firma
 * @param signingCertificateV2
 *        <code>true</code> si se desea usar la versi&oacute;n 2 del
 *        atributo <i>Signing Certificate</i> <code>false</code> para
 *        usar la versi&oacute;n 1
 * @param contentDescription Descripci&oacute;n textual del tipo de contenido firmado.
 * @param ctis Indicaciones sobre los tipos de compromisos adquiridos con la firma.
 * @param csm Metadatos sobre el firmante.
 * @return El archivo de firmas con la nueva firma.
 * @throws IOException Cuando se produce algun error con la lectura o escritura de datos.
 * @throws NoSuchAlgorithmException Excepci&oacute;n cuando no se encuentra el algoritmo de
 *                                  firma.
 * @throws CertificateException Si se produce alguna excepci&oacute;n con los certificados de
 *                              firma.
 * @throws AOException Cuando ocurre alguno error con contemplado por las otras
 *                     excepciones declaradas */
byte[] counterSigner(final P7ContentSignerParameters parameters, final byte[] data,
        final CounterSignTarget targetType, final int[] targets, final PrivateKey key,
        final java.security.cert.Certificate[] certChain, final AdESPolicy policy,
        final boolean signingCertificateV2, final String contentDescription,
        final List<CommitmentTypeIndicationBean> ctis, final CAdESSignerMetadata csm)
        throws IOException, NoSuchAlgorithmException, CertificateException, AOException {

    // 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 SignedData
    e.nextElement();
    // Contenido de SignedData
    final ASN1TaggedObject doj = (ASN1TaggedObject) e.nextElement();
    final ASN1Sequence contentSignedData = (ASN1Sequence) doj.getObject();

    final SignedData sd = SignedData.getInstance(contentSignedData);

    // Obtenemos los signerInfos del SignedData
    final ASN1Set signerInfosSd = sd.getSignerInfos();

    // 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());
    }
    // e introducimos los del firmante actual.
    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);
    }

    // CRLS no usado
    final ASN1Set certrevlist = null;

    // 5. SIGNERINFO
    // raiz de la secuencia de SignerInfo
    ASN1EncodableVector signerInfos = new ASN1EncodableVector();

    // FIRMA EN ARBOL
    if (targetType.equals(CounterSignTarget.TREE)) {
        signerInfos = counterTree(signerInfosSd, parameters, key, certChain, contentDescription, policy,
                signingCertificateV2, ctis, csm);
    }
    // FIRMA DE LAS HOJAS
    else if (targetType.equals(CounterSignTarget.LEAFS)) {
        signerInfos = counterLeaf(signerInfosSd, parameters, key, certChain, contentDescription, policy,
                signingCertificateV2, ctis, csm);
    }
    // FIRMA DE NODOS
    else if (targetType.equals(CounterSignTarget.NODES)) {
        // Firma de Nodos
        SignedData sigDat;
        SignedData aux = sd;

        int nodo = 0;
        for (int i = targets.length - 1; i >= 0; i--) {
            nodo = targets[i];
            signerInfos = counterNode(aux, parameters, key, certChain, contentDescription, nodo, policy,
                    signingCertificateV2, ctis, csm);
            sigDat = new SignedData(sd.getDigestAlgorithms(), sd.getEncapContentInfo(), certificates,
                    certrevlist, new DERSet(signerInfos));

            // Esto se realiza asi por problemas con los casting.
            final ASN1InputStream sd2 = new ASN1InputStream(sigDat.getEncoded(ASN1Encoding.DER));
            final ASN1Sequence contentSignedData2 = (ASN1Sequence) sd2.readObject();// contenido del SignedData
            sd2.close();
            aux = SignedData.getInstance(contentSignedData2);
        }

        // construimos el Signed Data y lo devolvemos
        return new ContentInfo(PKCSObjectIdentifiers.signedData, aux).getEncoded(ASN1Encoding.DER);
    }
    // FIRMA DE LOS SIGNERS
    else if (targetType.equals(CounterSignTarget.SIGNERS)) {
        // Firma de Nodos
        SignedData sigDat;
        SignedData aux = sd;

        int nodo = 0;
        for (int i = targets.length - 1; i >= 0; i--) {
            nodo = targets[i];
            signerInfos = counterNode(aux, parameters, key, certChain, contentDescription, nodo, policy,
                    signingCertificateV2, ctis, csm);
            sigDat = new SignedData(sd.getDigestAlgorithms(), sd.getEncapContentInfo(), certificates,
                    certrevlist, new DERSet(signerInfos));

            // Esto se realiza as&iacute; por problemas con los casting.
            final ASN1InputStream sd2 = new ASN1InputStream(sigDat.getEncoded(ASN1Encoding.DER));
            final ASN1Sequence contentSignedData2 = (ASN1Sequence) sd2.readObject();// contenido del SignedData
            sd2.close();

            aux = SignedData.getInstance(contentSignedData2);
        }

        // construimos el Signed Data y lo devolvemos
        return new ContentInfo(PKCSObjectIdentifiers.signedData, aux).getEncoded(ASN1Encoding.DER);
    }

    // construimos el Signed Data y lo devolvemos
    return new ContentInfo(PKCSObjectIdentifiers.signedData, new SignedData(sd.getDigestAlgorithms(),
            sd.getEncapContentInfo(), certificates, certrevlist, new DERSet(signerInfos)))
                    .getEncoded(ASN1Encoding.DER);

}

From source file:es.gob.afirma.signers.multi.cades.CAdESTriPhaseCoSigner.java

License:Open Source License

/** Realiza una post-cofirma CAdES.
 * @param pkcs1sign Firma PKCS#1 de la pre-cofirma (de los SignedAttributes)
 * @param preCoSign Pre-cofirma CAdES (SignedAttributes)
 * @param content Contenido a post-cofirmar (indicar null si se desea omitir su inclusi&oacute;n en la firma)
 * @param signatureAlgorithm Algoritmo de firma
 * @param signerCertificateChain Cadena de certificados del firmante
 * @param sign Firma donde insertar la cofirma
 * @return Cofirma CAdES/*  w w  w  .  ja  v a2 s.c om*/
 * @throws IOException Cuando ocurren problemas de entrada / salida
 * @throws CertificateEncodingException Si alguno de los certificados proporcionados tienen problemas de formatos */
public static byte[] postCoSign(final byte[] pkcs1sign, final byte[] preCoSign, final byte[] content,
        final String signatureAlgorithm, final X509Certificate[] signerCertificateChain, final byte[] sign)
        throws IOException, CertificateEncodingException {
    // Firma en ASN.1
    final ASN1OctetString asn1sign = new DEROctetString(pkcs1sign);

    // 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);

    // digEncryptionAlgorithm
    final AlgorithmIdentifier encAlgId = SigUtils.makeAlgId(AOAlgorithmID.getOID("RSA")); //$NON-NLS-1$
    final AlgorithmIdentifier digAlgId = SigUtils
            .makeAlgId(AOAlgorithmID.getOID(AOSignConstants.getDigestAlgorithmName(signatureAlgorithm)));

    final ASN1Sequence contentSignedData = getContentSignedData(sign);
    final SignedData sd = SignedData.getInstance(contentSignedData);

    // CERTIFICADOS
    // Obtenemos la lista de certificados

    final ASN1Set certificatesSigned = sd.getCertificates();
    final Enumeration<?> certs = certificatesSigned.getObjects();
    final ASN1EncodableVector vCertsSig = new ASN1EncodableVector();

    // COGEMOS LOS CERTIFICADOS EXISTENTES EN EL FICHERO
    while (certs.hasMoreElements()) {
        vCertsSig.add((ASN1Encodable) certs.nextElement());
    }

    ASN1Set certificates = null;
    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);
    }

    // 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++) {
        signerInfos.add(SignerInfo.getInstance(signerInfosSd.getObjectAt(i)));
    }

    // Creamos los signerInfos del SignedData
    signerInfos
            .add(new SignerInfo(identifier, digAlgId, ASN1Set.getInstance(preCoSign), encAlgId, asn1sign, null // unsignedAttr
    ));

    final ContentInfo encInfo = getContentInfoFromContent(content);

    // Construimos el Signed Data y lo devolvemos
    return new ContentInfo(PKCSObjectIdentifiers.signedData,
            new SignedData(sd.getDigestAlgorithms(), encInfo, certificates, (ASN1Set) null, // CRLS no usado
                    new DERSet(signerInfos) // UnsignedAttr
            )).getEncoded(ASN1Encoding.DER);

}

From source file:es.gob.afirma.signers.multi.cades.CAdESTriPhaseCounterSigner.java

License:Open Source License

/** Crea una contrafirma a partir de los datos
 * del firmante, el archivo que se firma y del archivo que contiene las
 * firmas.<br>/*ww  w  .j ava 2s  . com*/
 * @param parameters
 *        par&aacute;metros necesarios que contienen tanto la firma del
 *        archivo a firmar como los datos del firmante.
 * @param data
 *        Archivo que contiene las firmas.
 * @param targetType
 *        Lo que se quiere firmar. Puede ser el &aacute;rbol completo,
 *        las hojas, un nodo determinado o unos determinados firmantes.
 * @param key Clave privada a usar para firmar.
 * @param certChain Cadena de certificados del firmante
 * @param policy Pol&iacute;tica de firma
 * @param signingCertificateV2
 *        <code>true</code> si se desea usar la versi&oacute;n 2 del
 *        atributo <i>Signing Certificate</i> <code>false</code> para
 *        usar la versi&oacute;n 1
 * @param contentType
 *         Tipo de contenido definido por su OID.
 * @param contentDescription
 *         Descripci&oacute;n textual del tipo de contenido firmado.
 * @return El archivo de firmas con la nueva firma.
 * @throws java.io.IOException
 *         Excepci&oacute;n cuando se produce algun error con lectura
 *         escritura de ficheros.
 * @throws java.security.NoSuchAlgorithmException
 *         Excepci&oacute;n cuando no se encuentra el algoritmo de
 *         firma.
 * @throws java.security.cert.CertificateException
 *         Si se produce alguna excepci&oacute;n con los certificados de
 *         firma.
 * @throws AOException
 *         Cuando ocurre alguno error con contemplado por las otras
 *         excepciones declaradas */
public CAdESPreCounterSignResult preCounterSign(final P7ContentSignerParameters parameters, final byte[] data,
        final CounterSignTarget targetType, final PrivateKey key,
        final java.security.cert.Certificate[] certChain, final AdESPolicy policy,
        final boolean signingCertificateV2, final String contentType, final String contentDescription)
        throws IOException, NoSuchAlgorithmException, CertificateException, AOException {

    // Inicializamos el contador global y la lista de SignedDatas
    this.counterIndex = 0;
    this.signedDatas = new ArrayList<byte[]>();

    // 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 SignedData
    e.nextElement();
    // Contenido de SignedData
    final ASN1TaggedObject doj = (ASN1TaggedObject) e.nextElement();
    final ASN1Sequence contentSignedData = (ASN1Sequence) doj.getObject();

    final SignedData sd = SignedData.getInstance(contentSignedData);

    // Obtenemos los signerInfos del SignedData
    final ASN1Set signerInfosSd = sd.getSignerInfos();

    // 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());
    }
    // e introducimos los del firmante actual.
    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);
    }

    // CRLS no usado
    final ASN1Set certrevlist = null;

    // 5. SIGNERINFO
    // raiz de la secuencia de SignerInfo
    ASN1EncodableVector signerInfos = new ASN1EncodableVector();

    // FIRMA EN ARBOL
    if (CounterSignTarget.TREE.equals(targetType)) {
        signerInfos = counterTree(signerInfosSd, parameters, key, certChain, contentType, contentDescription,
                policy, signingCertificateV2);
    }
    // FIRMA DE LAS HOJAS
    else if (CounterSignTarget.LEAFS.equals(targetType)) {
        signerInfos = counterLeaf(signerInfosSd, parameters, key, certChain, contentType, contentDescription,
                policy, signingCertificateV2);
    } else {
        throw new IllegalArgumentException("Modo de contrafirma no soportado: " + targetType); //$NON-NLS-1$
    }

    // construimos el Signed Data y lo devolvemos dentro del resultado
    return new CAdESPreCounterSignResult(
            new ContentInfo(PKCSObjectIdentifiers.signedData,
                    new SignedData(sd.getDigestAlgorithms(), sd.getEncapContentInfo(), certificates,
                            certrevlist, new DERSet(signerInfos))).getEncoded(ASN1Encoding.DER),
            this.signedDatas);
}

From source file:es.gob.afirma.signers.pkcs7.ObtainContentSignedData.java

License:Open Source License

/** M&eacute;todo que obtiene el contenido firmado de un tipo Signed Data
 * tanto en CADES como en CMS. Si la firma no contiene los datos, devuelve <code>null</code>.
 * @param data//from   w  w w .  j  av a2s. com
 *        datos que contienen la firma.
 * @return el contenido firmado.
 * @throws IOException Si no se pueden leer los datos */
public static byte[] obtainData(final byte[] data) throws IOException {
    byte[] contenido = 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 ASN1ObjectIdentifier doi = (ASN1ObjectIdentifier) e.nextElement();
    // Contenido a obtener informacion
    final ASN1TaggedObject doj = (ASN1TaggedObject) e.nextElement();

    // buscamos si es signedData
    if (doi.equals(PKCSObjectIdentifiers.signedData)) {
        // obtenemos el signed Data
        final SignedData sd = SignedData.getInstance(doj.getObject());
        final ContentInfo ci = sd.getEncapContentInfo();
        // obtenemos el contenido si lo tiene.
        if (ci.getContent() != null) {
            contenido = ((DEROctetString) ci.getContent()).getOctets();
        } else {
            LOGGER.warning("No existe contenido en esta firma."); //$NON-NLS-1$
        }
    } else {
        LOGGER.warning("No se puede obtener el contenido de esta firma."); //$NON-NLS-1$
    }

    return contenido;
}

From source file:es.gob.afirma.signers.pkcs7.ObtainContentSignedData.java

License:Open Source License

/** M&eacute;todo que obtiene la huella digital de los datos firmados en una firma CMS/CAdES.
 * La huella se obtenida estar&aacute; generada con el algoritmo de huella indicado, si este
 * algoritmo es el que se utiliz&oacute; en alguna de las operaci&oacute;nes de firma con la
 * que se gener&oacute; esta firma. Si no se utiliz&oacute; este algoritmo, se devuelve
 * {@code null}.//from   ww  w  .  ja  v  a2s.co m
 * @param signature Firma de la que obtener la huella digital.
 * @param digestAlgorithm Algoritmo con el que se gener&oacute; la huella digital que buscamos.
 * @return La huella digital de los datos firmados generada con el algoritmo indicado, o
 * {@code null} si esta no se encuentra en la firma.
 * @throws IOException Si no se pueden leer los datos */
public static byte[] obtainMessageDigest(final byte[] signature, final String digestAlgorithm)
        throws IOException {

    // LEEMOS EL FICHERO QUE NOS INTRODUCEN
    final ASN1InputStream is = new ASN1InputStream(signature);
    final ASN1Sequence dsq = (ASN1Sequence) is.readObject();
    is.close();

    final Enumeration<?> e = dsq.getObjects();

    // Elementos que contienen los elementos OID Data
    final ASN1ObjectIdentifier doi = (ASN1ObjectIdentifier) e.nextElement();

    // Comprobamos que sea una firma
    if (!doi.equals(PKCSObjectIdentifiers.signedData)) {
        LOGGER.warning("No se puede obtener el contenido de esta firma."); //$NON-NLS-1$
        return null;
    }

    // Contenido a obtener informacion
    final ASN1TaggedObject doj = (ASN1TaggedObject) e.nextElement();
    final SignedData sd = SignedData.getInstance(doj.getObject());
    final ASN1Set signerInfosSd = sd.getSignerInfos();

    byte[] messageDigest = null;

    for (int i = 0; i < signerInfosSd.size(); i++) {
        final SignerInfo si = SignerInfo.getInstance(signerInfosSd.getObjectAt(i));
        final AlgorithmIdentifier algHash = si.getDigestAlgorithm();
        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().equals(oids.toString())) {
                    final DERSet derSetHash = (DERSet) elemento.getObjectAt(1);
                    final DEROctetString derHash = (DEROctetString) derSetHash.getObjectAt(0);
                    messageDigest = derHash.getOctets();
                    break;
                }
            }
            if (messageDigest != null) {
                break;
            }
        }
    }
    if (messageDigest == null) {
        LOGGER.warning("No se ha encontrado en la firma una huella digital generada con el algoritmo: " //$NON-NLS-1$
                + digestAlgorithm);
    }
    return messageDigest;
}

From source file:eu.europa.esig.dss.cades.signature.CAdESLevelBETSITS101733Test.java

License:Open Source License

@Override
protected void onDocumentSigned(byte[] byteArray) {
    try {/*  w ww  . jav  a2  s  . co m*/

        CAdESSignature signature = new CAdESSignature(byteArray);
        assertNotNull(signature.getCmsSignedData());

        ASN1InputStream asn1sInput = new ASN1InputStream(byteArray);
        ASN1Sequence asn1Seq = (ASN1Sequence) asn1sInput.readObject();

        logger.info("SEQ : " + asn1Seq.toString());

        assertEquals(2, asn1Seq.size());

        ASN1ObjectIdentifier oid = ASN1ObjectIdentifier.getInstance(asn1Seq.getObjectAt(0));
        assertEquals(PKCSObjectIdentifiers.signedData, oid);
        logger.info("OID : " + oid.toString());

        ASN1TaggedObject taggedObj = DERTaggedObject.getInstance(asn1Seq.getObjectAt(1));

        logger.info("TAGGED OBJ : " + taggedObj.toString());

        ASN1Primitive object = taggedObj.getObject();
        logger.info("OBJ : " + object.toString());

        SignedData signedData = SignedData.getInstance(object);
        logger.info("SIGNED DATA : " + signedData.toString());

        ASN1Set digestAlgorithms = signedData.getDigestAlgorithms();
        logger.info("DIGEST ALGOS : " + digestAlgorithms.toString());

        ContentInfo encapContentInfo = signedData.getEncapContentInfo();
        logger.info("ENCAPSULATED CONTENT INFO : " + encapContentInfo.getContentType() + " "
                + encapContentInfo.getContent());

        ASN1Set certificates = signedData.getCertificates();
        logger.info("CERTIFICATES (" + certificates.size() + ") : " + certificates);

        List<X509Certificate> foundCertificates = new ArrayList<X509Certificate>();
        for (int i = 0; i < certificates.size(); i++) {
            ASN1Sequence seqCertif = ASN1Sequence.getInstance(certificates.getObjectAt(i));
            logger.info("SEQ cert " + i + " : " + seqCertif);

            X509CertificateHolder certificateHolder = new X509CertificateHolder(seqCertif.getEncoded());
            CertificateToken certificate = DSSASN1Utils.getCertificate(certificateHolder);
            X509Certificate x509Certificate = certificate.getCertificate();
            x509Certificate.checkValidity();

            logger.info("Cert " + i + " : " + certificate);

            foundCertificates.add(x509Certificate);
        }

        ASN1Set crLs = signedData.getCRLs();
        logger.info("CRLs : " + crLs);

        ASN1Set signerInfosAsn1 = signedData.getSignerInfos();
        logger.info("SIGNER INFO ASN1 : " + signerInfosAsn1.toString());
        assertEquals(1, signerInfosAsn1.size());

        ASN1Sequence seqSignedInfo = ASN1Sequence.getInstance(signerInfosAsn1.getObjectAt(0));

        SignerInfo signedInfo = SignerInfo.getInstance(seqSignedInfo);
        logger.info("SIGNER INFO : " + signedInfo.toString());

        SignerIdentifier sid = signedInfo.getSID();
        logger.info("SIGNER IDENTIFIER : " + sid.getId());

        IssuerAndSerialNumber issuerAndSerialNumber = IssuerAndSerialNumber.getInstance(signedInfo.getSID());
        logger.info("ISSUER AND SN : " + issuerAndSerialNumber.toString());

        BigInteger serial = issuerAndSerialNumber.getSerialNumber().getValue();

        X509Certificate signerCertificate = null;
        for (X509Certificate x509Certificate : foundCertificates) {
            // TODO check issuer name
            if (serial.equals(x509Certificate.getSerialNumber())) {
                signerCertificate = x509Certificate;
            }
        }
        assertNotNull(signerCertificate);

        ASN1OctetString encryptedDigest = signedInfo.getEncryptedDigest();
        logger.info("ENCRYPT DIGEST : " + encryptedDigest.toString());

        ASN1Sequence seq = ASN1Sequence.getInstance(object);

        ASN1Integer version = ASN1Integer.getInstance(seq.getObjectAt(0));
        logger.info("VERSION : " + version.toString());

        ASN1Set digestManualSet = ASN1Set.getInstance(seq.getObjectAt(1));
        logger.info("DIGEST SET : " + digestManualSet.toString());
        assertEquals(digestAlgorithms, digestManualSet);

        ASN1Sequence seqDigest = ASN1Sequence.getInstance(digestManualSet.getObjectAt(0));
        // assertEquals(1, seqDigest.size());

        ASN1ObjectIdentifier oidDigestAlgo = ASN1ObjectIdentifier.getInstance(seqDigest.getObjectAt(0));
        assertEquals(new ASN1ObjectIdentifier(DigestAlgorithm.SHA256.getOid()), oidDigestAlgo);

        ASN1Sequence seqEncapsulatedInfo = ASN1Sequence.getInstance(seq.getObjectAt(2));
        logger.info("ENCAPSULATED INFO : " + seqEncapsulatedInfo.toString());

        ASN1ObjectIdentifier oidContentType = ASN1ObjectIdentifier
                .getInstance(seqEncapsulatedInfo.getObjectAt(0));
        logger.info("OID CONTENT TYPE : " + oidContentType.toString());

        ASN1TaggedObject taggedContent = DERTaggedObject.getInstance(seqEncapsulatedInfo.getObjectAt(1));

        ASN1OctetString contentOctetString = ASN1OctetString.getInstance(taggedContent.getObject());
        String content = new String(contentOctetString.getOctets());
        assertEquals(HELLO_WORLD, content);
        logger.info("CONTENT : " + content);

        byte[] digest = DSSUtils.digest(DigestAlgorithm.SHA256, HELLO_WORLD.getBytes());
        String encodeHexDigest = Hex.toHexString(digest);
        logger.info("CONTENT DIGEST COMPUTED : " + encodeHexDigest);

        ASN1Set authenticatedAttributes = signedInfo.getAuthenticatedAttributes();
        logger.info("AUTHENTICATED ATTRIBUTES : " + authenticatedAttributes.toString());

        // ASN1Sequence seqAuthAttrib = ASN1Sequence.getInstance(authenticatedAttributes.getObjectAt(0));

        logger.info("Nb Auth Attributes : " + authenticatedAttributes.size());

        String embeddedDigest = "";
        for (int i = 0; i < authenticatedAttributes.size(); i++) {
            ASN1Sequence authAttrSeq = ASN1Sequence.getInstance(authenticatedAttributes.getObjectAt(i));
            logger.info(authAttrSeq.toString());
            ASN1ObjectIdentifier attrOid = ASN1ObjectIdentifier.getInstance(authAttrSeq.getObjectAt(0));
            if (PKCSObjectIdentifiers.pkcs_9_at_messageDigest.equals(attrOid)) {
                ASN1Set setMessageDigest = ASN1Set.getInstance(authAttrSeq.getObjectAt(1));
                ASN1OctetString asn1ObjString = ASN1OctetString.getInstance(setMessageDigest.getObjectAt(0));
                embeddedDigest = Hex.toHexString(asn1ObjString.getOctets());
            }
        }
        assertEquals(encodeHexDigest, embeddedDigest);

        ASN1OctetString encryptedInfoOctedString = signedInfo.getEncryptedDigest();
        String signatureValue = Hex.toHexString(encryptedInfoOctedString.getOctets());

        logger.info("SIGNATURE VALUE : " + signatureValue);

        Cipher cipher = Cipher.getInstance("RSA");
        cipher.init(Cipher.DECRYPT_MODE, signerCertificate);
        byte[] decrypted = cipher.doFinal(encryptedInfoOctedString.getOctets());

        ASN1InputStream inputDecrypted = new ASN1InputStream(decrypted);

        ASN1Sequence seqDecrypt = (ASN1Sequence) inputDecrypted.readObject();
        logger.info("Decrypted : " + seqDecrypt);

        DigestInfo digestInfo = new DigestInfo(seqDecrypt);
        assertEquals(oidDigestAlgo, digestInfo.getAlgorithmId().getAlgorithm());

        String decryptedDigestEncodeBase64 = Utils.toBase64(digestInfo.getDigest());
        logger.info("Decrypted Base64 : " + decryptedDigestEncodeBase64);

        byte[] encoded = signedInfo.getAuthenticatedAttributes().getEncoded();
        MessageDigest messageDigest = MessageDigest.getInstance(DigestAlgorithm.SHA256.getName());
        byte[] digestOfAuthenticatedAttributes = messageDigest.digest(encoded);

        String computedDigestEncodeBase64 = Utils.toBase64(digestOfAuthenticatedAttributes);
        logger.info("Computed Base64 : " + computedDigestEncodeBase64);

        assertEquals(decryptedDigestEncodeBase64, computedDigestEncodeBase64);

        Utils.closeQuietly(asn1sInput);
        Utils.closeQuietly(inputDecrypted);
    } catch (Exception e) {
        logger.error(e.getMessage(), e);
        fail(e.getMessage());
    }
}

From source file:eu.europa.esig.dss.cades.signature.CAdESLevelBTest.java

License:Open Source License

@Override
protected void onDocumentSigned(byte[] byteArray) {
    try {//from ww w.  ja  v  a 2 s .  com

        CAdESSignature signature = new CAdESSignature(byteArray);
        assertNotNull(signature.getCmsSignedData());

        ASN1InputStream asn1sInput = new ASN1InputStream(byteArray);
        ASN1Sequence asn1Seq = (ASN1Sequence) asn1sInput.readObject();

        logger.info("SEQ : " + asn1Seq.toString());

        assertEquals(2, asn1Seq.size());

        ASN1ObjectIdentifier oid = ASN1ObjectIdentifier.getInstance(asn1Seq.getObjectAt(0));
        assertEquals(PKCSObjectIdentifiers.signedData, oid);
        logger.info("OID : " + oid.toString());

        ASN1TaggedObject taggedObj = DERTaggedObject.getInstance(asn1Seq.getObjectAt(1));

        logger.info("TAGGED OBJ : " + taggedObj.toString());

        ASN1Primitive object = taggedObj.getObject();
        logger.info("OBJ : " + object.toString());

        SignedData signedData = SignedData.getInstance(object);
        logger.info("SIGNED DATA : " + signedData.toString());

        ASN1Set digestAlgorithms = signedData.getDigestAlgorithms();
        logger.info("DIGEST ALGOS : " + digestAlgorithms.toString());

        ContentInfo encapContentInfo = signedData.getEncapContentInfo();
        logger.info("ENCAPSULATED CONTENT INFO : " + encapContentInfo.getContentType() + " "
                + encapContentInfo.getContent());

        ASN1Set certificates = signedData.getCertificates();
        logger.info("CERTIFICATES (" + certificates.size() + ") : " + certificates);

        List<X509Certificate> foundCertificates = new ArrayList<X509Certificate>();
        for (int i = 0; i < certificates.size(); i++) {
            ASN1Sequence seqCertif = ASN1Sequence.getInstance(certificates.getObjectAt(i));
            logger.info("SEQ cert " + i + " : " + seqCertif);

            X509CertificateHolder certificateHolder = new X509CertificateHolder(seqCertif.getEncoded());
            X509Certificate certificate = new JcaX509CertificateConverter()
                    .setProvider(BouncyCastleProvider.PROVIDER_NAME).getCertificate(certificateHolder);

            certificate.checkValidity();

            logger.info("Cert " + i + " : " + certificate);

            foundCertificates.add(certificate);
        }

        ASN1Set crLs = signedData.getCRLs();
        logger.info("CRLs : " + crLs);

        ASN1Set signerInfosAsn1 = signedData.getSignerInfos();
        logger.info("SIGNER INFO ASN1 : " + signerInfosAsn1.toString());
        assertEquals(1, signerInfosAsn1.size());

        ASN1Sequence seqSignedInfo = ASN1Sequence.getInstance(signerInfosAsn1.getObjectAt(0));

        SignerInfo signedInfo = SignerInfo.getInstance(seqSignedInfo);
        logger.info("SIGNER INFO : " + signedInfo.toString());

        SignerIdentifier sid = signedInfo.getSID();
        logger.info("SIGNER IDENTIFIER : " + sid.getId());

        IssuerAndSerialNumber issuerAndSerialNumber = IssuerAndSerialNumber.getInstance(signedInfo.getSID());
        logger.info("ISSUER AND SN : " + issuerAndSerialNumber.toString());

        BigInteger serial = issuerAndSerialNumber.getSerialNumber().getValue();

        X509Certificate signerCertificate = null;
        for (X509Certificate x509Certificate : foundCertificates) {
            // TODO check issuer name
            if (serial.equals(x509Certificate.getSerialNumber())) {
                signerCertificate = x509Certificate;
            }
        }
        assertNotNull(signerCertificate);

        ASN1OctetString encryptedDigest = signedInfo.getEncryptedDigest();
        logger.info("ENCRYPT DIGEST : " + encryptedDigest.toString());

        ASN1Sequence seq = ASN1Sequence.getInstance(object);

        ASN1Integer version = ASN1Integer.getInstance(seq.getObjectAt(0));
        logger.info("VERSION : " + version.toString());

        ASN1Set digestManualSet = ASN1Set.getInstance(seq.getObjectAt(1));
        logger.info("DIGEST SET : " + digestManualSet.toString());
        assertEquals(digestAlgorithms, digestManualSet);

        ASN1Sequence seqDigest = ASN1Sequence.getInstance(digestManualSet.getObjectAt(0));
        // assertEquals(1, seqDigest.size());

        ASN1ObjectIdentifier oidDigestAlgo = ASN1ObjectIdentifier.getInstance(seqDigest.getObjectAt(0));
        assertEquals(new ASN1ObjectIdentifier(DigestAlgorithm.SHA256.getOid()), oidDigestAlgo);

        ASN1Sequence seqEncapsulatedInfo = ASN1Sequence.getInstance(seq.getObjectAt(2));
        logger.info("ENCAPSULATED INFO : " + seqEncapsulatedInfo.toString());

        ASN1ObjectIdentifier oidContentType = ASN1ObjectIdentifier
                .getInstance(seqEncapsulatedInfo.getObjectAt(0));
        logger.info("OID CONTENT TYPE : " + oidContentType.toString());

        ASN1TaggedObject taggedContent = DERTaggedObject.getInstance(seqEncapsulatedInfo.getObjectAt(1));

        ASN1OctetString contentOctetString = ASN1OctetString.getInstance(taggedContent.getObject());
        String content = new String(contentOctetString.getOctets());
        assertEquals(HELLO_WORLD, content);
        logger.info("CONTENT : " + content);

        byte[] digest = DSSUtils.digest(DigestAlgorithm.SHA256, HELLO_WORLD.getBytes());
        String encodeHexDigest = Hex.toHexString(digest);
        logger.info("CONTENT DIGEST COMPUTED : " + encodeHexDigest);

        ASN1Set authenticatedAttributes = signedInfo.getAuthenticatedAttributes();
        logger.info("AUTHENTICATED ATTRIBUTES : " + authenticatedAttributes.toString());

        // ASN1Sequence seqAuthAttrib = ASN1Sequence.getInstance(authenticatedAttributes.getObjectAt(0));

        logger.info("Nb Auth Attributes : " + authenticatedAttributes.size());

        String embeddedDigest = StringUtils.EMPTY;
        for (int i = 0; i < authenticatedAttributes.size(); i++) {
            ASN1Sequence authAttrSeq = ASN1Sequence.getInstance(authenticatedAttributes.getObjectAt(i));
            logger.info(authAttrSeq.toString());
            ASN1ObjectIdentifier attrOid = ASN1ObjectIdentifier.getInstance(authAttrSeq.getObjectAt(0));
            if (PKCSObjectIdentifiers.pkcs_9_at_messageDigest.equals(attrOid)) {
                ASN1Set setMessageDigest = ASN1Set.getInstance(authAttrSeq.getObjectAt(1));
                ASN1OctetString asn1ObjString = ASN1OctetString.getInstance(setMessageDigest.getObjectAt(0));
                embeddedDigest = Hex.toHexString(asn1ObjString.getOctets());
            }
        }
        assertEquals(encodeHexDigest, embeddedDigest);

        ASN1OctetString encryptedInfoOctedString = signedInfo.getEncryptedDigest();
        String signatureValue = Hex.toHexString(encryptedInfoOctedString.getOctets());

        logger.info("SIGNATURE VALUE : " + signatureValue);

        Cipher cipher = Cipher.getInstance("RSA");
        cipher.init(Cipher.DECRYPT_MODE, signerCertificate);
        byte[] decrypted = cipher.doFinal(encryptedInfoOctedString.getOctets());

        ASN1InputStream inputDecrypted = new ASN1InputStream(decrypted);

        ASN1Sequence seqDecrypt = (ASN1Sequence) inputDecrypted.readObject();
        logger.info("Decrypted : " + seqDecrypt);

        DigestInfo digestInfo = new DigestInfo(seqDecrypt);
        assertEquals(oidDigestAlgo, digestInfo.getAlgorithmId().getAlgorithm());

        String decryptedDigestEncodeBase64 = Base64.encodeBase64String(digestInfo.getDigest());
        logger.info("Decrypted Base64 : " + decryptedDigestEncodeBase64);

        byte[] encoded = signedInfo.getAuthenticatedAttributes().getEncoded();
        MessageDigest messageDigest = MessageDigest.getInstance(DigestAlgorithm.SHA256.getName());
        byte[] digestOfAuthenticatedAttributes = messageDigest.digest(encoded);

        String computedDigestEncodeBase64 = Base64.encodeBase64String(digestOfAuthenticatedAttributes);
        logger.info("Computed Base64 : " + computedDigestEncodeBase64);

        assertEquals(decryptedDigestEncodeBase64, computedDigestEncodeBase64);

        IOUtils.closeQuietly(asn1sInput);
        IOUtils.closeQuietly(inputDecrypted);
    } catch (Exception e) {
        logger.error(e.getMessage(), e);
        fail(e.getMessage());
    }
}