-1

I have this piece of code written in PHP, which adds, as i presume, some information about an SSL-certificate to a HTTP-request(It's just a simple http-request, isn't it?). It's added either to body-request or header, that i don't know for sure.

//some code before that
curl_setopt($curl,CURLOPT_SSLCERT,'cert.crt');
curl_setopt($curl,CURLOPT_SSLKEY,'cert.key');
//some code after

//the request itself
$json_response = curl_exec($curl);

The problem is - i don't know how to make this stuff in C#. It'd be easy if i had any knowledge how it's done in curl, like what it exactly does under it's cover.

My current request.

      //
            var request = CreateHttpRequest(url, method);
            var json = param?.ToJson();


            if (json != null)
            {
                var postData = Encoding.UTF8.GetBytes(json);
                request.ContentLength = postData.Length;
                using (var stream = request.GetRequestStream())
                    stream.Write(postData, 0, postData.Length);
            }

            using (var webResponse = request.GetResponse())
            using (var streamReader = new StreamReader(webResponse.GetResponseStream(), Encoding.UTF8))
             {
                    var result = streamReader.ReadToEnd();
                    return result.ParseJson(type);
             }

    //
    private HttpWebRequest CreateHttpRequest(string url, HttpMethod method)
    {
        var request = (HttpWebRequest)WebRequest.Create(url);
        request.ContentType = "application/json";
        request.Accept = "application/json, application/javascript, text/*";
        request.Headers.Add("Accept-Encoding", "gzip,deflate");
        request.Method = method.ToString().ToUpper();
        return request;
    }
D Thr.
  • 123
  • 5
  • I don't know much C#, but there seem to be quite a few questions about this topic here. Try googling `c# http request certificate site:stackoverflow.com` and see if any of those are useful. – Don't Panic Sep 11 '17 at 15:56
  • I don't think you need to worry about that in c# – BOR4 Sep 11 '17 at 16:07
  • @Don'tPanic i'll try that, thank you, but maybe someone knows about it. – D Thr. Sep 11 '17 at 16:10
  • @BOR4 i'm not worried at all, but the API service, which im using rn, works around ssl-certificates as their main authentication system. – D Thr. Sep 11 '17 at 16:11

2 Answers2

1

In order to use client certificate (loaded from .crt and .key files) in your HTTP-request, add following lines in CreateHttpRequest method before return:

string certificateText = File.ReadAllText("cert.crt");
string privateKeyText = File.ReadAllText("cert.key");
ICertificateProvider provider =
    new CertificateFromFileProvider(certificateText, privateKeyText);

request.ClientCertificates.Add(provider.Certificate);

Taken from this answer. To have CertificateFromFileProvider install OpenSSL.X509Certificate2.Provider Nuget package.

stop-cran
  • 4,229
  • 2
  • 30
  • 47
  • No it still doesn't do it. No exceptions, `CertificateFromFileProvider` returns just a plain certificate without a private key. – D Thr. Jan 23 '18 at 11:10
1

Ended up using OpenSSL library.

    public X509Certificate2 CreateCertifacte(string pathToCertificate)
    {
        var keyBytes = File.ReadAllBytes($"{pathToCertificate}/cert.key");
        var certBytes = File.ReadAllBytes($"{pathToCertificate}/cert.crt");

        var certBio = new BIO(certBytes);
        var keyBio = new BIO(keyBytes);
        var key = CryptoKey.FromPrivateKey(keyBio, "_");

        var cert = new X509Certificate(certBio);
        var name = cert.SerialNumber+".pfx";
        var stacks = new Stack<X509Certificate>();
        new X509Store().AddTrusted(cert);

        var certRealPkcs12 = new PKCS12("_", key, cert, stacks);
        using (var file = BIO.File(name, "wb"))
        {
            file.SetClose(BIO.CloseOption.Close); // don't ask me why, i don't know. this one just works.
            certRealPkcs12.Write(file);
        }
        certRealPkcs12.Dispose();

        var realCertOut =
            new X509Certificate2(File.ReadAllBytes(name), "_");
        return realCertOut;
    }

Update:

For the netstandard version you can use my fork. Keep in mind that it hasn't been tested all the way through yet (not sure if i ever will), so something wont probably work.

D Thr.
  • 123
  • 5
  • @sina_Islam, try this one -> https://github.com/Trapov/openssl-net/tree/feature-netstandard-support/ManagedOpenSsl.NetCore Keep in mind that I've added the netstandard version **myself**, so this case will work just fine, but some others might not. – D Thr. Jan 10 '19 at 16:44
  • @D Thr, thank for your suggestion. I am working on nopcommerce 4.0 and facing this problem when try to establish a secure connection over the payment getway. The problem is my application is running on .net core environment but tergated framework is 4.6.1. So when I try to user you suggested code it does not working. I have been struggeling last coupe of days and do not get any workaround. – sina_Islam Jan 12 '19 at 09:09