Skip to content

Making a Windows smartcard login certificate with OpenSSL.

, 1 min read

This post is from 2012. Some details, links, and recommendations may be out of date.

I use OpenSSL for testing certificate related stuff all the time, while using its test clients as a administrative tool can require contortions sometimes it’s very useful thing to have in my toolbox.

Today I needed to throw together a certificate for Windows smartcard login, a valid Windows Smart Card Login certificate has the following attributes:

  1. Is issued by an CA that is trusted as an Enterprise CA
  2. Is issued by a CA that has the “Smartcard Logon” EKU (1.3.6.1.4.1.311.20.2.2)
  3. Has the “Smartcard Logon” EKU
  4. Has the “Digital Signature” “Key Usage”
  5. Has the principal name of the subscriber in the SubjectAltName extension as a UPN (1.3.6.1.4.1.311.20.2.3)

With that background how does one do this in OpenSSL? Well lets focus on the last 3 (3,4,5) as they are about the subscriber certificate.

To create this certificate you would create an OpenSSL section that looks something like this:

[ v3_logon_cert ]

# Typical end-user certificate profile

 

keyUsage = critical, nonRepudiation, digitalSignature, keyEncipherment

extendedKeyUsage = critical, clientAuth, emailProtection, msSmartcardLogin

basicConstraints = critical, CA:FALSE

 

subjectKeyIdentifier = hash

authorityKeyIdentifier = keyid,issuer

 

authorityInfoAccess = @customerca_aia

 

subjectAltName = otherName:msUPN;UTF8:john.doe@example.com, email:john.doe@example.com

 

certificatePolicies=ia5org,@rootca_polsect

There are a few other “reference” sections you can find the INF file I used these additions with in my script for testing Qualified Subordination.

Hope this helps you too,

Ryan

Identity & AuthenticationPKI & CertificatesEngineering & Code#OpenSSL#Smartcard Logon#Smartcards

Use and to move through the timeline.

5 comments

Comments are closed. These were left on the original WordPress site.

  1. From Erwann :

    For more clarity, I'd replace the "1.3.6.1.4.1.311.20.2.2" by "msSmartcardLogin" in the extendedKeyUsage list, and the "1.3.6.1.4.1.311.20.2.3" by "msUPN" in the subjectAltName declaration.

    I also usually write the subjectAltName like this:
    subjectAltName = otherName:msUPN;UTF8:$ENV::UPN, email:$ENV::UPN

    Before calling the certificate creation script, just add an environment variable named UPN.
    The main drawback I found is that when the config file is loaded, even if the section containing the extension isn't used (v3_logon_cert here), the $ENV::UPN is evaluated and must not fail, therefore the UPN environment variable MUST exist (just set a dummy value).

  2. Based on Erwann's comment Iused the two variables vs using the explicit OIDs I did not know OpenSSL had these configured. I did not include the $ENV approach as my script isnt doing this uniformly at this time.

  3. Hello,

    I want to create a self signed certificate with openssl and contain the principal name(1.3.6.1.4.1.311.20.2.3).

    Using the steps from here it fails to accept the certificate on my apache server. It fail with
    Certificate Verification: Error (18): self signed certificate
    SL Library Error: error:14089086:SSL routines:ssl3_get_client_certificate:certificate verify failed

    Any suggestions?
    Gabi

    1. Gabi, you will have to configure apache to trust your self-signed certificate like it was a CA. See : http://www.cafesoft.com/products/cams/ps/docs32/admin/ConfiguringApache2ForSSLTLSMutualAuthentication.html

  4. Hi,
    For better clarity, I recommend replacing “1.3.6.1.4.1.311.20.2.2” with msSmartcardLogin in the extendedKeyUsage list, and 1.3.6.1.4.1.311.20.2.3 with msUPN in the subjectAltName declaration.

    I usually format the subjectAltName as:
    subjectAltName = otherName:msUPN;UTF8:$ENV::UPN, email:$ENV::UPN`

    Before running the certificate creation script, set an environment variable named UPN. The main caveat is that when the config file loads, even unused sections (like v3\_logon\_cert) still evaluate `$ENV::UPN`. Therefore, the UPN variable must always exist—even a dummy value works. https://ssoidportal.org/