0

I'm signing a PDF document with a mobile signing service. I recieve a certificate from the service after it has signed the hash of the document. I am able to replace zero padded signature container in the document with the certificate without any problems, but I"m having problems with including a certificate chain.

I have the root, intermediate and leaf certificates with the application, but I'm not able to include them in the signature. What I thought I would be able to do was to create a chain in code and then inject the encoded bytes from that chain, but this results in an invalid certificate.

The code I'm using to do that is as follows:

X509CertificateParser cp = new X509CertificateParser();

var certFromServer = getCertFromServer();

var rootCert = cp.ReadCertificate(new X509Certificate2(rootCertPath).RawData);
var interCert = cp.ReadCertificate(new X509Certificate2(interCertPath)RawData);
var leafCert = cp.ReadCertificate(new X509Certificate2(leafCertPath).RawData);

List<X509Certificate> intermediateCerts = new List<X509Certificate> {
    interCert, 
    leafCert
};

X509CertificateParser parser = new X509CertificateParser();
PkixCertPathBuilder builder = new PkixCertPathBuilder();

X509CertStoreSelector holder = new X509CertStoreSelector {
    Certificate = parser.ReadCertificate(certFromServer)
};

intermediateCerts.Add(holder.Certificate);

HashSet rootCerts = new HashSet {new TrustAnchor(rootCert, null)};

PkixBuilderParameters builderParams = new PkixBuilderParameters(rootCerts, holder)
    {
        IsRevocationEnabled = false
    };

X509CollectionStoreParameters intermediateStoreParameters =
    new X509CollectionStoreParameters(intermediateCerts);

builderParams.AddStore(X509StoreFactory.Create(
    "Certificate/Collection", intermediateStoreParameters)
);

PkixCertPathBuilderResult result = builder.Build(builderParams);


byte[] certChainBytes = result.CertPath.GetEncoded("PKCS7"); 

// ExternalSignatureContainer is a container that simply returns the cert bytes 
// from its Sign method without changing them.
IExternalSignatureContainer container = new ExternalSignatureContainer(certChainBytes);

MakeSignature.SignDeferred(reader, _signatureFieldName, baos, container);

The method to create the chain is from the following StackOverflow question: Build certificate chain in BouncyCastle in C#

What is the correct way to build a certificate chain for the signature container in iTextSharp?

Community
  • 1
  • 1
  • *ExternalSignatureContainer is a container that simply returns the cert bytes from its Sign method without changing them.* - but the `Sign` method shall return *a container with the **signature** and other objects*; you don't seem to insert any signature at all into the PDF... Thus, overhaul your `ExternalSignatureContainer` to return a container containing both your signature and the certificates. – mkl Feb 04 '14 at 10:29
  • The `Sign` method returns a byte array. I can't find any examples on how to create a container of the certificates and then return a byte array based on it. So how do I actually create that container of these objects? I would think what I'm doing right now is what the `Sign` method should be doing anyway, but I guess I'm wrong there. - This way works if I simply create the `ExternalSignatureContianer` with the single certificate from the server as a parameter, that is then returned in the `Sign` method. – Axel Örn Sigurðsson Feb 04 '14 at 10:54
  • 1
    The `Sign` method shall return the signature container to embed. Usually (unless you are using **adbe.x509.rsa_sha1** or something proprietary) this is a PKCS#7 or CMS container (which are very similar) containing the certificates and exactly one (immediate) SignerInfo structure which in turn contains the basic signature. Depending on whether your *mobile signing service* actually returns a PKCS#7/CMS signature container or merely a PKCS#1 signature, you have to look up how to enhance an existing container with certificates or build one from scratch. Return this enhanced/newly built container. – mkl Feb 04 '14 at 11:15
  • Thanks for the comment. It turns out that I'm infact recieving a PKCS#7 container from the service. I've spent the last few hours looking into how to enhance an existing container with certificates without any luck. Do you have any knowledge on how that would be possible, or if it even is? I feel like this might even be material for a new question since it's not really iText specific. – Axel Örn Sigurðsson Feb 04 '14 at 15:40
  • 1
    I'm used to working with a different security library (a proprietary one) and, therefore, am not so knowledgeable concerning bc. So do make it a question in its own right. But have you already checked which certificates already are included in that container you get from the service? – mkl Feb 04 '14 at 16:42
  • Yes. The mobile signing provider only provides the user certificate, since it wants to minimize the overhead, they provided the leaf, inter and root certificates for us to include. Thank you for all the help, I'll create a new question for this problem. – Axel Örn Sigurðsson Feb 05 '14 at 08:45

0 Answers0