How configure SSL for an IIS Express site that uses multiple hostnames? - ssl

My web application project encompasses multiple web sites served under the umbrella of a single IIS Express site. I succeeded in following Scott Hanselman's excellent blog post, and IIS Express successfully serves both http://foo.local and http://bar.local from the same web application root directory.
However, I need both sites to support SSL. Following Hanselman's advice, I can create an SSL certificate and "attach" it to a single IP-port combination.
makecert -r -pe -n "CN=foo.local" -b 01/01/2000 -e 01/01/2036 -eku 1.3.6.1.5.5.7.3.1 -ss my -sr localMachine -sky exchange -sp "Microsoft RSA SChannel Cryptographic Provider" -sy 12
netsh http add sslcert ipport=0.0.0.0:443 appid='{214124cd-d05b-4309-9af9-9caa44b2b74b}' certhash=284475d4a4eb5c4d3ab7da4fdefa928186482376
That succeeds, but I am unable to repeat the process for the second site. Evidently only one SSL certificate can be applied to a single IP-port combination.
How can I make an SSL certificate that covers both https://foo.local and https://bar.local, or otherwise "attach" one for each site?

jww's answer led me in the right direction. Beyond Hanselman's instructions, here's what I had to do.
First of all, I enabled SNI on my site bindings in IIS Express' applicationhosts.config. This just meant appending the sslFlags attribute:
<binding protocol="https" bindingInformation="*:443:foo.local" sslFlags="1" />
<binding protocol="https" bindingInformation="*:443:bar.local" sslFlags="1" />
(credit: Configure SNI On IIS8?)
Then instead of using makecert, I created a self-signed certificate using PowerShell's New-SelfSignedCertificate cmdlet:
New-SelfSignedCertificate -DnsName foo.local, bar.local -CertStoreLocation cert:\LocalMachine\My
(credit: How to create a Self-Signed SAN Certificate in Windows 8)
Beside that, I followed Hanselman's instructions to use netsh http add sslcert... to "register" the certificate for the IP-port, and to use the MMC "Certificates" snap-in to make it trusted.

Evidently only one SSL certificate can be applied to a single IP-port combination...
You need IIS 8 or above to use multiple certificates. IIS 8 support Server Name Indication (SNI). See Server Name Indication (SNI) with IIS 8 (Windows Server 2012).
How can I make an SSL certificate that covers both https://foo.local and https://bar.local ...
Create one certificate. In the certificate, place both names in the Subject Alternate Name (SAN). Place a friendly name in the CN.
The CN should be a friendly name because:
The IETF deprecated placing a DNS name in the CN
The CA/Browser Forums deprecated placing a DNS name in the CN
CN's are often displayed to users, so they should be friendly
... or otherwise "attach" one for each site?
Upgrade to IIS 8 or Server 2012.
Following Hanselman's advice... makecert -r -pe -n "CN=foo.local"
His advice is wrong here.

Related

Working with SSL on the development box

I need to make sure that my web application works with HTTPS for secure account information. So I followed Hanselman's blog post to set it up:
Working with SSL at Development Time is easier with IISExpress
Everything was working like mentioned. However a couple of weeks ago it stopped working with the following error:
Error 101 (net::ERR_CONNECTION_RESET): The connection was reset.
I did not change anything on the local box or my code except for Windows updates. Can anyone tell me whats wrong? I can explain more if more clarification is required.
My application is an MVC4 application with a SQL Server DB.
I fixed this issue by following the steps described in a post from scott hanselman.
The following steps fixed the issue for me:
makecert -r -pe -n "CN=<SOMENAME>" -b 01/01/2000 -e 01/01/2036 -eku
1.3.6.1.5.5.7.3.1 -ss my -sr localMachine -sky exchange -sp "Microsoft RSA SChannel Cryptographic Provider" -sy 12
netsh http delete sslcert ipport=0.0.0.0:44300
Look up the thumbprint of the certificate by using MMC.exe
netsh http add sslcert ipport=0.0.0.0:44300 appid={<SOMEGUID>} certhash=<THUMBPRINT>

Self-hosting using SSL and WCF - can't bind certificate to port

I have a WCF service that I want to access using SSL. I'm on my developer machine, so I was thinking of self-hosting the service. I've been following Configuring HTTP and HTTPS.
I've created a self-signed certificate which I added to the Trusted Root Certification Authorities. I've created another two certificates signed by the first one, one for the client and the other for the server. I followed Using makecert to create certificates for development.
I can't get past the SSL certificates configuration step. When I'm binding the certificate to the port number using netsh it throws an SSL error:
Certificate add failed, Error: 1312 A specified logon session does not exist. It may already have been terminated.
Does the certificate need some special field or some other thing for this to work?
CA certificate:
makecert -n "CN=TestCA" -cy authority -a sha1 -sv "TestCA.pvk" -r "TEST_CA.cer"
Service certificate:
makecert -n "CN=rneapp.com" -ic "TEST_CA.cer" -iv "TestCA.pvk" -a sha1 -sky exchange -pe -sv "rneapp.com.pvk" "rneapp.com.cer"
Client certificate:
makecert -n "CN=rneClient" -ic "TEST_CA.cer" -iv "TestCA.pvk" -a sha1 -sky exchange -pe -sv "rneClient.pvk" "rneClient.cer"
I'm using this command to bind the certificate to the port:
netsh http add sslcert ipport=0.0.0.0:8465 certhash=a853f3b5b48b8a506bdc4212ba2726a3bfea2bb6 appid={2E53B9B0-17AE-4EBC-A1AE-43D53A6FD07D} clientcertnegotiation=enable
When I encountered the same issue, moving the certificate from Current User to Local Computer storage helped, so try checking your certificate storage.
Built-in help for netsh http add sslcert also mentions this with regard to certstorename option:
certstorename - Store name for the certificate. Defaults
to MY. Certificate must be stored in the
local machine context.
I also run into similar error code through different process of creating the self-signed certificate and find the source of my own problem. Using netsh, bind an SSL certificate to a port number is failing
Here is the article I follow to create the self-signed certificate and it is quite complete and thorough.
I have exactly the same issue on Windows 7 and Windows Server 2008 R2 but for me it is working the first time I bind the certificate with the port. However if I delete the binding (netsh.exe http delete sslcert ipport=0.0.0.0:9101) and bind again with the same certificate, it fails. If I try another port, it fails. If I create a brand new certificate then I can bind again. But again deleting/binding will fail.
I follow the same rules as this question:
Can't register a C# generated selfsigned SSL certificate with netsh (error 1312)
I also tried to install KB981506 http://support.microsoft.com/kb/981506 but it failed to install "The update is not applicable to your computer". Maybe I have it already.
I have a feeling something is not deleted in a right way when the binding is deleted. ProcessMonitor doesn't show any thing weird when I try to bind again.
This seems to be a known issue. Check out this Microsoft KB article.
You may also be setting up the certificates incorrectly. Check out this MSDN forum post for how another person was making a similar mistake and getting the 1312 error which was just distracting him from the real problem which was his certificate configuration.
I had a similar problem today, and this is how I fixed it. When I have watched certificates installed on my local computer/my in mmc.exe, I have seen that my certificate haven't icon with key.
So when I combine *.cer and *.pvk file to *.pfx with:
pvk2pfx -pvk "private_key.pvk" -spc "public.cert" -pfx "test.pfx"
And then import *.pfx file with mmc.exe.
Then the next commands will execute with no errors:
netsh http add sslcert...
netsh http delete sslcert...
I have posted this answer to similar Stack Overflow question, Can't register a C# generated selfsigned SSL certificate with netsh (error 1312).

Access client certificate properties from WCF Service

I am writing a WCF service where I need to access the Hash Code of client certificates that are used to connect to the service.
I am looking for a property or method similar to Request.ClientCertificate from ASP.NET 2.0 days but cannot find anything that allows easy access to the client certificate.
Our service is set up such that it is running with SSL using basicHttpBinding and security mode of "Transport".
IIS has been set up to Require SSL and Accept certificates.
One thing to note is that our server certificate used to secure the endpoint is from a different CA to that of the client certificates - the client certificates are intended to be validated solely through custom code (thus the need to get the hash code of a connecting certificate).
I have created a custom implementation of the IDispatchMessageInspector to see if there is any access to a client certificate from there but to no avail.
Has anyone attempted this and had success before?
Looks like what the best option for you would be to implement a custom Certificate Validator for your service. This is basically a class that derives from X509CertificateValidator and is then registered through the config file.
There's more complete information on how to do this on this article.
For reference if anyone else attempts to apply client certificate authentication the following steps were required to get it to work (we are using basicHttpBinding within WCF for this instance and running in a local instance of IIS):
Set up IIS to use a HTTPS binding for the site and secure this in IIS with a server certificate
Within IIS change the SSL Settings for your site to Require SSL and Require client certificates (It must be Require - Accept will not work)
Within the WCF configuration ammend the basicHttpBinding and set security mode to "Transport" and the transport clientCredentialType to "Certificate"
Ensure that the root certificate (the one used to create any client certificates) is within the "Trusted Root Cerrtification Authorities" for the Local Computer on which IIS is running.
NOTE If you are in a development environment you may need to generate your own root certificate, the makecert command line application is very useful for this; simply run the following command:
makecert -n "CN=My Test Auth" -r -cy authority -a sha1 -sv "My Private Key.pvk" TestAuth.cer
This creates a certificate called TestAuth.cer (which needs to be added to the Computer's "Trusted Root Cerrtification Authorities") and a private key file called "My Private Key.pvk".
Now to generate a client certificate you can run this command:
makecert -a sha1 -n "CN=myConnectionCert" -ic "TestAuth.cer" -iv "My Private Key.pvk" -ss My
This created a certificate with a subject of myConnectionCert and adds it to your personal certificate store - when you now access the site (to view the service page for example) IE should prompt you to select the certificate - chose the one you have just created and you should see the service page as normal.

WCF with netTcpBinding and Certificate transport security

I need to secure a WCF service that uses netTcpBinding and connects directly with a Windows Forms based application. I only need it to be secured at the transport layer.
I'm pretty sure that I have it working locally, i.e. I can run the service locally, and connect to it with the client.
When I try to setup the service so that it is running on a server as opposed to my local machine, I'm having certificate issues. The error log says that the certificate must have a private key that is capable of key exchange and that the process must have access rights for the private key.
I'm using a development certificate created using makecert.
makecert -n "CN=MY COMPANY DEBUG" -pe -sky exchange Debug.cer
I must admit that I'm very new to using certificates. Does anyone have any pointers on how I can fix this, or a better way to use a certificate to add transport security to a WCF service using netTcpBinding?
Thanks.
Try this:
makecert -n "CN=MY COMPANY DEBUG" -pe -sky exchange Debug.cer -sv Debug.pvk
pvk2pfx -pvk Debug.pvk -spc Debug.cer -pfx Debug.pfx
You will then end up with three files, the .cer file (public key), the .pvk (private key), and the .pfx (key exchange with both). You can then install the .pfx file on the server like so:
certutil -p "" -importPFX Certificates\Debug.pfx
At the client end, you only need to install the .cer file. These installs (.cer and .pfx above) you can also do through the Certificates MMC snap-in (Start, Run, MMC.exe, then add the Certificates snap-in for the current machine).
Read this (covers https case but still may help) and this.
Since we are talking about transport-level security, I don't think your server process should know anything about certificate you are using to provide it.

How to create a self-signed wildcard SSL certificate for IIS 6?

I'm trying to create a self-signed wildcard SSL certificate for use on a number of development and test servers running IIS 6. Following various guides has led to a couple ways of generating the certificates, but I haven't had any luck getting it to work. The most successful ways I've had were following this OpenSSL guide and using makecert.exe like so:
makecert.exe -r -b 01/01/2009 -e 01/01/2042 -sr LocalMachine -ss MY -a sha1 -n CN="*.example.com" -sky exchange -pe -eku 1.3.6.1.5.5.7.3.1 -sy 12 -sp "Microsoft RSA SChannel Cryptographic Provider" wildcard.cer
Both of which generate certificates that IIS 6 will accept, but when I actually try to view the site I get the following error in firefox:
Data Transfer Interrupted
The connection to dev.example.com was interrupted while the page was loading.
IE just gives:
Internet Explorer cannot display the webpage
Most likely causes:
You are not connected to the Internet.
The website is encountering problems.
There might be a typing error in the address.
This error happens whether I try to access it by domain name, machine name, localhost, local ip, or loopback ip.
So...how can I create a self-signed wildcard cert that IIS 6 will work with? Or how can I fix the problems I'm experiencing with the ones I've already created?
You can use the IIS 6 Resource Kit provided by MS, an command line app called SelfSSL. It can generate the SSL key and import it into your IIS installation.
IIS 6 Resource Kit
you can do a wildcard certificate with *.domain.local and multiple ssl protocols by using the c:\inetpub\adminscripts adsutil.vbs set w3svc[siteid]\SecureBindings ":443:name.domain.local"
Did you realize that you would need to change from "example.com" to some thing more appropriate to your situation ("localhost" might be one of them during testing).
For IIS 7 - there is a wzard to do this. It takes about 30 seconds to setup.
For IIS 6 - it's a bit trickier. It takes about 30 minutes to setup.
Which one are you using?
I strongly recommend moving to IIS 7 - it is very foreign at first, but they've made a lot of improvements.
Given that you probably can't upgrade to IIS 7, I had to do the following to implement what you want in IIS 6.
1) create certificate server
2) generate request
3) grant request
4) install certificate
It's a bit of a pain to setup the certificate authority server, but it comes with Windows Server and the walkthrough is pretty straight forward.
We discovered that the Certificate Authority wasn't being trusted because of domain settings and was causing the errors. We ended up deploying a star cert generated by a trusted CA and that cleared up the problems.