I'm ultimately attempting to get a PHP CAS client (zend server 8 with apache) to trust a CAS server (tomcat 7), and to that end have gone as far as to gin up my own private key infrastructure, here seen with password replaced with buttocks:


#root key
openssl genrsa -out rootCA.key -aes256 -passout pass:butts 4096
openssl req -x509 -new -key rootCA.key -out rootCA.crt -subj '/C=US/O=World Domination/CN=WorldDom Root CA' -days 3650 -sha256 -passin pass:butts

#intermdiate key
openssl genrsa -out intermediateCA.key -aes256 -passout pass:butts 4096
openssl req -new -key intermediateCA.key -out intermediateCA.csr -subj '/C=US/O=<orgname>/CN=<orgname> Intermediate CA' -passin pass:butts

#X509V3 extension config file
cat <<EOF > v3_ca.ext 

#sign intermediate with root key & X509V3 extensions
openssl x509 -req -in intermediateCA.csr -CA rootCA.crt -CAkey rootCA.key -CAcreateserial -CAserial rootCA.srl -extfile v3_ca.ext -out intermediateCA.crt -days 365 -sha256 -passin pass:butts

#works at this stage
openssl verify -CAfile rootCA.crt intermediateCA.crt
openssl x509 -in intermediateCA.crt -text

openssl genrsa -out server.key -aes256 -passout pass:butts 4096
openssl req -new -key server.key -out server.csr -subj '/C=US/O=<orgDiv>/CN=CASsrv' -passin pass:butts
openssl x509 -req -in server.csr -CA intermediateCA.crt -CAkey intermediateCA.key -CAcreateserial -CAserial intermediateCA.srl -out server.crt -days 365 -sha256 -passin pass:butts

#decrypt for web server use
mv server.key server.key.secure
openssl rsa -in server.key.secure -out server.key -passin pass:butts

openssl genrsa -out client.key -aes256 -passout pass:butts 4096
openssl req -new -key client.key -out client.csr -subj '/C=US/O=<orgSubDiv>/CN=ZServer/emailAddress=test@example.com' -passin pass:butts
openssl x509 -req -in client.csr -CA intermediateCA.crt -CAkey intermediateCA.key -CAcreateserial -CAserial intermediateCA.srl -out client.crt -days 365 -sha256 -passin pass:butts
cat intermediateCA.crt rootCA.crt > CAchain.pem
openssl pkcs12 -export -passout pass:butts -in client.crt -inkey client.key -certfile CAchain.pem -out client.p12 -passin pass:butts

#works here too
openssl verify -CAfile CAchain.pem server.crt (or client.crt)
openssl x509 -in server.crt -text   

Now CAchain.pem, server.crt & server.key files can be used in Apache HTTP Server, for example, to enable HTTPS. rootCA.crt certificate should be imported to the trusted authorities in browser or mail client.

Ostensibly rootCA.crt certificate should be imported to the trusted authorities in browser or mail client. This too is a strange journey:

rootCA import

sudo cp rootCA.crt /etc/ssl/certs/worldDomCA.crt
#symlink named after its hash.4, hash result is same after rename so I used the local version rather than the renamed etc/ssl version
sudo ln -s /etc/ssl/certs/worldDomCA.crt /etc/ssl/certs/'openssl x509 -hash -noout -in rootCA.crt'.4
#this just hangs, disturbingly
openssl verify -CApath /etc/ssl/certs/worldDomCA.crt

Admittedly, I'm not sure where even to put the CAchain & server cert files, but more notably s_client complains that the cert's still self-signed somehow, instead of just hanging like verify. Judging from the subject & issuer lines


the certs include the DN of the box on which they where forged. Could I get away with this if I made my CAs on another box, then brought it in & used it to sign my server/client certs? Notably both servers are running on the same box, since this whole mess is still under exploratory evaluation.


To verify your chain you need to add the trust anchor to OpenSSL's list. This consists of placing your root CA certificate in a known location and running the update-ca-trust command.

On my Fedora system, the directory is /etc/pki/ca-trust/source/anchors. Running update-ca-trust appends the certificate to /etc/pki/ca-trust/extracted/openssl/ca-bundle.trust.crt. Different distros use different paths, so some research may be needed here.

To verify the path run:

$ openssl verify -CApath /etc/pki/ca-trust/extracted/openssl/ca-bundle.trust.crt -untrusted intermediateCA.crt server.crt
server.crt: OK

Again, the path to -CApath may be different on your machine.

openssl s_client checks the certificates as a SSL/TLS client. Therefore you point it at a remote server URL. Before that, you need to install both the subordinate CA certificate and the end-entity (server) certificate and private key on that remote machine. That process, of course, depends on what application you're using for your remote server. For example, with apache you place the files in a sensible location and point to them in your site configuration with:

SSLEngine on
SSLCertificateFile /etc/pki/tls/certs/server.crt
SSLCertificateKeyFile /etc/pki/tls/private/server.key    
SSLCertificateChainFile /etc/pki/tls/certs/world-domination.ca-bundle

(Note that SSLCertificateChainFile is deprecated from version 2.4.8 onwards)

The output you have seems to suggest that the currently installed certificates on that remote machine are the self-signed ones generated at install time.

  • update-ca-trust seems to not exist in SLES 11, but it turns out that was what my CAchain file is actually for, as openssl wants the full chain of trust but only takes the two file arguments. However, it turns out that actually I need to get tomcat to present a server cert signed by my PKI CA, and get apache to trust that -- the reason I keep getting self-signed is that it's looking at the Tomcat server cert. Does s_client necessarily have to point at a /remote/ server? Again, both actors are on the same box, the php server's just on port 80 while CAS is on the tomcat server at 8443. – Archgeek Apr 1 '16 at 15:53
  • You need Tomcat to present the certificate bundle, not a single certificate (assuming you have more than one in the chain) - that is specified in the RFC for SSL/TLS. openssl s_client can point at localhost if needed - it doesn't care as long as there's a service listening. – garethTheRed Apr 2 '16 at 8:51

Welp, 'turns out the the answer is "Yes, but no need." Most of that PKI generation there is just fine, though not all of those files actually get used -- the CAchain files aren't really needed save for verification as openssl verify only takes two arguments, the client files weren't needed, and the srl files are byproducts. At issue is the issuing CN matching the requesting CN, as clients check certs by domain.

In order to get Tomcat to present the PKI cert and not the self-signed cert a lot of guides recommend to get HTTPS up and running, there are two additional steps:

convert to pkcs12

openssl pkcs12 -export -chain -passout pass:butts -in server.crt -inkey server.key -out server.p12 -name alias -CAfile (intermediateCA.crt or CAchain.crt) -caname steeve

then import to Tomcat'sJKS keystore

...making sure the new entry matches what tomcat's config is looking for, and changing the alias of the original first

keytool -changealias -alias tomcat -destalias derpcat -storepass changeit
keytool -importkeystore -deststorepass changeit -destkeypass changeit -destkeystore server.keystore -srckeystore server.p12 -srcstoretype PKCS12 -srcstorepass butts -alias tomcat

storepass and keypass must match for this to work.

s_client still burbles about the rootCA being self-signed, and the rootCA needs to be installed by the client (I can't blame them for not trusting "World Domination"), but the CAS redirect SSO is now running seamlessly.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.