I created a PDF PAdES signature using PDFBOX and I am using the ETSI online validator 1 (it requires registration) and right now I am getting only two errors on the report but im kind of lost about what they are or how can I fix them.
This is the etsi online validator report:
And this is the code I am using to sign:
@Override
public byte[] sign(InputStream content) throws IOException {
try {
CMSSignedDataGenerator signGenerator = new CMSSignedDataGenerator();
X509Certificate userCert = (X509Certificate) this.certificateChain[0];
ContentSigner mySigner = new CustomSigner(this.signerKeyHandle);
// TODO check to use cavium as digest provider
MessageDigest md = MessageDigest.getInstance("SHA-256", "Cavium");
md.update(userCert.getEncoded());
byte[] userCertHash = md.digest();
X509CertificateHolder issuerCert = new X509CertificateHolder(this.certificateChain[1].getEncoded());
// IssuerSerial is = new IssuerSerial(issuerCert.get,
// issuerCert.getSerialNumber());
ESSCertIDv2 certid = new ESSCertIDv2(new AlgorithmIdentifier(NISTObjectIdentifiers.id_sha256),
userCertHash);
ESSCertIDv2[] essCert1Arr = { certid };
SigningCertificateV2 sigcert = new SigningCertificateV2(certid);
final DERSet attrValues = new DERSet(sigcert);
Attribute attr = new Attribute(PKCSObjectIdentifiers.id_aa_signingCertificateV2, attrValues);
ASN1EncodableVector v = new ASN1EncodableVector();
v.add(attr);
AttributeTable atttributeTable = new AttributeTable(v);
//Create a standard attribute table from the passed in parameters - certhash
CMSAttributeTableGenerator attrGen = new DefaultSignedAttributeTableGenerator(atttributeTable){
protected Hashtable createStandardAttributeTable(Map parameters)
{
Hashtable result = super.createStandardAttributeTable(parameters);
result.remove(CMSAttributes.signingTime);
return result;
}
};
JcaSignerInfoGeneratorBuilder signerBuilder = new JcaSignerInfoGeneratorBuilder( new JcaDigestCalculatorProviderBuilder().build());
signerBuilder.setSignedAttributeGenerator(attrGen);
SignerInfoGenerator signerInfoGenerator = signerBuilder.build(mySigner, userCert);
signGenerator.addSignerInfoGenerator(signerInfoGenerator);
signGenerator.addCertificates(new JcaCertStore(Arrays.asList(certificateChain)));
CMSProcessableInputStream msg = new CMSProcessableInputStream(content);
CMSSignedData signedData = signGenerator.generate(msg, false);
return signedData.getEncoded();
} catch (GeneralSecurityException | CMSException | OperatorCreationException e) {
System.err.println(e.getMessage());
throw new RuntimeException("unable to sign pdf!");
}
}
Im not quite sure where those problems could be or why are they generated, at the beginning I had 5 and right now im only down to these two, so any input will be greatly appreciated
The Original Question
You use the
DefaultSignedAttributeTableGenerator
:According to its JavaDocs it will
In particular it will create a
signingTime
signed attribute.But for (non-legacy) PAdES signatures the embedded CMS containers must not contain a
signingTime
attribute, see ETSI EN 319 142-1 section 6.3 for Baseline signaturesand already the original ETSI TS 102 778-3 section 4.5.3 for PAdES-BES and PAdES-EPES signatures requires that
(Strictly speaking the current ETSI EN 319 142-2 PAdES-E-BES and PAdES-E-EPES profiles do not appear to forbid the use anymore, they merely recommend using the M signature dictionary entry instead. But software checking for BES/EPES usually still are based on the old TS which does forbid, see above. And nowadays one should go for Baseline signatures anyways...)
Thus, you should use a
CMSAttributeTableGenerator
implementation instead that does not include the signing time attribute, e.g. by copying theDefaultSignedAttributeTableGenerator
code and removing the signing time from itscreateStandardAttributeTable
method.The Updated Question
In a comment you say that after fixing the issue above one error remains:
The last (fourth) signed attribute in your
SignerInfo
is an Algorithm Identifier Protection Attribute according to RFC 6211 from April 2011. Considering the age of the ETSI signature conformance checker it may indeed not know this attribute.If you want the conformance checker to not display that error, simply remove that attribute from the
DefaultSignedAttributeTableGenerator
's standard attribute table just like you removed the signing time attribute.