Other posts in the series:
Hello folks! Today I'm starting with a series of a topics where I will cover how to use certificate enrollment APIs with Windows PowerShell.
Target audience for the series is (but not limited to): Systems Administrators, PKI administrators, geeks. While I'll try to keep things as simple as possible, there will be some low-level details (300+) which you can ignore if you don't understand them.
Prior to Windows Server 2008 and Windows Vista, certificate enrollment APIs were exposed by XEnroll COM interfaces which were not very powerful and fairly complex to use. You even can compare certificate request wizards in Windows XP and in Windows Vista. Windows Vista and Windows Server 2008 introduced a brandy new certificate enrollment experience with a set of powerful and flexible COM interfaces — CertEnroll. CertEnroll interfaces are described here: Certificate Enrollment API. And we will discuss about these APIs.
Let's define few key notes before you start. What is certificate request? Certificate request is a signed content that contains required information that is used by CA server to construct certificate. The following information is usually included in requests:
in fact, certificate extensions is not a dedicated field and is an attribute with the well-known OID = 1.2.840.113549.1.9.14.
Probably you heard these abbreviations like PKCS#10, PKCS#7, CMS, CMC? While previous information is clear and almost self-explanatory, these abbreviations are not. PKCS is Public-Key Cryptography Standards. There are a lot of such standards identified by numbers: PKCS#1, PKCS#1.2, PKCS#8, PKCS#9, PKCS#10, PKCS#12 and so on. CMS is Cryptography Message Syntax which provides a method for digitally signing data, digesting data, encrypting data, and authenticating data.
Talking about out subject, we will mostly deal with PKCS#10 — which is the only standard which represents actual certificate request. You can argue that you have a ton of CMC requests. In a fact, PKCS#7 and CMC are wrappers or containers. PKCS#7 message may wrap a PKCS#10 request and add additional information.
A common example of PKCS#7 container is Enroll On Behalf Of (EOBO). When you perform EOBO, actual request is generated by using PKCS#10. You may remember that EOBO requests are signed by enrollment agent. Enrollment agent's certificate and signature must be added to the request. Since PKCS#10 was not originally intended to handle such situations, the whole request is wrapped to PKCS#7 message. And everything becomes simple: actual PKCS#10 is added to PKCS#7 as a nested object. Enrollment agent's certificate is included as another nested object and the whole content is signed:
Actually PKCS#7 may contain a variety of cryptographic messages. For example, PKCS#7 containers are used by Key Archival. When you export archived key from CA database, exported blob is PKCS#7 message which wraps underlying encrypted object and additional information.
I think, there is enough of theory and in the next post we will start with practice. Keep alive!
to be continued…
Vadims-
Question about creating the PrivateKey object, why include the KeyUsage property in the HashTable when setting the KeySpec propery to 1 (XCN_AT_KEYEXCHANGE)?
I noticed that no matter what values I provided for KeyUsage, the value of said property in the instantiated object was always coming back as 5. I could change it after creation, but not as part of the creation. Then I read the documentation about KeySpec HERE and it provided the answer as to why this was happening:
"If you specify XCN_AT_KEYEXCHANGE, the KeyUsage property is set to XCN_NCRYPT_ALLOW_DECRYPT_FLAG | XCN_NCRYPT_ALLOW_KEY_AGREEMENT_FLAG."
Looking at the allowable values in the X509PrivateKeyUsageFlags enumeration listed HERE those two values are 0x1 and 0x4 respectively which sum to 0x5. Maybe this behavior was different back in 2012 when the article was originally written?
Alex
Disregard my comment here...somehow I managed to post it in Part 1 when it was intended for Part 2.
Post your comment:
Comments: