Example usage for org.bouncycastle.asn1 DERSequence DERSequence

List of usage examples for org.bouncycastle.asn1 DERSequence DERSequence

Introduction

In this page you can find the example usage for org.bouncycastle.asn1 DERSequence DERSequence.

Prototype

public DERSequence(ASN1Encodable[] elements) 

Source Link

Document

Create a sequence containing an array of objects.

Usage

From source file:edu.vt.middleware.crypt.signature.AbstractDSASignature.java

License:Open Source License

/**
 * Produces DER-encoded byte array output from the raw DSA signature output
 * parameters, r and s./*from   ww w .  jav a2  s. c  o m*/
 *
 * @param  r  DSA signature output integer r.
 * @param  s  DSA signature output integer s.
 *
 * @return  DER-encoded concatenation of byte representations of r and s.
 *
 * @throws  edu.vt.middleware.crypt.CryptException  On cryptographic errors.
 */
private byte[] encode(final BigInteger r, final BigInteger s) throws CryptException {
    final ByteArrayOutputStream out = new ByteArrayOutputStream();
    final ASN1EncodableVector v = new ASN1EncodableVector();
    v.add(new DERInteger(r));
    v.add(new DERInteger(s));
    try {
        new DEROutputStream(out).writeObject(new DERSequence(v));
    } catch (IOException e) {
        throw new CryptException("Error encoding DSA signature.", e);
    }
    return out.toByteArray();
}

From source file:edu.vt.middleware.crypt.util.DERHelper.java

License:Open Source License

/**
 * Creates a DER SEQUENCE type from the given DER encodable objects in the
 * order they are listed./*from w  w  w .  j  a va 2  s.c  o m*/
 *
 * @param  items  One or more DER encodable items.
 *
 * @return  DER SEQUENCE over given items.
 */
public static DERSequence sequence(final DEREncodable... items) {
    final ASN1EncodableVector v = new ASN1EncodableVector();
    for (DEREncodable item : items) {
        v.add(item);
    }
    return new DERSequence(v);
}

From source file:ee.ria.xroad.common.hashchain.DigestList.java

License:Open Source License

/**
 * Takes as input a sequence of hashes and combines them using DigestList
 * data structure.//w w w. j  av  a  2 s  . com
 */
static byte[] concatDigests(String digestMethodUri, byte[]... items) throws Exception {
    ASN1Encodable[] digestList = new ASN1Encodable[items.length];

    for (int i = 0; i < items.length; ++i) {
        digestList[i] = singleDigest(digestMethodUri, items[i]);
    }

    DERSequence step = new DERSequence(digestList);
    return step.getEncoded(DER);
}

From source file:ee.ria.xroad.common.hashchain.DigestList.java

License:Open Source License

/**
 * Takes as input a sequence of hashes and combines them using DigestList
 * data structure./*  w ww  . j ava 2s.co  m*/
 */
static byte[] concatDigests(DigestValue... items) throws Exception {
    ASN1Encodable[] digestList = new ASN1Encodable[items.length];

    for (int i = 0; i < items.length; ++i) {
        digestList[i] = singleDigest(items[i].getDigestMethod(), items[i].getDigestValue());
    }

    DERSequence step = new DERSequence(digestList);
    return step.getEncoded(DER);
}

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

License:Open Source License

/** M&eacute;todo que genera la parte que contiene la informaci&oacute;n del
 * Usuario. Se generan los atributos que se necesitan para generar la firma.
 * @param cert Certificado del firmante// w w  w.j  av  a  2s.c om
 * @param datos Datos firmados
 * @param policy Pol&iacute;tica de firma
 * @param messageDigest
 * @return Los datos necesarios para generar la firma referente a los datos
 *         del usuario.
 * @throws java.security.NoSuchAlgorithmException
 * @throws java.io.IOException
 * @throws CertificateEncodingException */
static ASN1EncodableVector generateSignerInfo(final X509Certificate cert, final String digestAlgorithmName,
        final byte[] datos, final AdESPolicy policy, final byte[] messageDigest)
        throws NoSuchAlgorithmException, IOException, CertificateEncodingException {

    // ALGORITMO DE HUELLA DIGITAL
    final AlgorithmIdentifier digestAlgorithmOID = SigUtils
            .makeAlgId(AOAlgorithmID.getOID(digestAlgorithmName));

    // // ATRIBUTOS

    // authenticatedAttributes
    final ASN1EncodableVector contexExpecific = initContexExpecific(digestAlgorithmName, datos,
            PKCSObjectIdentifiers.data.getId(), messageDigest);

    // Serial Number
    // comentar lo de abajo para version del rfc 3852
    contexExpecific.add(new Attribute(RFC4519Style.serialNumber,
            new DERSet(new DERPrintableString(cert.getSerialNumber().toString()))));

    if (!"SHA1".equals(AOSignConstants.getDigestAlgorithmName(digestAlgorithmName))) { //$NON-NLS-1$

        //********************************************/
        //***** La Nueva operatividad esta comentada */
        //********************************************/
        // INICIO SINGING CERTIFICATE-V2

        /** IssuerSerial ::= SEQUENCE { issuer GeneralNames, serialNumber
         * CertificateSerialNumber */

        final TBSCertificateStructure tbs = TBSCertificateStructure
                .getInstance(ASN1Primitive.fromByteArray(cert.getTBSCertificate()));

        /** ESSCertIDv2 ::= SEQUENCE { hashAlgorithm AlgorithmIdentifier
         * DEFAULT {algorithm id-sha256}, certHash Hash, issuerSerial
         * IssuerSerial OPTIONAL }
         * Hash ::= OCTET STRING */

        final byte[] certHash = MessageDigest.getInstance(digestAlgorithmName).digest(cert.getEncoded());
        final ESSCertIDv2[] essCertIDv2 = { new ESSCertIDv2(digestAlgorithmOID, certHash,
                new IssuerSerial(new GeneralNames(new GeneralName(tbs.getIssuer())), tbs.getSerialNumber())) };

        /** PolicyInformation ::= SEQUENCE { policyIdentifier CertPolicyId,
         * policyQualifiers SEQUENCE SIZE (1..MAX) OF PolicyQualifierInfo
         * OPTIONAL }
         * CertPolicyId ::= OBJECT IDENTIFIER
         * PolicyQualifierInfo ::= SEQUENCE { policyQualifierId
         * PolicyQualifierId, qualifier ANY DEFINED BY policyQualifierId } */

        final SigningCertificateV2 scv2;
        if (policy.getPolicyIdentifier() != null) {

            /** SigningCertificateV2 ::= SEQUENCE { certs SEQUENCE OF
             * ESSCertIDv2, policies SEQUENCE OF PolicyInformation OPTIONAL
             * } */
            scv2 = new SigningCertificateV2(essCertIDv2, getPolicyInformation(policy)); // con
            // politica
        } else {
            scv2 = new SigningCertificateV2(essCertIDv2); // Sin politica
        }

        // Secuencia con singningCertificate
        contexExpecific.add(new Attribute(PKCSObjectIdentifiers.id_aa_signingCertificateV2, new DERSet(scv2)));

        // FIN SINGING CERTIFICATE-V2

    } else {

        // INICIO SINGNING CERTIFICATE

        /** IssuerSerial ::= SEQUENCE { issuer GeneralNames, serialNumber
         * CertificateSerialNumber } */

        final TBSCertificateStructure tbs = TBSCertificateStructure
                .getInstance(ASN1Primitive.fromByteArray(cert.getTBSCertificate()));

        final IssuerSerial isuerSerial = new IssuerSerial(new GeneralNames(new GeneralName(tbs.getIssuer())),
                tbs.getSerialNumber());

        /** ESSCertID ::= SEQUENCE { certHash Hash, issuerSerial IssuerSerial
         * OPTIONAL }
         * Hash ::= OCTET STRING -- SHA1 hash of entire certificate */
        final ESSCertID essCertID = new ESSCertID(
                MessageDigest.getInstance(digestAlgorithmName).digest(cert.getEncoded()), isuerSerial);

        /** PolicyInformation ::= SEQUENCE { policyIdentifier CertPolicyId,
         * policyQualifiers SEQUENCE SIZE (1..MAX) OF PolicyQualifierInfo
         * OPTIONAL }
         * CertPolicyId ::= OBJECT IDENTIFIER
         * PolicyQualifierInfo ::= SEQUENCE { policyQualifierId
         * PolicyQualifierId, qualifier ANY DEFINED BY policyQualifierId } */

        final SigningCertificate scv;
        if (policy.getPolicyIdentifier() != null) {

            /** SigningCertificateV2 ::= SEQUENCE { certs SEQUENCE OF
             * ESSCertIDv2, policies SEQUENCE OF PolicyInformation OPTIONAL
             * } */
            /*
             * HAY QUE HACER UN SEQUENCE, YA QUE EL CONSTRUCTOR DE BOUNCY
             * CASTLE NO TIENE DICHO CONSTRUCTOR.
             */
            final ASN1EncodableVector v = new ASN1EncodableVector();
            v.add(new DERSequence(essCertID));
            v.add(new DERSequence(getPolicyInformation(policy)));
            scv = SigningCertificate.getInstance(new DERSequence(v)); // con politica
        } else {
            scv = new SigningCertificate(essCertID); // Sin politica
        }

        /** id-aa-signingCertificate OBJECT IDENTIFIER ::= { iso(1)
         * member-body(2) us(840) rsadsi(113549) pkcs(1) pkcs9(9) smime(16)
         * id-aa(2) 12 } */
        // Secuencia con singningCertificate
        contexExpecific.add(new Attribute(PKCSObjectIdentifiers.id_aa_signingCertificate, new DERSet(scv)));
    }

    // INICIO SIGPOLICYID ATTRIBUTE

    if (policy.getPolicyIdentifier() != null) {
        /*
         * SigPolicyId ::= OBJECT IDENTIFIER Politica de firma.
         */
        final ASN1ObjectIdentifier doiSigPolicyId = new ASN1ObjectIdentifier(
                policy.getPolicyIdentifier().toLowerCase().replace("urn:oid:", "")); //$NON-NLS-1$ //$NON-NLS-2$

        /*
         *   OtherHashAlgAndValue ::= SEQUENCE {
         *     hashAlgorithm    AlgorithmIdentifier,
         *     hashValue        OCTET STRING }
         *
         */

        // Algoritmo para el hash
        final AlgorithmIdentifier hashid;
        // si tenemos algoritmo de calculo de hash, lo ponemos
        if (policy.getPolicyIdentifierHashAlgorithm() != null) {
            hashid = SigUtils.makeAlgId(AOAlgorithmID
                    .getOID(AOSignConstants.getDigestAlgorithmName(policy.getPolicyIdentifierHashAlgorithm())));
        }
        // si no tenemos, ponemos el algoritmo de firma.
        else {
            hashid = digestAlgorithmOID;
        }
        // hash del documento, descifrado en b64
        final byte[] hashed;
        if (policy.getPolicyIdentifierHash() != null) {
            hashed = Base64.decode(policy.getPolicyIdentifierHash());
        } else {
            hashed = new byte[] { 0 };
        }

        final DigestInfo otherHashAlgAndValue = new DigestInfo(hashid, hashed);

        /*
         *   SigPolicyQualifierInfo ::= SEQUENCE {
         *       SigPolicyQualifierId  SigPolicyQualifierId,
         *       SigQualifier          ANY DEFINED BY policyQualifierId }
         */
        SigPolicyQualifierInfo spqInfo = null;
        if (policy.getPolicyQualifier() != null) {
            spqInfo = new SigPolicyQualifierInfo(policy.getPolicyQualifier().toString());
        }

        /*
         * SignaturePolicyId ::= SEQUENCE {
         *  sigPolicyId           SigPolicyId,
         *  sigPolicyHash         SigPolicyHash,
         *  sigPolicyQualifiers   SEQUENCE SIZE (1..MAX) OF
         *                          SigPolicyQualifierInfo OPTIONAL}
         *
         */
        final ASN1EncodableVector v = new ASN1EncodableVector();
        // sigPolicyId
        v.add(doiSigPolicyId);
        // sigPolicyHash
        v.add(otherHashAlgAndValue.toASN1Primitive()); // como sequence
        // sigPolicyQualifiers
        if (spqInfo != null) {
            v.add(spqInfo.toASN1Primitive());
        }

        final DERSequence ds = new DERSequence(v);

        // Secuencia con singningCertificate
        contexExpecific.add(
                new Attribute(PKCSObjectIdentifiers.id_aa_ets_sigPolicyId, new DERSet(ds.toASN1Primitive())));
        // FIN SIGPOLICYID ATTRIBUTE
    }

    return contexExpecific;
}

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

License:Open Source License

/**
 * Obtiene un PolicyInformation a partir de los datos de la pol&iacute;tica.
 * Sirve para los datos de SigningCertificate y SigningCertificateV2. Tiene que llevar algunos
 * datos de la pol&iacute;tica./*from   w  ww  . j a  v  a 2  s  . c  o  m*/
 * <pre>
 * PolicyInformation ::= SEQUENCE {
 * policyIdentifier   CertPolicyId,
 * policyQualifiers   SEQUENCE SIZE (1..MAX) OF
 *                          PolicyQualifierInfo OPTIONAL }
 *
 *
 * CertPolicyId ::= OBJECT IDENTIFIER
 *
 * PolicyQualifierInfo ::= SEQUENCE {
 *      policyQualifierId  PolicyQualifierId,
 *      qualifier          ANY DEFINED BY policyQualifierId }
 *
 * -- policyQualifierIds for Internet policy qualifiers
 *
 * id-qt          OBJECT IDENTIFIER ::=  { id-pkix 2 }
 * id-qt-cps      OBJECT IDENTIFIER ::=  { id-qt 1 }
 * id-qt-unotice  OBJECT IDENTIFIER ::=  { id-qt 2 }
 *
 * PolicyQualifierId ::=
 *      OBJECT IDENTIFIER ( id-qt-cps | id-qt-unotice )
 *
 * Qualifier ::= CHOICE {
 *      cPSuri           CPSuri,
 *      userNotice       UserNotice }
 *
 * CPSuri ::= IA5String
 *
 * UserNotice ::= SEQUENCE {
 *      noticeRef        NoticeReference OPTIONAL,
 *      explicitText     DisplayText OPTIONAL}
 *
 * NoticeReference ::= SEQUENCE {
 *      organization     DisplayText,
 *      noticeNumbers    SEQUENCE OF INTEGER }
 *
 * DisplayText ::= CHOICE {
 *      ia5String        IA5String      (SIZE (1..200)),
 *      visibleString    VisibleString  (SIZE (1..200)),
 *      bmpString        BMPString      (SIZE (1..200)),
 *      utf8String       UTF8String     (SIZE (1..200)) }
 * </pre>
 *
 * @param policy    Pol&iacute;tica de la firma.
 * @return          Estructura con la pol&iacute;tica preparada para insertarla en la firma.
 */
private static PolicyInformation[] getPolicyInformation(final AdESPolicy policy) {

    if (policy == null) {
        throw new IllegalArgumentException("La politica de firma no puede ser nula en este punto"); //$NON-NLS-1$
    }

    /*
     * PolicyQualifierInfo ::= SEQUENCE {
     *          policyQualifierId  PolicyQualifierId,
     *          qualifier          ANY DEFINED BY policyQualifierId }
     */

    final PolicyQualifierId pqid = PolicyQualifierId.id_qt_cps;
    DERIA5String uri = null;

    if (policy.getPolicyQualifier() != null && !policy.getPolicyQualifier().equals("")) { //$NON-NLS-1$
        uri = new DERIA5String(policy.getPolicyQualifier().toString());
    }

    final ASN1EncodableVector v = new ASN1EncodableVector();
    PolicyQualifierInfo pqi = null;
    if (uri != null) {
        v.add(pqid);
        v.add(uri);
        pqi = new PolicyQualifierInfo(new DERSequence(v));
    }

    /*
     * PolicyInformation ::= SEQUENCE {
     *     policyIdentifier   CertPolicyId,
     *     policyQualifiers   SEQUENCE SIZE (1..MAX) OF
     *                          PolicyQualifierInfo OPTIONAL }
     */

    if (policy.getPolicyQualifier() == null || pqi == null) {
        return new PolicyInformation[] { new PolicyInformation(
                new ASN1ObjectIdentifier(policy.getPolicyIdentifier().toLowerCase().replace("urn:oid:", ""))) //$NON-NLS-1$ //$NON-NLS-2$
        };
    }

    return new PolicyInformation[] { new PolicyInformation(
            new ASN1ObjectIdentifier(policy.getPolicyIdentifier().toLowerCase().replace("urn:oid:", "")), //$NON-NLS-1$//$NON-NLS-2$
            new DERSequence(pqi)) };

}

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

License:Open Source License

/** Devuelve una representaci&oacute;n DER-encodable the esta estancia.
 * @return un valor <code>DERObject</code>. */
@Override//from w w  w  .  java2 s .co  m
public ASN1Primitive toASN1Primitive() {
    final ASN1EncodableVector dev = new ASN1EncodableVector();
    dev.add(this.sigPolicyQualifierId);
    dev.add(this.sigQualifier);
    return new DERSequence(dev);
}

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

License:Open Source License

/** Genera una estructura <i>SigningCertificateV2</i> seg&uacute;n RFC 5035:
 *
 * <pre>/*from  www.j a  v  a  2  s . com*/
 * id-aa-signingCertificate OBJECT IDENTIFIER ::= { iso(1)
 *      member-body(2) us(840) rsadsi(113549) pkcs(1) pkcs9(9)
 *      smime(16) id-aa(2) 12
 * }
 *
 * SigningCertificate ::=  SEQUENCE {
 *      certs        SEQUENCE OF ESSCertID,
 *      policies     SEQUENCE OF PolicyInformation OPTIONAL
 * }
 * </pre>
 *
 * @param cert Certificado del firmante
 * @param digestAlgorithmName Nombre del algoritmo de huella digital a usar
 * @param policy Pol&iacute;tica de firma
 * @return Estructura <i>SigningCertificate</i> seg&uacute;n RFC 5035
 * @throws CertificateEncodingException Si el certificado proporcionado no es v&aacute;lido
 * @throws NoSuchAlgorithmException Si no se soporta el algoritmo de huella indicado */
private static Attribute getSigningCertificateV1(final X509Certificate cert, final String digestAlgorithmName,
        final AdESPolicy policy) throws CertificateEncodingException, NoSuchAlgorithmException {

    // INICIO SINGNING CERTIFICATE

    /** IssuerSerial ::= SEQUENCE { issuer GeneralNames, serialNumber
     * CertificateSerialNumber } */

    final GeneralName gn = new GeneralName(X500Name.getInstance(cert.getIssuerX500Principal().getEncoded()));
    final GeneralNames gns = new GeneralNames(gn);

    final IssuerSerial isuerSerial = new IssuerSerial(gns, cert.getSerialNumber());

    /** ESSCertID ::= SEQUENCE { certHash Hash, issuerSerial IssuerSerial
     * OPTIONAL }
     * Hash ::= OCTET STRING -- SHA1 hash of entire certificate */
    final byte[] certHash = MessageDigest.getInstance(digestAlgorithmName).digest(cert.getEncoded());
    final ESSCertID essCertID = new ESSCertID(certHash, isuerSerial);

    /** PolicyInformation ::= SEQUENCE { policyIdentifier CertPolicyId,
     * policyQualifiers SEQUENCE SIZE (1..MAX) OF PolicyQualifierInfo
     * OPTIONAL }
     * CertPolicyId ::= OBJECT IDENTIFIER
     * PolicyQualifierInfo ::= SEQUENCE { policyQualifierId
     * PolicyQualifierId, qualifier ANY DEFINED BY policyQualifierId } */

    final SigningCertificate scv;
    if (policy != null && policy.getPolicyIdentifier() != null) {

        /** SigningCertificateV2 ::= SEQUENCE {
         *    certs SEQUENCE OF ESSCertIDv2,
         *    policies SEQUENCE OF PolicyInformation OPTIONAL
         *  } */

        /*
         * HAY QUE HACER UN SEQUENCE, YA QUE EL CONSTRUCTOR DE BOUNCY
         * CASTLE NO TIENE DICHO CONSTRUCTOR.
         */
        final ASN1EncodableVector v = new ASN1EncodableVector();
        v.add(new DERSequence(essCertID));
        v.add(new DERSequence(getPolicyInformation(policy)));
        scv = SigningCertificate.getInstance(new DERSequence(v)); // con politica
    } else {
        scv = new SigningCertificate(essCertID); // Sin politica
    }

    /** id-aa-signingCertificate OBJECT IDENTIFIER ::= {
     *    iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) pkcs9(9) smime(16) id-aa(2) 12
     *  } */

    return new Attribute(PKCSObjectIdentifiers.id_aa_signingCertificate, new DERSet(scv));
}

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

License:Open Source License

private static Attribute getSigPolicyId(final String digestAlgorithmName, final AdESPolicy policy)
        throws IOException {

    /** SigPolicyId ::= OBJECT IDENTIFIER Politica de firma. */

    final ASN1ObjectIdentifier doiSigPolicyId = new ASN1ObjectIdentifier(
            policy.getPolicyIdentifier().toLowerCase(Locale.US).replace("urn:oid:", "") //$NON-NLS-1$ //$NON-NLS-2$
    );//from   w ww  .  j  av  a 2 s  .c o m

    /**  OtherHashAlgAndValue ::= SEQUENCE {
     *     hashAlgorithm    AlgorithmIdentifier,
     *     hashValue        OCTET STRING
     *   } */

    // Algoritmo para el hash
    final AlgorithmIdentifier hashid;
    // Si tenemos algoritmo de calculo de hash, lo ponemos
    if (policy.getPolicyIdentifierHashAlgorithm() != null) {
        hashid = SigUtils.makeAlgId(AOAlgorithmID
                .getOID(AOSignConstants.getDigestAlgorithmName(policy.getPolicyIdentifierHashAlgorithm())));
    }
    // Si no tenemos, ponemos el algoritmo de firma.
    else {
        hashid = SigUtils.makeAlgId(AOAlgorithmID.getOID(digestAlgorithmName));
    }

    // Huella del documento
    final byte[] hashed;
    if (policy.getPolicyIdentifierHash() != null) {
        hashed = Base64.decode(policy.getPolicyIdentifierHash());
    } else {
        hashed = new byte[] { 0 };
    }

    final DigestInfo otherHashAlgAndValue = new DigestInfo(hashid, hashed);

    /** AOSigPolicyQualifierInfo ::= SEQUENCE {
     *       SigPolicyQualifierId  SigPolicyQualifierId,
     *       SigQualifier          ANY DEFINED BY policyQualifierId
     *  } */

    AOSigPolicyQualifierInfo spqInfo = null;
    if (policy.getPolicyQualifier() != null) {
        spqInfo = new AOSigPolicyQualifierInfo(policy.getPolicyQualifier().toString());
    }

    /** SignaturePolicyId ::= SEQUENCE {
     *    sigPolicyId           SigPolicyId,
     *    sigPolicyHash         SigPolicyHash,
     *    sigPolicyQualifiers   SEQUENCE SIZE (1..MAX) OF AOSigPolicyQualifierInfo OPTIONAL
     *  } */

    final ASN1EncodableVector v = new ASN1EncodableVector();
    // sigPolicyId
    v.add(doiSigPolicyId);
    // sigPolicyHash
    v.add(otherHashAlgAndValue.toASN1Primitive()); // como sequence
    // sigPolicyQualifiers
    if (spqInfo != null) {
        v.add(new DERSequence(spqInfo.toASN1Primitive()));
    }

    final DERSequence ds = new DERSequence(v);

    return new Attribute(PKCSObjectIdentifiers.id_aa_ets_sigPolicyId, new DERSet(ds.toASN1Primitive()));

}

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

License:Open Source License

/** Obtiene un <i>PolicyInformation</i> a partir de los datos de la pol&iacute;tica.
 * Sirve para los datos de SigningCertificate y SigningCertificateV2. Tiene que llevar algunos
 * datos de la pol&iacute;tica./* w w  w.ja v a 2s  . co  m*/
 *
 * <pre>
 * PolicyInformation ::= SEQUENCE {
 *       policyIdentifier   CertPolicyId,
 *       policyQualifiers   SEQUENCE SIZE (1..MAX) OF PolicyQualifierInfo OPTIONAL
 * }
 *
 * CertPolicyId ::= OBJECT IDENTIFIER
 *
 * PolicyQualifierInfo ::= SEQUENCE {
 *      policyQualifierId  PolicyQualifierId,
 *      qualifier          ANY DEFINED BY policyQualifierId
 * }
 *
 * -- policyQualifierIds for Internet policy qualifiers
 *
 * id-qt          OBJECT IDENTIFIER ::=  { id-pkix 2 }
 * id-qt-cps      OBJECT IDENTIFIER ::=  { id-qt 1 }
 * id-qt-unotice  OBJECT IDENTIFIER ::=  { id-qt 2 }
 *
 * PolicyQualifierId ::= OBJECT IDENTIFIER ( id-qt-cps | id-qt-unotice )
 *
 * Qualifier ::= CHOICE {
 *      cPSuri           CPSuri,
 *      userNotice       UserNotice
 * }
 *
 * CPSuri ::= IA5String
 *
 * UserNotice ::= SEQUENCE {
 *      noticeRef        NoticeReference OPTIONAL,
 *      explicitText     DisplayText OPTIONAL
 * }
 *
 * NoticeReference ::= SEQUENCE {
 *      organization     DisplayText,
 *      noticeNumbers    SEQUENCE OF INTEGER
 * }
 *
 * DisplayText ::= CHOICE {
 *      ia5String        IA5String      (SIZE (1..200)),
 *      visibleString    VisibleString  (SIZE (1..200)),
 *      bmpString        BMPString      (SIZE (1..200)),
 *      utf8String       UTF8String     (SIZE (1..200))
 * }
 * </pre>
 *
 * @param policy    Pol&iacute;tica de la firma.
 * @return          Estructura con la pol&iacute;tica preparada para insertarla en la firma. */
private static PolicyInformation[] getPolicyInformation(final AdESPolicy policy) {

    if (policy == null) {
        throw new IllegalArgumentException("La politica de firma no puede ser nula en este punto"); //$NON-NLS-1$
    }

    /** PolicyQualifierInfo ::= SEQUENCE {
     *          policyQualifierId  PolicyQualifierId,
     *          qualifier          ANY DEFINED BY policyQualifierId
     *  } */

    final PolicyQualifierId pqid = PolicyQualifierId.id_qt_cps;
    DERIA5String uri = null;

    if (policy.getPolicyQualifier() != null && !policy.getPolicyQualifier().equals("")) { //$NON-NLS-1$
        uri = new DERIA5String(policy.getPolicyQualifier().toString());
    }

    final ASN1EncodableVector v = new ASN1EncodableVector();
    PolicyQualifierInfo pqi = null;
    if (uri != null) {
        v.add(pqid);
        v.add(uri);
        pqi = PolicyQualifierInfo.getInstance(new DERSequence(v));
    }

    /** PolicyInformation ::= SEQUENCE {
     *     policyIdentifier   CertPolicyId,
     *     policyQualifiers   SEQUENCE SIZE (1..MAX) OF PolicyQualifierInfo OPTIONAL
     *  } */

    if (policy.getPolicyQualifier() == null || pqi == null) {
        return new PolicyInformation[] { new PolicyInformation(new ASN1ObjectIdentifier(
                policy.getPolicyIdentifier().toLowerCase(Locale.US).replace("urn:oid:", "") //$NON-NLS-1$ //$NON-NLS-2$
                )) };
    }

    return new PolicyInformation[] { new PolicyInformation(
            new ASN1ObjectIdentifier(policy.getPolicyIdentifier().toLowerCase(Locale.US).replace("urn:oid:", "") //$NON-NLS-1$ //$NON-NLS-2$
            ), new DERSequence(pqi)) };

}