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.applet.CMSInformation.java

License:Open Source License

/**
 * Método principal que obtiene la información a partir de un fichero firmado
 * de tipo CMS.//from  w  w w.j a va 2 s  .c o m
 * @param data Objeto CMS.
 * @return Texto descriptivo del objeto CMS.
 * @throws IOException Si ocurre algún problema leyendo o escribiendo los datos
 * @throws AOInvalidFormatException Error de formato no válido.
 */
static String getInformation(final byte[] data) throws IOException, AOInvalidFormatException {

    final ASN1InputStream is = new ASN1InputStream(data);

    // 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 Data
    final ASN1ObjectIdentifier doi = (ASN1ObjectIdentifier) e.nextElement();

    // Contenido a obtener informacion
    final ASN1TaggedObject doj = (ASN1TaggedObject) e.nextElement();

    final String datos;
    if (doi.equals(PKCSObjectIdentifiers.data)) {
        datos = AppletMessages.getString("CMSInformation.0") + SP + DATA + CR; //$NON-NLS-1$
    } else if (doi.equals(PKCSObjectIdentifiers.digestedData)) {
        datos = getFromDigestedData(doj);
    } else if (doi.equals(PKCSObjectIdentifiers.encryptedData)) {

        datos = extractData(doj, TYPE_ENCRYPTED_DATA,
                AppletMessages.getString("CMSInformation.0") + SP + ENCRYPTED_DATA, BINARY_SIGN_CMS); //$NON-NLS-1$
    } else if (doi.equals(PKCSObjectIdentifiers.signedData)) {
        datos = extractData(doj, TYPE_SIGNED_DATA,
                AppletMessages.getString("CMSInformation.0") + SP + SIGNED_DATA, BINARY_SIGN_CMS); //$NON-NLS-1$
    } else if (doi.equals(PKCSObjectIdentifiers.envelopedData)) {
        datos = extractData(doj, TYPE_ENVELOPED_DATA,
                AppletMessages.getString("CMSInformation.0") + SP + ENVELOPED_DATA, BINARY_SIGN_CMS); //$NON-NLS-1$
    } else if (doi.equals(PKCSObjectIdentifiers.signedAndEnvelopedData)) {
        datos = extractData(doj, TYPE_SIGNED_ENVELOPED_DATA,
                AppletMessages.getString("CMSInformation.0") + SP + SIGNED_ENVELOPED_DATA, BINARY_SIGN_CMS); //$NON-NLS-1$
    } else if (doi.equals(PKCSObjectIdentifiers.id_ct_authData)) {
        datos = extractData(doj, TYPE_AUTHENTICATED_DATA,
                AppletMessages.getString("CMSInformation.0") + SP + AUTHENTICATED_DATA, BINARY_SIGN_CMS); //$NON-NLS-1$
    } else if (doi.equals(PKCSObjectIdentifiers.id_ct_authEnvelopedData)) {
        datos = extractData(doj, TYPE_AUTHENTICATED_ENVELOPED_DATA,
                AppletMessages.getString("CMSInformation.0") + SP + AUTH_ENVELOPED_DATA, BINARY_SIGN_CMS); //$NON-NLS-1$
    } else if (doi.equals(CMSObjectIdentifiers.compressedData)) {
        datos = getFromCompressedData(doj);
    } else {
        throw new AOInvalidFormatException(
                "Los datos introducidos no se corresponden con un tipo de objeto CMS soportado"); //$NON-NLS-1$
    }

    return datos;
}

From source file:es.gob.afirma.envelopers.cades.AOCAdESEnveloper.java

License:Open Source License

/** M&eacute;todo que realiza el resto de firmas permitidas por CADES. Son
 * las siguientes: <br/>// w w w . j a va 2s  . c  o  m
 * <ul>
 * <li>Data</li>
 * <li>Signed Data</li>
 * <li>Digested Data</li>
 * <li>Enveloped Data</li>
 * <li>Signed and Enveloped Data</li>
 * </ul>
 * Para la generaci&oacute;n de la clave interna se utiliza por defecto el
 * AES.
 * En el caso de que sea tipo "Enveloped data" o
 * "Signed and enveloped data", la clave se generar&aacute; usando el
 * algoritmo pasado como par&aacute;metro. Dicha clave se cifrar&aacute;
 * despu&eacute;s con la clave p&uacute;blica del certificado que identifica
 * al usuario destinatario.
 * Nota: El par&aacute;metro algorithm no es el agoritmo de cifrado, es para
 * el digestAlgorithm usado en los "Unsigned Attributes".
 * @param data
 *        Datos a envolver.
 * @param digestAlgorithm
 *        Algoritmo a usar para la firma (SHA1withRSA, MD5withRSA,...)
 * @param type
 *        Tipo de "envelop" que se quiere hacer.
 * @param keyEntry
 *        Clave privada a usar para firmar.
 * @param certDest
 *        Certificados de los usuarios a los que va destinado el sobre
 *        digital.
 * @param cipherAlgorithm
 *        Algoritmo utilizado para cifrar
 * @param xParams
 *        Par&aacute;metros adicionales
 * @return Envoltorio CADES.
 * @throws AOException
 *         Cuando ocurre cualquier problema en el proceso. */
@Override
public byte[] envelop(final byte[] data, final String digestAlgorithm, final String type,
        final PrivateKeyEntry keyEntry, final X509Certificate[] certDest,
        final AOCipherAlgorithm cipherAlgorithm, final String datTyp, final Properties xParams)
        throws AOException {

    final Properties extraParams = xParams != null ? xParams : new Properties();

    // Comprobamos que el archivo a tratar no sea nulo.
    if (data == null) {
        throw new IllegalArgumentException("El archivo a tratar no puede ser nulo."); //$NON-NLS-1$
    }

    final P7ContentSignerParameters csp = new P7ContentSignerParameters(data, digestAlgorithm);

    // tipos de datos a firmar.
    final String dataType = datTyp != null ? datTyp : PKCSObjectIdentifiers.data.getId();

    // Datos firmados.
    byte[] dataSigned = null;

    // Seleccion del algoritmo de cifrado.
    AOCipherConfig config = null;
    if (cipherAlgorithm == null) {
        // Por defecto usamos el AES.
        config = new AOCipherConfig(AOCipherAlgorithm.AES, AOCipherBlockMode.CBC, AOCipherPadding.PKCS5PADDING);
    }
    /*
     * En caso de usar un algoritmo de cifrado, si no funciona es porque el
     * Provider no lo soporta.
     */
    else {
        config = new AOCipherConfig(cipherAlgorithm, AOCipherBlockMode.CBC, AOCipherPadding.PKCS5PADDING);
    }

    try {
        // Busqueda del tipo que nos han solicitado.

        // Es Data.
        if (AOSignConstants.CMS_CONTENTTYPE_DATA.equals(type)) {
            dataSigned = CAdESData.genData(csp);
        }
        // Es Digested Data.
        else if (AOSignConstants.CMS_CONTENTTYPE_DIGESTEDDATA.equals(type)) {
            dataSigned = CAdESDigestedData.genDigestedData(csp, dataType);
        }
        // Es Enveloped Data. El null y el vacio se consideran Enveloped Data, el por defecto
        else if (AOSignConstants.CMS_CONTENTTYPE_ENVELOPEDDATA.equals(type) || type == null
                || "".equals(type)) { //$NON-NLS-1$
            if (keyEntry != null) {
                dataSigned = new CAdESEnvelopedData().genEnvelopedData(csp,
                        (X509Certificate[]) keyEntry.getCertificateChain(), config, certDest, dataType);
            } else {
                dataSigned = new CAdESEnvelopedData().genEnvelopedData(data, digestAlgorithm, config, certDest,
                        dataType);
            }
        }
        // Es Signed and Enveloped Data.
        else {
            dataSigned = new CAdESEPESSignedAndEnvelopedData().genCADESEPESSignedAndEnvelopedData(csp,
                    (X509Certificate[]) keyEntry.getCertificateChain(), config, new AdESPolicy(extraParams),
                    certDest, PKCSObjectIdentifiers.signedData.getId(), keyEntry);
        }
    } catch (final Exception e) {
        throw new AOException("Error generando el enveloped de CADES", e); //$NON-NLS-1$
    }

    return dataSigned;
}

From source file:es.gob.afirma.envelopers.cms.ValidateCMS.java

License:Open Source License

/** M&eacute;todo que verifica que es una firma de tipo "Signed data"
 * @param data//from  www.j ava 2 s. co m
 *        Datos CMS.
 * @return si es de este tipo. */
static boolean isCMSSignedData(final byte[] data) {
    boolean isValid = true;
    try {
        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();
        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;
    }
    return isValid;
}

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&ntilde;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 . ja v  a 2  s .c o m*/
 * @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.cades.CAdESValidator.java

License:Open Source License

/** Verifica si los datos proporcionados se corresponden con una estructura de tipo <i>SignedData</i>.
 * @param data Datos PKCS#7/CMS/CAdES./*from   ww w. j av  a2  s  .  com*/
 * @param enforceCAdES Si se establece a <code>true</code> se comprueba que los SignerInfos sean expl&iacute;citamente
 *                     de tipo CAdES, si se establece a <code>false</code> no se comprueba, por lo que se aceptan
 *                     <code>SignedData</code> de CMS y PKCS#7.
 * @return <code>true</code> si los datos proporcionados se corresponden con una estructura de tipo <i>SignedData</i>,
 * <code>false</code> en caso contrario.
 * @throws IOException Si ocurren problemas leyendo los datos */
public static boolean isCAdESSignedData(final byte[] data, final boolean enforceCAdES) throws IOException {
    try {
        final ASN1InputStream is = new ASN1InputStream(data);
        // 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 Data
        final ASN1ObjectIdentifier doi = (ASN1ObjectIdentifier) e.nextElement();
        if (!doi.equals(PKCSObjectIdentifiers.signedData)) {
            LOGGER.info(
                    "Los datos proporcionados no son de tipo SignedData de CAdES (no esta declarado el OID de SignedData)" //$NON-NLS-1$
            );
            return false;
        }

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

        if (enforceCAdES) {
            for (int i = 0; i < signerInfosSd.size(); i++) {
                if (!verifySignerInfo(SignerInfo.getInstance(signerInfosSd.getObjectAt(i)))) {
                    LOGGER.info(
                            "Los datos proporcionados no son de tipo SignedData de CAdES (al menos un SignerInfo no se ha declarado de tipo CAdES)" //$NON-NLS-1$
                    );
                    return false;
                }
            }
        }

    } catch (final Exception ex) {
        LOGGER.info("Los datos proporcionados no son de tipo SignedData de CAdES: " + ex); //$NON-NLS-1$
        return false;
    }

    return true;
}

From source file:es.gob.afirma.signers.cades.CAdESValidator.java

License:Open Source License

/** Verifica si los datos proporcionados se corresponden con una estructura de tipo <i>SignedAndEnvelopedData</i>.
 * @param data Datos PKCS#7/CMS/CAdES.// www. j a v  a 2  s  .c  om
 * @return <code>true</code> si los datos proporcionados se corresponden con una estructura de tipo <i>SignedAndEnvelopedData</i>,
 * <code>false</code> en caso contrario.
 * @throws IOException Si ocurren problemas relacionados con la lectura de los datos. */
static boolean isCAdESSignedAndEnvelopedData(final byte[] data) throws IOException {
    boolean isValid = false;

    // LEEMOS EL FICHERO QUE NOS INTRODUCEN
    final ASN1InputStream is = new ASN1InputStream(data);
    final ASN1Sequence dsq;
    try {
        dsq = (ASN1Sequence) is.readObject();
    } catch (final Exception e) {
        // No es una secuencia valida
        return false;
    } finally {
        is.close();
    }
    is.close();
    final Enumeration<?> e = dsq.getObjects();

    // Elementos que contienen los elementos OID Data
    final ASN1ObjectIdentifier doi = (ASN1ObjectIdentifier) e.nextElement();
    if (doi.equals(PKCSObjectIdentifiers.signedData)) {
        isValid = true;
    }
    // Contenido de SignedData
    final ASN1TaggedObject doj = (ASN1TaggedObject) e.nextElement();
    final ASN1Sequence datos = (ASN1Sequence) doj.getObject();

    final SignedAndEnvelopedData sd;
    try {
        sd = new SignedAndEnvelopedData(datos);
    } catch (final Exception ex) {
        LOGGER.info("Los datos proporcionados no son de tipo SignedAndEnvelopedData: " + ex); //$NON-NLS-1$
        return false;
    }

    final ASN1Set signerInfosSd = sd.getSignerInfos();

    for (int i = 0; i < signerInfosSd.size(); i++) {
        final SignerInfo si = SignerInfo.getInstance(signerInfosSd.getObjectAt(i));
        isValid = verifySignerInfo(si);
    }

    return isValid;
}

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&aacute;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&iacute;cita o Impl&iacute;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&uacute;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&oacute;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();/*  w ww .j av  a 2s  .  co  m*/
    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  w  ww.ja  v  a 2  s .c  om*/
 * @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&uacute;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&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 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);

}

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

License:Open Source License

/** Constructor de la clase. Se 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 . ja  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 dataType Identifica el tipo del contenido a firmar.
 * @param atri Atributo firmado que agregar a la firma.
 * @param uatri Atributo no firmado que agregar a la firma.
 * @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 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&oacute;n con los certificados de
 *                                                 firma.
 * @throws AOException Cuando ocurre cualquier error no contemplado por el resto de
 *                     las 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 String dataType, final Map<String, byte[]> atri,
        final Map<String, byte[]> uatri)
        throws IOException, NoSuchAlgorithmException, CertificateException, AOException {

    this.atrib2 = atri;
    this.uatrib2 = uatri;

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

    if (certChain.length != 0) {
        vCertsSig.add(Certificate.getInstance(ASN1Primitive.fromByteArray(certChain[0].getEncoded())));
        certificates = new BERSet(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);
    } // FIRMA DE LAS HOJAS
    else if (targetType.equals(CounterSignTarget.LEAFS)) {
        signerInfos = counterLeaf(signerInfosSd, parameters, key, certChain);
    } // 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, nodo);
            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);
    } 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, nodo);
            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.cms.GenSignedData.java

License:Open Source License

/** Genera una firma digital usando el sistema conocido como
 * <code>SignedData</code> y que podr&aacute; ser con el contenido del fichero codificado
 * o s&oacute;lo como referencia del fichero.
 * @param parameters Par&aacute;metros necesarios para obtener los datos de
 *                   <code>SignedData</code>.
 * @param omitContent Par&aacute;metro que indica si en la firma va el contenido del
 *                    fichero o s&oacute;lo va de forma referenciada.
 * @param applyTimestamp Si se aplica la marca de tiempo o no.
 * @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 Huella digital a aplicar en la firma.
 * @return La firma generada codificada.
 * @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&oacute;n con los certificados de
 *                                                 firma.
 * @throws java.io.IOException Cuando ocurre un error durante el proceso de descifrado
 *                             (formato o clave incorrecto,...)
 * @throws AOException Cuando ocurre un error durante el proceso de descifrado
 *                     (formato o clave incorrecto,...) */
byte[] generateSignedData(final P7ContentSignerParameters parameters, final boolean omitContent,
        final boolean applyTimestamp, 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 NoSuchAlgorithmException, CertificateException, IOException, AOException {

    if (parameters == null) {
        throw new IllegalArgumentException("Los parametros no pueden ser nulos"); //$NON-NLS-1$
    }//from  w w  w . java 2s.  c  o  m

    // 1. VERSION
    // la version se mete en el constructor del signedData y es 1

    // 2. DIGESTALGORITM
    // buscamos que timo de algoritmo es y lo codificamos con su OID

    final ASN1EncodableVector digestAlgs = new ASN1EncodableVector();
    final String signatureAlgorithm = parameters.getSignatureAlgorithm();
    final String digestAlgorithm = AOSignConstants.getDigestAlgorithmName(signatureAlgorithm);
    final AlgorithmIdentifier digAlgId = SigUtils.makeAlgId(AOAlgorithmID.getOID(digestAlgorithm));

    digestAlgs.add(digAlgId);

    // 3. CONTENTINFO
    // si se introduce el contenido o no

    ContentInfo encInfo;
    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;

    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.createBerSetFromList(ce);
    }

    final ASN1Set certrevlist = null;

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

    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
    final ASN1Set signedAttr = generateSignedInfo(digestAlgorithm,
            content2 != null ? content2 : parameters.getContent(), dataType, applyTimestamp, atrib,
            messageDigest);

    // ATRIBUTOS NO FIRMADOS.

    final ASN1Set unSignedAttr = generateUnsignedInfo(uatrib);

    // // FIN ATRIBUTOS

    // 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 = firma(signatureAlgorithm, key);
    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(new DERSet(digestAlgs), encInfo, certificates, certrevlist, new DERSet(signerInfos)))
                    .getEncoded(ASN1Encoding.DER);

}