Io uso un SmtpClient
per inviare e-mail tramite un server SMTP utilizzando SSL. Questo server SMTP è configurato per utilizzare un certificato autofirmato.Esegui convalida del certificato predefinito quando si esegue l'override di ServicePointManager.ServerCertificateValidationCallback
Dato che non è possibile installare il certificato su tutti i computer client, ho aggiunto uno ServicePointManager.ServerCertificateValidationCallback
per implementare una convalida personalizzata per il nostro certificato autofirmato.
Tuttavia, desidero eseguire la convalida personalizzata solo quando utilizzo lo SmtpClient
e ripristino il comportamento predefinito quando la convalida del certificato viene eseguita altrove.
Dal momento che il callback è una struttura statica, vorrei anche fare in modo che la richiamata non viene chiamato da un altro thread di quello che uso per inviare l'e-mail.
mi si avvicinò con il seguente codice:
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
Ciò che questo codice dovrebbe fare quando si invia una e-mail è quello di mantenere il default ServerCertificateValidationCallback
in una variabile, la bandiera di convalida personalizzato da eseguire, eseguire la convalida personalizzato sullo stesso thread del SmtpClient
, impedire altri thread di eseguire la convalida personalizzato utilizzando SyncLock
, poi ritornano al comportamento predefinito e consentire altri thread di continuare con la convalida certificato predefinito.
Tuttavia, lo ServerCertificateValidationCallback
è impostato su Nothing
per impostazione predefinita, pertanto non è possibile richiamare esplicitamente il callback di convalida predefinito.
C'è qualcosa che potrei invocare al posto di Return _defaultServerCertificateValidationCallback(s, certificate, chain, sslPolicyErrors)
che eseguire la convalida del certificato di default in caso di necessità?