Using client certificates in .NET part 8: working with client certificates in OWIN/Katana II

Introduction

In the previous post we started adding the necessary OWIN-related libraries to our Web API project: a couple of NuGet libraries and the Startup class. We publish our application to the local IIS and it doesn’t allow us to break the code within Startup.cs. We’ll soon see that we can still debug the OWIN components further down the call stack.

In this post we’ll add the necessary elements to a client certificate based authentication in .NET MVC with OWIN.

Read more of this post

Advertisement

Using client certificates in .NET part 7: working with client certificates in OWIN/Katana

Introduction

In the previous post we accomplished a couple of things. First we secured our demo Web API website with a client certificate. Second we enabled client certificates for it so that IIS doesn’t just ignore them. Finally we saw that the client certificate is also picked up in the customers controller when sent in code in a web request.

In this post we’ll start discussing how to add client certificate handling as an OWIN middleware component.

Make sure you open the demo Web API project in Visual Studio as an administrator.

Read more of this post

Using client certificates in .NET part 6: setting up client certificates for local test usage

Introduction

In the previous post we investigated how to attach a client certificate to the web request and how to extract it in a controller. We faced an issue that by default client certificates are ignored by IIS so we couldn’t actually read the certificate.

We’ll solve that problem in this post.

Read more of this post

Using client certificates in .NET part 5: working with client certificates in a web project

Introduction

In the previous post we looked at a couple pf examples on how to work with digital certificates in C# code. In particular we saw how to load certificates from a certificate store, how to search for and how to validate one.

In this post we’ll go through how to attach a client certificate to a web request and how to extract it in a .NET Web API 2 project.

Read more of this post

Using client certificates in .NET part 4: working with client certificates in code

Introduction

In the previous post we discussed how to install certificates into the certificate store. We looked at the tool mmc.exe and its certificate handler snap-in. We also inspected the imported certificates visually and verified that the client certificate is valid.

In this post we’ll see a couple of examples how to work with client certificates in code.

Read more of this post

Using client certificates in .NET part 3: installing the client certificate

Introduction

In the previous post we looked at two tools that help you create self-signed certificates: makecert.exe and pvk2pfx. Makecert performs the bulk of the certificate creation process and pvk2pfx is a packaging tool to build pfx files. Pfx files are easy to import into the certificate store. We also created a root certificate and derived a client certificated from that root. We therefore applied the idea of the chain of trust: if we trust the root then we also trust all its derived certificates.

In this post we’ll import the client certificate into the certificate store.

This process is very similar to importing the server side (SSL) certificate. We saw that process in this post.

certmgr and MMC snap in

The c:\windows\system32 folder includes two GUI tools for certificate management: certmgr.msc and mmc.exe. MMC.exe is a more general tool where you can import so-called snap-ins. Certificates have their own snap-in.

Run mmc.exe as an administrator. The following empty window will open:

Read more of this post

Using client certificates in .NET part 2: creating self signed client certificates

Introduction

In the previous post we went through a short introduction on client side certificates. We said that client certificates are used by web clients to strongly authenticate themselves. Client certificates can provide an extra step in the authentication process to tighten security.

In this post we’ll see how to create self-signed client certificates for testing using a tool called makecert.exe.

The process of creating client certificates on your local machine is almost identical to how we generated server side certificates in the series in this series.

Read more of this post

Using client certificates in .NET part 1: introduction

Introduction

Digital certificates play a crucial role in web security. If you work as a web developer then you’ve probably come across at least some security related project where you had to deal with certificates in code.

Certificates come in a couple of different versions depending on their function, the most pervasive of which probably being server side ones for SSL connections. We’ve gone through server side certificates in some detail before on this blog starting here. In this series we’ll concentrate on client certificates and see what role they can play in web security. Most of the material on server side certificates, especially the first 2 posts are also relevant for this discussion.

It’s important to note already now that you can combine a number of security levels and solutions in your projects:

  • You can have the traditional forms based authentication. You can read about it on this blog here and here.
  • Custom authentication. Here‘s a series dedicated to custom auth in Web API 2 as an OWIN/Katana component
  • Server-side certificates, see the reference above
  • Client-side certificates, to be discussed in this series
  • Various techniques related to cryptography, such as asymmetric encryption. You can check out the section called “Security and cryptography” on this page for inspiration.

…and there are probably many more options not listed here. The point is that these techniques can be combined, you are not restricted to just using one of them.

Read more of this post

How to enable SSL for a .NET project in Visual Studio

Say you have a .NET MVC or Web API project and you’d like to run it on SSL. In other words you’d like to start up the project on a URL similar to https://localhost:xxxx.

The first step is easy. You just select the MVC/Web API project name in the solution and locate the property called “SSL Enabled” in properties window:

Read more of this post

HTTPS and X509 certificates in .NET Part 5: validating certificates in code

Introduction

In the previous post we looked at some basic classes in the .NET framework that deal with X509 certificates. We saw how to load, inspect, install and remove certificates.

In this post we’ll continue working with certificates in code and concentrate on validation techniques.

Certificate validation in C#

The two most important objects in .NET that will help you validate a certificate are X509Chain and X509ChainPolicy.

The X509Chain object represents the chain of trust when checking the validity of a certificate. X509ChainPolicy fine-tunes how you’d like to validate the certificate, i.e. which criteria the chain of trust should fulfil.

Let’s see how the self-signed certificate we created before can be validated. Consider the following sample code:

private static void RunValidation()
{
	X509Store computerCaStore = new X509Store(StoreName.My, StoreLocation.LocalMachine);
	try
	{
		computerCaStore.Open(OpenFlags.ReadOnly);
		X509Certificate2Collection certificatesInStore = computerCaStore.Certificates;
		X509Certificate2Collection findResult = certificatesInStore.Find(X509FindType.FindBySubjectName, "mylocalsite.local", false);				
		foreach (X509Certificate2 cert in findResult)
		{
			X509Chain chain = new X509Chain();
			X509ChainPolicy chainPolicy = new X509ChainPolicy()
			{
				RevocationMode = X509RevocationMode.Online,
				RevocationFlag = X509RevocationFlag.EntireChain
			};
			chain.ChainPolicy = chainPolicy;
			if (!chain.Build(cert))
			{
				foreach (X509ChainElement chainElement in chain.ChainElements)
				{
					foreach (X509ChainStatus chainStatus in chainElement.ChainElementStatus)
					{
						Debug.WriteLine(chainStatus.StatusInformation);
					}
				}
			}
		}				
	}
	finally
	{
		computerCaStore.Close();
	}
}

You’ll recognise the part of this code where we open the certificate store and load the self-signed derived certificate. Note that the Find method will return a collection of X509 certificates but there’s no way to extract just a single element from a X509Certificate2Collection object. Even if you know that there’s only one certificate that fulfils the search criteria you’ll need to iterate over the collection.

Anyway, the validation part of the code starts within the foreach loop by constructing an X509Chain object. We then build a policy for the chain by specifying a couple of properties.

The RevokationMode enumeration will define whether or not we want to check the revocation list for this certificate: check it on-line, off-line or not at all. X509RevocationFlag will specify if we want to check the revocation list with or without the CA root. The X509ChainPolicy object has some more properties that will let you fine-grain the chain policy. The VerificationFlags enumeration will let you switch off parts of the chain, e.g.:

VerificationFlags = X509VerificationFlags.IgnoreInvalidName | X509VerificationFlags.IgnoreNotTimeValid

Normally you’d want to verify all properties so you’ll leave VerificationFlags untouched.

We then want to build the chain by calling the Build method with the certificate. If Build returns false then we know that something isn’t correct with the validation chain. So for each element in the chain elements we want to check the element status messages.

If you run the above code then you should get a validation error:

“The revocation function was unable to check revocation for the certificate.”

That’s because we specified that the online revocation list should be checked. However, there’s no revocation list anywhere on Earth that knows about our self-signed certificate. If we change the code to…

X509ChainPolicy chainPolicy = new X509ChainPolicy()
{
	RevocationMode = X509RevocationMode.NoCheck,
        RevocationFlag = X509RevocationFlag.EntireChain
};

…then the Build method passes as everything is fine with the certificate.

Open IIS for another test. We’ll use the IIS GUI to quickly create another certificate. Double-click on the following icon:

Certificates button in IIS

Then click on the following link in the right-hand panel:

Create self signed certificate link in IIS

Provide some friendly name for the certificate and click OK.

The certificate should appear in the Personal folder in the Certificates snap-in after a refresh. I called my certificate “iiscertificate”:

Certificate created in IIS visible in MMC snap in

If you double-click this certificate then you’ll see that it is valid. Now if we change the code back to online revocation list checking…

X509ChainPolicy chainPolicy = new X509ChainPolicy()
{
	RevocationMode = X509RevocationMode.Online,
        RevocationFlag = X509RevocationFlag.EntireChain
};

…and search for the IIS certificate…:

X509Certificate2Collection findResult = certificatesInStore.Find(X509FindType.FindBySubjectName, "andras1.Apica.local", false);

…then Build will return true, the IIS certificate is fully trusted even after the CRL is checked.

The certificate was also inserted into the Trusted Root Certification Authorities folder:

IIS certificate also listed among CA certificates

If you don’t see it then refresh the list by pressing F5.

Now remove the certificate from the trusted CA folder. Then go back to the Personal folder and double-click the IIS certificate. You should see that it is not trusted any more:

IIS certificate not trusted after removing from global CA store

If we run the same code again then Build returns false and we get the following validation error:

“A certificate chain processed, but terminated in a root certificate which is not trusted by the trust provider.”

The message clearly says that the root certificate is not trusted.

A more compact solution

The above code lets you fine-grain your chain building logic. There are specialised X509 validators in .NET that provide a more compact way of validating a certificate. Add the following references to your project:

References for X509 validators

The below example will build a validator that validates the chain of trust with all the validation flags turned on:

X509CertificateValidator chainTrustValidator = X509CertificateValidator.ChainTrust;
try
{
	chainTrustValidator.Validate(cert);
}
catch (Exception ex)
{
	Debug.WriteLine(ex.Message);
}

The Validate method will throw an exception if the validation fails. The untrusted IIS certificate will give the following exception message:

“The X.509 certificate CN=andras1.Apica.local chain building failed. The certificate that was used has a trust chain that cannot be verified. Replace the certificate or change the certificateValidationMode. A certificate chain processed, but terminated in a root certificate which is not trusted by the trust provider.”

That’s all folks about the basics of certificate validation in .NET.

This was the last post in this HTTPS basics series.

You can view the list of posts on Security and Cryptography here.

Elliot Balynn's Blog

A directory of wonderful thoughts

Software Engineering

Web development

Disparate Opinions

Various tidbits

chsakell's Blog

WEB APPLICATION DEVELOPMENT TUTORIALS WITH OPEN-SOURCE PROJECTS

Once Upon a Camayoc

Bite-size insight on Cyber Security for the not too technical.

%d bloggers like this: