1

I'm trying to convert/Create a PKCS7 "p7b" Certificate from signed certificate pem + chain using BouncyCastle or .net Cryptography class

I tried to use only BC without success, so I use BC only to read pem certs and then transform it to an X509Certificate2 object. What I'm looking for at the end is a pem string at the end starting with "-----BEGIN PKCS7-----" to save it as p7b file what have I done..

public void DownloadP7bFile(string certId)
    {
        var records = (DataView)myCertDataSource.Select(DataSourceSelectArguments.Empty);
        var selected = Guid.Parse(certId);

        foreach (DataRow row in records.Table.Rows)
        {
            if (!Guid.Parse(row.Field<Guid>("cert_id").ToString()).Equals(selected)) continue;

            var filename = row.Field<string>("cert_fqdn_main");
            var certContent2 = row.Field<string>("certHash_certificate");
            var certissuer = row.Field<string>("certHash_issuer");

            DataTable chaincerts = GetChainCertsFromDB(certissuer);

            //### get pem string from DB to BC cert objects
            Org.BouncyCastle.X509.X509Certificate serverCert = CreateCertObjFromPem(certContent2);
            Org.BouncyCastle.X509.X509Certificate interCert = CreateCertObjFromPem(chaincerts.Rows[0].Field<string>("cacert_pemhash"));
            Org.BouncyCastle.X509.X509Certificate rootCert = CreateCertObjFromPem(chaincerts.Rows[1].Field<string>("cacert_pemhash"));

            //### transform to X509Certificate2 object
            System.Security.Cryptography.X509Certificates.X509Certificate2 serverCert2 = new System.Security.Cryptography.X509Certificates.X509Certificate2();
            System.Security.Cryptography.X509Certificates.X509Certificate2 interCert2 = new System.Security.Cryptography.X509Certificates.X509Certificate2();
            System.Security.Cryptography.X509Certificates.X509Certificate2 rootCert2 = new System.Security.Cryptography.X509Certificates.X509Certificate2();
            serverCert2.Import(serverCert.GetEncoded());
            interCert2.Import(interCert.GetEncoded());
            rootCert2.Import(rootCert.GetEncoded());

            //### collect all needed certificates
            var collection = new System.Security.Cryptography.X509Certificates.X509Certificate2Collection();
            collection.Add(rootCert2);
            collection.Add(interCert2);
            collection.Add(serverCert2);

            var pkcs7ContentBytes = collection.Export(System.Security.Cryptography.X509Certificates.X509ContentType.Pkcs7);

            //### Test if pkcs7 can be read ###
            System.Security.Cryptography.Pkcs.SignedCms sigcms = new System.Security.Cryptography.Pkcs.SignedCms();
            sigcms.Decode(pkcs7ContentBytes);
            if (sigcms.Certificates.Count > 0)
            {
                Console.WriteLine("Aussteller: {0}", sigcms.Certificates[0].IssuerName.Name);
                Console.WriteLine("Gültig bis {0}", sigcms.Certificates[0].NotAfter);
            }
            var sigvar2 = sigcms.Encode();

            var pkcs7Content = Convert.ToBase64String(pkcs7ContentBytes); //das gute
            var certEncodedBytes = Convert.FromBase64String(pkcs7Content);
            var certContent = Encoding.UTF8.GetString(certEncodedBytes);

            var certContent7 = UTF8Encoding.UTF8.GetString(certEncodedBytes);
            var CertContent8 = Convert.ToBase64String(sigvar2);
            var CertContent8Bytes = Convert.FromBase64String(CertContent8);
            var certfromsig = sigcms.Certificates.Export(System.Security.Cryptography.X509Certificates.X509ContentType.Pkcs7);

            //var pkcs7cert = new System.Security.Cryptography.X509Certificates.X509Certificate2(certEncodedBytes);
            //var pkcs7cert2 = new System.Security.Cryptography.X509Certificates.X509Certificate2(sigvar2);
            //System.Security.Cryptography.Pkcs.EnvelopedCms pkcs7Envelop = new System.Security.Cryptography.Pkcs.EnvelopedCms();

            //File.WriteAllBytes(@"")

            //string utfString = Encoding.UTF8.GetString(pkcs7ContentBytes, 0, pkcs7ContentBytes.Length);
            var memoryStream = new MemoryStream(certEncodedBytes);
            //var cryptostream = new System.Security.Cryptography.CryptoStream(memoryStream);
            //memoryStream.Write(pkcs7ContentBytes, 0, pkcs7ContentBytes.Length);
            var test31 = memoryStream.ToArray();
            var test32 = memoryStream.Read(certEncodedBytes, 0, certEncodedBytes.Length);

            memoryStream.Flush();
            memoryStream.Close();


            //var test30 = DecoderConverter.ConvertX509ToPkcs7(rootCert, interCert, serverCert);

            PerformFileDownload(filename, "p7b", pkcs7Content);

            break;
        }
    }
leo
  • 51
  • 2
  • Why not to use .NET `X509Certificate2Collection.Export` method? – Crypt32 Jan 25 '19 at 14:58
  • I'm using the collection.export methode [code]//### collect all needed certificates var collection = new System.Security.Cryptography.X509Certificates.X509Certificate2Collection(); collection.Add(rootCert2); collection.Add(interCert2); collection.Add(serverCert2); var pkcs7ContentBytes = collection.Export(System.Security.Cryptography.X509Certificates.X509ContentType.Pkcs7); – leo Jan 28 '19 at 17:07
  • yes, this code is correct. You can convert resulting byte array to a Base64 string (`Convert.ToBase64String`) and manually add PEM header and footer. – Crypt32 Jan 28 '19 at 17:09
  • I tried this as well, toke the string from.. var pkcs7Content = Convert.ToBase64String(pkcs7ContentBytes); and manually added "-----BEGIN PKCS7-----" and "-----END PKCS7-----" I thought that I did test this, just tried it again, you are right that's the solution..... Thank you – leo Jan 28 '19 at 17:23
  • Yes, it is the solution. You must be missing something in your previous tests. – Crypt32 Jan 28 '19 at 17:24

0 Answers0