DevTest supports testing with protocols encrypted with SSL/TLS, and uses the standard Java mechanisms to do so. Unlike other tools, DevTest fully implements TLS in order to provide system-level verification, and therefore security shortcuts are not permitted.
It is therefore necessary that use of the Java SSL/TLS implementation be understood, and that there is familiarity with the SSL protocol itself.
A Brief description of SSL
TLS (Transport Layer Security) and its predecessor, SSL (Secure Sockets Layer), which are commonly referred to just as SSL, is a cryptographic method of securing communications over a computer network.
In this context, secure means
- Privacy - the communication is private – no eaves dropping should be possible
- Authentication – it should not be possible to connect to the wrong end-point
- Message Integrity - The communication has integrity at the data level – the data cannot be tampered with without detection.
SSL ensures privacy by using a 1-off encryption key for each session – this key is negotiated using public-key cryptography at the start of an SSL session. It is a common misconception that the asymmetric public-key cryptography is used throughout a SSL session, however such a scheme would be too computationally expensive, and is there only used to establish the session (the handshake).
SSL ensures that an end-point is that which is expected by verifying the that a certificate is trusted. Trust verification starts with checking that the certificate matches the host being connected to – this implies that the host part of any connection string must match either the CN (Common Name) of the certificate or one of the alternate names. The connection should fail if this is not the case.
Next the certificate will be checked to be “in date” and possibly verified against of list of known revoked certificates. If the certificate is out of date or revoked, then the connection should fail.
Assuming that the certificate matches the connection, the next step of verification is to identify, within the certificate, the entity that issued it. This entity will, in turn, have a certificate associated with it – this certificate may, or may not be a root certificate (all root certificates are self-signed). If it is a root certificate, it is checked to be in a list of certificate that are known to be trustworthy. If it is not a root certificate then its issuer is identified, as above, and this is checked against the list of root certificates that are trusted. This process will continue until the root certificate is reached, and either verified or not.
If the root certificate, or any other members of the certificate chain, are not trusted then the end certificate must not be trusted and the connection should fail.
There is a worked example in “The Anatomy of a Certificate Chain,” following.
3. Message Integrity
Each message contains a MAC (Message Authentication Code) that confirms that the data contained has not been modified since initial transmission. This MAC is a cryptographic hash of the message content and a shared secret token.
The Anatomy of a Certificate Chain
A certificate chain allows verification that a certificate was issued by a trusted body, by recursively checking that the certificate issuer is trusted.
As an example, let us examine a certificate that is commonly encountered-
Certificate 1 in chain
Valid from: 2016-12-01-14:16:00 to: 2017-02-23-14:16:00
Certificate issued to: CN=www.google.com, O=Google Inc, L=Mountain View, ST=California, C=US
Certificate issued by: Intermediate Level Certificate level 1: CN=Google Internet Authority G2, O=Google Inc, C=US
Here the CN refers to the Common Name, which is the entity to whom the certificate was issued. The Alternative Names refers to other ways that the owner of the certificate may be identified.
Of note here is the line starting “Certificate issued by” – this identifies the next level of the certification chain:
Certificate 2 in chain
Valid from: 2015-04-01-01:00:00 to: 2017-12-31-23:59:59
Certificate issued to: CN=Google Internet Authority G2, O=Google Inc, C=US
No Alternative Names
Certificate issued by: Intermediate Level Certificate level 2: CN=GeoTrust Global CA, O=GeoTrust Inc., C=US
Note here that the CN is the issue of the first certificate. Note also that the key may be used to sign other keys and certificates (keyCertSign in the usage field) and may also be used to sign a Certificate Revocation List which is used to declare certificates to be invalid.
This certificate was, in turn, issued by the holder of CN=GeoTrust Global CA, O=GeoTrust Inc., C=US
Certificate 3 in chain
Valid from: 2002-05-21-05:00:00 to: 2018-08-21-05:00:00
Certificate issued to: CN=GeoTrust Global CA, O=GeoTrust Inc., C=US
No Alternative Names
Certificate issued by: Root CA: OU=Equifax Secure Certificate Authority, O=Equifax, C=US
This certificate is broadly similar to the second, and was issued by a Root Certification Authority (CA), who is, in this case Equifax. Your system will hold a copy of the known good root CA certificates that are used to verify the last certificate in the verification chain.
It is necessary to agree to trust the root CA – there is no further verification mechanism other than the certificate being present in a revocation list.
The SSL handshake is used to establish the session, and is based on public-key cryptography. Since this is computationally expensive it is used only to secretly agree on a symmetric shared key that will be used for the rest of the connections life.
The implementation critically depends on two components owned by the server – the key and the certificate. In public-key encryption terminology the key is equivalent to the private key, and the certificate is the analogue of the public key. The mechanisms of public-key encryption are beyond the scope of this document – what needs to be understood is that anything encrypted with the public key can only be decrypted with the private key, and vice versa. The need for different keys at each end of the encrypted communication path is the reason that public-key cryptography is asymmetric encryption.
The handshake begins with the client connecting to the server and issuing a start message which is known as the Client Hello.
In this message the client sends the following information-
- SSL or TLS versions supported by the client, ordered by preference
- Ciphers supported, again ordered by preference
- A random number
- Whether or not compression is supported.
The server responses with the Server Hello. This contains
- A cipher suite chosen from the list supplied by the client
- A session ID
- A further random byes string, adding to that supplied by the client. This will be used to provide message authentication
- The server certificate (recall that this is the “public” key, and may therefore be freely shared).
- If required for mutual authentication a “client certificate request” that includes a list of valid certificate types and signing authorities.
The next actions take place at the client:
- The certificate is checked to be valid
- In date
- Not present on a revocation list
- The server’s certificate trust chain is verified (see above).
- The Common Name and Alternative Names are checked to ensure that one matches the server name used in a connection (for instance https://google.com/fredpage.html).
Assuming that the connection has been validated, the client derives a random byte string from by adding to that sent by the server, and encrypts this string with the certificate. This will be used as the symmetric key for the connection, and is the first component of the exchange that is not sent in plain text.
If the server requested a certificate, it is sent now, together with an authentication string (derived from the random string sent from the server). This authentication string is encrypted with the client’s key, and may therefore be verified by the server decrypting the string with the client’s certificate.
The client’s certificate is verified by the server to match the type and issuers stated in the Server Hello.
If the client does not have a certificate it will send a “no digital certificate alert.” Whilst this alert is not a fatal alert, behaviour of the server when receiving it is implementation dependant, and a server may choose to fail the handshake if a certificate is required.
Following the client response, the client sends a “finished” message to indicate that no further handshake information will be sent. This message is encrypted with the secret key agreed above.
The server will then respond with a “finished” message, likewise encrypted.
How Java Implements SSL Certificates and Trust.
In order to implement SSL, java needs to be made aware of key, certificates and certificate chains, as described above.
In order to make Java aware of these items, one uses “keystores,” which, despite their name, do not hold only keys but also certificates.
There are, principally, three keystores ins use in a typical SSL enabled java application, including DevTest.
At the top of the hierarchy is the cacerts keystore, which is located within the java runtime distribution, typically in jre/lib/security. This file contains the certificates for the Certification Authorities, as suggested by its name. Should you have a private certification authority in your organisation then Oracle suggest that the certificate for this be added to the cacerts file.
truststore (often truststore.ks or truststore.jks)
As with the “cacerts” keystore, this contains certificates that should be trusted, but that which are not, typically, widely published signing certificates. Note that any certificate provided here must either be trusted (via cacerts) or have its entire trust chain present here.
keystore (often keystore.ks or keystore.jks)
This keystore is typically used for certificate/key pairs used by a server or for mutual authentication. Once more, a trust relationship must be present – this can be via the truststore or via cacerts.
The keystores named above are used by a java application differently depending whether the application is performing as a server or as a client.
When the java application is a server, the server’s key and certificate are taken from the keystore. The client certificate, if any, will be verified against the truststore and/or cacerts.
When the application is a client, the server’s certificate is verified against the truststore and caerts. If requested, the client’s certificate (and associated key) are taken from the keystore.
The oracle Java Development Kit (JDK) provide the command line utility keytool that may be used to add or remove certificates and keys from a java keystore, although the syntax is difficult. There are, however, several graphical tools available that greatly simplify the task - of these tools, some examples are KeyStore Explorer, KeyStone and Portecle.
Server Name Identification (SNI) - an Introduction
Server Name Authentication is an optional enhancement to the TLS handshake wherein the client sends the name of the server to which it is connecting in the Client Hello.
The purpose of this enhancement is to allow a single server to host name based virtual servers whilst allowing each to have its own Certificate and Key pair. Prior to SNI, individual named servers would each require a server of their own or rely on a wildcard certificate and reside under a common domain.
With SNI, a single server may host multiple SSL virtual hosts, with the server itself identifying the correct target using the date held in the Client Hello.
For example, consider the following hypothetical example:
website1.fred.net and website2.eric.org are both hosted on the same server. Resolving their IP addresses shows them both to be located at 10.11.12.13.
Performing a reverse lookup of 10.11.12.13 shows that the canonical name of the host is myserver.mycorp.com. Connection directly to 10.11.12.13 confirms this to be valid
When connecting to https://website1.fred.net the client sends website1.fred.net in the Client Hello - this identifies the correct "site" for the server to use. Since the name is sent in the SSL negotiation, the name is unaffected by proxy usage.
The server is able, therefore, to return the correct certificate for the chosen site of website1.fred.net as opposed to the canonical site of myserver.mycorp.com or the alternative website2.eric.org
Diagnosis of SNI issues.
If SNI is suspected to be causing issues with connections from DevTest (or, more generally Java applications) then enabling SSL debugging will expose the characteristic signature of a connection being rejected immediately after sending the Client Hello - the collection will be closed from the server end and no Server Hello will be sent.
SNI and Java 8
There is a known issue with Java 8 supporting SNI correctly in all versions before 8u152. Versions after this should function correctly, but versions prior to this may not send SNI information when expected.
SNI and the Virtual Service Environment (VSE)
DevTest does not support multiple servers being hosted within a single VSE. As the VSE starts, it obtains its host name from the operating system (in the same manner that running the hostname command does) and this is used internally to identify it.
It is therefore essential that the certificate contain the host name as either the Common Name or as an alternative name, and that the connection name match this. Should connections have to be made using the IP address of the server then this should also be present in the certificate.