Openssl: Setup an intermediate CA

Hi,

first ramp up your root CA as described in my previous post.
Steps to create a intermediate CA. Create the intermediate CA structure in filesystem




1
2
3
4
5
cd
pwd
/root
mkdir -p intermediateCA
mkdir -p intermediateCA/crl intermediateCA/certs intermediateCA/newcerts intermediateCA/private intermediateCA/conf

Create the openssl config file /root/intermediateCA/conf/openssl.cnf

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
#
# openssl.cnf root CA config
#
# /root/intermediateCA/conf/openssl.cnf
#
[ ca ]
default_ca = myintermediateCA
 
[ myintermediateCA]
# Directory and file locations.
dir               = /root/intermediateCA
certs             = $dir/certs
crl_dir           = $dir/crl
new_certs_dir     = $dir/newcerts
database          = $dir/index.txt
serial            = $dir/serial
RANDFILE          = $dir/private/.rand
 
# The root key and root certificate.
private_key       = $dir/private/intermediateca.key
certificate       = $dir/certs/intermediateca.cer
 
# For certificate revocation lists.
crlnumber         = $dir/crlnumber
crl               = $dir/crl/crl.pem
crl_extensions    = crl_ext
default_crl_days  = 90
 
# Use at least sha256
default_md        = sha256
 
name_opt          = ca_default
cert_opt          = ca_default
default_days      = 3650
preserve          = no
policy            = policy_strict
 
[ policy_strict ]
# The root CA should only sign intermediate certificates that match.
countryName             = match
stateOrProvinceName     = match
organizationName        = match
organizationalUnitName  = optional
commonName              = supplied
emailAddress            = optional
 
[ policy_loose ]
# Allow the intermediate CA to sign a more diverse range of certificates.
countryName             = optional
stateOrProvinceName     = optional
localityName            = optional
organizationName        = optional
organizationalUnitName  = optional
commonName              = supplied
emailAddress            = optional
 
[ req ]
default_bits        = 2048
distinguished_name  = req_distinguished_name
string_mask         = utf8only
 
# Use at least sha256
default_md          = sha256
 
# Extension for -x509 option
x509_extensions     = v3_root_ca
 
[ req_distinguished_name ]
countryName                     = Country Name (2 letter code)
stateOrProvinceName             = State or Province Name
localityName                    = Locality Name
0.organizationName              = Organization Name
organizationalUnitName          = Organizational Unit Name
commonName                      = Common Name
emailAddress                    = Email Address
 
# Defaults
countryName_default             = DE
stateOrProvinceName_default     = Germany
localityName_default            = Nuremberg
0.organizationName_default      = my Company
organizationalUnitName_default  = my Department
emailAddress_default            = me@mycompany.org
 
[ v3_root_ca ]
# Extensions for the CA
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid:always,issuer
basicConstraints = critical, CA:true
#keyUsage = critical, digitalSignature, cRLSign, keyCertSign
keyUsage = critical, cRLSign, keyCertSign
 
[ v3_intermediate_ca ]
# Extensions for the intermediate CA
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid:always,issuer
basicConstraints = critical, CA:true, pathlen:0
#keyUsage = critical, digitalSignature, cRLSign, keyCertSign
keyUsage = critical, cRLSign, keyCertSign
 
[ client_cert ]
# Extensions for client certificates
basicConstraints = CA:FALSE
nsCertType = client, email
nsComment = "OpenSSL Generated Client Certificate"
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid,issuer
keyUsage = critical, nonRepudiation, digitalSignature, keyEncipherment
extendedKeyUsage = clientAuth, emailProtection
 
[ server_cert ]
# Extensions for server certificates
basicConstraints = CA:FALSE
nsCertType = server
nsComment = "OpenSSL Generated Server Certificate"
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid,issuer:always
keyUsage = critical, digitalSignature, keyEncipherment
extendedKeyUsage = serverAuth,clientAuth
 
[ crl_ext ]
# Extension for CRL
authorityKeyIdentifier=keyid:always
 
[ ocsp ]
# Extension for OCSP signing certificates
basicConstraints = CA:FALSE
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid,issuer
keyUsage = critical, digitalSignature
extendedKeyUsage = critical, OCSPSigning

create index und serial file

1
2
3
4
cd intermediateCA
touch index.txt
echo 1000 > serial
echo 1000 > crlnumber

If specified, openssl using the config defined at environment variable OPENSSL_CONF. Otherwise you have to set command line option -config for each command line call. When you omit the pass* parameter openssl will prompt for the password.

1
2
3
export OPENSSL_CONF=/root/intermediateCA/conf/openssl.cnf
openssl genrsa -aes256 -out private/intermediateca.key -passout pass:YourSecurePassword 4096
chmod 400 private/intermediateca.key

Show key details

1
openssl rsa -in private/intermediateca.key -text

Create a siging request for your intermediate CA.
Note: countryName (C), stateOrProvinceName (ST) ,organizationName (O) must match to the corresponding root CA properties(see openssl.cnf section policy_strict). The common name (CN) must differ

1
openssl req -key private/intermediateca.key -new -sha256 -out certs/intermediateca.csr -subj "/C=DE/ST=Frankonia/L=Nuremberg/O=my Company/OU=my Department/CN=My intermediateca CA 2017" -passin pass:YourSecurePassword

View details of your new intermediate CA certificate

1
openssl req -in certs/intermediateca.csr -text -noout


Switch to the root CA environment and sign the intermediate CA csr with your root CA certifiate with the x509v3 intermediate extensions.

1
2
export OPENSSL_CONF=/root/CA/conf/openssl.cnf
openssl ca -extensions v3_intermediate_ca -days 3650 -notext -md sha256 -in certs/intermediateca.csr -out certs/intermediate.cer -passin pass:YourSecurePassword

Show the details of your intermediate CA certificate

1
openssl x509 -in certs/intermediate.cer -text -noout

Verify the chain

1
2
openssl verify -CAfile /root/CA/certs/ca.cer certs/intermediate.cer
certs/intermediate.cer: OK

Create a file with the complete chain

1
cat /root/CA/certs/ca.cer certs/intermediate.cer >certs/fullchain.cer

Revoke the intermediate CA ceritifcate

1
2
3
export OPENSSL_CONF=/root/CA/conf/openssl.cnf
openssl ca -revoke /root/intermediateCA/certs/intermediate.cer -passin pass:YourSecurePassword
openssl ca -gencrl -out /root/CA/crl/crl.pem -passin pass:YourSecurePassword

If the company- , the state or province- or the Organization name differs from the root CA then you have to adjust the policy from policy_strict to policy_loose in the openssl.cnf file of your root CA:
policy = policy_loose

otherwise you get an error: The organizationName field is different between

Michael

4 thoughts on “Openssl: Setup an intermediate CA”

  1. Not worked here:

    openssl ca -extensions v3_intermediate_ca -days 3650 -notext -md sha256 -in certs/intermediateca.csr -out certs/intermediate.cer -passin pass:YourSecurePassword

Leave a Reply