title: Execute default certificate validation when overriding ServicePointManager.ServerCertificateValidationCallback
body: <p>I use a <code>SmtpClient</code> to send emails through a SMTP server using SSL. This SMTP server is configured to use a self-signed certificate.</p>
  
  <p>Since it's out of scope for me to install the certificate on all client machines, I added a <code>ServicePointManager.ServerCertificateValidationCallback</code> to implement a custom validation for our self-signed certificate.</p>
  
  <p>However, I would like to execute the custom validation only when I'm using the <code>SmtpClient</code>, and revert back to the default behavior when the certificate validation is performed elsewhere.</p>
  
  <p>Since the callback is a static property, I should also make sure that the callback isn't called by another thread than the one I use to send the email.</p>
  
  <p>I came up with the following code:</p>
  
  <pre class="lang-vb prettyprint-override"><code>Private Shared _defaultServerCertificateValidationCallback As System.Net.Security.RemoteCertificateValidationCallback
  Private Shared _overrideSmtpCertificateValidation As Boolean = False
  Private Shared _callbackLocker As New Object()
  
  Private Shared Function OurCertificateValidation(s As Object, certificate As Security.Cryptography.X509Certificates.X509Certificate, chain As Security.Cryptography.X509Certificates.X509Chain, sslPolicyErrors As Net.Security.SslPolicyErrors) As Boolean
  
      SyncLock _callbackLocker
  
          If _overrideSmtpCertificateValidation Then
              _overrideSmtpCertificateValidation = False
              Dim actualCertificate = Security.Cryptography.X509Certificates.X509Certificate.CreateFromCertFile("selfSignedSmtp.cert")
              Return certificate.Equals(actualCertificate)
          Else
              'Should execute the default certificate validation.
              Return _defaultServerCertificateValidationCallback(s, certificate, chain, sslPolicyErrors)
          End If
  
      End SyncLock
  
  End Function
  
  Public Sub SendMail()
      _defaultServerCertificateValidationCallback = System.Net.ServicePointManager.ServerCertificateValidationCallback
      System.Net.ServicePointManager.ServerCertificateValidationCallback = New System.Net.Security.RemoteCertificateValidationCallback(AddressOf OurCertificateValidation)
      _overrideSmtpCertificateValidation = True
      'Send mail using SMTP client here...
  End Sub
  </code></pre>
  
  <p>What this code should do when sending an email is to keep the default <code>ServerCertificateValidationCallback</code> in a variable, flag the custom validation to be performed, perform the custom validation on the same thread as the <code>SmtpClient</code>, prevent other threads from performing the custom validation by using <code>SyncLock</code>, then revert back to the default behavior and allow other threads to continue with the default certificate validation.</p>
  
  <p>However, the <code>ServerCertificateValidationCallback</code> is set to <code>Nothing</code> by default, so I cannot explicitly invoke the default validation callback.</p>
  
  <p>Is there something I could invoke instead of <code>Return _defaultServerCertificateValidationCallback(s, certificate, chain, sslPolicyErrors)</code> that would execute the default certificate validation when needed?</p>