How to setup HTTPS within Jetty: intermediate certificates

Introduction

The following concepts are needed to fully understand this article.

Intermediate Certificate

An intermediate certificate is a subordinate certificate issued by the trusted root specifically to issue end-entity server certificates. The result is a certificate chain known as Chained Root Certificates or Chain of Trust.

  1. The client sends a request to the SSL server.
  2. The server responds with the Identity and Intermediate certificates.
  3. The client confirms authenticity of the Intermediate certificate by decrypting the digital signature using the Root CA public key.
  4. Next the client confirms the authenticity of the Identity certificate by decrypting the digital signature using the Intermediates public key.
  5. The client then clarifies that the URL that is being requested by matching the DN (Distinguished Name) within the Identity Certificate.
  6. Traffic is then encrypted/decrypted by a) the client using the public key b) the server using the private key.

Chain of Trust

Filename extensions for X.509 certificates

Common filename extensions for X.509 certificates:

  • .pem – (Privacy-enhanced Electronic Mail) Base64 encoded DER certificate, enclosed between “—–BEGIN CERTIFICATE—–” and “—–END CERTIFICATE—–”
  • .cer, .crt, .der – usually in binary DER form, but Base64-encoded certificates are common too (see .pem above)
  • .p7b, .p7c – PKCS#7 SignedData structure without data, just certificate(s) or CRL(s)
  • .p12 – PKCS#12, may contain certificate(s) (public) and private keys (password protected)
  • .pfx – PFX, predecessor of PKCS#12 (usually contains data in PKCS#12 format, e.g., with PFX files generated in IIS)

On the other hand, .key is a file containing just the private-key of a specific certificate and is merely a conventional name and not a standardized one. It is .pem formatted.

Issue

  • Installing SSL certificate chains in Jetty.
  • How to publish Jenkins using HTTPS with an intermediate certificate.
  • The Chained Root Certificates or Chain of Trust is broken.

Environment

  • CloudBees Jenkins Enterprise
  • CloudBees Operation Center
  • Jenkins and the embedded Jetty HTTPS

Resolution

## Requirements:

  1. An exiting SSL cert for Jenkins - As example, $MYJENKINS.pfx but other formats are also possible.

  2. Identity Certificate files also known as Domain Certificate - $IDENTITY.crt.

  3. Intermediate Certificate should have the same class as your Domain Certificate - $INTERMEDIATE.crt.

  4. Root Certificate - $ROOT.crt

Notes:

a. Any of the certificates (2, 3 and 4) start with “—–BEGIN CERTIFICATE—–“. Please, make sure there is an end-of-line at the end of the file.

b. Certificates 3 and 4 should be available to download from your SSL Issuer.

## Steps:

1. Extract the private key from your own SSL certificate into a .key file. By default, it is in .pem format so it needs to be converted into PKCS#12 because it is the format required by Jetty Winstone container.

openssl pkcs12 -nocerts -in $MYJENKINS.pfx -out $MYJENKINS.key

2. cat together all the certificates in the chain. Order is important.

cat $IDENTITY.crt $INTERMEDIATE.crt $ROOT.crt  >  $NAME.chain.txt

3. Combine certificates and private key into a .p12 file.

openssl pkcs12 -export -inkey $MYJENKINS.key -in $NAME.chain.txt -out $NAME.chain.p12

4. Finally, create a keystore containing it all. Make sure the keystore file does not already exist.

keytool -importkeystore -srckeystore $NAME.chain.p12 -srcstoretype PKCS12 -destkeystore $MYJENKINS.keystore 

5. Test that the 3 certificates are included into the keystore

keytool -list -v -keystore "/path/to/$MYJENKINS.keystore"

A similar output like this should be displayed on the Terminal:

Keystore type: JKS
Keystore provider: SUN

Your keystore contains 1 entry

Alias name: 1
Creation date: Jun 24, 2016
Entry type: PrivateKeyEntry
Certificate chain length: 3
Certificate[1]:
Owner: CN=*.$YOUR_DOMAIN.com, ...
Issuer: CN=$YOUR_ISSUER Secure Certificate Authority  ...

...

Certificate[2]:
Owner: CN=$YOUR_ISSUER Secure Certificate Authority  ...
Issuer: CN=$YOUR_ISSUER Root Certificate Authority  ....

...

Certificate[3]:
Owner: CN=$YOUR_ISSUER Root Certificate Authority ...
Issuer: CN=$YOUR_ISSUER Root Certificate Authority ...

...

Notes:

a. If you have set different Jenkins environments (for instance TEST, DEV and PROD), steps from 2 to 5 should be repeated in each of those environments.
b. The resulting $MYJENKINS.keystore file must then be copied to each of machines to the path specified by --httpsKeyStore=/path/to/$MYJENKINS.keystore parameter of the Jenkins Arguments.

References

Have more questions? Submit a request

0 Comments

Please sign in to leave a comment.