King Midas was a greedy king and was granted a wish by Dionysus, the god of wine. The king wished that every thing he touched turned into gold. His wish was granted, and every thing he touched turned to gold. As a result he died of starvation. There is also a saying that you cannot make a silk purse out of a pig’s ear. I feel I have been gifted with the ability that anything I touch, breaks; as they say, making a pig’s ear out of a silk purse.
I thought changing my queue manager from using TLS 1.2 to TLS 1.3 would be easy. This blog post describes my journey. It was easy – I just had one problem which was easy to solve once I had spent a couple of hours work to identify the problem.
A short history of cipher specs in MQ.
In TLS 1.2 a cipher has a name like TLS _ KeyexchangeAlgorithm _ Keytype _ WITH _ BulkEncryption _ HashFunction. The values have to be consistent at both ends, and the Keytype must match the certificate used during the hand shake. Names like ECDHE_ECDSA_AES_128_CBC_SHA256 are the same as of TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, with the TLS_ chopped off and shortened. See here.
During the TLS 1.2 handshake the client sends a list of cipher suites it supports. The server has a list of cipher suites it supports. The lists are merged and any cipher specs in both lists are used in the subsequent processing. The lists can have 1 or more elements in them.
With the server, it is a bit more subtle than this. The client sends its list of cipher suites to the server. The server has a list of cipher suites it will accepts. In MQ 9.2 the qm.ini has
- AllowTLSV13 whether to add the TLS 1.3 cipher specs to the standard list. It defaults to yes.
- AllowedCipherSpecs which allows you to specify which cipher specs can be used in the handshake. It has a default list.
The first cipher spec which is in both the client and server lists is passed to the next stage of processing; checking with the svrconn channel’s SSLCIPHR parameter.
In MQ 9.1 and before, the channel lists had only one element in them. This meant the cipher spec TLS_A_B_WITH_C_D had to be specified at each end of the channel. If you wanted to change the cipher spec you had to change the svrconn channel definition, and all of the client’s definitions to use the new cipher spec – and then restart all of the channels. This was difficult to do, and hard to roll back.
In 9.1.1 the ANY_TLS12 list was implemented. This is a list of cipher specs, for example TLS_A_B_WITH_C_D, TLS_A_B_WITH_E_F, TLS_X_Y_WITH_C_D, TLS_X_Y_WITH_E_F.
During the handshake the client passed its cipher spec to the server. If the cipher spec was in this list the handshake would work. This meant client1 could use TLS_A_B_WITH_C_D and client2 could use a different cipher spec TLS_X_Y_WITH_E_F.
Client1 can easily change to use a stronger cipher spec TLS_X_Y_WITH_E_F. It just has to change its definition and restart.
This means you can do a phased change of clients using a channel.
You can specify the order of the cipher specification in the AllowedCipherSpecs list. Usually the order is strong to weak.
I recommend using the ONLY_TLSxx_OR_ABOVE so any supported cipher specs can be used.
|ANY_TLS12||ANY_TLS12||Yes TLS 1.2|
|ANY_TLS12||ANY_TLS12_OR_ABOVE||Yes TLS 1.2|
|ANY_TLS12_OR_ABOVE||ANY_TLS12||No. It will try default to TLS 1.3 and fail|
|ANY_TLS12_OR_ABOVE||ANY_TLS12_OR_ABOVE||Yes TLS 1.2 or 1.3, Default will be 1.3|
|ANY_TLS12_OR_ABOVE||ANY_TLS13||Yes TLS 1.3 – but not TLS 1.4 when it comes out|
|ANY_TLS12_OR_ABOVE||ANY_TLS13_OR_ABOVE||Yes TLS 1.3|
How to migrate clients to newer levels of TLS.
Now that MQ supports list of cipher specs the migration should be pretty easy.
Take the scenario where two different customers, needs to connect to my queue manager. Before 9.1.x it would have been very difficult to coordinate changes between the customers, who may be in different time zone.
The steps are
- Change the svrconn channel to the highest available list, for example
- With MQ 9.1.1 you can use ANY_TLS12
- With MQ 9.1.4 you can use ANY_TLS_12_OR_HIGHER
- With MQ 9.2 you can specify ANY_TLS13_OR_HIGHER (but do not use this till you have finished upgrading to TLS 1.3).
- Do this for all queue managers the client connects to.
- For the first client, change the client definition to use the server supported level. If the client code is at 9.1.4 or higher then should can use ANY_TLS_12_OR_HIGHER (best), or give a specific TLS 1.x certificate . See here for the list. The client cipher spec value must not be greater than the svrconn’s SSLCIPH value on all queue managers.
- Restart your client. If there are problems you can revert to the previous value and restart the client.
- Use DIS CHS(…) ALL on the server. It will list information like SSLCIPH(TLS_CHACHA20_POLY1305_SHA256). This is a TLS 1.3 cipher spec. Find any cipher specs which are not TLS 1.3 and fix then.
- Once you had done this for all clients using the channel, and for all queue managers using this channel, you should then be able to change the server definition to be ANY_TLS_13_OR_HIGHER and it should continue to work.
- You do not have to change the client to ANY_TLS13_OR_HIGHER, but you can as part of annual upgrade. It prevents people creating a server with a TLS lower than 1.3, and having clients connect to it.
What happened to me…
I set ANY_TLS_12_OR_HIGHER at the client, and ANY_TLS_12 at the server – so the wrong way round (but I did not know this at the time).
During the handshake the client agreed with the queue manager to use TLS_CHACHA20_POLY1305_SHA256, a TLS 1.3 cipher spec. This was then checked by the channel code which was ANY_TLS12. The “agreed” cipher spec was not supported so gave me the client AMQ9641E message.
EXPLANATION: The remote end of channel ‘…’ on host …’ has indicated a CipherSpec error ‘SSLCIPH(TLS_CHACHA20_POLY1305_SHA256 ) -> SSLCIPH(… )’. The channel did not start.
and the server message
AMQ9631E: The CipherSpec negotiated during the SSL handshake does not match the required CipherSpec for channel ‘…’.
There is a mismatch between the CipherSpecs on the local and remote ends of channel ‘ECRSA1024’. The channel will not run until this mismatch is resolved. The CipherSpec required in the local channel definition is ‘ANY_TLS12’. The name of the CipherSpec negotiated during the SSL handshake is ‘TLS_CHACHA20_POLY1305_SHA256’.
Action to resolve it
- If I changed the svrconn channel to ANY_TLS12_OR_HIGHER it worked, and the session used a TLS 1.3 cipher spec.
- I could have changed the client to have ANY_TLS12 but I could potentially have a lot of clients to change. Changing the svrconn was much simpler.