Search code examples
c#sslhttpsssl-certificatecertificate-store

How to determine if server has ssl certificate


I am creating a self-hosted owin server inside a windows service. I have implemented an ACME client to get a certificate from Let's Encrypt (to a domain given by the service's config.). However, if the service is run on a server which already has a certificate I do not need to request a new one. How can I determine, in code, if there is a certificate installed which applies for the domain set in the service's config?

The closest thing to a solution I found was to ignore existing certificates (if any) and always request a new one. Then when a certificate is received from Let's Encrypt, I save that certificate's serial to a file. On startup I then use the saved file (if any) to look for the existing certificate from the store:

public async Task<bool> NeedNewCertificate()
{
    string certSerial = await AsyncFileHandler.ReadFileAsync(CERT_SERIAL_FILENAME);

        using (var store = new X509Store(StoreName.My, StoreLocation.LocalMachine))
        {
            store.Open(OpenFlags.ReadOnly);
            var certCollection = store.Certificates.Find(X509FindType.FindBySerialNumber, certSerial, true);
            foreach (var cert in certCollection)
            {
                if (cert.NotBefore <= DateTime.Now && cert.NotAfter > DateTime.Now.AddDays(30)) // Let's Encrypt certificates are valid 90 days. They recommend renewing certificates every 30 days.
                    return false;
            }
        }
    return true;
}

Solution

  • That's a good enough way of doing it I think.

    Alternatively you can do a search in the certificate store that matches the parameters that you specify: the domain that the certificate is applied to, expiry date, etc. If you find the one that is valid, then you can use it.

    That is in fact most likely the definition for what you mean by "certificate is installed on the server".

    The attribute you probably would like to check is "Subject", e.g. you wold like these that have "CN = mydomain.com". You can have wildcard certificates as well, so you will need to figure out what types of certificates can be installed.