I am trying to restrict the intermediate CA to sign only end user certificates. However, I am not able to do so.
Man page of x509v3_config says
basicConstraints=critical,CA:TRUE, pathlen:0
A CA certificate must include the basicConstraints value with the CA field set to TRUE . An end user certificate must either set CA to FALSE or exclude the extension entirely. Some software may require the inclusion of basicConstraints with CA set to FALSE for end entity certificates.
The pathlen parameter indicates the maximum number of CAs that can appear below this one in a chain. So if you have a CA with a pathlen of zero it can only be used to sign end user certificates and not further CAs
Step 1: Create a self signed root CA - rootCA.crt
openssl genrsa -out rootCA.key 4096
openssl req -x509 -new -nodes -key rootCA.key -sha256 -out rootCA.crt
Step 2: Create a Certificate signing request using below configuration file.
openssl req -new -config extension.conf -out intermediate.csr
[ req ]
default_bits = 4096
default_md = sha256
prompt = no
encrypt_key = no
default_keyfile = privkey.key
distinguished_name = req_distinguished_name
req_extensions = v3_req
[ req_distinguished_name ]
countryName = DE
stateOrProvinceName = Bayern
localityName = Munich
0.organizationName = Test AG
organizationalUnitName = Services
emailAddress = [email protected]
[ v3_req ]
basicConstraints = critical,CA:true, pathlen:0
keyUsage = keyCertSign
The CSR is generated now
Step 3: Now sign the CSR with self-signed root CA with support from extension file
openssl x509 -req -in intermediate.csr -CA rootCA.crt -CAkey rootCA.key -CAcreateserial -extensions v3_req -extfile file.txt -out intermediate.crt -sha256
file.txt
[ v3_req ]
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid:always
Now intermediate certificate is generated.
Step 4: Create one more intermediate certificate and lets call it TEST certificate - using sightly modified configuration file as below:
[ req ]
default_bits = 4096
default_md = sha256
prompt = no
encrypt_key = no
default_keyfile = privkey.key
distinguished_name = req_distinguished_name
req_extensions = v3_req
[ req_distinguished_name ]
countryName = DE
stateOrProvinceName = Berlin
localityName = Berlin
0.organizationName = Dummy AG
organizationalUnitName = Product
emailAddress = [email protected]
[ v3_req ]
basicConstraints = critical,CA:true
keyUsage = keyCertSign
Generate the CSR
openssl req -new -config test.conf -out TEST.csr
Sign the CSR with intermediate.crt which should not be possible.
openssl x509 -req -in TEST.csr -CA intermediate.crt -CAkey privkey.key -CAcreateserial -out TEST.crt -sha256
As per the man page of x509v3_config, signing of the TEST.csr should fail as it is not the end user certificate.
The pathlen is 0 in my intermediate certificate. So I shouldn't be able to sign the TEST.csr. What am I doing wrong here? Can some one please kindly explain?