Friday, 10 February 2012

Creating your own certificate for a test SSL server

I've just needed to spoof an SSL server that one of my client apps connects to, in order to setup some test cases for specific responses.

The TcpListener needs an X509Certificate to use for encryption. An easy way to set this up is to use the makecert.exe utility from Mircosoft.

First, you create a trusted root certificate:
makecert -pe -n "CN=Test And Dev Root Authority" -ss my -sr LocalMachine  -sky signature 
-r "Test And Dev Root Authority.cer"
,Then you use this created cert to create a certificate for encryption:
makecert -pe -n "CN=apptest.com" -ss my -sr LocalMachine -sky exchange -eku 1.3.6.1.5.5.7.3.1 -is MY -ir LocalMachine  
-sp "Microsoft RSA SChannel Cryptographic Provider" -sy 12 apptest.com.cer

Be sure to copy the root authority certificate into you trusted root store.

An example of setting up a server is below, copied directly from here.


public static void RunServer(string certificate)
        {
            serverCertificate = X509Certificate.CreateFromCertFile(certificate);
            // Create a TCP/IP (IPv4) socket and listen for incoming connections.
            TcpListener listener = new TcpListener(IPAddress.Any, 4433);
            listener.Start();
            while (true)
            {
                Console.WriteLine("Waiting for a client to connect...");
                TcpClient client = listener.AcceptTcpClient();
                ProcessClient(client);
            }
        }
        static void ProcessClient(TcpClient client)
        {
            // A client has connected. Create the 
            // SslStream using the client's network stream.
            SslStream sslStream = new SslStream(
                client.GetStream(), false);
            // Authenticate the server but don't require the client to authenticate.
            try
            {
                sslStream.AuthenticateAsServer(serverCertificate,
                    false, SslProtocols.Ssl3, true);

                // Set timeouts for the read and write to 5 seconds.
                sslStream.ReadTimeout = 5000;
                sslStream.WriteTimeout = 5000;
                // Read a message from the client.   
                Console.WriteLine("Waiting for client message...");
                string messageData = ReadMessage(sslStream);
                Console.WriteLine("Received: {0}", messageData);

                // Send a message back to the client.
                byte[] message = Encoding.UTF8.GetBytes("hello from server <EOF>");
                Console.WriteLine("Sending hello message.");
                sslStream.Write(message);
            }
            catch (AuthenticationException e)
            {
                Console.WriteLine("Exception: {0}", e.Message);
                if (e.InnerException != null)
                {
                    Console.WriteLine("Inner exception: {0}", e.InnerException.Message);
                }
                Console.WriteLine("Authentication failed - closing the connection.");
                sslStream.Close();
                client.Close();
                return;
            }
            finally
            {
                // The client stream will be closed with the sslStream
                // because we specified this behavior when creating
                // the sslStream.
                sslStream.Close();
                client.Close();
            }
        }

No comments:

Post a Comment