问题
I am producing Long Term signature. I am trying to add revocation information (Crls, OCSP Responses, Certificate Chain) to the signature as an unsigned attributes but the revocation information is not been embedded in the final signature. Following is the code snippet:
Stream outputStream = new MemoryStream();
List<byte[]> ocspCollection = new List<byte[]>();
List<byte[]> crlCollection = new List<byte[]>();
List<byte[]> certsCollection = new List<byte[]>();
Stream readerStream = new MemoryStream(signedDocument);
PdfReader pdfReader = new PdfReader(readerStream);
PdfSigner pdfSigner = new PdfSigner(pdfReader, outputStream, new StampingProperties().UseAppendMode());
LtvVerification ltvVerification = new LtvVerification(pdfSigner.GetDocument());
X509Chain chain = new X509Chain();
chain.Build(signerCertificate);
foreach (X509ChainElement item in chain.ChainElements)
{
byte[] certBytes = item.Certificate.Export(X509ContentType.Cert);
certsCollection.Add(certBytes);
}
foreach (byte[] ocsp in revocationInfo.OCSPResponses)
{
ocspCollection.Add(ocsp);
}
foreach (byte[] crlBytes in revocationInfo.CRLs)
{
crlCollection.Add(crlBytes);
}
bool revocationInfoAdded = ltvVerification.AddVerification(signingRequest.FieldName, ocspCollection, crlCollection, certsCollection);
ltvVerification.AddVerification() method returns true in response.
Please find the signed document from below link: https://1drv.ms/b/s!AvIgyv7xAxxoihGn9aFbe9TQSps4?e=eKPdn8
Any help in this regard is highly appreciated. Regards
回答1:
Some working code
You used a PdfSigner
(which only makes sense when also applying a signature or document time stamp but you provided only the already signed file) and have some variables I do not have here. Thus, I essentially wrote an example based on a mere PdfDocument
and your shared files without those extra variables:
using (PdfReader pdfReader = new PdfReader("LTV Doc-Revocation Info Issue.pdf"))
using (PdfWriter pdfWriter = new PdfWriter("LTV Doc-Revocation Info Issue-WithRevocation.pdf"))
using (PdfDocument pdfDocument = new PdfDocument(pdfReader, pdfWriter, new StampingProperties().UseAppendMode()))
{
List<byte[]> ocspCollection = new List<byte[]>();
List<byte[]> crlCollection = new List<byte[]>();
List<byte[]> certsCollection = new List<byte[]>();
ocspCollection.Add(File.ReadAllBytes(@"Ocsp"));
crlCollection.Add(File.ReadAllBytes(@"Crl.crl"));
LtvVerification ltvVerification = new LtvVerification(pdfDocument);
ltvVerification.AddVerification("SH_SIGNATURE_532546", ocspCollection, crlCollection, certsCollection);
ltvVerification.Merge();
}
Inspecting the result one sees:
In particular the provided OCSP response and the provided CRL are embedded in the PDF, so the iText LtvVerification
class does its job.
Possible issues in your project
First of all your say:
I am trying to add revocation information (Crls, OCSP Responses, Certificate Chain) to the signature as an unsigned attributes
This already indicates a mismatch: You use the LtvVerification
class, and so do I in the working code above. This class does not change the embedded CMS containers. It does not add the revocation information to the unsigned attributes of the embedded CMS container but instead to the DSS (Document Security Store) structure of the PDF.
Embedding revocation data as unsigned attributes of the embedded CMS signature container actually is not possible in an interoperable way: You either use the signed adbe-revocationInfoArchival
attribute in the CMS container or the DSS outside of the CMS container.
(Some validators accept revocation data embedded CAdES-style in the unsigned attributes but strictly speaking that is forbidden in PAdES and not interoperable in PDF 2.0.)
So if you actually want to embed the revocation data in the CMS container, provide them to the PdfSigner
signing method of your choice, they all explicitly or implicitly accept revocation data to embed,
public virtual void SignDetached(IExternalSignature externalSignature, X509Certificate[] chain,
ICollection<ICrlClient> crlList, IOcspClient ocspClient, ITSAClient tsaClient,
int estimatedSize, PdfSigner.CryptoStandard sigtype)
public virtual void SignDetached(IExternalSignature externalSignature, X509Certificate[] chain,
ICollection<ICrlClient> crlList, IOcspClient ocspClient, ITSAClient tsaClient,
int estimatedSize, PdfSigner.CryptoStandard sigtype, SignaturePolicyInfo signaturePolicy)
public virtual void SignDetached(IExternalSignature externalSignature, X509Certificate[] chain,
ICollection<ICrlClient> crlList, IOcspClient ocspClient, ITSAClient tsaClient,
int estimatedSize, PdfSigner.CryptoStandard sigtype, SignaturePolicyIdentifier signaturePolicy)
or
public virtual void SignExternalContainer(IExternalSignatureContainer externalSignatureContainer,
int estimatedSize)
The former three explicitly accept CRL and OCSP clients (which can be implemented to provide pre-existing CRLs and OCSPs) while the latter gets the full CMS container from the given IExternalSignatureContainer
implementation, so in that implementation you can add any information to it you want.
来源:https://stackoverflow.com/questions/60318820/add-revocation-information-to-signature-using-itext7