Setting up your own certificate authority on IIS7 using OpenSSL and securing your web api with client certificates

Creating self signed certificates isn’t really all that complicated, but it can be a little intimidating the first time you do it.

What are we trying to achieve?

1) A web api that is protected by client certificates hosted on IIS7.
2) A way to test it out from our browser.

Why?

Well, the use case is a web api that is not open to the public. We want to secure it such that only clients with the relevant certificates can access the api.

Pre-requisites

A web site that is protected by a valid SSL certificate
OpenSSL – I installed this on a 64bit version of Win7. Be warned, you need Visual C++ 2008 redistributable installed first. Be warned, yet again, that even though open ssl should install in 64bit mode, I couldn’t get it working so I just took the 32 bit. Hasn’t done me any harm….. 🙂

Gotchas

Testing your api from a browser like IE requires you to have a p12 client certificate to import into your personal certificate store. This one caught me out for a while.

Setting up your root certificate authority

First create a key pair that you will use to sign your certificate:

openssl genrsa -des3 -out root-ca.key 1024

Enter a strong pass phrase. This is the most vital pass phrase you will ever come up with – your root certificate is what you will use to sign client certificates and it is what will be installed on your IIS7. Basically, if someone gets your root cert and your passphrase for it, they can create their own client certificates and your web api will trust them. If you are super paranoid, disconnect the server that you are using to create this certificate from the network forever.

Now use your key pair to create and sign a root certificate:

openssl req -new -x509 -days 3650 -key root-ca.key -out root-ca.crt

We are generating a certificate that will be valid for 10 years. Make it shorter if you prefer. You’ll be prompted for your root key pair pass phrase and a bunch of info – fill it in, forget about the email address.

You now have a root certificate – this is what you will install on your web server. You will also use the root certificate to sign client certificate requests. Once the client certificate request has been signed by with the root certificate, any requests to your secured api with these client certificates will be implicitly trusted by your web server.

Make your webserver recognise your new certificate as a trusted Certificate Authority

Copy your root-ca.crt file to your webserver. Now, either double click the .crt file or if you prefer, open up a command prompt, “mmc” and follow these instructions:
* Click File->Add/Remove Snap-in
* Select “Certificates” and choose “Computer Account”.
* Expand “Trusted Root Certification Authorities” and right-mouse button, “Import”.
* Find your root-ca.crt and complete the import.

Create a website and require certificates

Create a new site or application in IIS, and then using the IIS manager, select the SSL Settings.

Make sure Require SSL is checked and that the Client Certificates option is set to Require.

If you try to browse your website now, you should get an access is denied message.

Create a client certificate request

You’ve got your root cert. You’ve installed it on your webserver. You’ve locked down your website. All that’s left to do is create the client certificate, install it in your certificate store on the client machine and away you go.

Open up the command prompt on your client machine which has openssl installed on it and:

openssl genrsa -out client-cert.key 1024

As above, we generate a keypair, and then create the certificate request:


openssl req -new -key client-cert.key -out client-cert.csr

Again, you’ll be prompted for all sorts of information – fill it in. When you put the organisation name and common name, use something different from your root certificate above so you can keep tabs on things in your personal certificate store.

Now, we use the client certificate request and create a client certificate, signing the certificate with our root certificate:

openssl x509 -req -day 3650 -CA pathtoroot-ca.crt -CAkey pathtoroot-ca.key -CAcreateserial -in client-cert.csr -out client-cert.crt

You’ll be asked for your root certificate pass phrase – you remember, the one I told you was super-important above.

Very cool, we now have a client certificate that IIS will trust because it has been signed by a root certificate that IIS trusts. Woohooo.

And here is the gotcha – If you simply install this .crt in your certificate store and try to browse your locked down website, it just will not work!

And here is the fix – see Internet Explorer needs the certificate to be in a specific format (pkcs12) for it to actually present the certificate to the webserver when you go a-browsing. Luckily, openssl allows us to fix this issue:

openssl pkcs12 -export -clcerts -in client-cert.crt -inkey client-cert.key -out client-cert.p12

Import your p12 certificate into your local personal certificate store

Again, double click the .p12 file, or go through mmc to import the p12 certificate and you should be away. Close IE, re-open and browse to your locked down website. You should be greeted with your website.

Aaaaah. That wasn’t so bad was it?

Meteor – This is what Asp.Net webforms could have been

Meteor ticks the boxes for a realtime web application; “one language”, “realtime as default”. It looks like it eases the path of development, automatically updating your front end templates when your data changes by implementing an subscription model.

I’m playing with it. Enjoying the feeling of coding *everything* in one language. It’s definitely a smoother process for a developer. And all of a sudden, I get a feeling of deja-vu. Someone else tried to do this before, didn’t they? Someone named Microsoft. I remember back when ASP.NET came out and we all frantically switched from the old-and-inferior-scripting based technology to the all-new-and-improved-web-forms based technology. The promise was the same. No more hacking away in VBScript (erm I mean Asp) for your backend and Javascript for your frontend. No, instead you could write C# in your magical code-behind pages and all but forget about frontend jiggery-pockery.

Web forms really tries. You define your HTML in an aspx file – these are basically your templates. Elements can be set to have a data source which will, for example, infill the data for the element from your database. Elements can also be set to post back to the server anytime they change, get clicked or what have you.

Postbacks are tied to events in the C# code behind pages which means that you can move all your logic server side. It makes developing for the web more like writing a traditional style windows client application.

Now the html controls, of course, responded to Javascript to make the page post back. But it wasn’t Javascript that the developer had to write. It was auto-generated. Awesome. Awesome. Awesome. One language….C#.

Of course it isn’t without it’s downside. The ViewState – a massive chunk of data that kept….state between page loads. That’s a nasty piece of work. Ingenious in it’s own way, but nasty when you bump up against it. And of course there is the enormous expense of re-rendering the entire page every time a select box that is wired up to post back to the server changes. Large Web forms applications can become sloooooow on the client side.

Meteor does something similar. Only now with baked in Ajax goodness, the applications actually feel useable. I wonder if Microsoft missed the boat? I wonder if they could have leveraged Web forms, or something like it, to be more like Meteor. Maybe they do now – Web forms is still alive and well, but I haven’t (thank goodness) had to use it in a very long time so I’m somewhat out of touch.

Where Microsoft really shine, in my opinion, is with their IDE. Wiring up server side events to a button click really is easy – just open up your aspx file (the template), double click on the button and Visual Studio will wire up the event for you and pop you into the server side event so you can write your code. On a large page, this really does take some pain away. You don’t make stupid typos wiring up your button because you don’t have to type it in. It know Vim is awesome and all, but this part of the developer experience, Microsoft really does well.

Somewhere in the future, I imagine the best of both worlds. Something like Meteor + Visual Studio all open sourced and ready to go.

Customising your json output in Ruby on Rails 3.2

You know how it goes; you’ve found yourself developing a little application to store and display nursery rhyme lyrics because you’re a good parent and want to get the words right for your tot when you sing to them and really, who can remember all seven verses of Twinkle Twinkle Little Star. So, you scaffold something like:

rails g scaffold NurseryRhyme name:string rhyme:text

And you’re away. Typing (or in fact cut’n’pasting from Project Gutenberg). All is bliss. You nail the improvised high note right at the end of Frère Jacques and your kid smiles from ear to ear.

So now, our story breaks down. Suffice it to say you can grab your data from your auto-generated json api. And it looks something like this:

[
{"name":"Humpty dumpty","updated_at":"2012-04-11T20:07:46Z","rhyme":"Humpty dumpty sat on a wallrnHumpty dumpty had a great fallrnAll the kings horses and all the kings menrnCouldn't put humpty together againrn","id":1,"created_at":"2012-04-11T20:07:46Z"},
{"name":"Jack and Jill","updated_at":"2012-04-11T20:08:18Z","rhyme":"Jack and Jill went up the hillrnTo fetch a pail of waterrnJack fell down and broke his crownrnand Jill came tumbling after","id":2,"created_at":"2012-04-11T20:08:18Z"},
{"name":"Baa baa black sheep","updated_at":"2012-04-11T20:09:02Z","rhyme":"Baa baa black sheeprnHave you any woolrnYes sir Yes sirrnThree bags fullrnOne for the masterrnAnd one for the damernAnd one for the little boy rnWho lives down the lane","id":3,"created_at":"2012-04-11T20:09:02Z"}
]

But you want to import it into an application, that for some reason expects the json to be somewhat differently described. You need to trash the ids and dates and change “rhyme” to “lyric”. Plus, you need each rhyme nested in a “LovelyRhyme” element. Baaa (baa black sheep).

And here’s the tldr; How to customise your json output. Start by opening up your model. You should have something like this:

class NurseryRhyme < ActiveRecord::Base
  attr_accessible :name, :rhyme
end

Add in a little code, as follows:

  def as_json(options={})
     { :LovelyRhyme => { :name => name, :lyrics => rhyme } }
  end

And that will render you this:

[
{"LovelyRhyme":{"lyrics":"Humpty dumpty sat on a wallrnHumpty dumpty had a great fallrnAll the kings horses and all the kings menrnCouldn't put humpty together againrn","name":"Humpty dumpty"}},
{"LovelyRhyme":{"lyrics":"Jack and Jill went up the hillrnTo fetch a pail of waterrnJack fell down and broke his crownrnand Jill came tumbling after","name":"Jack and Jill"}},
{"LovelyRhyme":{"lyrics":"Baa baa black sheeprnHave you any woolrnYes sir Yes sirrnThree bags fullrnOne for the masterrnAnd one for the damernAnd one for the little boy rnWho lives down the lane","name":"Baa baa black sheep"}}]

Awesome. Thanks for reading.

CheckBoxList Helper extension method ASP.NET MVC 3

Here’s a quick and dirty html helper for checkboxes in ASP.NET MVC 3. I’m sure Microsoft will eventually package one with the MVC framework just like they will a radiobuttonlist helper, but in the meantime, this one suits my purposes.

Of course, from a front-end point of view, a multi-select listbox is also an option, but checkboxes are a little more robust when it comes to user interaction. Nothing is more annoying as a user than forgetting to ctrl-click and having all your previous selections disappear.

You can probably find variations around, most that I’ve seen use a generic list of a custom class – mine uses a MultiSelectList instead, just for fun.

public static class NSCheckboxListExtensions
    {
        public static MvcHtmlString CheckboxListFor<TModel, TProperty>(
                    this HtmlHelper<TModel> htmlHelper,
                    Expression<Func<TModel, TProperty>> expression,
                    MultiSelectList listOfValues)
        {
            var metaData = ModelMetadata.FromLambdaExpression(expression, htmlHelper.ViewData);
            var sb = new StringBuilder();

            if (listOfValues != null)
            {
                foreach (var item in listOfValues)
                {
                    var id = string.Format("{0}_{1}", htmlHelper.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldId(ExpressionHelper.GetExpressionText(expression)), item.Value);
                    var name = htmlHelper.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldId(ExpressionHelper.GetExpressionText(expression));
                    var label = htmlHelper.Label(id, HttpUtility.HtmlEncode(item.Text));

                    var cb = new TagBuilder("input");
                    cb.MergeAttribute("type", "checkbox");
                    cb.MergeAttribute("name", name);
                    cb.MergeAttribute("value", @item.Value);
                    cb.MergeAttribute("id", id);
                    if (@item.Selected)
                    {
                        cb.MergeAttribute("checked", "checked");
                    }
                    sb.AppendFormat("{0}{1}</br>", cb, label);
                }
            }
            return MvcHtmlString.Create(sb.ToString());
        }
    }

Installing Valgrind on Shared Hosting

So you want to tinker with the goodness that is Valgrind, but you want to do it on a shared host? No problem.

# grab the latest valgrind
curl -O http://valgrind.org/downloads/valgrind-3.7.0.tar.bz2

#run an md5sum and check it matches the one listed on the downloads page
md5sum valgrind-3.7.0.tar.bz2

#unpack the puppy
tar -xjvf valgrind-3.7.0.tar.bs2

cd valgrind-3.7.0

#configure and pass in a directory you have permission to
./configure --prefix=$HOME/opt

#make valgrind
make

#install it - will end up in directory specified above
make install

Now you should have a bunch of files under your $HOME/opt directory. If you try to run it now, you’ll probably end up with an error something like

valgrind: failed to start tool 'memcheck' for platform 'blahblah-linux': No such file or directory

No problem – open up your .bash_profile (in your home directory) and add this in somewhere:

VALGRIND_LIB="$HOME/opt/lib/valgrind"
export VALGRIND_LIB

Finally, reload your .bash_profile – either log out and in again or simply

source .bash_profile

IIS 6 ASP.NET MVC3 Page Cannot Be Found 404 Errors

404
404 Page not found

This is a sneaky little devil, this one. If you’ve done everything right and your site still isn’t being served up correctly, try this little trick:

Step 1: Collect Underpants by opening up IIS Manager and right clicking on “Web Service Extensions”:

Web Service Extensions
Web Service Extensions

Step 2: Select “Allow all Web service extensions for a specific application”

Step 3: Select “ASP.NET v4.0.30319” from the drop down and click “Ok”:
Allow ASP.NET v4.0.30319

ASP.NET MVC 3 Type ‘xxx.xxx’ could not be found.

Here’s a strange little error that I can’t, for some reason, get to the bottom of. My code is reasonably standard and working perfectly on my development machine. When I deploy to an IIS6 box that I’ve set up to work with ASP.NET MVC 3, I keep getting

Type ‘xxx.xxx’ could not be found. Make sure that the required schemas are loaded and that the namespaces are imported correctly

The error is strange – it only seems to happen when I have slightly more complicated logic in my controller. I had my dbcontext in its own namespace and since this was the namespace that seemed to be referenced in the error, the fix for me was to move my dbcontext out of its own namespace and put it in the Models namespace. Not super neat and tidy, but it works.