Tag Archives: X509

Using CAPICOM on Windows x64

So CAPICOM was one of the project I was responsible for while at Microsoft, its been discontinued but I always find it useful – it is kind of a Swiss Army knife for CryptoAPI certificate stores when paired with its VBS samples.

One of it’s problems is we never shipped with x64 bit version, you can do similar things with PowerShell and the .NET classes (this is why it was discontinued) but I still find this the quickest way to do stuff sometimes so I keep it in my toolbelt.

Here is what you need to know to make it work:

  1. Windows can run 32bit things in 64bit environments.
  2. You cannot have a 64bit thing call a 32bit thing.
  3. Windows ships a 32bit cmd prompt.
  4. Windows ships a 32bit regsrv32.

To use CAPICOM you need to:

  1. Download CAPICOM – http://www.microsoft.com/en-us/download/details.aspx?id=25281
  2. Install CAPICOM
  3. Register CAPICOM
  • Open an administrative command prompt
  • cd to “C:\Program Files (x86)\Microsoft CAPICOM SDK\Lib\X86”
  • copy CAPICOM.DLL %windir%\syswow64
  • %windir%\syswow64\regsvr32.exe %windir%\syswow64\capicom.dll
  • “exit” the command prompt

So what can you do? There are lots of things, tonight I used it to enumerate the extensions included in a PFX file, you can do this with OpenSSL too by looking at the ASN.1 but this way you get some of the Microsoft specific stuff expanded out to human readable things.

I should note that its old, its unsupported and it may have vulnerabilities in it — as such I unregister it when its not in use and I recomend you do the same.

Hope this helps someone,


RESTful X509, CRL and OCSP to JSON web-service

So the other day I got a bee in my bonnet and decided I wanted a simple web service I could pass common day X509 objects to and get a JSON representation of that same object. We had recently done a project in Go at work and we found it quick, robust and easy to build, additionally it looks it’s certificate support decent enough so I thought it was the way to go.

In comes Freelancer, I threw my rough (and that’s kind) goals in a paragraph or two and a few days later I had a bid proposal from an engineer in Chicago — Eli Frey.

Based on a quick review of the Go documentation for cryptography it looked like this was going to be pretty straight forward, and for the most part it was – we did find that there were a few cases that just were not possible without more work than we wanted to put in, I will summarize those a little later.

As things progressed we also decided to add the ability to get an X509 certificate from the interface. Normally one would do this by generating a PKCS #10 request (CSR) and sending it to a CA for processing, unfortunately one of those cases that required more work than we wanted to put in was parsing PKCS #10s since go does not as of yet support it. With that said a CSR is really just a self-signed certificate we just did the same thing with a self-signed X509 certificate request.

So how do these interfaces work? Here are a few examples of how you would call them:


Decode a PEM encoded X509 certificate
curl  -F “[email protected]” “api.x509labs.com/v1/x509/certificate?action=decode&inputEncoding=PEM”
Decode a DER encoded X509 certificate
curl –fail -F “[email protected]” “api.x509labs.com/v1/x509/certificate?action=decode&inputEncoding=DER”
Request and issue an X509 certificate based on a DER encoded self-signed certificate with one hostname
openssl genrsa -out request.key 2048
openssl req -config openssl.cfg -subj “/CN=www.example.com” -new -x509 -set_serial 01 -days 1 -key request.key -out request.cer
curl –fail -F “[email protected]” “api.x509labs.com/v1/x509/certificate?action=issue&hostnames=bob.com&inputEncoding=DER”
Request and issue an X509 certificate based on a PEM encoded self-signed certificate with one hostname
openssl genrsa -out request.key 2048
openssl req -config openssl.cfg -subj “/CN=www.example.com” -new -x509 -set_serial 01 -days 1 -key request.key -out request.cer
curl –fail -F “[email protected]” “api.x509labs.com/v1/x509/certificate?action=issue&hostnames=bob.com&inputEncoding=PEM”
Request and issue an X509 certificate based on a PEM encoded self-signed certificate with several hostnames
openssl genrsa -out request.key 2048
openssl req -config openssl.cfg -subj “/CN=www.example.com” -new -x509 -set_serial 01 -days 1 -key request.key -out request.cer
curl –fail -F “[email protected]” “api.x509labs.com/v1/x509/certificate?action=issue&hostnames=bob.com,fred.com&inputEncoding=PEM”
Decode a set of PEM encoded X509 certificates
curl –fail -F “[email protected]” “api.x509labs.com/v1/x509/certificates?action=decode&inputEncoding=PEM”
Decode a PEM encoded X509 crl
curl –fail -F “[email protected]” “api.x509labs.com/v1/x509/crl?action=decode&inputEncoding=PEM”
Decode a DER encoded X509 crl
curl –fail -F “[email protected]” “api.x509labs.com/v1/x509/crl?action=decode&inputEncoding=DER”
Decode an OCSP response
openssl ocsp -noverify -no_nonce -respout ocsp.resp -reqout ocsp.req -issuer ca.cer -cert www.cer -url “http://ocsp2.globalsign.com/gsextendvalg2” -header “HOST” “ocsp2.globalsign.com” -text
curl –fail -F “[email protected]” “api.x509labs.com/v1/x509/ocsp?action=decode&type=response”



So even though this started out as a pet project I actually think these interfaces are pretty useful, the largest limitations of these interfaces are:


  1. Not every element of the structures is included in the JSON serialization, for example AIA, CDP, Name Constraints and Certificate Policy are not present (most extensions actually); this is because there is not a decoder for them in GO.
  2. ECC based certificates are not supported, this is because at this time the released version of GO doesn’t include support for these.
  3. Only issuing certificates based on self-signed X509 certificates are supported, this is as I mentioned a result of the lack of support for the PKCS #10 object in GO.
  4. No OID is specified for the Signature algorithm, this is because it’s not exposed in GO.
  5. Only one certificate profile is supported when using the issue action, this is mostly due to limitations in go (time was also a factor) for example the lack of AIA and OCSP support mean these regardless of CA key material these certs are just good for playing around.
  6. No user supplied information is included in the generated certificate, this was really just a function of time and building a proper workflow that would not be valuable without addressing other go limitations.
  7. Requested certificates that contain RSA keys must have a bit length of at least 2048 bits in length, just a best practice.
  8. Requested certificates will only be issued if the submitted certificate contains a self-signed certificate with a valid signature, this is to ensure the requestor actually holds the private key.
  9. Not all SAN types are supported, only DNSnames really again a limitation of GO.
  10. Certificates with name constraints are not supported, again a limitation of GO.
  11. Not possible to put EKU in certificates, again a limitation of GO.



  1. ResponderID is not specified, this is because it’s not exposed in GO.
  2. Only responses with a single response are supported, this is because more that response is not exposed in GO.
  3. No OCSP extensions are supported, this is because this is not exposed in GO.
  4. Only responses are supported, this is because the request is not supported in GO.


Here are some things you might want to know about these interfaces:

  1. Both X509crl and X509ocsp default to DER but you can specify PEM in the encode query string parameter.
  2. X509Certificate defaults to the PEM encoding but DER is supported via the encode query string parameter.
  3. X509Certificates defaults to PEM encoding but DER is not supported.
  4. X509Certificates takes the file you might use in Apache or Nginx to configure which certificates to send — a concatenation of PEM encoded certificates.
  5. All interfaces use HTTP error codes to report issues.
  6. I can’t propose they will always be up and available, be reliable, performant or accurate 🙂

All in-all I think this was a fun project and I really enjoyed working with Eli and Freelancer (though its mail client is awful and the site needs some UI work).


How to tell DV and OV certificates apart


There are in essence three kinds of SSL certificates: Domain Validated, Organization Validated and Extended Validated. I am not going to write about the differences here it seems that there are hundreds of articles on this topic on the Internet.

What I think has not been given sufficient coverage is how one is able to look at a certificate and determine what type it is.

One would think that this would be easy; In theory if nothing was explicitly stated it would be a Domain Validated certificate (since it is the weakest validation), otherwise someone would put something in the certificate making it clear that the certificate was either Organization Validated or Extended Validated.

Unfortunately it’s not this simple, the main issue being the historic lack of coordination within the CA industry.

Each Certificate Authority (CA) has its own unique practices relating to how they mark their certificates so with the existing deployed certificates there is no singular rule or approach can be used to definitively know what level of validation was done for a given certificate.

Thankfully it looks like that this problem is betting better thanks to the adoption of the Baseline Requirements but in the meantime we have to make do with heuristics.

Deterministic Approach

Today the only way to know with confidence that a certificate is of a specific type is to know the practices of each CA.

In X.509 the way an issuer is supposed to express something like this is via the Certificate Policies extension which is defined in RFC 5280.

This allows a CA to express a unique identifier (an OID) in their certificates that maps to a document that describes its practices associated with this certificate. This identifier can be used programmatically to do make trust decisions about a certificate or to differentiate the user interface in an application based on what type of certificate is being used.

This is exactly how browsers today can tell if a certificate is an Extended Validation (EV) certificate. In essence they have some configuration that says “I trust GlobalSign to issue EV certificates, when a certificate is presented to me from them that has this policy OID show the EV user experience”.

The Baseline Requirements use the same approach defining identifiers for Domain Validated and Organization Validated certificates, these are:

Type Policy Identifier
Domain Validated
Organization Validated


Having these identifiers takes us a long way towards our goal of deterministic evaluation of certificate issuance policy — that said not all CAs have adopted them which is technically alright since the Baseline Requirements do allow them to use their own Policy Identifiers.

Heuristic Approach

Since the Baseline Requirements were only established this year it will take some time for the existing install base of certificates to be re-issued to use these Policy Identifiers called about above. This doesn’t mean you can’t tell the certificates apart today, it does mean it is quite a bit messier though.

Here is some pseudo-code provided to me as an example from a friend that they used in one of their projects:

type = null;

if (cert is self-signed) then

     type = SS;        /* SS = Self-signed */

else if (cert was issued by a known “CA”) then

     type = DV;  /* DV = Domain Validation */ else if (cert contains a known EV Policy OID) then

     type = EV;  /* EV = Extended Validation */ else if (cert “Subject O” and “Subject CN” are the same or “Subject OU” contains “Domain Control Validated”) then {

     if (cert contains no Subject L, St or PostalCode) then

         type = DV;


else if (cert “Subject O” is “Persona Not Validated” and the cert’s issuer was StartCom

     type = DV;

if (type is null)

     type = OV;

This logic is not comprehensive but should work well enough for most uses.


Unfortunately today there is not a deterministic way to tell if a certificate was Domain or Organization Validated, that said things are changing and within a few years hopefully it will be possible.

In the mean-time there are heuristics you can use that help tell these types of certificates apart.

Windows XP and Name Constraints

Recently I blogged about how Windows XP processes Name Constraints a little different than the RFC specifies — with the help of a friend I have a good set of examples of what would work and what would not work that illustrate what it does.

Assuming our Subject was:

C = US;S = Washington;L = Kirkland;O = GlobalSign;CN = globalsign.com


And that our Constraint was:


     [1]Subtrees (0..Max):

          DNS Name=globalsign.com

We would see different results when validating a certificate on XP than we would on a later version of Windows.

Notice we did not include any directoryName attributes? That is supposed to mean that there is no constraints on the directoryName. On Windows XP however if you include a directory name in the subject there MUST be at least one Directory Name attribute in the RDN to match against otherwise it will not pass its Name Constraints check.

So if we instead made our constraint:


     [1]Subtrees (0..Max):

          RFC822 Name=globalsign.com

     [3]Subtrees (0..Max):

          Directory Address:

          C = US

          S = Washington

          L = Kirkland

          O = Globalsign



A certificate with the following subject would match:

  • An empty DN, no RDNs
  • C = US
  • C = US;S = Washington
  • C = US;S = Washington;L = Kirkland
  • C = US;S = Washington;L = Kirkland;O = Globalsign
  • C = US;S = Washington;L = Kirkland;O = Globalsign;CN = globalsign.com
  • C = US;S =””;L = Kirkland;O =””;CN = globalsign.com

When XP processes the RDNs it starts with the first and progresses from there. You can’t skip an RDN. If an RDN is present it must match the entire RDN value or be empty.

As such the following wouldn’t match in our example:

  • S = Washington (Skipped the first RDN)
  • C = US;L = Kirkland (Skipped the second RDN)
  •  C = US;S = Washington;L = Kirkland;O = Globalsign Development Center (partial “O” value).

The prior blog post on this topic I described before talks about how an enterprise can work around this behavior (by setting some registry keys) but a public certificate issuer can too, for example by inserting just one RDN value and ensuring the subordinate CA issues with that RDN value in its certificates.

This way a site can have the flexibility it wants to change its directory structure without re-issuing the certificate containing the Name Constraints.


XP and the undefined Name Constraints

So Qualified Subordination is super important, it’s what really allows us to implement Least Privilege in PKI hierarchies.

This concept is implemented in Windows XP as of SP3 because there was a back-port of the Windows Vista certificate chain validation logic included in SP3.

With that said there is at least one difference between VISTA, Windows 7 and Windows 8 chain validation logic in the way Name Constraints is processed.

More precisely once it sees a name constraint applied to a certificate it requires that only the names and scope of names expressed in the Name Constraint extension are present in the certificate.

For example, lets say I restrict a CA to issue only for the DNS domain of example.com, once this is put in the certificate I can no longer include “O=Example Company Name” in the subject of the certificates issued by that CA.

If I want the CA to be able to include that organization name in the certificates it issues I have to express that using the DirectoryName constraint.

This is not compliant with the RFC and was later changed so VISTA, Windows 7 and Windows 8 do not behave this way.

That said you can change the behavior in XP by tweaking the following registry key:


This is a bitmask represented as a REG_DWORD, it is defined in WinCrypt.h as but the flag following definitions will tell you how to tweak this one part:


// Set the following flag to disable checking for not defined name

// constraints.


// When set, CertGetCertificateChain won’t check for or set the following



// In LH, checking for not defined name constraints is always disabled.


You could deploy this behavior via group policy if you did not want the behavior, it’s probably easier to just include the names you are willing to let the CA issue to but changing the behavior in this way in an option for some.

Hope this helps,


Updated my script for Qualified Subordination testing

I did some testing with ECC and SHA2 today and as such decided to update my script for testing Qualified Subordination to make it easy to get certificates that use these algorithms.

There are now several configurable variables in makepki.bat:

  • key = possible values include RSA or ECC
  • rsasize = possible values include 1024,2048,4096
  • eccsize= possible values include secp256r1,secp384r1,secp521r1
  • hash = possible values include sha1,sha256,sha384,sha512

With these its very easy to get chains to do testing with that include these algorithms, have fun.


Using ECC keys in X509 certificates

Recently the CAB Forum published a document called the Baseline Requirements for the Issuance and Management of Publicly Trusted Certificates.

This document was authored by both browsers and public CAs and is used by the browser vendors to mandate what minimum technical requirements need to be met for inclusion into their “Root Programs”.

One of the changes specified in this document is that subscriber certificates (aka SSL certificates) containing RSA keys must have a bit length of 2048. This is a change for a lot of CAs (GlobalSign had made this change some time ago) one that has implications to server operators.

Just take a look at the Crypto Plus Plus Benchmarks to see how much more expensive 2048 bit RSA. For most users this additional computational cost won’t be an issue but in some cases customers may need to increase the computing power they allocate for SSL establishment.

But what alternatives do you have? Well there is one, certificates with ECC keys; using these have the potential to significantly decrease the computational costs for SSL negotiations (even over your old 1024bit RSA certificate) but they come at a significant penalty – compatibility.

ECC was not supported in Windows until VISTA which was released in 2009, this basically means 100% of the XP clients out there (around 29% of the browsers on the internet as of July 2012) would be unable to establish a session with your website if you switched exclusively to ECC.

This is important for more than just Internet Explorer users since even Chrome and Safari use CryptoAPI for certificate validation when on Windows.

This would mean these users would see something like this:


That is pretty scary, so how long until we can use this more broadly? It’s hard to say there is a good article titled “The developers guide to browser adoption rates” that sheds some light, that and the historic gs.statcounter.com results. Based on these unless there is a sudden change (which is possible these machines are getting pretty old) I would assume that we have around 4-5 years of XP out there yet.

Hope this helps,


Using SHA2 based signatures in X509 certificates

It’s been an exciting decade for cryptography; as a result we see smaller key sizes and weaker algorithms getting deprecated.

One driver of such things is the U.S. Federal Government, specifically NIST.

One example of this would be NIST Special Publication 800-131A which disallows the use of SHA1 after December 2013. What this means is if you are in the U.S. Federal Government or you work with them you may have to revise your technology strategy to use SHA2 in its place.

But what if you don’t have any policy mandate forcing you to do this switch? Well it’s a good idea but it has consequences too, namely compatibility.

You see SHA2 was published in 2001 so anything produced before then will not support it. The most notable example is Windows XP which as of July 2012 has about 29% presence on the Internet.

This is important for more than just Internet Explorer users since even Chrome and Safari use CryptoAPI for certificate validation when on Windows.

The good news is that XP SP3 which was released in 2008 added support for this new suite of hash algorithms, that begs the question how many of those XP machines have XP SP3?

Unfortunately I don’t have any public references that can answer this question but let’s that 85% of all XP machines on the Internet have gotten this update (I have good confidence in this number) that means that 15% of those 29% would not be able to connect to your server over SSL if you used SHA2.

This would mean these users would see something like this:



That is pretty scary, so how long until we can use this more broadly? It’s hard to say there is a good article titled “The developers guide to browser adoption rates” that sheds some light, that and the historic gs.statcounter.com results. Based on these unless there is a sudden change (which is possible these machines are getting pretty old) I would assume that we have around 4-5 years of XP out there yet.

Hope this helps,


How to get your own OID arc

X509 uses Object Identifiers (OIDs) to uniquely identify things, for example one assigns a OID to their Certificate Policy Statements (CPS) so that it is possible to programmatically detect if a certificate meets a specific policy.

OIDs are managed as a namespace, this prevents “collision”. As such one needs to request an OID be assigned to them.

The “arc” part comes when you get your OID, you can assign any number you want at the end of your OID. For example, one might be assigned and decide to “break” it up into chunks as follows:

  1. – Documents
  2. – Certificate Extensions
  3. – Resource Identifiers

Underneath each of these you would assign unique numbers by appending a new number, for example might be your CAs Certificate Practice Statement (CPS).

So how do you get one of these OIDs then? That’s easy it’s Internet Assigned Numbers Authority (IANA) who assigns these, they call them Private Enterprise Numbers. Getting one is easy enough just fill out a web application form. To do that you will only need 7 pieces of information, these include:

  1. Organization Name
  2. Organization Address
  3. Organization Phone
  4. Contact Name
  5. Contact Address
  6. Contact Phone
  7. Contact Email

Remember the idea is that the information you provide here will be used for people to reach you if they want to ask questions about these things you have uniquely identified so choose the values wisely.

It can take up to 60 days to get one of these (although usually the application is processed in about one week).

Once you got the object identifier, you should register the code on the site www.oid-info.com and/or www.alvestrand.no in this way will be easily accessible by those who are seeking information about the owner of object identifier.

Hope this helps.


Revocation repositories, IPv6 support, message size, and performance

So the last few weeks I have spent a reasonable amount of time looking at performance and networking related problems associated with revocation repositories. I still have some additional work to do but I figured I would capture some of my findings in a quick post.

CRL repositories and IPv6
CA Host Supports V6
GlobalSign crl.globalsign.com Yes
Comodo crl.comodoca.com No/Sometimes
CyberTrust sureseries-crl.cybertrust.ne.jp No
Symantec/GeoTrust EVSSL-crl.geotrust.com No
Symantec/VeriSign EVIntl-crl.verisign.com No
DigiCert crl3.digicert.com No
StartSSL crl.startssl.com No
TrustWave crl.securetrust.com No
TrustCenter crl.ix.tcclass3.tcuniversal-i.trustcenter.de No
GoDaddy crl.godaddy.com No
Entrust crl.entrust.net No
Certum crl.certum.pl No

* IPv6 Capability was checked via http://ipv6-test.com/validate.php


OCSP repositories and IPv6
CA Host Supports V6
GlobalSign ocsp.globalsign.com Yes
COMODO ocsp.comodoca.com No
GoDaddy ocsp.godaddy.com No
DigiCert ocsp.digicert.com No
StartCom ocsp.startssl.com No
TrustCenter ocsp.tcuniversal-I.trustcenter.de No
TrustWave ocsp.trustwave.com No
Enstrust ocsp.entrust.net No
Symantec/GeoTrust ocsp.geotrust.com No
Symantec/VeriSign ocsp.verisign.com No
CyberTrust sureseries-ocsp.cybertrust.ne.jp No
Certum ocsp.certum.pl No

* IPv6 Capability was checked via http://ipv6-test.com/validate.php


CRL Size
CA CRL Size # Entries
Certum http://crl.certum.pl/evca.crl 862 7
Symantec/Geotrust http://EVSSL-crl.geotrust.com/crls/gtextvalca.crl 720 12
Cybertrust http://sureseries-crl.cybertrust.ne.jp/SureServer/2021_ev/cdp.crl 1742 17
GlobalSign http://crl.globalsign.com/gs/gsextendvalg2.crl 1114 18
TrustWave http://crl.securetrust.com/STCA.crl 2158 65
StartSSL http://crl.startssl.com/crt4-crl.crl 2339 90
DigiCert http://crl3.digicert.com/evca1-g1.crl 5393 100
GoDaddy http://crl.godaddy.com/gds3-37.crl 6848 153
Comodo http://crl.comodoca.com/COMODOExtendedValidationSecureServerCA.crl 12959 351
TrustCenter http://crl.ix.tcclass3.tcuniversal-i.trustcenter.de/crl/v2/tc_class3_L1_CA_IX.crl 16138 407
Entrust http://crl.entrust.net/level1e.crl 40995 1005
Symantec/VeriSign http://EVIntl-crl.verisign.com/EVIntl2006.crl 207922 5972
* CRL count was determined using “curl url>crl & openssl crl -in crl -inform der -text | grep -c “Serial”
* Size was determined using the Content-Length header, “curl –verbose –url *”


OCSP response Size
CA Host Size
Comodo ocsp.comodoca.com 471
Digicert ocsp.digicert.com 471
GlobalSign ocsp2.globalsign.com 1491
CyberTrust sureseries-ocsp.cybertrust.ne.jp 1588
StartSSL ocsp.startssl.com 1596
Symantec/Verisign ocsp.verisign.com 1739
GoDaddy ocsp.godaddy.com 1923
Entrust ocsp.entrust.net 1939
Certum ocsp.certum.pl 2113
Trustwave ocsp.trustwave.com 2519
TrustCenter ocsp.tcuniversal-I.trustcenter.de 3135
Symantec/Geotrust ocsp.geotrust.com 3346

* Size was determined using the Content-Length header, “curl –verbose –url *”


OCSP Response Performance
CA Host Average (ms)
GlobalSign ocsp2.globalsign.com


DigiCert ocsp.digicert.com


GoDaddy ocsp.godaddy.com


COMODO ocsp.comodoca.com


StartCom ocsp.startssl.com


Enstrust ocsp.entrust.net


Symantec/GeoTrust ocsp.geotrust.com


Symantec/VeriSign ocsp.verisign.com


TrustWave ocsp.trustwave.com


TrustCenter ocsp.tcuniversal-I.trustcenter.de


CyberTrust sureseries-ocsp.cybertrust.ne.jp


Certum ocsp.certum.pl


* Measuring with Monitis points in US-MID, US-EST-US-WST, Canada, Denmark, Netherlands, Germany, Spain, UK, Sweden, China, Austrailia, Signapore, Japan were used.


CRL Repository Performance
CA Host Average (ms)
GlobalSign crl.globalsign.com 101
DigiCert crl3.digicert.com 102
Entrust crl.entrust.net 120
Comodo crl.comodoca.com 178
GoDaddy crl.godaddy.com 186
StartCom crl.startssl.com 267
TrustWave crl.securetrust.com 272
Symantec/GeoTrust EVSSL-crl.geotrust.com 298
Symantec/Verisign EVIntl-crl.verisign.com 298
TrustCenter crl.ix.tcclass3.tcuniversal-i.trustcenter.de 371
Certum crl.certum.pl 426
CyberTrust sureseries-crl.cybertrust.ne.jp 454
* Measuring with Monitis points in US-MID, US-EST-US-WST, Canada, Denmark, Netherlands, Germany, Spain, UK, Sweden, China, Austrailia, Signapore, Japan were used.