ScottGu just pushed out an article on Self-Signed certificates on IIS 7.0 which reminded me to blog about certificates and CardSpace.

One of the problems in getting started with CardSpace is it's reliance on certificates. The relaying party needs an SSL certificate and the STS needs a certificate. MS distribute their test certificates for Fabrikam and Adatum in the CardSpace samples, but what if you don't want to pretend to be You end up making your own.

However there's a problem. The STS sample as delivered checks the CRL when it decrypts the RST. Generally self signed certificates, such as those generated using the IIS7 interface or via SelfSSL from the IIS Resource Kit (documented in KB article 840671) do not have CRLs and so the sample STS code will die horribly.

So how do you check if you have a CRL, and if it is available? You look at the certificate properties;
certificate properties

The image above shows the details for the Fabrikam certificate. You will notice the highlighted field, CRL Distribution Point, and the details shown. This shows you the URL that CardSpace will check for the revocation list. If this is unreachable, or if (in the case of self signed certificates it is blank) then the validation of the RST will fail, you may well see exceptions in the form of

System.IdentityModel.Tokens.SecurityTokenValidationException: The X.509 certificate chain building failed. The certificate that was used has a trust chain that cannot be verified. Replace the certificate or change the certificateValidationMode. The revocation function was unable to check revocation for the certificate.

So what can you do? Simple; turn the CRL checking off. This requires a code change. In the constructor for the simple STS a code line creates an instance of SamlSecurityTokenAuthenticator, which takes a number of Token Authenticators as its parameter. One of those will be the X509SecurityTokenAuthenticator. The constructor for this class has a number of overloads which allow us to override the validator used to check a certificate. Using this we can turn CRL checking off (or indeed write our own validator which could, for example, only accept SSL certificates signed by an issuer we trust).

So in order to utilise your self signed certificate you need to override the validator. The easiest way is to not have one at all. Change the code that instantiates the SamlSecurityTokenAuthenticator to be

SamlSecurityTokenAuthenticator authenticator =
  new SamlSecurityTokenAuthenticator(new List<SecurityTokenAuthenticator>(
    new SecurityTokenAuthenticator[]{new RsaSecurityTokenAuthenticator(),
      new X509SecurityTokenAuthenticator(X509CertificateValidator.None)}), MaximumTokenSkew);

and CRL checking (and pretty much every other type of X509 check) will stop, and your self signed certificate will be usable.

Obviously this is not something you want to do in release code; consider wrapping the line with #if DEBUG to stop it being released that way by accident.


Technorati tags: ,