<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:media="http://search.yahoo.com/mrss/"><channel><title>2020-03 on Funky Si's Test</title><link>https://blog-test.funkysi1701.com/2020/03/</link><description>Recent content in 2020-03 on Funky Si's Test</description><generator>Hugo -- gohugo.io</generator><language>en-gb</language><managingEditor>funkysi1701@gmail.com (Simon Foster)</managingEditor><webMaster>funkysi1701@gmail.com (Simon Foster)</webMaster><lastBuildDate>Tue, 03 Mar 2020 20:00:45 +0000</lastBuildDate><atom:link href="https://blog-test.funkysi1701.com/2020/03/index.xml" rel="self" type="application/rss+xml"/><item><title>Testing expiring SSL certificates</title><link>https://blog-test.funkysi1701.com/posts/2020/testing-for-expiring-ssl-certificates/</link><author>funkysi1701@gmail.com (funkysi1701)</author><pubDate>Tue, 03 Mar 2020 20:00:45 +0000</pubDate><guid>https://blog-test.funkysi1701.com/posts/2020/testing-for-expiring-ssl-certificates/</guid><category term="Security">Security</category><category term="SSL">SSL</category><category term="Testing">Testing</category><description>&lt;p&gt;Let&amp;rsquo;s Encrypt is amazing, you can easily add SSL certificates to any website and automate the renewal process. I have talked &lt;a href="https://www.funkysi1701.com/posts/2018/lets-encrypt-is-awesome/" target="_blank" rel="noopener noreferrer"&gt;before&lt;/a&gt;
about how impressive it is.&lt;/p&gt;
&lt;p&gt;Once you start adding SSL certificates to your production sites however you may want to check when they expire so you don&amp;rsquo;t get caught out. You can always open your site in your favourite browser and view the certificate information and expiry date.&lt;/p&gt;
&lt;p&gt;
&lt;img class="img-fluid" alt="SSL Cert" src="https://blog-test.funkysi1701.com/images/2020/jb78re4fmm1ofx81f3mu.jpg" loading="lazy"
width="671" height="608"
/&gt;
However there is a way to automate this check.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-csharp" data-lang="csharp"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;[Fact]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;public&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;void&lt;/span&gt; IsSSLExpiring()
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; handler = &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; HttpClientHandler
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ServerCertificateCustomValidationCallback = CustomCallback
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; };
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; client = &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; HttpClient(handler);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; HttpResponseMessage response = client.GetAsync(&lt;span style="color:#e6db74"&gt;&amp;#34;https://www.example.com&amp;#34;&lt;/span&gt;).GetAwaiter().GetResult();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; Assert.True(response.IsSuccessStatusCode);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;private&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;bool&lt;/span&gt; CustomCallback(HttpRequestMessage arg1, X509Certificate2 arg2, X509Chain arg3, SslPolicyErrors arg4)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; now = DateTime.UtcNow;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; expire = arg2.NotAfter;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; diff = (expire - now).TotalDays;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; Assert.InRange(diff, &lt;span style="color:#ae81ff"&gt;30&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;1000&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; arg4 == SslPolicyErrors.None;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This code gets the SSL expiry date from &lt;a href="https://www.example.com" target="_blank" rel="noopener noreferrer"&gt;https://www.example.com&lt;/a&gt;
and will fail the xunit test if the expiry date is less than 30 days in the future. I then schedule my tests to run regularly on all my environments with a Let&amp;rsquo;s Encrypt Certificate and this gives me advanced warning if a SSL certificate is about to expire.&lt;/p&gt;
&lt;p&gt;The Assert.InRange(diff, 30, 1000) line will fail the test if the expiry date is less than 30 days or greater than 1000, but as the default expiry for Let&amp;rsquo;s Encrypt certificates is three months it will never be greater than 1000 days even with a freshly installed certificate. These values can be tweaked to suit your use case, however 30 days is enough time for me to investigate what is happening.&lt;/p&gt;
&lt;p&gt;To execute my tests I use a scheduled build in Azure DevOps, but anything that regularly can run your tests will do the job.&lt;/p&gt;
&lt;p&gt;The code above is just a simple example to get your started for my purposes I have put all my URLs into config files and just pass these into my tests, so I don&amp;rsquo;t need a custom test for every different URL.&lt;/p&gt;</description></item></channel></rss>