Tag Archives: SSL Certificates

Creating Your Own CA that issues Extended Validation SSL Certificates

If you have your own FreeIPA install, you may try the marketing thing to get the green bar for some of your SSL certificates. Sadly, issuing your own Extended Validation (EV) certificates and getting the green bar on all browsers is not simple (without special recompiled code, its not possible). The exact reason is described in this article. In way, this is a good thing as it is intended to have stronger security by the the browsers.

We verified 3 browers: Firefox 40, Chrome 45, IE 11.

Why internally issued EV certs & Green bar is not allowed

The answer simply boils down to trust. For EV certs, browsers don’t trust anyone but a hardcoded list in their code. For example in Firefox’s code here :  http://lxr.mozilla.org/firefox/source/security/manager/ssl/src/nsIdentityChecking.cpp

This is to ensure there is no accidentally inserted root certificates into the store that can verify EV certs.

Questionable ‘Higher’ Security/Trust model for hard coded EV Issuer Certificate Stores

Our opinion is this isn’t any real security or trust, it seems to be based in the notion that somehow hiding the EV Issuer Certificates in the browser executable is secure. We find this is slightly worse security than letting OS manage the certificate store. The our argument is, hard coding EV issuer certificates places ‘highly trusted’ certificates in the same trust zone as the browser process space. So a malware does not have mount a privilege escalation attack to mislead the user that a website is ‘highly trusted’. This leads to an inverse security where EV Issuer certificates are  arguably less trusted than the ones in the OS store. Here the assumption we are making is hacking OS cert stores takes a lot more sophistication and escalation into ring 3 (compared to no escalation) to trick the user into believing a fake EV certificate.

This security only limits user naive mistakes and not sophisticated or above average malware.

We evaluated the source code of Firefox and you can see one of the starting functions for checking if the certificate is EV is: nsNSSCertificate::hasValidEVOidTag

This function checks if the certifcate’s EV OID (Extended Policy Object ID values) matches OID from a hard coded EV issuer certs in getRootsForOid(SECOidTag oid_tag) which accesses a static array static struct nsMyTrustedEVInfo myTrustedEVInfos[] . This hardcoding of root certs precludes adding your EV issuing CA certificate to the trusted root in Mozilla certificate store. So no green bar even if your certificate has all the requirements of an EV certificate and have added a trusted CA to Mozilla.

Edit – Mozilla’s security team was nice enough to comment on our analysis – Their take was they take this position to influence CA standards and EV expectations. Our analysis still remains unchanged

Chrome follows a similar policy. IE is different, if you can get to GPO on your CA system, you can set the external OIDs that will allow a green bar. Unfortunately, IE is not a full solution as many people in our org use other browsers.

However, you can generate an ‘EV’ certificate in FreeIPA

Why would one care  if we can’t get green bar? If you can become an intermediate CA of a another CA that will allow you to generate EV certs (which I have not found any CA allowing this). Or if you plan to become an EV cert issuing CA yourself and want to embed your certificate in the browsers. If not for anything, for academic reasons.

FreeIPA Certificate Profile for EV Certificate Issuance

The main characteristics of an EV certificate is presence of OSCP, AIA and Certificate Subject in particular way and the certificate should have a Policy ID and CPS statement line.

Start with IPA’s default caIPAserviceCert (see ipa certprofile-find) Here are the important diffs in the profile to add the certificatePoliciesExt:

policyset.evServerCertSet.1.constraint.class_id=subjectNameConstraintImpl
policyset.evServerCertSet.1.constraint.name=Subject Name Constraint
policyset.evServerCertSet.1.constraint.params.accept=true
policyset.evServerCertSet.1.constraint.params.pattern=.*CN=.+
policyset.evServerCertSet.1.default.class_id=userSubjectNameDefaultImpl
policyset.evServerCertSet.1.default.name=Subject Name Default
policyset.evServerCertSet.1.default.params.name=
. . .
policyset.evServerCertSet.12.constraint.class_id=noConstraintImpl
policyset.evServerCertSet.12.constraint.name=No Constraint
policyset.evServerCertSet.12.default.class_id=certificatePoliciesExtDefaultImpl
policyset.evServerCertSet.12.default.name=Certificate Policies Extension Default
policyset.evServerCertSet.12.default.params.Critical=false
policyset.evServerCertSet.12.default.params.PoliciesExt.num=1
policyset.evServerCertSet.12.default.params.PoliciesExt.certPolicy0.enable=true
policyset.evServerCertSet.12.default.params.PoliciesExt.certPolicy0.policyId=1.3.6.1.4.1.35351.1000.100
policyset.evServerCertSet.12.default.params.PolicyQualifiers.num=1
policyset.evServerCertSet.12.default.params.PoliciesExt.certPolicy0.PolicyQualifiers0.CPSURI.enable=true
policyset.evServerCertSet.12.default.params.PoliciesExt.certPolicy0.PolicyQualifiers0.CPSURI.value=http://idm01.corp.silverskysoft.com/cpsstatement.html
policyset.evServerCertSet.12.default.params.PoliciesExt.certPolicy0.PolicyQualifiers0.usernotice.enable=true
policyset.evServerCertSet.12.default.params.PoliciesExt.certPolicy0.PolicyQualifiers0.usernotice.noticeReference.organization=$request.req_subject_name.cn$
policyset.evServerCertSet.12.default.params.PoliciesExt.certPolicy0.PolicyQualifiers0.usernotice.explicitText.value=SeeLegal
policyset.evServerCertSet.list=1,2,3,4,5,6,7,8,9,10,11,12

The policyID should be an ANSI OID (which can get expensive to obtain). For testing, you can use one from Wikipedia assigned to existing EV CAs.  The other cheaper way is to get an Private Enterprise Number from IANA and use the OID from that point on.

Then import the config file into FreeIPA:
ipa certprofile-import caIPAWebServiceEVCert --store=true --file=websslprofile

Certificate Signing Request

In your CSR, it must contain businessCategory=Private Organization/serialNumber=000

For in depth explanation what fields are required, visit the CA Browser forum https://cabforum.org and look for EV SSL specifications.

Also, thanks to a very nice CSR decode tool at CertLogik: https://certlogik.com/decoder/ that helped in our investigations.