Archive for the ‘Security’ Category

SignedXml.CheckSignature() can’t find the certificate for verification

No Comments »

The System.Security.Cryptography.Xml namespace has been there since the dawn of time, and the look and feel of the API is rough at best. To top that, the MSDN documentation isn’t really something to lean on either, and it’s been a long, long time since I last tried to get acquainted with it.

I’ve done some work to integrate Windows Identity Foundation (WIF) with the ESB we’re using at work, and I wanted to implement message security (encryption and signing). Since the messages are XML-based, and that I really didn’t want any homegrown security solutions, I found it natural to use EncryptedXml and SignedXml from the aforementioned namespace to do the job. My weapon of choice was x509 certificates and the proof-of-possession key (AES-256-CBC) from the SAML 1.1 token issued by the STS, and by tweaking the EncryptedXml configuration, I managed to massage the information about the x509 key down to a bare minimum (to keep the message size down).

Now, creating the detached signature on the publisher side was a no-brainer as well, but on the other end of the “cable” I wasn’t able to verify the signature. I tried “everything”, but to no avail. I bugged Barry Dorrans (@blowdart) on Twitter, since he’s as a guy that knows “a thing or two” about .NET Security. Barry had a couple of pointers, but none that resolved my issue.

So, weaponed with the .NET Reflector and some moral support from Barry via email, I started to dig into the System.Security assembly. It reeks of all sorts of code smells, and it took a while before I found the piece of information I was looking for:

Using SignedXml.CheckSignature() w/o sending in an X509Certificate2 instance explicitly, will only look in Current User\Other People or Local Machine\Other People. Be aware that Other People is an alias for AddressBook too.

Configurable PrincipalPermission attribute


I while ago, a question came up in the WCF Forum about configuring the role and/or user name properties of the PrincipalPermission attribute. As I answered, it is possible to create a custom version of the attribute (deriving from the CodeAccessSecurityAttribute, since the PrincipalPermission attribute is sealed) and pull the property values from the {web|app}.config file.

I implemented a solution for this about a year ago and planned to put up a blog post about it, but it never made it out to the public (the main cause is probably that I experienced a blog-block period of my life :-P).

The same requirement may be a viable solution i system I’m currently working on for a customer, so I dug through my archives and found the old code.

I’ve polished it a bit made it available here under the Apache License 2.0.

The extended version, PrincipalPermissionEx can be used in two modes; either as a “normal” derivable PrincipalPermission attribute or an attribute that uses the configuration system (or a combination of both).

Instead of using the generic PrincipalPermission attribute, you’ll make derived version for each system role with a sensible name – making it more reliable and resistant to typos; e.g.

public void PrivilegedOperation(…)

instead of:

[PrincipalPermission(Role = "MYDOMAIN\SuperUsers")]
public void PrivilegedOperation(…)

Take a look at the supplied sample code to see how this is implemented.

The usage of PrincipalPermission-based authorization is useful in a variety of scenarios; it can be applied to WCF services, ASP.NET & Smart Client applications. Note that if you put the user name/role in the configuration file, you will need to ensure that the file is locked down with an appropriate ACL to prevent tampering by malicious users. This might not apply to solutions hosted on a locked down server (i.e. IIS-hosted web applications and services) but for smart / desktop clients where the user might have higher privileges to files on the local file system it is necessary to be aware of this.

As always, feedback is welcome :-)

kick it on