I am trying to insert a .p7s byte array info to signature field, I follow this image below:

My steps:
Prepare Signature Container
the original PDF is "tmp/example.pdf" and the output of this part is "results/prepared.pdf"
PdfSigner signer = new PdfSigner(new PdfReader("tmp/example.pdf"), new FileStream("results/prepared.pdf", FileMode.Create), new StampingProperties().UseAppendMode());
signer.SetFieldName("Signature1");
PdfDocument _pdfDocument = new PdfDocument(new PdfReader("tmp/example.pdf"));
PdfSignatureAppearance sigAppearance = signer.GetSignatureAppearance();
sigAppearance
.SetPageRect(new Rectangle(144, 144, 200, 100))
.SetPageNumber(1)
.SetContact("This is contact")
.SetReason("This is reason")
.SetLocation("This is location")
.SetSignatureCreator("This is signature creator");
MyExternalSignatureContainer _container = new MyExternalSignatureContainer(PdfName.Adobe_PPKLite, PdfName.Adbe_pkcs7_detached, _chain);
IExternalSignatureContainer container = _container;
signer.SignExternalContainer(container, 8192);
byte[] _sb = _container.Signed_Bytes;
My External Signature Container Class
public byte[] Sign(Stream data)
{
iText.Signatures.PdfPKCS7 _sgn = new iText.Signatures.PdfPKCS7(null, chain, "SHA256", false);
byte[] _hash = iText.Signatures.DigestAlgorithms.Digest(data, "SHA256");
byte[] _sh = _sgn.GetAuthenticatedAttributeBytes(_hash, PdfSigner.CryptoStandard.CMS,
null, null);
Signed_Bytes = _sh;
return new byte[0]; ;
}
until this part, everything goes fine, I got "results/prepared.pdf" hash and sent to external signing service and got the .p7s
now I want to insert the .p7s byte[] into the signature value part of a PDF structure based on the image above.
I try to get the PdfDictionay's ByteRange info of "results/prepared.pdf" using code below, I expect to get injected .p7s to signature container of "results/prepared.pdf" at "results/injected.pdf"
PdfDocument pdfDocument = new PdfDocument(new PdfReader("results/prepared.pdf"), new PdfWriter("results/injected.pdf").SetSmartMode(true));
SignatureUtil signatureUtil = new SignatureUtil(pdfDocument);
PdfSignature signature = signatureUtil.GetSignature("Signature1");
PdfDictionary _pd = signatureUtil.GetSignatureDictionary("Signature1");
Now I got the result of "_pd" as follow:
{<</ByteRange [0 107457 123843 2688 ] /ContactInfo This is contact /Contents
my understanding (please correct me if I am wrong) is I should put .p7s byte array to 107457 as start position.
Try to inject .p7s into existing signature container
I try to make paddedSig array below and copy .p7s to it:
byte[] _p7s = System.IO.File.ReadAllBytes("tmp/example.p7s");
byte[] paddedSig = new byte[8192];
System.Array.Copy(_p7s, 0, paddedSig, 0, _p7s.Length);
and then try to put paddedSig to PdfDictionary as below:
PdfDictionary _pd = signatureUtil.GetSignatureDictionary("Signature1");
pd.Put(PdfName.Contents, new PdfString(paddedSig).SetHexWriting(true));
pdfDocument.Close();
a new PDF named "results/injected.pdf" generated, but:
Signature contains incorrect, unrecognized, corrupted or suspicious data. Support Information: SigDict /Contents illegal data
What did I miss? .. How to inject .p7s into prepared signature container?
To response Mkl's post:
What I don't understand is how to embed returning PKCS#7 byte into the pdf.. assume byte[] _p7s is the result from API_CALL
byte[] _p7s = API_CALL;
byte[] paddedSig = new byte[8192];
System.Array.Copy(_p7s, 0, paddedSig, 0, _p7s.Length);
and then try to put paddedSig to PdfDictionary as below:
PdfDictionary _pd = signatureUtil.GetSignatureDictionary("Signature1");
pd.Put(PdfName.Contents, new PdfString(paddedSig).SetHexWriting(true));
pdfDocument.Close();
the result is:
Signature contains incorrect, unrecognized, corrupted or suspicious data. Support Information: SigDict /Contents illegal data
Trying with .p7s file
I have an example.p7s file, I try to embed using the code provided as below:
byte[] _p7s = System.IO.File.ReadAllBytes("tmp/example.p7s");
private static void Embed_P7S(Org.BouncyCastle.X509.X509Certificate[] _chain, byte[] _p7s)
{
PdfDocument document = new PdfDocument(new PdfReader("results/example-prepared.pdf"));
Stream output = new FileStream("results/example-prepared-signed.pdf", FileMode.Create);
ExternalInjectingSignatureContainer container2 = new ExternalInjectingSignatureContainer(_p7s);
PdfSigner.SignDeferred(document, "Signature1", output, container2);
}
}
internal class ExternalInjectingSignatureContainer :IExternalSignatureContainer
{
public ExternalInjectingSignatureContainer(byte[] signature)
{
Signature = signature;
}
public void ModifySigningDictionary(PdfDictionary signDic)
{
}
public byte[] Sign(Stream data)
{
return Signature;
}
public byte[] Signature;
}
result:
example-prepared-signed.pdf no certificate shown (this is like the original pdf) but the size bigger than the original pdf
original.pdf is 105KB example-prepared is 124KB example-prepared-signed is 121KB