Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SSL certificate pre-fetch .NET

I am writing a utility that would allow me to monitor the health of our websites. This consists of a series of validation tasks that I can run against a web application. One of the tests is to anticipate the expiration of a particular SSL certificate.

I am looking for a way to pre-fetch the SSL certificate installed on a web site using .NET or a WINAPI so that I can validate the expiration date of the certificate associated with a particular website.

One way I could do this is to cache the certificates when they are validated in the ServicePointManager.ServerCertificateValidationCallback handler and then match them up with configured web sites, but this seems a bit hackish. Another would be to configure the application with the certificate for the website, but I'd rather avoid this if I can in order to minimize configuration.

What would be the easiest way for me to download an SSL certificate associated with a website using .NET so that I can inspect the information the certificate contains to validate it?

EDIT:

To extend on the answer below there is no need to manually create the ServicePoint prior to creating the request. It is generated on the request object as part of executing the request.

    private static string GetSSLExpiration(string url)
    {
        HttpWebRequest request = WebRequest.Create(url) as HttpWebRequest;
        using (WebResponse response = request.GetResponse()) { }
        if (request.ServicePoint.Certificate != null)
        {
            return request.ServicePoint.Certificate.GetExpirationDateString();
        }
        else
        {
            return string.Empty;
        }
    }
like image 360
Wil P Avatar asked Mar 24 '10 17:03

Wil P


1 Answers

I've just tried this, which "works on my machine (tm)".

It returns the text string representing the expiry date on the server's certificate, and requires an actual hit to be made on the web site.

private string GetSSLExpiryDate(string url)
{
    Uri u = new Uri(url);
    ServicePoint sp = ServicePointManager.FindServicePoint(u);

    string groupName = Guid.NewGuid().ToString();
    HttpWebRequest req = HttpWebRequest.Create(u) as HttpWebRequest;
    req.ConnectionGroupName = groupName;

    using (WebResponse resp = req.GetResponse())
    {
        // Ignore response, and close the response.
    }
    sp.CloseConnectionGroup(groupName);

    // Implement favourite null check pattern here on sp.Certificate
    string expiryDate = sp.Certificate.GetExpirationDateString();

    return expiryDate;
}

I'm afraid I don't know all the rights and wrongs of using ServicePoint, and any other hoops that you might need to jump through, but you do get an SSL expiry date for the actual web site you want to know about.

EDIT: ensure the "url" parameter use the https:// protocol.

e.g. string contosoExpiry = GetSSLExpiryData("https://www.contoso.com/");

like image 196
Neil Moss Avatar answered Oct 20 '22 01:10

Neil Moss