Old Certificates Identification and Removal

 

Certificate renewal on Web sites can be a big nightmare, especially if you have hundreds of them and if you don’t know when they are going to expire. Also, sometime you have change the Issuing CA from one to another and finding out the certificate chain on multiple sites can be a time consuming process. Of course you can open each site with IE or some other browser and look at each cert and document it that way. There are couple approaches that can help with automation of this task.

The first one would be running a script on each web server. This script can collect information about all certificates installed and provide some intelligent reporting. The problems with this approach are multiple: web servers can be running different platforms, so the script that can easily run on Windows might not run on other web servers. Another problem would be to actually be able to find the actual servers to run the script and then the issue with rights to run the script on the target server.

 

Another approach we can take is to run script on central workstation and target each web site from it. Open the site that is protected with SSL certificate, read information from the certificate and log it into the output report. This way we really don’t care about web server platform, its physical location and other potential issues. Sounds like a much better approach.

 

So here is a little PowerShell script that can help you with identifying certificate expiration and certificate chain on the target web servers.

 

First, you need to get a list of all web sites that have been protected with SSL certificates. Put URLs for these sites into input file (in this example, I call it sslinput.txt) that our script will read:

 

Websites

securesite.domain1.com

securesite.domain2.com

securesite.domainX.com

 

Second, save the following script to the DiscoverSSL.PS1 file and run it from PowerShell command. The script will produce an output file (ssloutput.txt) with information about each certificate.

 

$webinputpath = "C:\sslinput.txt"

$outputpath = "C:\ssloutput.txt"

function Get-RemoteCertificate ($serverName,$port)

  {

  $client = New-Object System.Net.Sockets.tcpclient($serverName, $port)

  $sslStream = New-Object System.Net.Security.SslStream($client.GetStream(),$false, $null,$null)

  $sslStream.AuthenticateAsClient($serverName)

  $remoteCert = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2($sslstream.remoteCertificate)

  Add-Content $outputpath "Certificate for $servername on port $port"

  Add-Content $outputpath "Subject: $remoteCert.Subject"

  if ($remoteCert.Verify() -eq $true) {Add-Content $outputpath "Revocation status: OK"} else { Add-Content $outputpath "Revocation status: REVOKED"}

  Add-Content $outputpath ""

  Add-Content $outputpath "---------------------------------------------------------------------------"

  Add-Content $outputpath ""

  $client.close()

  }

import-csv $webinputpath | foreach-object {get-remoteCertificate -servername $_.websites -port 443}

 

Limitations

1. This script will not provide information on certificates if the computer running this script does not trust the Root CA chaining from the issued SSL certificate.

2. This script will not provide information on self issued certificates. See #1.

3. This script will not provide information on certificates if their common name does not match the input URL. It will not work if the input file provides IP addresses or DNS names that do not match the target certificate.

4. In all 3 cases the output file will be logged with error message indicating that script could not authenticate to the target SSL certificate.