Building an OpenSSL Certificate Authority - Creating Your Intermediary Certificate
Creating Your Intermediary Certificate Authority
Previously we created the first part of our OpenSSL CA by building our root certificate. We are now ready to complete our CA chain by creating and signing the intermediary certificate. The intermediary will be responsible for signing client and server certificate requests. It acts as an authoritative proxy for the root certificate hence the name intermediary. The chain of trust will extend from the root certificate to the intermediary certificate down to the certificates you'll deploy within your infrastructure.
Create your directory structure
Create a new subdirectory under
/root/ca
to segregate intermediary files our root configuration .
# sudo bash # mkdir /root/ca/intermediate
We're creating the same directory structure previously used under
/root/ca
within /root/ca/intermediary
. It's your decision if you if you want to do something different. Some of my best friends are flat directory structures and we don't judge personal practices.
Create your intermediary CA database to keep track of signed certificates
# cd /root/ca/intermediate # mkdir certs crl csr private # touch index.txt # echo 1000 > serial
Create a crlnumber file for the intermediary CA to use
# echo 1000 > /root/ca/intermediate/crlnumber
Similar to the earlier serial statement, this will create the crlnumber file and start the numerical iteration at 1000. This will be used for future certificate revocation needs.
Create your OpenSSL intermediary config file
Copy the GIST openssl_intermediate.cnf file to
/root/ca/intermediate/openssl_intermediate.cnf
and modify the contents for your own naming conventions. Similar to the root_ca.cnf
, the [CA]
is required and will gather it's configuration from the [CA_default]
section. Changes to the [int_ca]
include:
[ CA_default ] # Directory and file locations. dir = /root/ca/intermediate private_key = $dir/private/int.cheese.key.pem certificate = $dir/cers/int.cheese.crt.pem crlnumber = $dir/crlnumber crl = $dir/crl/int.cheese.crl.pem crl_extensions = crl_ext policy = policy_loose
We have new certificate names for our intermediary use and define
policy_loose
so future certificate requests don't have to match country, state/province, or organization.
Create the Intermediary's Private Key and Certificate Signing Request
Similar to the root certificate, we're following the NSA Suite B requirements and matching the root's elliptical curve, secp384r1. We'll also create the CSR and private key all in one line, making your scripts and life a bit easier.
# cd /root/ca # openssl req -config intermediate/openssl_intermediate.cnf -new -newkey ec:<(openssl ecparam -name secp384r1) -keyout intermediate/private/int.cheese.key.pem -out intermediate/csr/int.cheese.csr Generating an EC private key writing new private key to 'intermediate/private/int.cheese.key.pem' Enter PEM pass phrase: ****** Verifying - Enter PEM pass phrase: ****** ----- You are about to be asked to enter information that will be incorporated into your certificate request. What you are about to enter is what is called a Distinguished Name or a DN. There are quite a few fields but you can leave some blank For some fields there will be a default value, If you enter '.', the field will be left blank. ----- Country Name (2 letter code) [US]: State or Province Name [WA]: Locality Name [Seattle]: Organization Name [Grilled Cheese Inc.]: Organizational Unit Name [Grilled Cheese Intermediary CA]: Common Name []:Grilled Cheese Inc. Intermediary Certificate Authority Email Address [grilledcheese@yummyinmytummy.us]:
Sign the certificate request with the root certificate and use the openssl_intermediate.cnf config file to specify the
[v3_intermediate_ca]
extension instead of the [v3_ca]
as we did for the root. The openssl_intermediate.cnf
has a few changes which we need to note.
[ v3_intermediate_ca ] # Extensions for a typical intermediate CA (`man x509v3_config`). subjectKeyIdentifier = hash authorityKeyIdentifier = keyid:always,issuer basicConstraints = critical, CA:true, pathlen:0 keyUsage = critical, digitalSignature, cRLSign, keyCertSign crlDistributionPoints = @crl_info authorityInfoAccess = @ocsp_info [crl_info] URI.0 = http://crl.grilledcheese.us/whoremovedmycheese.crl [ocsp_info] caIssuers;URI.0 = http://ocsp.grilledcheese.us/cheddarcheeseroot.crt OCSP;URI.0 = http://ocsp.grilledcheese.us/
The Certificate Revocation List (crl) and Online Certificate Status Protocol (OCSP) should be included within the intermediary certificate. This lets systems know where check and see if the intermediary certificate was revoked by the root at any given time. We will cover this in detail later and browsers do not necessarily check the intermediary certificates for revocation, but they absolutely do for the site certificates. We're adding CRL and OCSP to the Intermediary CA for best practices purpose.
Create the intermediate certificate
Sign the
csr/int.cheese.cs
r with the root's certificate. We are going to drop down to /root/ca
so the creation of the intermediary certificate is stored within the root's index.txt
and we'll also use the root's OpenSSL Config file openssl_root.cnf
.
# openssl ca -config openssl_root.cnf -extensions v3_intermediate_ca -days 3600 -md sha384 -in intermediate/csr/int.cheese.csr -out intermediate/certs/int.cheese.crt.pem Using configuration from openssl_root.cnf Enter pass phrase for /root/ca/private/ca.cheese.key.pem: Check that the request matches the signature Signature ok Certificate Details: Serial Number: 4097 (0x1001) Validity Not Before: Aug 24 21:51:07 2017 GMT Not After : Jul 3 21:51:07 2027 GMT Subject: countryName = US stateOrProvinceName = WA organizationName = Grilled Cheese Inc. organizationalUnitName = Grilled Cheese Intermediary CA commonName = Grilled Cheese Inc. Intermediary Certificate Authority emailAddress = grilledcheese@yummyinmytummy.us X509v3 extensions: X509v3 Subject Key Identifier: 7E:2D:A5:D0:9B:70:B9:E3:D2:F7:C0:0A:CF:70:9A:8B:80:38:B1:CD X509v3 Authority Key Identifier: keyid:27:C8:F7:34:2F:30:81:97:DE:2E:FC:DD:E2:1D:FD:B6:8F:5A:AF:BB X509v3 Basic Constraints: critical CA:TRUE, pathlen:0 X509v3 Key Usage: critical Digital Signature, Certificate Sign, CRL Sign X509v3 CRL Distribution Points: Full Name: URI:http://crl.grilledcheese.us/whomovedmycheese.crl Authority Information Access: CA Issuers - URI:http://ocsp.grilledcheese.us/cheddarcheeseroot.crt OCSP - URI:http://ocsp.grilledcheese.us/ Certificate is to be certified until Jul 3 21:51:07 2027 GMT (3600 days) Sign the certificate? [y/n]:y 1 out of 1 certificate requests certified, commit? [y/n]y Write out database with 1 new entries Data Base Updated
Validate the Certificate Contents with OpenSSL.
# openssl x509 -noout -text -in intermediate/certs/int.cheese.crt.pem Certificate: Data: Version: 3 (0x2) Serial Number: 4097 (0x1001) Signature Algorithm: ecdsa-with-SHA384 Issuer: C = US, ST = WA, L = Seattle, O = Grilled Cheese Inc., OU = Grilled Cheese Root CA, CN = Grilled Cheese Inc. Root Certificate Authority, emailAddress = grilledcheese@yummyinmytummy.us Validity Not Before: Aug 24 21:51:07 2017 GMT Not After : Jul 3 21:51:07 2027 GMT Subject: C = US, ST = WA, O = Grilled Cheese Inc., OU = Grilled Cheese Intermediary CA, CN = Grilled Cheese Inc. Intermediary Certificate Authority, emailAddress = grilledcheese@yummyinmytummy.us Subject Public Key Info: Public Key Algorithm: id-ecPublicKey Public-Key: (384 bit) pub: 04:9b:14:9a:55:6d:db:15:7f:d7:8b:fd:37:4d:ba: e8:50:8e:88:32:99:27:4e:20:36:25:8b:7b:ac:bb: 2f:d6:61:c1:5a:c8:e6:4c:98:20:3f:cf:86:3c:bf: f4:f3:b0:1c:1c:0b:cc:7f:e4:4b:13:59:58:a1:53: 87:cb:4c:17:66:04:21:01:6a:44:5f:22:31:7d:3d: fe:a2:e7:73:c8:77:7c:1a:f9:9c:4a:9d:e7:77:6a: c7:9e:3e:f0:4a:b0:37 ASN1 OID: secp384r1 NIST CURVE: P-384 X509v3 extensions: X509v3 Subject Key Identifier: 7E:2D:A5:D0:9B:70:B9:E3:D2:F7:C0:0A:CF:70:9A:8B:80:38:B1:CD X509v3 Authority Key Identifier: keyid:27:C8:F7:34:2F:30:81:97:DE:2E:FC:DD:E2:1D:FD:B6:8F:5A:AF:BB X509v3 Basic Constraints: critical CA:TRUE, pathlen:0 X509v3 Key Usage: critical Digital Signature, Certificate Sign, CRL Sign X509v3 CRL Distribution Points: Full Name: URI:http://crl.grilledcheese.us/whomovedmycheese.crl Authority Information Access: CA Issuers - URI:http://ocsp.grilledcheese.us/cheddarcheeseroot.crt OCSP - URI:http://ocsp.grilledcheese.us/ Signature Algorithm: ecdsa-with-SHA384 30:65:02:30:74:07:ba:fe:4b:71:78:d8:d2:7f:84:c0:50:b4: b6:df:6c:f6:57:f5:d9:2c:4b:e1:d4:d8:1d:78:fd:7e:bf:0a: 81:86:bb:40:c5:9b:97:6f:83:04:5f:d3:85:36:6c:d6:02:31: 00:d3:08:78:1c:da:6d:ef:1d:bb:27:df:0b:76:eb:ab:84:b2: 91:04:25:1a:85:5b:d5:c3:cd:66:e4:9e:14:b2:c0:ed:9c:59: b7:18:c3:26:eb:df:78:13:68:47:66:b5:43
Similar to the root, we can note the usage and algorithms but we have the addition of:
* X509v3 CRL Distribution Points: Full Name: URI:http://crl.grilledcheese.us/whomovedmycheese.crl *Authority Information Access: CA Issuers - URI:http://ocsp.grilledcheese.us/cheddarcheeseroot.crt OCSP - URI:http://ocsp.grilledcheese.us/
Create the certificate chain
The root certificate and intermediary certificate must be available to the requesting client/server in order to validate the chain of trust. To complete the trust validation, a certificate chain must be available to the client application. A certificate chain usually takes the form of separate certificates installed into Root and Intermediary containers (as the case for Windows), or bundled together either in a .pfx cert and cert chain bundle or a PEM formatted text file. Concatenate the root and intermediate certificates together to create a PEM certificate chain text file.
# cd /root/ca # $cat intermediate/certs/int.cheese.crt.pem certs/ca.cheese.crt.pem > intermediate/certs/chain.cheese.crt.pem
The file should look similar to this with two separate BEGIN and END statements for each certificate (example condensed for space):
# cat intermediate/certs/chain.cheese.crt.pem -----BEGIN CERTIFICATE----- MIID/TCCA4OgAwIBAgICEAEwCgYIKoZIzj0EAwMwgdQxCzAJBgNVBAYTAlVTMQsw CQYDVQQIDAJXQTEQMA4GA1UEBwwHU2VhdHRsZTEcMBoGA1UECgwTR3JpbGxlZCBD ...... hkjOPQQDAwNoADBlAjB0B7r+S3F42NJ/hMBQtLbfbPZX9dksS+HU2B14/X6/CoGG u0DFm5dvgwRf04U2bNYCMQDTCHgc2m3vHbsn3wt266uEspEEJRqFW9XDzWbknhSy wO2cWbcYwybr33gTaEdmtUM= -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- MIIDQTCCAsegAwIBAgIJAP+99S/FDT0CMAoGCCqGSM49BAMDMIHUMQswCQYDVQQG EwJVUzELMAkGA1UECAwCV0ExEDAOBgNVBAcMB1NlYXR0bGUxHDAaBgNVBAoME0dy ...... CgYIKoZIzj0EAwMDaAAwZQIwd6H54qs6WkvOjWouMD8Bz4523fYfA9mzXKE9bTYE +wH3MycDhd4kVhfJGuQ7NcSoAjEAzQ5s4NUm0/uIVvpnn+m+tI+UHCy3dBnO7BXS /kiTCl//67LTrlpoh9zJLFSNBGh/ -----END CERTIFICATE-----
Note: In the real world hosting application should never have the entire chain available as it defeats a core principle of PKI. It's recommended in test labs to distribute the root certificate to all testing client applications and systems and include only the intermediary along with the server certificate. This way the client can establish the trust between the intermediary and root certificates. Next we'll move on to creating our CLR endpoint list and OCSP certificate.
Our intermediary certificate is now created and signed and we are ready to move on. To complete the CA our next article we will create our certificate revocation list (CRL) endpoint and online certificate status protocol (OCSP) certificate allowing us to revoke certificates. Lab environments rarely need revocation functionality but modern clients check for CLR and OCSP URIs so it's nessisary to have the configruation defined at minimum. Let's proceed.
- RWood_383320Nimbostratus
Very good sequence of articles. I am on the Windows platform using the standard command/DOS windows and was able to follow along for 95% of the instructions. One of the adjustments I had to make was when you combined the creation of the key and SCR in one line. I had to break it up into separate commands (unless someone know the windows version to combine the to commands.)
- privatenet7Nimbostratus
Hi Chase,
Thanks very much for excellent and detailed lessons on how to create Root CA and Intermediate Certificates. You've covered all the revelant variables in each scenario, of which I still coudn't find after extensive searches from other websites. .
The Root CA lesson was easy to follow.
However, the Intermediate Certificate lesson was a bit curly to follow, as detailed below:
1. Uncertain whether to use "[CA]" and "[CA_default]" sections OR "[int_ca]", but I used the former sections and they work:
"/root/ca/intermediate/openssl_intermediate.cnf
and modify the contents for your own naming conventions. Similar to the
root_ca.cnf
, the
[CA]
is required and will gather it's configuration from the
[CA_default]
section. Changes to the
[int_ca]
include:
[ CA_default ]
# Directory and file locations.
dir = /root/ca/intermediate
private_key = $dir/private/int.cheese.key.pem
certificate = $dir/cers/int.cheese.crt.pem
crlnumber = $dir/crlnumber
crl = $dir/crl/int.cheese.crl.pem
crl_extensions = crl_ext
policy = policy_looseWe have new certificate names for our intermediary use and define
policy_loose"
2. v3_intermediate_ca:
Does not matched with Root CA.
Output: [root@ca ca]# openssl ca -config ca.cnf -extensions v3_intermediate_ca -days 256 -md sha384 -in intermediate/csr/int.sansui.csr -out intermediate/certs/int.sansui.crt.pem
Using configuration from ca.cnf
Enter pass phrase for /root/ca/private/ca.sansui.key.pem:
Error Loading extension section v3_intermediate_ca
140437868918672:error:02001002:system library:fopen:No such file or directory:bss_file.c:175:fopen('/root/ca/index.txt.attr','rb')
140437868918672:error:2006D080:BIO routines:BIO_new_file:no such file:bss_file.c:182:
140437868918672:error:0E078072:configuration file routines:DEF_LOAD:no such file:conf_def.c:195:
140437868918672:error:0E06D06C:configuration file routines:NCONF_get_string:no value:conf_lib.c:324:group=CA_default name=email_in3. Missing Distinguished Name in "intermediate.cnf" file:
Output:
[root@ca ca]# openssl req -config intermediate/intermediate.cnf -new -newkey ec:<(openssl ecparam -name secp384r1) -keyout intermediate/private/int.sansui.key.pem -out intermediate/csr/int.sansui.csr
Generating a 384 bit EC private key
writing new private key to 'intermediate/private/int.sansui.key.pem'
Enter PEM pass phrase:
Verifying - Enter PEM pass phrase:
-----
unable to find 'distinguished_name' in config
problems making Certificate Request
140128708568976:error:0E06D06C:configuration file routines:NCONF_get_string:no value:conf_lib.c:324:group=req name=distinguished_nameI got it working with some minor changes.
Can you please confirm do I use the Root CA or the Intermediate Certificate to sign the End Enity? If using the Intermediate Certificate, can you please provide the command syntax?