/* DigiDoc4J library * * This software is released under either the GNU Library General Public * License (see LICENSE.LGPL). * * Note that the only valid version of the LGPL license as far as this * project is concerned is the original GNU Library General Public License * Version 2.1, February 1999 */ package org.digidoc4j.impl.bdoc.xades; import java.util.Date; import java.util.List; import org.apache.commons.lang.StringUtils; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.x500.AttributeTypeAndValue; import org.bouncycastle.asn1.x500.RDN; import org.bouncycastle.asn1.x500.X500Name; import org.bouncycastle.cert.ocsp.BasicOCSPResp; import org.bouncycastle.cert.ocsp.RespID; import org.digidoc4j.SignatureProfile; import org.digidoc4j.X509Cert; import org.digidoc4j.exceptions.CertificateNotFoundException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import eu.europa.esig.dss.x509.CertificateToken; public class TimemarkSignature extends BesSignature { private final static Logger logger = LoggerFactory.getLogger(TimemarkSignature.class); private X509Cert ocspCertificate; private BasicOCSPResp ocspResponse; private Date ocspResponseTime; public TimemarkSignature(XadesValidationReportGenerator xadesReportGenerator) { super(xadesReportGenerator); } @Override public SignatureProfile getProfile() { return SignatureProfile.LT_TM; } @Override public X509Cert getOCSPCertificate() { if (ocspCertificate != null) { return ocspCertificate; } initOcspResponse(); if (ocspResponse == null) { return null; } ocspCertificate = findOcspCertificate(); return ocspCertificate; } @Override public List<BasicOCSPResp> getOcspResponses() { return getDssSignature().getOCSPSource().getContainedOCSPResponses(); } @Override public Date getOCSPResponseCreationTime() { if (ocspResponseTime != null) { return ocspResponseTime; } initOcspResponse(); if (ocspResponse == null) { return null; } ocspResponseTime = ocspResponse.getProducedAt(); return ocspResponseTime; } @Override public Date getTrustedSigningTime() { return getOCSPResponseCreationTime(); } private void initOcspResponse() { if (ocspResponse == null) { ocspResponse = findOcspResponse(); if (ocspResponse == null) { logger.warn("Signature is missing OCSP response"); } } } private BasicOCSPResp findOcspResponse() { logger.debug("Finding OCSP response"); List<BasicOCSPResp> containedOCSPResponses = getOcspResponses(); if (containedOCSPResponses.isEmpty()) { logger.debug("Contained OCSP responses is empty"); return null; } if (containedOCSPResponses.size() > 1) { logger.warn("Signature contains more than one OCSP response: " + containedOCSPResponses.size() + ". Using the first one."); } return containedOCSPResponses.get(0); } private X509Cert findOcspCertificate() { String ocspCN = getOCSPCommonName(); for (CertificateToken cert : getDssSignature().getCertificates()) { String certCn = getCN(new X500Name(cert.getSubjectX500Principal().getName())); if (StringUtils.equals(certCn, ocspCN)) { return new X509Cert(cert.getCertificate()); } } logger.error("OCSP certificate for " + ocspCN + " was not found in TSL"); throw new CertificateNotFoundException("OCSP certificate for " + ocspCN + " was not found in TSL"); } private String getOCSPCommonName() { RespID responderId = ocspResponse.getResponderId(); String commonName = getCN(responderId.toASN1Primitive().getName()); logger.debug("OCSP common name: " + commonName); return commonName; } private String getCN(X500Name x500Name) { RDN[] rdNs = x500Name.getRDNs(new ASN1ObjectIdentifier("2.5.4.3")); if (rdNs == null || rdNs.length == 0) { return null; } AttributeTypeAndValue[] typesAndValues = rdNs[0].getTypesAndValues(); if (typesAndValues == null || typesAndValues.length == 0) { return null; } String name = typesAndValues[0].getValue().toString(); return name; } }