This blog post started as one line in the Using z/OS LDAP with TLS post. After it took two days to get working, I thought it deserved its own page.
Displaying the handshake
Using Wireshark to display TLS traffic is harder with TLS 1.3, as most of the handshake is now encrypted. See here on how to display it.
What supports LDAP and TLS 1.3?
I could not get Openldap on Ubuntu 18.04 to use TLS 1.3 – I do not think it has the support.
I could use the z/OS LDAPSEARCH with TLS 1.3, see below.
Java should work with the right set up.
Updating LDAP server on z/OS
Updates to enable TLS V1.3 protocol support for GSKIT has some good information.
You need to add the following to the configuration file
# TLS 1.3 only supports sslFipsState off
Below are the environment variables I used for the LDAP server on z/OS
I think this is the super set of data, and should be used as a starter list. You can remove unwanted cipher specs once you have it working. It is easier doing it this way compared to adding those you need (because it is hard to find what you need).
You need to add the TLS 1.3 cipher specs to the GSK_V3_CIPHER_SPECS_EXPANDED in the environment file.
This variable needs to include 0806,0805,0804.
TLSv1.3 uses client and server key-shares to facilitate the encryption of TLSv1.3 handshake messages and to determine the key exchange algorithms.
You give a preference as to which elliptic curve to use.
You need to list the key shared values (from this list (table 5)), where secp256r1 has the value 0023.
GSK_SERVER_TLS_KEY_SHARES is used by the server. The client has GSK_CLIENT_TLS_KEY_SHARES
Remove any definitions in the keyshares which are not supported by TLS 1.3 (0019 and 0021) (even though you have GSK_PROTOCOL_TLSV1_2=on)
With these my LDAP started.
Once you have LDAP working, you can review the cipher specs, and remove the ones you no longer use. You should plan to remove the weaker cipher specs. If you remove a cipher spec and it is still needed, clients will fail to connect. You will need to replace the cipher specs and restart the server.
Using openssl s_client on Linux to establish a session to LDAP on z/OS.
Openssl s_client sends the TLS 1.3 supported cipher specs as part of the initial client hello handshake, so you can see the flows.
When I did this I got
s_client fails with SSL alert number 42.
From the z/OS GSK trace I can see
ERROR check_cert_extensions_3280_and_later(): authorityKeyIdentifier extension is missing
ERROR validate_certificate_basics(): Unable to verify certificate extensions: Error 0x0335306f
ERROR validate_certificate_mode(): Unable to validate certificate: Error 0x0335306f
ERROR cms_validate_certificate_mode_int(): Unable to validate certificate: Error 0x0335306f
ERROR read_tls13_certificate(): Unable to validate peer certificate: Error 0x0335306f
ERROR send_tls13_alert(): Sent TLS 1.3 alert 42 to 10.1.0.2
Where 0x0335306f (search for 0335306f) is
A certificate extension that is mandatory for the certificate to be used for the required purpose has not been found.
Ensure that the certificate chain is correct and complies with the validation mode defined for the connection. Collect a System SSL trace containing the error and then contact your service representative if the error persists.
A certificate authority can use multiple certificates to sign a certificate, for example you are refreshing or upgrading the certificate. Having the authorityKeyIdentifier says which certificate was used to sign it.
On the web there are documents which recommend its use, for example with openssl, the configuration file should have.
[ v3_ca ] subjectKeyIdentifier=hash authorityKeyIdentifier=keyid:always,issuer:always
On z/OS with RACF you get this attribute when using RACDCERT GENCERT … SIGNWITH() .
On my system I had misconfigured it
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid:always, issuer
I had to
- create a new CA with the above in the Openssl configuration file
- reissue the end user certificate
- update all my servers with the new CA
- update my LDAP CRL server
Wow – what a lot of work for a user error.
When I had done the above work, I used the
openssl x509 -in rsaca256.pem -text -noout
to list the end user certificate, and there was additional information
X509v3 Authority Key Identifier:
Using openLDAP ldapsearch on Ubuntu 18.04
I had problems getting ldapsearch on Linux to work with TLS 1.3, because it was difficult to get TLS 1.3 support – it did not send the TLS 1.3 cipher specs as part of the Client Hello. The documentation describes TLS_CIPHER_SUITE option. The Openssl syntax did not work, and the GnuTLS Syntax did work but I could not get it working with TLS 1.3 – perhaps it is not supported.
Using ldapsearch from z/OS
This was easy to set up, and I could use the gsktrace from each end to observe the flows.
I set up a bash script
tls=”-Z -K adcda/MQRING -N ADCDRSA -S EXTERNAL”
tls=”-Z -K adcda/MQRING -N ADCDEC -S EXTERNAL”
host=”-h 127.0.0.1 -p 1389″
host=”-h 10.1.0.2 -p 9443″
ldapsearch $host $tls $debug -b “o=Your Company” “(objectclass=*)” aclEntry
gsktrace colin.* > out
I defined an environment variable more than once, so I just needed to move the line down to change what was used. For example by swapping over the “tls” lines I could quickly use a different certificate.
I added the commands to format the gsktrace and display it.
Because I used the debug value “-d error+conns” I got
CONNS ldap_ssl_socket_init()1600: 4-byte ciphers format will be used
CONNS ldap_ssl_socket_init()1625: No 4-byte cipher specs specified in LDAP handle
CONNS ldap_ssl_socket_init()1689: SSL Protocol Version = 621
CONNS ldap_ssl_socket_init()1700: SSL Cipher Specs
Address: 1FA36946 Length: 4 (x’4′)
00000000: f1f3f0f3 *1303 *
ERROR ldap_parse_pwdpolicy_response_int()856: No server controls o=Your Company
I think these messages are OK, and do not show a problem.
You can see that cipher spec 1303 was used.
TLS 1.3 uses one of the following ciphers
- TLS_AES_128_GCM_SHA256 -1301
- TLS_AES_256_GCM_SHA384 – 1302
- TLS_CHACHA20_POLY1305_SHA256 1303
- TLS_AES_128_CCM_SHA256 -1304
- TLS_AES_128_CCM_8_SHA256 -1305