Java tutorial
/* * DSS - Digital Signature Services * * Copyright (C) 2013 European Commission, Directorate-General Internal Market and Services (DG MARKT), B-1049 Bruxelles/Brussel * * Developed by: 2013 ARHS Developments S.A. (rue Nicolas Bov 2B, L-1253 Luxembourg) http://www.arhs-developments.com * * This file is part of the "DSS - Digital Signature Services" project. * * "DSS - Digital Signature Services" 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. * * DSS 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 * "DSS - Digital Signature Services". If not, see <http://www.gnu.org/licenses/>. */ package eu.europa.ec.markt.dss.validation102853; import java.security.cert.CertificateParsingException; import java.security.cert.X509Certificate; import java.util.ArrayList; import java.util.Collection; import java.util.List; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.cms.Attribute; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.asn1.x509.Certificate; import org.bouncycastle.cert.X509CertificateHolder; import org.bouncycastle.cms.CMSSignedData; import org.bouncycastle.cms.SignerInformation; import org.bouncycastle.jce.provider.X509CertificateObject; import org.bouncycastle.tsp.TimeStampToken; import org.bouncycastle.util.StoreException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import eu.europa.ec.markt.dss.DSSUtils; import eu.europa.ec.markt.dss.exception.DSSException; /** * CertificateSource that retrieves items from a CAdES Signature * * @version $Revision: 1821 $ - $Date: 2013-03-28 15:56:00 +0100 (Thu, 28 Mar 2013) $ */ public class CAdESCertificateSource extends SignatureCertificateSource { private static final Logger LOG = LoggerFactory.getLogger(CAdESCertificateSource.class); final private CMSSignedData cmsSignedData; final SignerInformation signerInformation; private List<CertificateToken> keyInfoCerts; private List<CertificateToken> encapsulatedCerts; public CAdESCertificateSource(final TimeStampToken timeStamp, final CertificatePool certPool) { this(timeStamp.toCMSSignedData(), ((SignerInformation) timeStamp.toCMSSignedData().getSignerInfos().getSigners().iterator().next()), certPool); } /** * The constructor with additional signer id parameter. All certificates are extracted during instantiation. * * @param cmsSignedData * @param signerInformation * @param certPool */ public CAdESCertificateSource(final CMSSignedData cmsSignedData, final SignerInformation signerInformation, final CertificatePool certPool) { super(certPool); if (cmsSignedData == null) { throw new DSSException("cmsSignedData is null, it must be provided!"); } this.cmsSignedData = cmsSignedData; this.signerInformation = signerInformation; extract(); } @Override protected void extract() throws DSSException { if (certificateTokens == null) { certificateTokens = new ArrayList<CertificateToken>(); keyInfoCerts = extractKeyInfoCertificates(); encapsulatedCerts = extractEncapsulatedCertificates(); /** * TODO: (Bob) New source of certificates was added with new timestamp? */ } } /** * Returns the list of certificates included in (XAdES equivalent) * ".../xades:UnsignedSignatureProperties/xades:CertificateValues/xades:EncapsulatedX509Certificate" node * * @return list of X509Certificate(s) */ public List<CertificateToken> getEncapsulatedCertificates() throws DSSException { return encapsulatedCerts; } /** * @throws eu.europa.ec.markt.dss.exception.DSSException * */ private ArrayList<CertificateToken> extractEncapsulatedCertificates() throws DSSException { final ArrayList<CertificateToken> encapsulatedCerts = new ArrayList<CertificateToken>(); try { // Gets certificates from CAdES-XL certificate-values inside SignerInfo attribute if present if (signerInformation != null && signerInformation.getUnsignedAttributes() != null) { final Attribute attr = signerInformation.getUnsignedAttributes() .get(PKCSObjectIdentifiers.id_aa_ets_certValues); if (attr != null) { final ASN1Sequence seq = (ASN1Sequence) attr.getAttrValues().getObjectAt(0); for (int ii = 0; ii < seq.size(); ii++) { final Certificate cs = Certificate.getInstance(seq.getObjectAt(ii)); final X509Certificate cert = new X509CertificateObject(cs); final CertificateToken certToken = addCertificate(cert); if (!encapsulatedCerts.contains(certToken)) { encapsulatedCerts.add(certToken); } } } } //TODO (cades): Read UnsignedAttribute: S/MIME Authenticated Attributes {iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) pkcs-9(9) smime(16) aa(2) id-aa-ets-CertificateRefs(21)} //TODO (cades): Read certificates from inner timestamps (signature timestamps and archive timestamps) ? } catch (CertificateParsingException e) { throw new DSSException(e); } return encapsulatedCerts; } /** * Returns the list of certificates included in (XAdES equivalent) "ds:KeyInfo/ds:X509Data/ds:X509Certificate" node * * @return list of X509Certificate(s) */ public List<CertificateToken> getKeyInfoCertificates() throws DSSException { return keyInfoCerts; } /** * @throws org.bouncycastle.util.StoreException * * @throws eu.europa.ec.markt.dss.exception.DSSException * */ @SuppressWarnings("unchecked") private ArrayList<CertificateToken> extractKeyInfoCertificates() throws StoreException, DSSException { final ArrayList<CertificateToken> keyInfoCerts = new ArrayList<CertificateToken>(); final Collection<X509CertificateHolder> collection = (Collection<X509CertificateHolder>) cmsSignedData .getCertificates().getMatches(null); for (final X509CertificateHolder certificateHolder : collection) { final X509Certificate certificate = DSSUtils.getCertificate(certificateHolder); final CertificateToken certToken = addCertificate(certificate); if (!keyInfoCerts.contains(certToken)) { keyInfoCerts.add(certToken); } } return keyInfoCerts; } }