ServerCertificateCallbackShim.cs

using System;
using System.Management.Automation;
using System.Net;
using System.Net.Security;
using System.Security.Cryptography.X509Certificates;
 
namespace TlsCertificateValidation
{
    public static class ServerCertificateCallbackShim
    {
        private static void WriteLine(bool write, string line)
        {
            if( !write )
                return;
             
            Console.WriteLine(line);
        }
 
        private static bool ConsoleEnabled()
        {
            var enableConsoleOutput =
                Environment.GetEnvironmentVariable("TLSCV_ENABLE_CONSOLE_OUTPUT");
            return !string.IsNullOrEmpty(enableConsoleOutput);
        }
 
        public static void RegisterScriptBlockValidator(ScriptBlock validator)
        {
 
            WriteLine(ConsoleEnabled(), "Validator registered");
 
            ServicePointManager.ServerCertificateValidationCallback = (
                object sender,
                X509Certificate certificate,
                X509Chain chain,
                SslPolicyErrors sslPolicyErrors
            ) =>
                {
                    var write = ConsoleEnabled();
 
                    WriteLine(write, " starting");
                    var result = validator.Invoke( new[] { sender, certificate, chain, sslPolicyErrors } );
                    WriteLine(write, " completed");
 
                    if( result.Count == 0 )
                    {
                        WriteLine(write, " returned no results");
                        return false;
                    }
 
                    if( result[0] == null || result[0].BaseObject == null )
                    {
                        WriteLine(write, " returned null");
                        return false;
                    }
                     
                    var baseObject = result[0].BaseObject;
                    var msg = " returned ([" + baseObject.GetType().FullName + "] " + baseObject.ToString() +
                              ").";
                    WriteLine(write, msg);
                    try
                    {
                        return Convert.ToBoolean(baseObject);
                    }
                    catch( Exception ex )
                    {
                        WriteLine(write, " failed to return boolean");
                        msg = "Failed to convert ([" + baseObject.GetType().FullName + "] " +
                                  baseObject.ToString() + ") to a boolean. " +
                                  "ServerCertificateValidationCallback script blocks must return a " +
                                  "boolean or a value that is convertable to a boolean.";
                        throw new Exception(msg, ex);
                    }
                };
        }
    }
}