2

Hoping someone can shed light on this. In Powershell, the following code generates output of the website certificate:

$req = [Net.HttpWebRequest]::Create('https://www.google.com')
$req.GetResponse()
$req.Servicepoint.certificate

       Handle Issuer                                       Subject
       ------ ------                                       -------
2266454817712 CN=GTS CA 1O1, O=Google Trust Services, C=US CN=www.google.com...

In Powershell Core, it returns a null/blank in $req.Servicepoint.certificate.

BindIPEndPointDelegate :
ConnectionLeaseTimeout : -1
Address                : https://www.google.com/
MaxIdleTime            : 100000
UseNagleAlgorithm      : True
ReceiveBufferSize      : -1
Expect100Continue      : True
IdleSince              : 20/09/2019 9:42:48 AM
ProtocolVersion        : 1.1
ConnectionName         : https
ConnectionLimit        : 2
CurrentConnections     : 0
Certificate            :
ClientCertificate      :
SupportsPipelining     : True
1

It looks like .NET Core issue 36979 explains this pretty well.

In short, System.Net.HttpWebRequest is obsolete and was only partially re-implemented in .NET Core. In particular, ServicePoint and ServicePointManager classes exist but don't really function.

They recommend migrating to System.Net.Http.HttpClient instead and one user offered the following code sample to demonstrate how to retrieve the certificate with it.

using System;
using System.Net.Http;
using System.Net.Security;
using System.Security.Cryptography.X509Certificates;

namespace NetCoreConsoleApp1
{
    class Program
    {
        static void Main(string[] args)
        {
            var handler = new HttpClientHandler();
            handler.ServerCertificateCustomValidationCallback = CustomCallback;
            var client = new HttpClient(handler);

            HttpResponseMessage response = client.GetAsync("https://www.google.com.mx/").GetAwaiter().GetResult();
            Console.WriteLine(response.StatusCode);
            Console.WriteLine((int)response.StatusCode);
        }

        private static bool CustomCallback(HttpRequestMessage arg1, X509Certificate2 arg2, X509Chain arg3, SslPolicyErrors arg4)
        {
            Console.WriteLine(arg2.GetEffectiveDateString());
            Console.WriteLine(arg2.GetExpirationDateString());
            Console.WriteLine(arg2.Issuer);
            Console.WriteLine(arg2.Subject);

            return arg4 == SslPolicyErrors.None;
        }
    }
}
  • Cheers Ryan, great pickup. I didn't find that on my initial research but it was sitting there plain as day. – Geoff Vass Sep 20 at 10:16
0

If anybody's interested, here's how I reworked that for PS Core:

$Req = [System.Net.Sockets.TcpClient]::new('www.google.com', '443')
$Stream = [System.Net.Security.SslStream]::new($Req.GetStream())
$Stream.AuthenticateAsClient('www.google.com')
$Stream.RemoteCertificate
$Stream.RemoteCertificate.GetExpirationDateString()

(etc)

Ssl​Stream.​Remote​Certificate Property

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.