We have been working on moving Continua CI to .net 4.6.1 for a future release, and during this conversion (so far, mostly just updating nuget packages), we discovered an issue that turned out to be caused by a change to .net certificate validation.
If you use self signed X509 certificates and target the .net framework 4.6.1 then you are in some fun, especially if you used makecert to generate the certificate. There is a change in behaviour in the way certificates are validated, which will leave you pulling you hair out for hours. The error you may encounter will look something like this :
"The Identity check failed for the outgoing message. The remote endpoint did not provide a domain name system (DNS) claim and therefore did not satisfied DNS identity 'localhost'. This may be caused by lack of DNS or CN name in the remote endpoint X.509 certificate's distinguished name."
If you google the error message, you will find plenty of references to using a DnsEndpointIdentity, only in our case, we were already doing exactly as the answers on stackoverflow were suggesting! Since we were migrating from .net 4.0 to .net 4.6.1, I started looking for info on the changes in each version of the .net framework. Eventually, I came across this page :
This was the only mention of X509 certificates I could find in the change history, but it seems like it could be related, so I tried what it suggested, and low and behold, problem solved! With some further investigation of this work around, I found some issueson the wcf github repo with several references to the behaviour of certificate validation.
So it turns out, in .NET 4.6.1 they broke the certificate validation, by only looking at the Subject Alternate Name (SAN) extension, and not falling back to the Subject Name CN field as it should. The pull request I linked to above, is for the WCF for .NET core, not 4.6.1 - so I have no way of knowing if this will be fixed for 4.6.x.
Whilst an app.config change can work around the issue, the real fix is to generate certificates that include SAN extension.
Generating a certificate without MakeCert
Makecert.exe, which is commonly used (on windows at least) does not support the SAN extension, M
akecert is deprecated, so it's unlikely there will be an update to make it able to generate certificates with the SAN certificate extension. Windows 8/Server 2012R2 & later versions of Windows include a new powershell cmdlet to generate certificates. For Windows 7 the best option is this :
This appears to what the Windows 8 & later cmdlet is based on, it's relatively simple to use and generates certificates that validate properly with WCF on .NET 4.6.1
New-SelfSignedCertificateEx -Subject "CN=MyServer" -KeySpec Exchange
-KeyUsage "DataEncipherment, KeyEncipherment, DigitalSignature"
-Path c:\certs\example.pfx -Exportable -SAN "MyServer" -SignatureAlgorithm sha256
-AllowSMIME -Password (ConvertTo-SecureString "abc123dontuseme" -AsPlainText -Force)
Note the above command is on multiple lines to make it easier to read, it can be on one line.