All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.itextpdf.signatures.cms.SignerInfo Maven / Gradle / Ivy

The newest version!
/*
    This file is part of the iText (R) project.
    Copyright (c) 1998-2025 Apryse Group NV
    Authors: Apryse Software.

    This program is offered under a commercial and under the AGPL license.
    For commercial licensing, contact us at https://itextpdf.com/sales.  For AGPL licensing, see below.

    AGPL licensing:
    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU Affero General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU Affero General Public License for more details.

    You should have received a copy of the GNU Affero General Public License
    along with this program.  If not, see .
 */
package com.itextpdf.signatures.cms;

import com.itextpdf.bouncycastleconnector.BouncyCastleFactoryCreator;
import com.itextpdf.commons.bouncycastle.IBouncyCastleFactory;
import com.itextpdf.commons.bouncycastle.asn1.IASN1Encodable;
import com.itextpdf.commons.bouncycastle.asn1.IASN1EncodableVector;
import com.itextpdf.commons.bouncycastle.asn1.IASN1Enumerated;
import com.itextpdf.commons.bouncycastle.asn1.IASN1InputStream;
import com.itextpdf.commons.bouncycastle.asn1.IASN1Integer;
import com.itextpdf.commons.bouncycastle.asn1.IASN1ObjectIdentifier;
import com.itextpdf.commons.bouncycastle.asn1.IASN1OctetString;
import com.itextpdf.commons.bouncycastle.asn1.IASN1Primitive;
import com.itextpdf.commons.bouncycastle.asn1.IASN1Sequence;
import com.itextpdf.commons.bouncycastle.asn1.IASN1Set;
import com.itextpdf.commons.bouncycastle.asn1.IASN1TaggedObject;
import com.itextpdf.commons.bouncycastle.asn1.IDEROctetString;
import com.itextpdf.commons.bouncycastle.asn1.IDERSequence;
import com.itextpdf.commons.bouncycastle.asn1.IDERSet;
import com.itextpdf.commons.bouncycastle.asn1.IDERTaggedObject;
import com.itextpdf.commons.bouncycastle.asn1.ocsp.IOCSPObjectIdentifiers;
import com.itextpdf.commons.bouncycastle.asn1.x509.IAlgorithmIdentifier;
import com.itextpdf.commons.bouncycastle.asn1.x509.ITBSCertificate;
import com.itextpdf.kernel.crypto.DigestAlgorithms;
import com.itextpdf.kernel.crypto.OID;
import com.itextpdf.kernel.exceptions.PdfException;
import com.itextpdf.signatures.CertificateInfo;
import com.itextpdf.signatures.CertificateUtil;
import com.itextpdf.signatures.exceptions.SignExceptionMessageConstant;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.cert.CertificateEncodingException;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;

/**
 * This class represents the SignerInfo structure from
 * rfc5652   Cryptographic Message Syntax (CMS)
 */
public class SignerInfo {
    private static final IBouncyCastleFactory BC_FACTORY = BouncyCastleFactoryCreator.getFactory();
    private static final int DEFAULT_SIGNATURE_SIZE = 1024;

    private AlgorithmIdentifier digestAlgorithm;
    private AlgorithmIdentifier signingAlgorithm;
    private final Collection signedAttributes = new ArrayList<>();
    private final Collection unSignedAttributes;
    private byte[] serializedSignedAttributes;
    private Collection ocspResponses;
    private Collection crlResponses;
    private byte[] signatureData;
    private boolean signedAttributesReadOnly;
    private X509Certificate signerCertificate;

    /**
     * Creates an empty SignerInfo structure.
     */
    public SignerInfo() {
        CmsAttribute contentType =
                new CmsAttribute(OID.CONTENT_TYPE,
                        BC_FACTORY.createDERSet(BC_FACTORY.createASN1ObjectIdentifier(OID.PKCS7_DATA)));
        signedAttributes.add(contentType);
        unSignedAttributes = new ArrayList<>();
    }

    /**
     * Creates a SignerInfo structure from an ASN1 structure.
     *
     * @param signerInfoStructure the ASN1 structure containing signerInfo
     * @param certificates        the certificates of the CMS, it should contain the signing certificate
     *
     * @throws IOException if issues occur during ASN1 objects creation.
     */
    public SignerInfo(IASN1Encodable signerInfoStructure, Collection certificates) throws IOException {
        int index = 0;
        try {
            IASN1Sequence signerInfoSeq = BC_FACTORY.createASN1Sequence(signerInfoStructure);
            IASN1Integer version = BC_FACTORY.createASN1Integer(signerInfoSeq.getObjectAt(index++));
            if (version.getValue().intValue() == 1) {
                processIssuerAndSerialNumberSignerCertificate(signerInfoSeq.getObjectAt(index++), certificates);
            } else {
                processSubjectKeyIdentifierSignerCertificate(signerInfoSeq.getObjectAt(index++), certificates);
            }
            digestAlgorithm = new AlgorithmIdentifier(signerInfoSeq.getObjectAt(index++));
            IASN1TaggedObject taggedSingedAttributes =
                    BC_FACTORY.createASN1TaggedObject(signerInfoSeq.getObjectAt(index));
            if (taggedSingedAttributes != null) {
                index++;
                setSerializedSignedAttributes(BC_FACTORY.createASN1Set(taggedSingedAttributes, false)
                        .getEncoded(BC_FACTORY.createASN1Encoding().getDer()));
            }
            signingAlgorithm = new AlgorithmIdentifier(signerInfoSeq.getObjectAt(index++));

            IDEROctetString signatureDataOS = BC_FACTORY.createDEROctetString(signerInfoSeq.getObjectAt(index++));
            if (signatureDataOS != null) {
                signatureData = signatureDataOS.getOctets();
            }

            if (signerInfoSeq.size() > index) {
                IASN1TaggedObject taggedUnsingedAttributes =
                        BC_FACTORY.createASN1TaggedObject(signerInfoSeq.getObjectAt(index));
                unSignedAttributes = processAttributeSet(BC_FACTORY.createASN1Set(taggedUnsingedAttributes, false));
            } else {
                unSignedAttributes = new ArrayList<>();
            }
        } catch (NullPointerException npe) {
            throw new PdfException(SignExceptionMessageConstant.CMS_INVALID_CONTAINER_STRUCTURE, npe);
        }
    }

    /**
     * Returns the algorithmId to create the digest of the data to sign.
     *
     * @return the OID of the digest algorithm.
     */
    public AlgorithmIdentifier getDigestAlgorithm() {
        return digestAlgorithm;
    }

    /**
     * Sets the algorithmId to create the digest of the data to sign.
     *
     * @param algorithmId the OID of the algorithm
     */
    public void setDigestAlgorithm(AlgorithmIdentifier algorithmId) {
        digestAlgorithm = algorithmId;
    }

    /**
     * Adds or replaces the message digest signed attribute.
     *
     * @param digest ASN.1 type MessageDigest
     */
    public void setMessageDigest(byte[] digest) {
        if (signedAttributesReadOnly) {
            throw new IllegalStateException(SignExceptionMessageConstant.CMS_SIGNERINFO_READONLY);
        }
        CmsAttribute digestAttribute = new CmsAttribute(OID.MESSAGE_DIGEST, BC_FACTORY.createDERSet(
                                BC_FACTORY.createDEROctetString(digest)));
        signedAttributes.add(digestAttribute);
    }

    /**
     * Sets the certificate that is used to sign.
     *
     * @param certificate the certificate that is used to sign
     * @throws CertificateEncodingException if an encoding error occurs.
     */
    public void setSigningCertificate(X509Certificate certificate) throws CertificateEncodingException {
        this.signerCertificate = certificate;

        ITBSCertificate tbsCert = BC_FACTORY.createTBSCertificate(certificate.getTBSCertificate());
        if (signingAlgorithm != null) {
            return;
        }
        if (tbsCert.getSubjectPublicKeyInfo().getAlgorithm().getParameters() != null) {
            if (tbsCert.getSubjectPublicKeyInfo().getAlgorithm().getParameters().isNull()) {
                this.signingAlgorithm = new AlgorithmIdentifier(
                        tbsCert.getSubjectPublicKeyInfo().getAlgorithm().getAlgorithm().getId(),
                        BC_FACTORY.createDERNull());
                return;
            }
            this.signingAlgorithm = new AlgorithmIdentifier(
                    tbsCert.getSubjectPublicKeyInfo().getAlgorithm().getAlgorithm().getId(),
                    tbsCert.getSubjectPublicKeyInfo().getAlgorithm().getParameters().toASN1Primitive());
            return;
        }
        this.signingAlgorithm = new AlgorithmIdentifier(
                tbsCert.getSubjectPublicKeyInfo().getAlgorithm().getAlgorithm().getId());
    }

    /**
     * Gets the certificate that is used to sign.
     *
     * @return the certificate that is used to sign.
     */
    public X509Certificate getSigningCertificate() {
        return signerCertificate;
    }

    /**
     * Gets the signature data.
     *
     * @return the signature data.
     */
    public byte[] getSignatureData() {
        return signatureData;
    }

    /**
     * Sets the certificate that is used to sign a document and adds it to the signed attributes.
     *
     * @param certificate        the certificate that is used to sign
     * @param digestAlgorithmOid the oid of the digest algorithm to be added to the signed attributes
     *
     * @throws CertificateEncodingException if an encoding error occurs.
     * @throws NoSuchAlgorithmException     when the algorithm is unknown.
     * @throws NoSuchProviderException      when provider is unknown.
     */
    public void setSigningCertificateAndAddToSignedAttributes(X509Certificate certificate, String digestAlgorithmOid)
            throws CertificateEncodingException, NoSuchAlgorithmException, NoSuchProviderException {
        setSigningCertificate(certificate);
        addSignerCertificateToSignedAttributes(certificate, digestAlgorithmOid);
    }

    /**
     * Adds a set of OCSP responses as signed attributes.
     *
     * @param ocspResponses a set of binary representations of OCSP responses.
     */
    public void setOcspResponses(Collection ocspResponses) {
        if (signedAttributesReadOnly) {
            throw new IllegalStateException(SignExceptionMessageConstant.CMS_SIGNERINFO_READONLY);
        }
        this.ocspResponses = Collections.unmodifiableCollection(ocspResponses);
        setRevocationInfo();
    }

    /**
     * Adds a set of CRL responses as signed attributes.
     *
     * @param crlResponses a set of binary representations of CRL responses.
     */
    public void setCrlResponses(Collection crlResponses) {
        if (signedAttributesReadOnly) {
            throw new IllegalStateException(SignExceptionMessageConstant.CMS_SIGNERINFO_READONLY);
        }
        this.crlResponses = Collections.unmodifiableCollection(crlResponses);
        setRevocationInfo();
    }

    /**
     * Adds the signer certificate to the signed attributes as a SigningCertificateV2 structure.
     *
     * @param cert               the certificate to add
     * @param digestAlgorithmOid the digest algorithm oid that will be used
     *
     * @throws NoSuchAlgorithmException     when the algorithm is unknown.
     * @throws NoSuchProviderException      when the security provider is not known.
     * @throws CertificateEncodingException when there was a problem parsing th certificate.
     */
    public void addSignerCertificateToSignedAttributes(X509Certificate cert, String digestAlgorithmOid)
            throws NoSuchAlgorithmException, NoSuchProviderException, CertificateEncodingException {
        if (signedAttributesReadOnly) {
            throw new IllegalStateException(SignExceptionMessageConstant.CMS_SIGNERINFO_READONLY);
        }
        MessageDigest md = DigestAlgorithms.getMessageDigestFromOid(digestAlgorithmOid,
                BC_FACTORY.getProviderName());
        IASN1EncodableVector certContents = BC_FACTORY.createASN1EncodableVector();
        // don't add if it is the default value
        if (!OID.SHA_256.equals(digestAlgorithmOid)) {
            IAlgorithmIdentifier algoId = BC_FACTORY.createAlgorithmIdentifier(
                    BC_FACTORY.createASN1ObjectIdentifier(digestAlgorithmOid));
            certContents.add(algoId);
        }
        byte[] dig = md.digest(cert.getEncoded());
        certContents.add(BC_FACTORY.createDEROctetString(dig));
        IASN1Sequence issuerName = BC_FACTORY.createASN1Sequence(
                CertificateInfo.getIssuer(cert.getTBSCertificate()));
        IDERTaggedObject issuerTagged = BC_FACTORY.createDERTaggedObject(true, 4, issuerName);
        IDERSequence issuer = BC_FACTORY.createDERSequence(issuerTagged);
        IASN1Integer serial = BC_FACTORY.createASN1Integer(cert.getSerialNumber());
        IASN1EncodableVector v = BC_FACTORY.createASN1EncodableVector();
        v.add(issuer);
        v.add(serial);
        IDERSequence issuerS = BC_FACTORY.createDERSequence(v);
        certContents.add(issuerS);
        IDERSequence certContentsSeq = BC_FACTORY.createDERSequence(certContents);
        IDERSequence certContentsSeqSeq = BC_FACTORY.createDERSequence(certContentsSeq);
        IDERSequence certContentsSeqSeqSeq = BC_FACTORY.createDERSequence(certContentsSeqSeq);
        IDERSet certContentsSeqSeqSeqSet = BC_FACTORY.createDERSet(certContentsSeqSeqSeq);
        CmsAttribute attribute = new CmsAttribute(OID.AA_SIGNING_CERTIFICATE_V2, certContentsSeqSeqSeqSet);

        signedAttributes.add(attribute);
    }

    /**
     * Sets the actual signature.
     *
     * @param signatureData a byte array containing the signature
     */
    public void setSignature(byte[] signatureData) {
        this.signatureData = Arrays.copyOf(signatureData, signatureData.length);
    }

    /**
     * Optional.
     * Sets the OID and parameters of the algorithm that will be used to create the signature.
     * This will be overwritten when setting the signing certificate.
     *
     * @param algorithm The OID and parameters of the algorithm that will be used to create the signature.
     */
    public void setSignatureAlgorithm(AlgorithmIdentifier algorithm) {
        this.signingAlgorithm = algorithm;
    }

    /**
     * Value 0 when no signerIdentifier is available.
     * Value 1 when signerIdentifier is of type issuerAndSerialNumber.
     * Value 3 when signerIdentifier is of type subjectKeyIdentifier.
     *
     * @return CMS version.
     */
    public int getCmsVersion() {
        return 1;
    }

    /**
     * Optional.
     *
     * 

* Attributes that should be part of the signed content * optional, but it MUST be present if the content type of * the EncapsulatedContentInfo value being signed is not id-data. * In that case it must at least contain the following two attributes: * *

* A content-type attribute having as its value the content type * of the EncapsulatedContentInfo value being signed. Section * 11.1 defines the content-type attribute. However, the * content-type attribute MUST NOT be used as part of a * countersignature unsigned attribute as defined in Section 11.4. * *

* A message-digest attribute, having as its value the message * digest of the content. Section 11.2 defines the message-digest * attribute. * * @return collection of the signed attributes. */ public Collection getSignedAttributes() { return Collections.unmodifiableCollection(signedAttributes); } /** * Adds a new attribute to the signed attributes. * This become readonly after retrieving the serialized version {@link SignerInfo#serializeSignedAttributes()}. * * @param attribute the attribute to add */ public void addSignedAttribute(CmsAttribute attribute) { if (signedAttributesReadOnly) { throw new IllegalStateException(SignExceptionMessageConstant.CMS_SIGNERINFO_READONLY); } signedAttributes.add(attribute); } /** * Retrieves the optional unsigned attributes. * * @return the optional unsigned attributes. */ public Collection getUnSignedAttributes() { return Collections.unmodifiableCollection(unSignedAttributes); } /** * Optional. * *

* Adds attribute that should not or can not be part of the signed content. * * @param attribute the attribute to add */ public void addUnSignedAttribute(CmsAttribute attribute) { unSignedAttributes.add(attribute); } /** * Removes unsigned attribute from signer info object based on attribute type. * * @param type {@link String} attribute type */ public void removeUnSignedAttribute(String type) { unSignedAttributes.removeIf(cmsAttribute -> cmsAttribute.getType().equals(type)); } /** * Retrieves the encoded signed attributes of the signer info. * This makes the signed attributes read only. * * @return the encoded signed attributes of the signer info. * * @throws IOException if issues occur during ASN1 objects creation. */ public byte[] serializeSignedAttributes() throws IOException { if (!signedAttributesReadOnly) { IDERSet derView = getAttributesAsDERSet(signedAttributes); serializedSignedAttributes = derView.getEncoded(BC_FACTORY.createASN1Encoding().getDer()); signedAttributesReadOnly = true; } return Arrays.copyOf(serializedSignedAttributes, serializedSignedAttributes.length); } /** * Sets the signed attributes from a serialized version. * This makes the signed attributes read only. * * @param serializedSignedAttributes the encoded signed attributes. */ public final void setSerializedSignedAttributes(byte[] serializedSignedAttributes) { if (signedAttributesReadOnly) { throw new IllegalStateException(SignExceptionMessageConstant.CMS_SIGNERINFO_READONLY); } this.signedAttributesReadOnly = true; this.serializedSignedAttributes = Arrays.copyOf(serializedSignedAttributes, serializedSignedAttributes.length); try { signedAttributes.clear(); this.signedAttributes.addAll( processAttributeSet(BC_FACTORY.createASN1Primitive(serializedSignedAttributes))); } catch (IOException e) { throw new PdfException(e); } } /** * Calculates an estimate size for the SignerInfo structure. * This takes into account the values added including the signature, but does not account for unset items like * a timestamp response added after actual signing. * * @return the estimated size of the structure. * * @throws IOException if issues occur during ASN1 objects creation. * @throws CertificateEncodingException if issues occur during processing of certificates. */ public long getEstimatedSize() throws IOException, CertificateEncodingException { IDERSequence derView = getAsDerSequence(true); byte[] temp = derView.getEncoded(BC_FACTORY.createASN1Encoding().getDer()); return temp.length; } /** * Serializes the SignerInfo structure and makes the signed attributes readonly. * * @return the encoded SignerInfo structure. * * @throws CertificateEncodingException if issues occur during processing of certificates. */ public IDERSequence getAsDerSequence() throws CertificateEncodingException { return getAsDerSequence(false); } /** * Serializes the SignerInfo structure and makes the signed attributes readonly. * With the possibility to skip making the signed attributes read only for estimation purposes. * * @param estimationRun set to true to not make signed attributes read only * * @return the encoded SignerInfo structure. * * @throws CertificateEncodingException if issues occur during processing of certificates. */ IDERSequence getAsDerSequence(boolean estimationRun) throws CertificateEncodingException { IASN1EncodableVector signerInfoV = BC_FACTORY.createASN1EncodableVector(); // version signerInfoV.add(BC_FACTORY.createASN1Integer(getCmsVersion())); // sid IASN1EncodableVector issuerAndSerialNumberV = BC_FACTORY.createASN1EncodableVector(); if (signerCertificate != null) { issuerAndSerialNumberV.add(CertificateInfo.getIssuer(signerCertificate.getTBSCertificate())); issuerAndSerialNumberV.add(BC_FACTORY.createASN1Integer(signerCertificate.getSerialNumber())); } signerInfoV.add(BC_FACTORY.createDERSequence(issuerAndSerialNumberV)); // digest algorithm IASN1EncodableVector digestalgorithmV = BC_FACTORY.createASN1EncodableVector(); digestalgorithmV.add(BC_FACTORY.createASN1ObjectIdentifier(this.digestAlgorithm.getAlgorithmOid())); digestalgorithmV.addOptional(digestAlgorithm.getParameters()); signerInfoV.add(BC_FACTORY.createDERSequence(digestalgorithmV)); // signed attributes if (!signedAttributes.isEmpty() || signedAttributesReadOnly) { if (estimationRun || !signedAttributesReadOnly) { signerInfoV.add(BC_FACTORY.createDERTaggedObject(false, 0, getAttributesAsDERSet(signedAttributes))); } else { try (IASN1InputStream saIS = BC_FACTORY.createASN1InputStream(serializedSignedAttributes)) { signerInfoV.add(BC_FACTORY.createDERTaggedObject(false, 0, saIS.readObject())); } catch (IOException e) { throw new PdfException(e); } } } // signatureAlgorithm if (signingAlgorithm != null) { IASN1EncodableVector signatureAlgorithmV = BC_FACTORY.createASN1EncodableVector(); signatureAlgorithmV.add(BC_FACTORY.createASN1ObjectIdentifier(signingAlgorithm.getAlgorithmOid())); signatureAlgorithmV.addOptional(signingAlgorithm.getParameters()); signerInfoV.add(BC_FACTORY.createDERSequence(signatureAlgorithmV)); } // signatureValue byte[] workingSignatureData; if (signatureData == null) { workingSignatureData = new byte[DEFAULT_SIGNATURE_SIZE]; } else { workingSignatureData = signatureData; } IASN1OctetString signatureDataOS = BC_FACTORY.createDEROctetString(workingSignatureData); signerInfoV.add(signatureDataOS); // UnsignedAttributes if (!unSignedAttributes.isEmpty()) { signerInfoV.add(BC_FACTORY.createDERTaggedObject(false, 1, getAttributesAsDERSet(unSignedAttributes))); } return BC_FACTORY.createDERSequence(signerInfoV); } private void processSubjectKeyIdentifierSignerCertificate(IASN1Encodable asnStruct, Collection certificates) throws IOException { IASN1OctetString subjectKeyIdentifierOs = BC_FACTORY.createASN1OctetString( BC_FACTORY.createASN1TaggedObject(asnStruct).getObject()); try (IASN1InputStream aIn = BC_FACTORY.createASN1InputStream( new ByteArrayInputStream(subjectKeyIdentifierOs.getOctets()))) { IASN1Primitive subjectKeyIdentifier = aIn.readObject(); for (X509Certificate certificate : certificates) { IASN1Primitive ski = CertificateUtil.getExtensionValue(certificate, OID.X509Extensions.SUBJECT_KEY_IDENTIFIER); if (ski.equals(subjectKeyIdentifier)) { this.signerCertificate = certificate; return; } } } throw new PdfException(SignExceptionMessageConstant.CMS_CERTIFICATE_NOT_FOUND); } private void processIssuerAndSerialNumberSignerCertificate(IASN1Encodable asnStruct, Collection certificates) { IASN1Sequence signIdSeq = BC_FACTORY.createASN1Sequence(asnStruct); IASN1Integer serial = BC_FACTORY.createASN1Integer(signIdSeq.getObjectAt(1)); for (X509Certificate certificate : certificates) { if (certificate.getSerialNumber().equals(serial.getValue())) { this.signerCertificate = certificate; break; } } if (signerCertificate == null) { throw new PdfException(SignExceptionMessageConstant.CMS_CERTIFICATE_NOT_FOUND); } } private static Collection processAttributeSet(IASN1Encodable asnStruct) { IASN1Set usaSet = BC_FACTORY.createASN1Set(asnStruct); Collection attributes = new ArrayList<>(usaSet.size()); for (int i = 0; i < usaSet.size(); i++) { IASN1Sequence attrSeq = BC_FACTORY.createASN1Sequence(usaSet.getObjectAt(i)); IASN1ObjectIdentifier attrType = BC_FACTORY.createASN1ObjectIdentifier(attrSeq.getObjectAt(0)); IASN1Primitive attrVal = BC_FACTORY.createASN1Primitive(attrSeq.getObjectAt(1)); attributes.add(new CmsAttribute(attrType.getId(), attrVal)); } return attributes; } private void setRevocationInfo() { signedAttributes.removeIf(a -> OID.ADBE_REVOCATION.equals(a.getType())); if (containsRevocationData()) { IASN1EncodableVector revocationV = BC_FACTORY.createASN1EncodableVector(); createCRLStructure(revocationV); createOCPSStructure(revocationV); CmsAttribute digestAttribute = new CmsAttribute(OID.ADBE_REVOCATION, BC_FACTORY.createDERSequence(revocationV)); signedAttributes.add(digestAttribute); } } private void createCRLStructure(IASN1EncodableVector revocationV) { if (crlResponses != null && !crlResponses.isEmpty()) { IASN1EncodableVector v2 = BC_FACTORY.createASN1EncodableVector(); for (byte[] bCrl : crlResponses) { if (bCrl == null) { continue; } try (IASN1InputStream t = BC_FACTORY.createASN1InputStream(new ByteArrayInputStream(bCrl))) { v2.add(t.readObject()); } catch (IOException e) { throw new PdfException(e); } } revocationV.add(BC_FACTORY.createDERTaggedObject( true, 0, BC_FACTORY.createDERSequence(v2))); } } private void createOCPSStructure(IASN1EncodableVector revocationV) { if (ocspResponses != null && !ocspResponses.isEmpty()) { IASN1EncodableVector vo1 = BC_FACTORY.createASN1EncodableVector(); for (byte[] ocspBytes : ocspResponses) { IDEROctetString doctet = BC_FACTORY.createDEROctetString(ocspBytes); IASN1EncodableVector v2 = BC_FACTORY.createASN1EncodableVector(); IOCSPObjectIdentifiers objectIdentifiers = BC_FACTORY.createOCSPObjectIdentifiers(); v2.add(objectIdentifiers.getIdPkixOcspBasic()); v2.add(doctet); IASN1Enumerated den = BC_FACTORY.createASN1Enumerated(0); IASN1EncodableVector v3 = BC_FACTORY.createASN1EncodableVector(); v3.add(den); v3.add(BC_FACTORY.createDERTaggedObject( true, 0, BC_FACTORY.createDERSequence(v2))); vo1.add(BC_FACTORY.createDERSequence(v3)); } revocationV.add(BC_FACTORY.createDERTaggedObject( true, 1, BC_FACTORY.createDERSequence(vo1))); } } private boolean containsRevocationData() { return (ocspResponses != null && !ocspResponses.isEmpty()) || (crlResponses != null && !crlResponses.isEmpty()); } private static IDERSet getAttributesAsDERSet(Collection attributeSet) { IASN1EncodableVector attributes = BC_FACTORY.createASN1EncodableVector(); for (CmsAttribute attr : attributeSet) { IASN1EncodableVector v = BC_FACTORY.createASN1EncodableVector(); v.add(BC_FACTORY.createASN1ObjectIdentifier(attr.getType())); v.add(attr.getValue()); attributes.add(BC_FACTORY.createDERSequence(v)); } return BC_FACTORY.createDERSet(attributes); } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy