Related to this (too broad) question: How to implement my PKI?

I have a self-signed CA (ca0)

I would like to create a CA (ca1) with limited power derived from that first CA. ca1 should only be able to sign certificates for *.foo.com and for foo.com.

From this question, I found out that the Name Constraints extension is probably what I want.

The key for ca1 already exists and is ca1.foo.key.pem.

I already have an incomplete command for creating the request:

libressl req -new -sha512 -key ca1.foo.key.pem -out ca1.foo.csr.pem

What should I add to that line to limit ca1's power?

1 Answer 1


You'll need to add the NameConstraints extension to the request using LibreSSL's config file. The following example is an extract - you'll need to add the various sections to your current config file and tweak the constraints:

[ req ]

# Don't prompt for the DN, use configured values instead
# This saves having to type in your DN each time.

prompt             = no
string_mask        = default
distinguished_name = req_dn

# The size of the keys in bits:
default_bits       = 4096

# The extensions added when generating a CSR
req_extensions     = req_ext

[ req_dn ]

countryName            = GB
stateOrProvinceName    = Somewhere
organizationName       = Example
organizationalUnitName = PKI
commonName             = Example CA

[ req_ext ]

# Extensions added to the request

subjectKeyIdentifier    = hash

basicConstraints            = critical, CA:TRUE
# basicConstraints          = critical, CA:TRUE, pathlen:1

keyUsage = critical, keyCertSign, cRLSign

# Policies and constraints are not recommended for Root CAs
# But could be enforced on subordinate CAs

nameConstraints        = @name_constraints

#policyConstraints = requireExplicitPolicy:1

#inhibitAnyPolicy = 1

#certificatePolicies = @CertPol

[ name_constraints ]
permitted;DNS.1 = example.org
permitted;DNS.2 = example.com
permitted;dirName.1 = style_1
permitted;dirName.2 = style_2

[ style_1 ]
1.OU=head office

[ style_2 ]

[ CertPol ]
policyIdentifier =
CPS = http://pki.example.org/cps.html

If you're not using the default configuration file you'll need to add -config <config file> to your command line.

Note: I've not tried this on LibreSSL - only on OpenSSL but I believe both use the same syntax.

  • Where are number.field (1.OU, 1.DC), and the DC field documented? I haven't found that documentation anywhere. May 14, 2020 at 9:18
  • The numbering in that man page goes after the field, not before. Is it the same? May 14, 2020 at 11:16
  • I'm guessing that n.DC is the domain levels. Am I right? For example for foo.bar.org it would be 1.DC=org 2.DC=bar 3.DC=foo. If not, what is DC exactly for? May 14, 2020 at 11:50
  • I tried openssl req -new -sha512 -key ca1.key.pem -out ca1.csr.pem (I edited /etc/ssl/openssl.cnf directly) and got: May 14, 2020 at 12:00
  • 1
    You're correct re the DC elements. I've added a full example that should work with a few tweaks. May 14, 2020 at 13:07

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .