I would like your help identifying why step 5 (near the end) is necessary.
I have a working set of steps that create a keystore.ks with a chain that includes a local Certificate Authority cert. HTTPS communication between the master tomcat (the client) and the slave tomcat (the server) work; which is great, except I am concerned that I'm including to much in the slave keystore.ks.
The master tomcat (the client) has a truststore.ks which has a single entry which was created this way:
1) Create a new private key and a new certificate (CA) file (new_ca.pem):
openssl req -x509 -passout pass:mykeypassword -new -config caConfig.txt -days 7300
-out new_ca.pem -keyout new_ca_pk.pem
2) Import into the truststore.ks
keytool -importcert -noprompt -alias myrootca -keypass mykeypassword
-keystore truststore.ks -storepass changeit -storetype jks -file new_ca.pem
The slave tomcat (the server) has a keystore.ks with a single entry created this way:
1) Generate a certificate and private key pair:
keytool -genkey -noprompt -dname "CN=10.93.101.33, C=US, O=MyCompany, OU=MyCompany
Manufacturing, ST=MA, L=MyTown" -validity 7000 -alias tomcat -keypass aPassword
-keystore keystore.ks -storepass aPassword
2) Create a certificate signing request
keytool -certreq -alias tomcat -file 10.93.101.33.csr -keypass aPassword
-keystore keystore.ks -storepass aPassword
3) Sign the CSR
openssl ca -batch -passin pass:mykeypassword -config caConfig.txt -days 7000
-in 10.93.101.33.csr -out 10.93.101.33.crt
4) Convert to PEM format
openssl x509 -in 10.93.101.33.crt -out 10.93.101.33.crt -outform PEM
5) Concatenate the files
cat 10.93.101.33.crt new_ca.pem > 10.93.101.33.chain
6) Update keystore with the full certificate chain
keytool -import -alias tomcat -noprompt -file 10.93.101.33.chain -keypass aPassword
-keystore keystore.ks -storepass aPassword
The above steps DO create a working system. The client tomcat can communicate with the server tomcat via https without the issues of trust. I'm concerned with a couple of things, why do I need to add the CA cert to the server tomcat's keystore? Lastly, is there an easier way of doing this?
Thanks for your time.
---------- EDIT --------------
The complete caConfig.txt:
HOME = /home/hammer/hmweb/CertificateGenerator/CACertificate
RANDFILE = $ENV::HOME/.rnd
dir = $HOME
[ ca ]
default_ca = CA_default
[ CA_default ]
serial = $dir/serial.txt
database = $dir/index.txt
unique_subject = no
new_certs_dir = $dir/newcerts
certificate = $dir/new_ca.pem
private_key = $dir/cakey.pem
crl = $dir/crl.pem
default_days = 7300
default_crl_days = 3650 # how long before next CRL
default_md = sha1
preserve = no
email_in_dn = no
policy = policy_match
x509_extensions = usr_cert
# Comment out the following two lines for the "traditional"
# (and highly broken) format.
name_opt = ca_default # Subject Name options
cert_opt = ca_default # Certificate field options
# For the CA policy
[ policy_match ]
countryName = match
stateOrProvinceName = match
organizationName = match
organizationalUnitName = optional
commonName = supplied
emailAddress = optional
# For the 'anything' policy
# At this point in time, you must list all acceptable 'object'
# types.
[ policy_anything ]
countryName = optional
stateOrProvinceName = optional
localityName = optional
organizationName = optional
organizationalUnitName = optional
commonName = supplied
emailAddress = optional
####################################################################
[ req ]
default_bits = 2048
default_keyfile = cert.key
string_mask = MASK:0x2002
utf8 = yes
prompt = no
distinguished_name = req_distinguished_name
policy = policy_anything
x509_extensions = v3_ca # The extensions to add to the self signed cert
####################################################################
[ usr_cert ]
# These extensions are added when 'ca' signs a request.
# This goes against PKIX guidelines but some CAs do it and some software
# requires this to avoid interpreting an end user certificate as a CA.
basicConstraints=CA:FALSE
# This will be displayed in Netscape's comment listbox.
nsComment = "OpenSSL Generated Certificate"
# PKIX recommendations harmless if included in all certificates.
subjectKeyIdentifier=hash
authorityKeyIdentifier=keyid,issuer:always
[ req_distinguished_name ]
countryName = US
stateOrProvinceName = MA
localityName = MyTown
0.organizationName = MyCompany
organizationalUnitName = MyCompany Manufacturing
commonName = !!COMMON_NAME_REPLACE_ME!!
[ v3_req ]
# Extensions to add to a certificate request
basicConstraints = CA:FALSE
subjectKeyIdentifier = hash
[ v3_ca ]
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid:always,issuer:always
basicConstraints = CA:true
You only need step 5 if a chain is required. (This is a very similar problem to what's described for a client-certificate chain in this question.)
The minimal requirement is to include the chain of certificate up to, but excluding, the CA that can be expected to be one of the trust anchors (truststore) of the remote party. Your step 5 isn't necessary if you can expect the remote party to trust the CA that issued the certificate itself (which is indeed the case according to the way you've built the client truststore). Needless to say that if you skip step 5, you'll still need step 6 with the certificate file (i.e. chain of length 1) instead of the concatenated chain file.
For example:
Assuming you have: "Server Cert" issued by "Root CA"
Either the client has the "Root CA", or it doesn't. In both cases, there's no point sending the "Root CA", since it won't give additional information to the client. A client that trusts "Root CA" will be able to build a certificate path from "Server Cert"; a client that doesn't simply won't be able to trust that server cert anyway.
Assuming you have: "Server Cert" issued by "Intermediate CA 1" issued by "Intermediate CA 2" issued by "Root CA"
Of course, example 1 is merely a special case of example 2. This is why some people are reluctant to use the expression "Root CA": whether a CA cert sits at the top of a chain and is self-signed is barely relevant when constructing the chain of trust. All you need is the remote party to trust in advance a CA certificate that will be able to verify that last certificate in the chain you present (whether that chain is of length 1 or more).