package eu.europa.esig.dss.cades.requirements;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import org.bouncycastle.asn1.ASN1InputStream;
import org.bouncycastle.asn1.ASN1ObjectIdentifier;
import org.bouncycastle.asn1.ASN1Sequence;
import org.bouncycastle.asn1.ASN1Set;
import org.bouncycastle.asn1.ASN1TaggedObject;
import org.bouncycastle.asn1.DERTaggedObject;
import org.bouncycastle.asn1.cms.SignedData;
import org.bouncycastle.asn1.cms.SignerInfo;
import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
import org.bouncycastle.cert.X509CertificateHolder;
import org.junit.Before;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import eu.europa.esig.dss.DSSASN1Utils;
import eu.europa.esig.dss.DSSDocument;
import eu.europa.esig.dss.utils.Utils;
import eu.europa.esig.dss.x509.CertificateToken;
public abstract class AbstractRequirementChecks {
private static final Logger logger = LoggerFactory.getLogger(AbstractRequirementChecks.class);
private SignedData signedData;
private SignerInfo signerInfo;
@Before
public void init() throws Exception {
DSSDocument signedDocument = getSignedDocument();
ASN1InputStream asn1sInput = new ASN1InputStream(signedDocument.openStream());
ASN1Sequence asn1Seq = (ASN1Sequence) asn1sInput.readObject();
assertEquals(2, asn1Seq.size());
ASN1ObjectIdentifier oid = ASN1ObjectIdentifier.getInstance(asn1Seq.getObjectAt(0));
assertEquals(PKCSObjectIdentifiers.signedData, oid);
ASN1TaggedObject taggedObj = DERTaggedObject.getInstance(asn1Seq.getObjectAt(1));
signedData = SignedData.getInstance(taggedObj.getObject());
ASN1Set signerInfosAsn1 = signedData.getSignerInfos();
assertEquals(1, signerInfosAsn1.size());
signerInfo = SignerInfo.getInstance(ASN1Sequence.getInstance(signerInfosAsn1.getObjectAt(0)));
Utils.closeQuietly(asn1sInput);
}
protected abstract DSSDocument getSignedDocument() throws Exception;
/**
* SignedData.certificates shall be present in B/T/LT/LTA
*/
@Test
public void checkSignedDataCertificatesPresent() throws Exception {
ASN1Set certificates = signedData.getCertificates();
logger.info("CERTIFICATES (" + certificates.size() + ") : " + certificates);
for (int i = 0; i < certificates.size(); i++) {
ASN1Sequence seqCertif = ASN1Sequence.getInstance(certificates.getObjectAt(i));
X509CertificateHolder certificateHolder = new X509CertificateHolder(seqCertif.getEncoded());
CertificateToken certificate = DSSASN1Utils.getCertificate(certificateHolder);
certificate.getCertificate().checkValidity();
}
}
/**
* Content-type shall be present in B/T/LT/LTA
*/
@Test
public void checkContentTypePresent() {
assertTrue(isSignedAttributeFound(PKCSObjectIdentifiers.pkcs_9_at_contentType));
}
/**
* Message-digest shall be present in B/T/LT/LTA
*/
@Test
public void checkMessageDigestPresent() {
assertTrue(isSignedAttributeFound(PKCSObjectIdentifiers.pkcs_9_at_messageDigest));
}
/**
* Signing-time shall be present in B/T/LT/LTA
*/
@Test
public void checkSigningTimePresent() {
assertTrue(isSignedAttributeFound(PKCSObjectIdentifiers.pkcs_9_at_signingTime));
}
/**
* signature-time-stamp shall be present in T/LT/LTA
*/
@Test
public void checkSignatureTimeStampPresent() {
assertTrue(isUnsignedAttributeFound(PKCSObjectIdentifiers.id_aa_signatureTimeStampToken));
}
/**
* certificate-value shall not be present (B/T 1 or 0 ; LT/LTA 0)
*/
@Test
public abstract void checkCertificateValue();
/**
* complete-certificate-references shall not be present (B/T 1 or 0 ; LT/LTA 0)
*/
@Test
public abstract void checkCompleteCertificateReference();
/**
* revocation-values shall not be present (B/T 1 or 0 ; LT/LTA 0)
*/
@Test
public abstract void checkRevocationValues();
/**
* complete-revocation-references shall not be present (B/T 1 or 0 ; LT/LTA 0)
*/
@Test
public abstract void checkCompleteRevocationReferences();
/**
* CAdES-C-timestamp shall not be present (B/T >= 0 ; LT/LTA 0)
*/
@Test
public abstract void checkCAdESCTimestamp();
/**
* time-stamped-certs-crls-references shall not be present (B/T >= 0 ; LT/LTA 0)
*/
@Test
public abstract void checkTimestampedCertsCrlsReferences();
protected boolean isSignedAttributeFound(ASN1ObjectIdentifier oid) {
return countSignedAttribute(oid) > 0;
}
protected boolean isUnsignedAttributeFound(ASN1ObjectIdentifier oid) {
return countUnsignedAttribute(oid) > 0;
}
protected int countSignedAttribute(ASN1ObjectIdentifier oid) {
ASN1Set authenticatedAttributes = signerInfo.getAuthenticatedAttributes();
return countInSet(oid, authenticatedAttributes);
}
protected int countUnsignedAttribute(ASN1ObjectIdentifier oid) {
ASN1Set unauthenticatedAttributes = signerInfo.getUnauthenticatedAttributes();
return countInSet(oid, unauthenticatedAttributes);
}
private int countInSet(ASN1ObjectIdentifier oid, ASN1Set set) {
int counter = 0;
if (set != null) {
for (int i = 0; i < set.size(); i++) {
ASN1Sequence attrSeq = ASN1Sequence.getInstance(set.getObjectAt(i));
ASN1ObjectIdentifier attrOid = ASN1ObjectIdentifier.getInstance(attrSeq.getObjectAt(0));
if (oid.equals(attrOid)) {
counter++;
}
}
}
return counter;
}
}