get ICipherParameters from X509Certificate2

View: New views
1 Messages — Rating Filter:   Alert me  

get ICipherParameters from X509Certificate2

by pmalis :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hello,
I would like to sign pdf with timestamp using windows certificate from certificate store (x509certificate2).
When I sign with pfx certificate I use this code and it works fine:

        private static void SignWithTimeStamp()
                {
                       
                        string IN_FILE = "doc.pdf";
                        string OUT_FILE = "hello_signed_cs.pdf";
                        string CERT_PATH = "cert.pfx";
                        string CERT_PASSW= "password";

                        FileStream fs = new FileStream(CERT_PATH, FileMode.Open);
                        Pkcs12Store ks = new Pkcs12Store(fs, CERT_PASSW.ToCharArray());
                        string alias = null;
                        foreach (string al in ks.Aliases)
                        {
                                if (ks.IsKeyEntry(al) && ks.GetKey(al).Key.IsPrivate)
                                {
                                        alias = al;
                                        break;
                                }
                        }
                        fs.Close();
                        ICipherParameters pk = ks.GetKey(alias).Key;
                        X509CertificateEntry[] x = ks.GetCertificateChain(alias);
                        X509Certificate[] chain = new X509Certificate[x.Length];
                        for (int k = 0; k < x.Length; ++k)
                        {
                                chain[k] = x[k].Certificate;
                        }

                        ITSAClient tsc = new TSAClientBouncyCastle(TSA_URL, TSA_ACCNT, TSA_PASSW);

                        PdfReader reader = new PdfReader(IN_FILE);
                        FileStream fout = new FileStream(OUT_FILE, FileMode.Create);
                        PdfStamper stp = PdfStamper.CreateSignature(reader, fout, '\0');
                        PdfSignatureAppearance sap = stp.SignatureAppearance;

                        sap.SetCrypto(null, chain, null, PdfSignatureAppearance.SELF_SIGNED);

                        sap.SetVisibleSignature(new Rectangle(100, 100, 300, 200), 1, "Signature");

                        PdfSignature dic = new PdfSignature(PdfName.ADOBE_PPKLITE,
                                                            new PdfName("adbe.pkcs7.detached"));
                        dic.Reason = sap.Reason;
                        dic.Location = sap.Location;
                        dic.Contact = sap.Contact;
                        dic.Date = new PdfDate(sap.SignDate);
                        sap.CryptoDictionary = dic;

                        int contentEstimated = 15000;
                        // Preallocate excluded byte-range for the signature content (hex encoded)
                        Hashtable exc = new Hashtable();
                        exc[PdfName.CONTENTS] = contentEstimated * 2 + 2;
                        sap.PreClose(exc);

                        PdfPKCS7 sgn = new PdfPKCS7(pk, chain, null, "SHA1", false);
                        IDigest messageDigest = DigestUtilities.GetDigest("SHA1");
                        Stream data = sap.RangeStream;
                        byte[] buf = new byte[8192];
                        int n;
                        while ((n = data.Read(buf, 0, buf.Length)) > 0)
                        {
                                messageDigest.BlockUpdate(buf, 0, n);
                        }
                        byte[] hash = new byte[messageDigest.GetDigestSize()];
                        messageDigest.DoFinal(hash, 0);
                        DateTime cal = DateTime.Now;
                        byte[] ocsp = null;
                        if (chain.Length >= 2)
                        {
                                String url = PdfPKCS7.GetOCSPURL(chain[0]);
                                if (url != null && url.Length > 0)
                                        ocsp = new OcspClientBouncyCastle(chain[0], chain[1], url).GetEncoded();
                        }
                        byte[] sh = sgn.GetAuthenticatedAttributeBytes(hash, cal, ocsp);
                        sgn.Update(sh, 0, sh.Length);

                        //HERE get timestamp
                        byte[] encodedSig = sgn.GetEncodedPKCS7(hash, cal, tsc, ocsp);
                        if (contentEstimated + 2 < encodedSig.Length)
                                throw new Exception("Not enough space");

                        byte[] paddedSig = new byte[contentEstimated];
                        Array.Copy(encodedSig, 0, paddedSig, 0, encodedSig.Length);

                        PdfDictionary dic2 = new PdfDictionary();
                        dic2.Put(PdfName.CONTENTS, new PdfString(paddedSig).SetHexWriting(true));
                        sap.Close(dic2);
                }

This code work fine. But when I use X509Certificate2 from certificate store I can't convert its private key to ICipherParameters.

Is it possible? Can I use X509Certificate2 for signing with timestamp?

I get certificate and certificate chain with:

//get certificate from certificate store, this certificate has exportable private key
X509Certificate2 certificate = GetCertificate();
X509CertificateParser cp = new X509CertificateParser();
X509Certificate[] chain = new[] { cp.ReadCertificate(certificate.RawData) };

Thank you for info.