Windows Azure, SSL, Self-Signed Certificate and Annoying HTTPS Input Endpoint Does Not Contain Private Key Error

Deploying a Web Role with HTTPS Endpoint enabled with Self-Signed Certificate and a annoying problem of HTTPS input endpoint does not contain private key
2012-02-04 00:23
Tugberk Ugurlu


While I was trying out the Windows Azure features yesterday, I had a deployment problem. The case was to deploying SSL enabled web role. Let’s walk through the steps I have taken.

Since it was a try out, I decided to create a self-signed certificate instead of buying one. The case of how I created the self-signed certificate was fairly simple. I opened up the Visual Studio Command Prompt (2010) and cd to directory path where I would like to put the certificate file I was about to create. Then, I used the following makecert command line utility to create the certificate. Here is the code I used:

makecert -sky exchange -r -n "CN=TugberkUgurlu.Com" -pe -a sha1 -len 2048 -ss My "Azure.TugberkUgurlu.Com.cer"

I had my .cer file under c:\Azure\Certs directory. Also, I executed the following script on PowerShell console and I saw the certificate listed there.

 

dir cert:\CurrentUser\My

 

In order to upload the certificate to windows azure, I needed to export the certificate from .cer file to .pfx. Here where things get messy. I used the followig powershell script to create one but I was about to realize that it was the wrong decision. We'll see why in a minute.

$c = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2("c:\azure\certs\Azure.TugberkUgurlu.Com.cer")
$bytes = $c.Export("Pfx","password")
[System.IO.File]::WriteAllBytes("c:\azure\certs\Azure.TugberkUgurlu.Com.pfx", $bytes)

.cer and .pfx certificates

The next step was to deploy this .pfx file to Certificates store of my windows azure hosted service. In order to complate this challange, I went to Windows Azure portal, navigated to my hosted service. Right click on the blue Certificate folder (I think it is a folder icon but not sure exactly what it is) and click Add Certificate:

Azure Hosted Service, Add Certificate

It poped up a dialog box for me to upload that certificate file. I completed the steps and there it was. I had the certificate deployed on my hosted service.

Finally, I was done setting things up and I can jump right to my application. Wait, I wasn't done yet complately! I had to set things up at the application level so that I could hook it up to that certificate I had just uploded.

At that stage, first thing I did was to grab the thumbprint of the certificate. I ran the following PowerShell command to grab the thumbprint of the certificate:

(New-Object System.Security.Cryptography.X509Certificates.X509Certificate2("c:\azure\certs\Azure.TugberkUgurlu.Com.cer")).Thumbprint

With that thumbprint, I went to my project and added the following code inside ServiceConfiguration.Clound.cscfg and ServiceConfiguration.Local.cscfg under Role node:

<Certificates>
  <Certificate name="Azure.TugberkUgurlu.Com" thumbprint="AAD5DDD0CA9B4D3CFEF1652130142020770B8BDF" thumbprintAlgorithm="sha1"/>
</Certificates>

The ServiceDefinition.csdef file needed a little more touch than the configuration files. Here is the complate csdef file after the set-up:

<ServiceDefinition name="HttpsEnabledCloudProject" xmlns="http://schemas.microsoft.com/ServiceHosting/2008/10/ServiceDefinition">
  <WebRole name="MvcWebRole1" vmsize="Small">
    <Sites>
      <Site name="Web">
        <Bindings>
          <Binding name="Endpoint1" endpointName="Endpoint1" hostHeader="azure.tugberkugurlu.com" />
          <Binding name="HttpsIn" endpointName="HttpsIn" hostHeader="azure.tugberkugurlu.com" />
        </Bindings>
      </Site>
    </Sites>
    <Endpoints>
      <InputEndpoint name="Endpoint1" protocol="http" port="80" />
      <InputEndpoint name="HttpsIn" protocol="https" port="443" certificate="Azure.TugberkUgurlu.Com" />
    </Endpoints>
    <Imports>
      <Import moduleName="Diagnostics" />
    </Imports>
    <Certificates>
      <Certificate name="Azure.TugberkUgurlu.Com" storeLocation="LocalMachine" storeName="My" />
    </Certificates>
  </WebRole>
</ServiceDefinition>

Everything looked right at that point but got an ugly error message telling me that my deployment had been failed:

HTTP Status Code: 400. Error Message: Certificate with thumbprint AAD5DDD0CA9B4D3CFEF1652130142020770B8BDF associated with HTTPS input endpoint HttpsIn does not contain private key

Windows Azure Visual Studio Deployment Error

After a couple of searched on the internet, I ended up checking the private key of my certificate and here is the result:

$cert.HasPrivateKey

That looked awkward and might be the problem. Then I grabed the certificate from the certificate store and check the private key. That was the evidence that it was the problem:

$cert.HasPrivateKey

At that point, I created the .pfx file from the certificate in my certificate store with following code:

$cert = (get-item cert:\CurrentUser\My\AAD5DDD0CA9B4D3CFEF1652130142020770B8BDF)
$bytes = $cert.Export("Pfx","password")
[System.IO.File]::WriteAllBytes("c:\azure\certs\Azure.TugberkUgurlu.Com_2.pfx", $bytes)

At last, I deleted the certificate which was under my hosted service and reuploaded the new one I had just created.

Lastly, I ran the publish process again without changing anything inside my code, configuration or service definition files and I suceedded!

Windows Azure Visual Studio Deployment

Here is the SSL enabled application running in the cloud:

Windows Azure SSL Enable Application

Please comment if you have the same problem as me so that I won't feel lonely in this small World:)



New Comment