Today I am going to talk a little bit about certificate mapping. This topic is somewhat related to my last post about disabling mapping, but you once you disable the UPN mapping what type of mapping is available to you?
The image below ( stolen from MSDN ) outlines the mapping of user accounts to smartcard logon. The easiest ( and most common) one to understand is the SAN to UPN mapping, where the SAN in the smartcard certificate matches a username’s UserPrincipalName in the AD.
I have noted in green – the ones which are correct and boxed the incorrect ones in red. Oddly enough in one place it says “Issue,Subject, and serial” and in the other it says “X509:<I><SR>” ( which is correct ) and not “X509:<I><S><SR>” ( which is incorrect ) .
The more complex, and less documented ( or documented incorrectly ) are as follows:
The only one which is kind of tricky ( other than actually knowing the correct identifiers ) is the Serial number. Here is an example of a cert and serial:
When dealing with certificates there is a CERT_CONTEXT data structure which has the CERT_INFO structure which contains the information of a certificate. The specific field which is looked at is ‘SerialNumber’. MSDN describes serial number as follows:
A BLOB that contains the serial number of a certificate. The least significant byte is the zero byte of the pbData member of SerialNumber. The index for the last byte of pbData, is one less than the value of the cbData member of SerialNumber. The most significant byte is the last byte of pbData. Leading 0x00 or 0xFF bytes are removed. For more information, see CertCompareIntegerBlob.
Note the text in red - this basically means that the last byte is the first byte returned – in other words, reversed. So the serial number as seen in the screen shot above 10e8bd03000000000032, will be read as 32000000000003bde810.
And this (32000000000003bde810 ) is what the code will be looking for, so this is what needs to be entered in the altSecID field.
Alrighty then – now that that’s all cleared up, on to other things.
NOTE: I removed the semicolons from the examples ( they are left in from the cut and paste from LDP.EXE -- they now reflect what needs to be manually inserted as the literal value for altSecID -- like "X509:<I>DC=local,DC=dod,CN=SpatDoD Root CA<S>CN=gman"
What does the "Client certificate does not need to meet NT_AUTH policy" notation in the flowchart mean? If the cert doesn't need to meet the NTAuth policy, what policy does it need to meet?
It means that the issuing CA of the cert does not need to be in the NTAuth store. See support.microsoft.com/.../295663 for more info on that store
I love this method. We have combined this with the UseSubjectAltName=0 registry key on the DCs to allow us to use Smart cards issued from external CA’s without having to trust the CA’s (and having to trust that they aren’t creating a Certificate with the SAN of my enterprise admin. Why would we do this? Think government.
I am using the X509:<SHA1-PUKEY> method. But wanted to leave one warning. We set these values programmatically as part of our identity system. But in testing I would copy a certificates thumbprint into notepad. Then use search and replace to get rid of the spaces, put a X509:<SHA1-PUKEY> in front. And then put the whole thing into the altSecurityIdentities attribute of the test user.
And then get really confused because it didn’t work.
Everything looks right. And it works when I do it programmatically.
It turns out that if you look at it with a dsquery command (I was searching to see if anyone else had a matching hash.
You get: X509:<SHA1-PUKEY>?2BE1954D50282082B54065F356868127AC44B60A
Notice the ? before the hash?
That’s actually a control character. You don’t see it in the graphical interface. But if you try to delete it it’s there.
Once I removed the hidden ? everything worked fine (and I could stop pulling out my hair).
This isn’t an issue with certificate mapping, just something odd about how I put the value in by hand. Just wanted to put this here in case other people have similar problems.
To get the right SerialNumber of a certificate, you can use the command : certutil -dump -v myCert.cer
Serial Number: 61157eee000000000011
11 00 00 00 00 00 ee 7e 15 61
Then you have your AltSecId :
Ahh thanks Gaubert - never noticed that certutil dumped that format
In an X509 certificate the issuer and subject can contain CRLF (Carriage Return Line Feed) characters. When mapping a user to a certificate using subject and issuer fields that contain this sequence of characters, you need to replace them with the "," character (msdn.microsoft.com/.../hh536384.aspx).
Interestingly, Microsoft's Active Directory Users and Computers tool does not replace CRLF with a comma in the altSecurityIdentities value which results in an invalid mapping. I guess that would be a bug in that tool.