Sometime you may have to create X.509 certificate on the fly. Imagine you are writing a WCF Service to be hosted in App Fabric or creating a WCF Service Web Role to be hosted in Microsoft Data center. In these scenarios you don’t have access to local file system and in the service you are performing Azure subscription level operation using Windows Azure Management API. So to authenticate WCF Service against Windows Service subscription you need to provide the certificate.

 

image

 

Essentially there are three steps involved in this process,

  1. Read X.509 Certificate file (.cer) from AZURE BLOB.
  2. Create X.509 certificate from the downloaded file from Azure BLOB.
  3. Pass the created certificate as part of request to authenticate.

 

Read Certificate file from Windows AZURE BLOB storage as byte array

image

In above code snippet, we are reading certificate file from BLOB as an array of byte data. You need to add reference of Microsoft.WindowsAzure and Microsoft.WindowsAzure.StorageClient . Container Name is name of your public container.

Create X.509 certificate

Once you have byte array form Azure BLOB, you can create X.509 certificate to be authenticated using the byte array as below,

image

Pass the Certificate to authenticate

 

clip_image001

clip_image002

Here while making call you can add certificate created from AZURE BLOB file .

For your reference full source code is as below,

 



using System;
using System.IO;
using System.Linq;
using System.Net;
using System.Security.Cryptography.X509Certificates;
using System.Xml.Linq;
using Microsoft.WindowsAzure;
using Microsoft.WindowsAzure.StorageClient;



namespace ConsoleApplication26
{
    class Program
    {
        static void Main(string[] args)
        {

                      CloudStorageAccount cloudStorageAccount = CloudStorageAccount.Parse("DataConnectionString");
            CloudBlobClient cloudBlobClient = cloudStorageAccount.CreateCloudBlobClient();
            CloudBlobContainer cloudBlobContainer = cloudBlobClient.GetContainerReference("ContainerName");
            CloudBlob cloudBlob = cloudBlobContainer.GetBlobReference("debugmode.cer");
            Console.WriteLine(cloudBlob.DownloadText());
            Console.ReadKey(true);
            byte[] byteData = cloudBlob.DownloadByteArray();
            X509Certificate2 certificate = new X509Certificate2(byteData);

           var request = (HttpWebRequest)WebRequest.Create("https://management.core.windows.net/697714da-b267-4761-bced-b75fcde0d7e1/services/hostedservices");
           request.Headers.Add("x-ms-version:2009-10-01");
           request.ClientCertificates.Add(certificate);

            var response = request.GetResponse().GetResponseStream();
            var xmlofResponse = new StreamReader(response).ReadToEnd();

            XDocument doc = XDocument.Parse(xmlofResponse);
            XNamespace ns = "http://schemas.microsoft.com/windowsazure";
            var servicesName = from r in doc.Descendants(ns + "HostedService")
                               select new HostedServices
                               {
                                   serviceName = r.Element(ns + "ServiceName").Value
                               };

            foreach (var a in servicesName)
            {
                Console.WriteLine(a.serviceName);
            }



            Console.ReadKey(true);


        }

        static public  byte[] ReadToEnd(System.IO.Stream stream)
        {
            long originalPosition = stream.Position;
            stream.Position = 0;
            try
            {
                byte[] readBuffer = new byte[4096];
                int totalBytesRead = 0;
                int bytesRead;
                while ((bytesRead = stream.Read(readBuffer, totalBytesRead, readBuffer.Length - totalBytesRead)) > 0)
                {
                    totalBytesRead += bytesRead;
                    if (totalBytesRead == readBuffer.Length)
                    {
                        int nextByte = stream.ReadByte();
                        if (nextByte != -1)
                        {
                            byte[] temp = new byte[readBuffer.Length * 2];
                            Buffer.BlockCopy(readBuffer, 0, temp, 0, readBuffer.Length);
                            Buffer.SetByte(temp, totalBytesRead, (byte)nextByte);
                            readBuffer = temp;
                            totalBytesRead++;
                        }
                    }
                }
                byte[] buffer = readBuffer;
                if (readBuffer.Length != totalBytesRead)
                {
                    buffer = new byte[totalBytesRead];
                    Buffer.BlockCopy(readBuffer, 0, buffer, 0, totalBytesRead);
                }
                return buffer;
            }
            finally
            {
                stream.Position = originalPosition;
            }
        }

     public    class HostedServices
        {
            public string serviceName { get; set; }
        }
    }
}


 

I hope this post was useful. Thanks for reading Smile

 

Advertisements

5 thoughts on “Creating X.509 certificate from Windows Azure BLOB

  1. Are you sure this is going to work? For the Azure Management API’s you need the certificate AND the private key, so you should use a .pfx file (which unfortunatly is protected with a password).

    Your scenario works on your local machine, because the private key happens to be installed there. Does it work in the cloud?

  2. Hi Erik ,

    You are very right. This solution would not work on Cloud. if you move above idea to cloud then you will have to provide PFX along with Password while making call 🙂

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s