Tag Archives: dogtag

Creating A Subordinate Certificate Authority in FreeIPA

Within an organization using Free IPA there may be a need to create a subordinate CA. A subordinate CA can issue certificates on behalf of the Root CA in the organization so it should be treated with the same security as an organization’s Root CA. The main advantage is Subordinate CA can be revoked if it goes rogue and so keep part of the organization still working.

Free IPA 4.2.0 allows the use of certificate profiles (certificate template) to sign new certificate requests. This allows you to create your own profiles that will allow sign any type of certificate request. Earlier than FreeIPA 4.2.0, this was not possible, although the underlying dogtag PKI already allowed it.

RFC 5280 is the X.509 certificate description and specifically subordinate CA description. If you have openSSL installed, look at man x509v3_config for detailed description of V3 extensions.

Characteristics of a Sub-CA

For all practical purposes a Sub-CA is a CA that ideally:

  • Has the CA flag set to true
  • Preferably not issue further Sub-CA certificates

Creating the Certificate Profile

A subordinate CA is a very powerful element in the PKI’s trust chain. So ensure people who have access to it have adequate knowledge of what’s happening.

Here is the raw config file we used for our Sub CA certificate profile. Some notes follow this long listing.

[root@idm01 fedora]# cat caSubCACert2.cfg 
desc=This certificate profile is for enrolling Subordinate Certificate Authority certificates.
visible=true
enable=true
auth.instance_id=raCertAuth
classId=caEnrollImpl
enableBy=ipara
name=Manual Certificate Manager Subordinate Signing Certificate Enrollment
input.list=i1,i2
input.i1.class_id=certReqInputImpl
input.i2.class_id=submitterInfoInputImpl
output.list=o1
output.o1.class_id=certOutputImpl
policyset.list=caSubCertSet
policyset.caSubCertSet.list=1,2,3,4,5,6,8,9,10
policyset.caSubCertSet.1.constraint.class_id=subjectNameConstraintImpl
policyset.caSubCertSet.1.constraint.name=Subject Name Constraint
policyset.caSubCertSet.1.constraint.params.pattern=.*CN=.+
policyset.caSubCertSet.1.constraint.params.accept=true
policyset.caSubCertSet.1.default.class_id=userSubjectNameDefaultImpl
policyset.caSubCertSet.1.default.name=Subject Name Default
policyset.caSubCertSet.1.default.params.name=
policyset.caSubCertSet.2.constraint.class_id=validityConstraintImpl
policyset.caSubCertSet.2.constraint.name=Validity Constraint
policyset.caSubCertSet.2.constraint.params.range=7305
policyset.caSubCertSet.2.constraint.params.notBeforeCheck=false
policyset.caSubCertSet.2.constraint.params.notAfterCheck=false
policyset.caSubCertSet.2.default.class_id=caValidityDefaultImpl
policyset.caSubCertSet.2.default.name=CA Certificate Validity Default
policyset.caSubCertSet.2.default.params.range=7305
policyset.caSubCertSet.2.default.params.startTime=0
policyset.caSubCertSet.3.constraint.class_id=keyConstraintImpl
policyset.caSubCertSet.3.constraint.name=Key Constraint
policyset.caSubCertSet.3.constraint.params.keyType=-
policyset.caSubCertSet.3.constraint.params.keyParameters=1024,2048,3072,4096,nistp256,nistp384,nistp521
policyset.caSubCertSet.3.default.class_id=userKeyDefaultImpl
policyset.caSubCertSet.3.default.name=Key Default
policyset.caSubCertSet.4.constraint.class_id=noConstraintImpl
policyset.caSubCertSet.4.constraint.name=No Constraint
policyset.caSubCertSet.4.default.class_id=authorityKeyIdentifierExtDefaultImpl
policyset.caSubCertSet.4.default.name=Authority Key Identifier Default
policyset.caSubCertSet.5.constraint.class_id=basicConstraintsExtConstraintImpl
policyset.caSubCertSet.5.constraint.name=Basic Constraint Extension Constraint
policyset.caSubCertSet.5.constraint.params.basicConstraintsCritical=true
policyset.caSubCertSet.5.constraint.params.basicConstraintsIsCA=true
policyset.caSubCertSet.5.constraint.params.basicConstraintsMinPathLen=0
policyset.caSubCertSet.5.constraint.params.basicConstraintsMaxPathLen=0
policyset.caSubCertSet.5.default.class_id=basicConstraintsExtDefaultImpl
policyset.caSubCertSet.5.default.name=Basic Constraints Extension Default
policyset.caSubCertSet.5.default.params.basicConstraintsCritical=true
policyset.caSubCertSet.5.default.params.basicConstraintsIsCA=true
policyset.caSubCertSet.5.default.params.basicConstraintsPathLen=0
policyset.caSubCertSet.6.constraint.class_id=keyUsageExtConstraintImpl
policyset.caSubCertSet.6.constraint.name=Key Usage Extension Constraint
policyset.caSubCertSet.6.constraint.params.keyUsageCritical=true
policyset.caSubCertSet.6.constraint.params.keyUsageDigitalSignature=true
policyset.caSubCertSet.6.constraint.params.keyUsageNonRepudiation=true
policyset.caSubCertSet.6.constraint.params.keyUsageDataEncipherment=false
policyset.caSubCertSet.6.constraint.params.keyUsageKeyEncipherment=false
policyset.caSubCertSet.6.constraint.params.keyUsageKeyAgreement=false
policyset.caSubCertSet.6.constraint.params.keyUsageKeyCertSign=true
policyset.caSubCertSet.6.constraint.params.keyUsageCrlSign=true
policyset.caSubCertSet.6.constraint.params.keyUsageEncipherOnly=false
policyset.caSubCertSet.6.constraint.params.keyUsageDecipherOnly=false
policyset.caSubCertSet.6.default.class_id=keyUsageExtDefaultImpl
policyset.caSubCertSet.6.default.name=Key Usage Default
policyset.caSubCertSet.6.default.params.keyUsageCritical=true
policyset.caSubCertSet.6.default.params.keyUsageDigitalSignature=true
policyset.caSubCertSet.6.default.params.keyUsageNonRepudiation=true
policyset.caSubCertSet.6.default.params.keyUsageDataEncipherment=false
policyset.caSubCertSet.6.default.params.keyUsageKeyEncipherment=false
policyset.caSubCertSet.6.default.params.keyUsageKeyAgreement=false
policyset.caSubCertSet.6.default.params.keyUsageKeyCertSign=true
policyset.caSubCertSet.6.default.params.keyUsageCrlSign=true
policyset.caSubCertSet.6.default.params.keyUsageEncipherOnly=false
policyset.caSubCertSet.6.default.params.keyUsageDecipherOnly=false
policyset.caSubCertSet.8.constraint.class_id=noConstraintImpl
policyset.caSubCertSet.8.constraint.name=No Constraint
policyset.caSubCertSet.8.default.class_id=subjectKeyIdentifierExtDefaultImpl
policyset.caSubCertSet.8.default.name=Subject Key Identifier Extension Default
policyset.caSubCertSet.8.default.params.critical=false
policyset.caSubCertSet.9.constraint.class_id=signingAlgConstraintImpl
policyset.caSubCertSet.9.constraint.name=No Constraint
policyset.caSubCertSet.9.constraint.params.signingAlgsAllowed=SHA1withRSA,SHA256withRSA,SHA512withRSA,SHA1withDSA,SHA1withEC,SHA256withEC,SHA384withEC,SHA512withEC
policyset.caSubCertSet.9.default.class_id=signingAlgDefaultImpl
policyset.caSubCertSet.9.default.name=Signing Alg
policyset.caSubCertSet.9.default.params.signingAlg=-
policyset.caSubCertSet.9.constraint.class_id=noConstraintImpl
policyset.caSubCertSet.9.constraint.name=No Constraint
policyset.caSubCertSet.9.default.class_id=crlDistributionPointsExtDefaultImpl
policyset.caSubCertSet.9.default.name=CRL Distribution Points Extension Default
policyset.caSubCertSet.9.default.params.crlDistPointsCritical=false
policyset.caSubCertSet.9.default.params.crlDistPointsEnable_0=true
policyset.caSubCertSet.9.default.params.crlDistPointsIssuerName_0=CN=Certificate Authority,o=ipaca
policyset.caSubCertSet.9.default.params.crlDistPointsIssuerType_0=DirectoryName
policyset.caSubCertSet.9.default.params.crlDistPointsNum=1
policyset.caSubCertSet.9.default.params.crlDistPointsPointName_0=http://<your IPA's CRL revocation list>
policyset.caSubCertSet.9.default.params.crlDistPointsPointType_0=URIName
policyset.caSubCertSet.9.default.params.crlDistPointsReasons_0=
policyset.caSubCertSet.10.constraint.class_id=noConstraintImpl
policyset.caSubCertSet.10.constraint.name=No Constraint
policyset.caSubCertSet.10.default.class_id=authInfoAccessExtDefaultImpl
policyset.caSubCertSet.10.default.name=AIA Extension Default
policyset.caSubCertSet.10.default.params.authInfoAccessADEnable_0=true
policyset.caSubCertSet.10.default.params.authInfoAccessADLocationType_0=URIName
policyset.caSubCertSet.10.default.params.authInfoAccessADLocation_0=
policyset.caSubCertSet.10.default.params.authInfoAccessADMethod_0=1.3.6.1.5.5.7.48.1
policyset.caSubCertSet.10.default.params.authInfoAccessCritical=false
policyset.caSubCertSet.10.default.params.authInfoAccessNumADs=1
profileId=caSubCertAuth2
[root@idm01 fedora]# 

This constraint says, the CSR must have a “CN=” string somewhere.

policyset.caSubCertSet.1.constraint.params.pattern=.*CN=.+

The following says that the certificate is for a CA and path len =0, which means the CA can issue further Sub CAs.

policyset.caSubCertSet.5.constraint.params.basicConstraintsIsCA=true
policyset.caSubCertSet.5.constraint.params.basicConstraintsMinPathLen=0
policyset.caSubCertSet.5.constraint.params.basicConstraintsMaxPathLen=0
policyset.caSubCertSet.5.default.params.basicConstraintsIsCA=true
policyset.caSubCertSet.5.default.params.basicConstraintsPathLen=0

Importing the profile into FreeIPA

[root@idm01 fedora]# ipa certprofile-import caSubCertAuth2 --store=true --file=caSubCACert2.cfg 
Profile description: This certificate profile is for enrolling Subordinate Certificate Authority certificates (v2).
---------------------------------
Imported profile "caSubCertAuth2"
---------------------------------
 Profile ID: caSubCertAuth2
 Profile description: This certificate profile is for enrolling Subordinate Certificate Authority certificates (v2).
 Store issued certificates: TRUE
[root@idm01 fedora]#

Don’t forget to add the Certificate ACL allowing appropriate groups s access to the certificate profile either from the WebUI or command line.

Certificate Signing Request

The CSR is not different than other requests you can use OpenSSL to create a CSR. Just ensure the CN and others follow the restrictions that is set in the profile above.

Issuing the Certificate

[root@idm01 fedora]# ipa cert-request ./cert.req --principal SUBCA/SUBCA01.silverskysoft.com --profile-id caSubCertAuth2

This should issue the certificate.

That’s cool, but where’s the green bar?

The green bar that shows up when you visit certain e-commerce websites is a very nice marketing thing. As a result, some users would like to see the green bar. Our next quest is to see if we can create certificate profile that allows generating a certificate with EV flags set. Cursory reading of documentation shows its not well documented and probably not possible.