Information Security Asked by cpp_enthusiast on December 1, 2020
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?
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?
openssl is the swiss-army knife of PKI. It will do whatever you ask it to. I often need "illegal" certs when testing applications. The fact that openssl is not a drama queen about this makes it my tool of choice for PKI testing.
So you have a cert chain
Root [pathLen: 1] --> Int1 [pathLen: 0] --> Int1 [pathLen: ?] --> EE
Yes, that cert is illegal because of the EE is pathLen: 1
from Int1. Where you will see errors is not on issuance, but when you try to use this cert. Try putting that cert on a website (for example openssl s_server
in front of a python3 -m http.server 8000 --bind 127.0.0.1
). Try connecting to it with browsers. The browsers should throw cert errors (if they don't, open bug reports with the browser, you may even get a bug bounty since that would be a real security issue).
Answered by Mike Ounsworth on December 1, 2020
First, if you look at the cert you created in step 3 with openssl x509 -text <intermediate.crt
you'll see it doesn't have any BC extension (nor KU either). This is because creating a cert with openssl x509 -req -CA/CAkey
does not use any extensions (more exactly, requested extensions) from the CSR. See Missing X509 extensions with an openssl-generated certificate https://serverfault.com/questions/845806/how-to-issue-ssl-certificate-with-san-extension https://superuser.com/questions/862838/s-mime-for-mac-and-ios .
But even if you fix this, OpenSSL mostly doesn't check the certificate when it does a privatekey operation, except in the SSL/TLS protocol (which requires full checks). (And in one case, smime|cms -encrypt
, it apparently doesn't check even on a publickey operation.) The man page might more accurately say a CA cert with pathlen=0 can only validly sign leaf certs, not other sub-CA certs: OpenSSL, with either openssl ca
or openssl x509 -req -CA [-CAkey]
will actually sign a cert that violates pathlen (or even CA=false!), but if you subsequently use that cert in most cases it will fail validation and be rejected.
Answered by dave_thompson_085 on December 1, 2020
Get help from others!
Recent Questions
Recent Answers
© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP