I'm trying to create an X.509 certificate file that will work with the following code as found in the smtp4dev project:
var certificate = new X509Certificate(Settings.Default.SSLCertificatePath);
var clientCertificateRequired = false;
var protocols = SslProtocols.Ssl2 | SslProtocols.Ssl3 | SslProtocols.Tls;
var checkRevocation = false;
var stream = new SslStream(stream);
stream.AuthenticateAsServer(certificate, clientCertificateRequired, protocols, checkRevocation);
Settings.Default.SSLCertificatePath
points to a .cer file.
Whatever I try, this fails with a System.NotSupportedException
with the message:
The server mode SSL must use a certificate with the associated private key.
I have created an X509 certificate using the New-SelfSignedCertificate PowerShell CommandLet in an elevated PowerShell session:
New-SelfSignedCertificate `
-DnsName "localhost" `
-CertStoreLocation "cert:\CurrentUser\My" `
-FriendlyName "smtp4dev" `
-TextExtension "2.5.29.37={text}1.3.6.1.5.5.7.3.1" `
-KeyUsage DigitalSignature,KeyEncipherment,DataEncipherment `
-Provider "Microsoft RSA SChannel Cryptographic Provider"
I added these options to mirror as closely as possible a certificate that is already stored on my machine, and that was generated by the IIS Express installer. Because that particular certificate does work, although I don't know why.
Both certificates are located in the Local Computer > Personal
certificate store. For both certificates the Certificate Manager mentions that "You have a private key that corresponds to this certificate".
When I compare the properties of these 2 certificates, the smtp4dev certificate differs from the IIS Express Development Certificate in the following 3 ways (besides the Thumbprint and Serial number):
- Key Usage is marked as a critical extension
- Subject Alternative Name extension with value
DNS Name=localhost
- Subject Key Identifier extension with value
e7 12 f5 ...
I exported both certificates to my desktop without the private key as "Base-64 encoded x.509 (.CER)" files using the Certificate Manager. (Including the private key would limit the export format to PKCS #12 (.PFX) which is not supported by smtp4dev.)
After exporting the certificates this way, when I double-click them, neither shows the message about having the private key.
Only the IIS Express Development Certificate works in the code shown at the beginning of this question. The smtp4dev one does not.
Other things I tried:
I often come across tutorials that use
makecert
, but I don't have that program.I have tried using a self-signed certificate generated by
openssl
and only setting theCommon Name
tolocalhost
but I get the same exception ("The server mode SSL must use a certificate with the associated private key").Changing the code to use X509Certificate2 is not an option, as it would be time-consuming to get another release of smtp4dev with the patch applied, since the project seems not to be actively developed.
Trying a different certificate file format (such as PFX) is actually possible, as long as I rename the file to .cer I can trick smtp4dev into using the certificate. This allows me to include the private key in the certificate. It works with an export of the IIS Express Development Certificate, but it doesn't work with an export of the smtp4dev certificate.