For a recent project I needed to host a WCF service in an Azure Cloud Service Worker Role.
This WCF service was secured using Client Certficiate authentication.
During a typical SSL handshake, the server will send a list of all trusted Root Certificate Authorities in the ServerHello message.
Based upon this list of Root CA's, the client can then pick a Client Certificate whose Root CA is in the trusted list send by the server.
If a server sends an empty list of trusted Root CA's, a client can then send any CLient Certificate it wants.
On the server the certificate will still be validated, but it can be validated against root CA's that you don't necessarily want to use.
In Windows Server 2012 the default behaviour is to not send the list of trusted Root CA's during the SSL handshake.
Luckily this behaviour can be modified by setting a registry key "SendTrustedIssuerList"
Furthermore, the default Azure Windows Server 2012 image contains a small list of trusted Root CA's.
The list can be extended by adding additional Root CA's to the Windows Certificate Store.
If these changes need to be done on an Azure Cloud Service, these changes also need to be applied after a Cloud Service is re-imaged.
In a Cloud Service, this can be done by adding a Startup Task.
Since the Startup Task also needs to be able to add certificates to the Certificate Store, these certificates should be part of Cloud Service deploy package.
Therefor the certificates must be added to the project as well.
The project would then look something like this:
In the Startup script, first the Root CA certificates are installed, then the Intermediate certificates and after that the registry is updated.
REM Install certificates. FOR %%c in (%~dp0\root\*.cer) DO certutil -addstore root %%c A FOR %%c in (%~dp0\intermediate\*.cer) DO certutil -f -addstore CA %%c REM Make sure the server is sending the Trusted Root List. reg add "HKLM\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL" /f /v "SendTrustedIssuerList" /t REG_DWORD /d "1"
In the ServiceDefinition.csdef the Startup Task itself can be defined.
Because the Startup Task needs access to the registry and Certificate Store, it needs to run in an elevated context.
<Startup> <Task commandLine="Startup\startup.cmd" executionContext="elevated" taskType="simple"> </Task> </Startup>
After deploying this to Azure, during an SSL handshake, a client will always send a certificate based upon the server's trusted Root CA's.
A few additional notes: