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

eu.europa.esig.dss.asic.cades.merge.AbstractASiCWithCAdESContainerMerger Maven / Gradle / Ivy

Go to download

DSS ASiC with CAdES contains the code for the creation and validation of ASiC containers with CAdES signature(s).

The newest version!
/**
 * DSS - Digital Signature Services
 * Copyright (C) 2015 European Commission, provided under the CEF programme
 * 

* This file is part of the "DSS - Digital Signature Services" project. *

* This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. *

* This library 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 * Lesser General Public License for more details. *

* You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ package eu.europa.esig.dss.asic.cades.merge; import eu.europa.esig.dss.asic.cades.extract.ASiCWithCAdESContainerExtractor; import eu.europa.esig.dss.asic.cades.ASiCWithCAdESFilenameFactory; import eu.europa.esig.dss.asic.cades.DefaultASiCWithCAdESFilenameFactory; import eu.europa.esig.dss.asic.cades.validation.ASiCContainerWithCAdESAnalyzerFactory; import eu.europa.esig.dss.asic.common.ASiCContent; import eu.europa.esig.dss.asic.common.extract.DefaultASiCContainerExtractor; import eu.europa.esig.dss.asic.common.merge.DefaultContainerMerger; import eu.europa.esig.dss.cades.CMSUtils; import eu.europa.esig.dss.cades.signature.CMSSignedDocument; import eu.europa.esig.dss.cades.validation.CMSDocumentAnalyzer; import eu.europa.esig.dss.spi.exception.IllegalInputException; import eu.europa.esig.dss.model.DSSDocument; import eu.europa.esig.dss.model.DSSException; import eu.europa.esig.dss.utils.Utils; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.cms.OtherRevocationInfoFormat; import org.bouncycastle.asn1.x509.AlgorithmIdentifier; import org.bouncycastle.cert.X509AttributeCertificateHolder; import org.bouncycastle.cert.X509CRLHolder; import org.bouncycastle.cert.X509CertificateHolder; import org.bouncycastle.cert.jcajce.JcaCertStore; import org.bouncycastle.cms.CMSException; import org.bouncycastle.cms.CMSSignedData; import org.bouncycastle.cms.SignerInformation; import org.bouncycastle.cms.SignerInformationStore; import org.bouncycastle.util.CollectionStore; import org.bouncycastle.util.Encodable; import org.bouncycastle.util.Store; import java.security.cert.CertificateEncodingException; import java.util.ArrayList; import java.util.Collection; import java.util.List; import java.util.Objects; import static org.bouncycastle.asn1.cms.CMSObjectIdentifiers.id_ri_ocsp_response; import static org.bouncycastle.asn1.ocsp.OCSPObjectIdentifiers.id_pkix_ocsp_basic; /** * This class contains common code for ASiC with CAdES container merger classes. * */ public abstract class AbstractASiCWithCAdESContainerMerger extends DefaultContainerMerger { /** * Defines rules for filename creation for new ZIP entries (e.g. signature files, etc.) */ protected ASiCWithCAdESFilenameFactory asicFilenameFactory = new DefaultASiCWithCAdESFilenameFactory(); /** * Empty constructor */ AbstractASiCWithCAdESContainerMerger() { // empty } /** * This constructor is used to create an ASiC With CAdES container merger from provided container documents * * @param containers {@link DSSDocument} containers to be merged */ protected AbstractASiCWithCAdESContainerMerger(DSSDocument... containers) { super(containers); } /** * This constructor is used to create an ASiC With CAdES from to given {@code ASiCContent}s * * @param asicContents {@link ASiCContent}s to be merged */ protected AbstractASiCWithCAdESContainerMerger(ASiCContent... asicContents) { super(asicContents); } /** * Sets {@code ASiCWithCAdESFilenameFactory} defining a set of rules for naming of newly create ZIP entries, * such as signature files. * * @param asicFilenameFactory {@link ASiCWithCAdESFilenameFactory} */ public void setAsicFilenameFactory(ASiCWithCAdESFilenameFactory asicFilenameFactory) { Objects.requireNonNull(asicFilenameFactory, "ASiCWithCAdESFilenameFactory cannot be null!"); this.asicFilenameFactory = asicFilenameFactory; } @Override protected boolean isSupported(DSSDocument container) { return new ASiCContainerWithCAdESAnalyzerFactory().isSupported(container); } @Override protected boolean isSupported(ASiCContent asicContent) { return new ASiCContainerWithCAdESAnalyzerFactory().isSupported(asicContent); } @Override protected DefaultASiCContainerExtractor getContainerExtractor(DSSDocument container) { return new ASiCWithCAdESContainerExtractor(container); } /** * This method merges signature documents representing CMS signatures into single CMS signature document. * * @param signatureDocuments a list of {@link DSSDocument}s representing CMS signatures to be merged * @return merged CMS {@link DSSDocument} */ protected DSSDocument mergeCmsSignatures(List signatureDocuments) { try { List cmsSignedDataList = getCMSSignedDataList(signatureDocuments); CMSSignedData originalCMSSignedData = cmsSignedDataList.iterator().next(); // getFirstCMSSignedData SignerInformationStore signerInformationStore = getSignerInformationStore(cmsSignedDataList); CMSSignedData mergedCmsSignedData = CMSSignedData.replaceSigners(originalCMSSignedData, signerInformationStore); JcaCertStore certificatesStore = getCertificatesStore(cmsSignedDataList); Store certAttributeStore = getCertAttributeStore(cmsSignedDataList); Store crlStore = getCRLStore(cmsSignedDataList); mergedCmsSignedData = CMSSignedData.replaceCertificatesAndCRLs(mergedCmsSignedData, certificatesStore, certAttributeStore, crlStore); List digestAlgorithms = getDigestAlgorithms(cmsSignedDataList); for (AlgorithmIdentifier algorithmIdentifier : digestAlgorithms) { mergedCmsSignedData = CMSUtils.addDigestAlgorithm(mergedCmsSignedData, algorithmIdentifier); } return new CMSSignedDocument(mergedCmsSignedData, getSignatureDocumentName(signatureDocuments)); } catch (CMSException | CertificateEncodingException e) { throw new DSSException(String.format("Unable to merge ASiC-S with CAdES container. Reason : %s", e.getMessage())); } } private List getCMSSignedDataList(List signatureDocuments) { List signedDataList = new ArrayList<>(); for (DSSDocument signatureDocument : signatureDocuments) { CMSDocumentAnalyzer documentValidator = new CMSDocumentAnalyzer(signatureDocument); signedDataList.add(documentValidator.getCmsSignedData()); } return signedDataList; } private SignerInformationStore getSignerInformationStore(List cmsSignedDataList) { List signerInformations = new ArrayList<>(); for (CMSSignedData signedData : cmsSignedDataList) { signerInformations.addAll(signedData.getSignerInfos().getSigners()); } return new SignerInformationStore(signerInformations); } private JcaCertStore getCertificatesStore(List cmsSignedDataList) throws CertificateEncodingException { List result = new ArrayList<>(); for (CMSSignedData signedData : cmsSignedDataList) { final Collection certificateHolders = signedData.getCertificates().getMatches(null); for (final X509CertificateHolder x509CertificateHolder : certificateHolders) { if (!result.contains(x509CertificateHolder)) { result.add(x509CertificateHolder); } } } return new JcaCertStore(result); } private Store getCertAttributeStore(List cmsSignedDataList) { List result = new ArrayList<>(); for (CMSSignedData signedData : cmsSignedDataList) { final Collection attributeCertificateHolders = signedData.getAttributeCertificates().getMatches(null); for (final X509AttributeCertificateHolder x509AttributeCertificateHolder : attributeCertificateHolders) { if (!result.contains(x509AttributeCertificateHolder)) { result.add(x509AttributeCertificateHolder); } } } return new CollectionStore<>(result); } private Store getCRLStore(List cmsSignedDataList) { List result = new ArrayList<>(); for (CMSSignedData signedData : cmsSignedDataList) { final Collection crlHolders = signedData.getCRLs().getMatches(null); for (final X509CRLHolder x509CRLHolder : crlHolders) { if (!result.contains(x509CRLHolder)) { result.add(x509CRLHolder); } } } result.addAll(getOtherRevocationInfoStore(cmsSignedDataList, id_pkix_ocsp_basic)); result.addAll(getOtherRevocationInfoStore(cmsSignedDataList, id_ri_ocsp_response)); return new CollectionStore<>(result); } @SuppressWarnings("unchecked") private List getOtherRevocationInfoStore(List cmsSignedDataList, ASN1ObjectIdentifier objectIdentifier) { List result = new ArrayList<>(); for (CMSSignedData signedData : cmsSignedDataList) { final Collection basicOcsps = signedData.getOtherRevocationInfo(objectIdentifier).getMatches(null); for (final ASN1Encodable ocsp : basicOcsps) { OtherRevocationInfoFormat otherRevocationInfo = new OtherRevocationInfoFormat(objectIdentifier, ocsp); if (!result.contains(otherRevocationInfo)) { result.add(otherRevocationInfo); } } } return result; } private List getDigestAlgorithms(List cmsSignedDataList) { List result = new ArrayList<>(); for (CMSSignedData cmsSignedData : cmsSignedDataList) { result.addAll(cmsSignedData.getDigestAlgorithmIDs()); } return result; } private String getSignatureDocumentName(List signatureDocuments) { if (Utils.isCollectionNotEmpty(signatureDocuments)) { return signatureDocuments.get(0).getName(); } throw new IllegalInputException("At least one signature file shall be provided for merging!"); } /** * This method returns all signature documents extracted from given {@code ASiCContent} containers * * @param asicContents {@link ASiCContent}s * @return a list of {@link DSSDocument}s */ protected List getAllSignatureDocuments(ASiCContent... asicContents) { List signatureDocuments = new ArrayList<>(); for (ASiCContent asicContent : asicContents) { signatureDocuments.addAll(asicContent.getSignatureDocuments()); } return signatureDocuments; } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy