PSK with TLSv1.3

Johannes Bauer dfnsonfsduifb at gmx.de
Wed Oct 23 09:24:49 UTC 2019


Hi list,

I'm in the process of refactoring/updating code that has been using
TLS-PSK with TLSv1.2 for a number of years successfully. I want to
upgrade it so that it uses TLSv1.3 exclusively.

I find it *exceptionally* hard to wrap my head around the new API and
the documentation/manpages are extremely confusing to me.

E.g., while
https://www.openssl.org/docs/manmaster/man3/SSL_CTX_set_psk_use_session_callback.html
mentions specifically TLSv1.3 clients, there's no mention of server
implementation and the text does not seem to have been updated for
TLSv1.3 entirely (e.g., there's mention of "the callback" -- clearly
previously there was only one, now there's two,
SSL_psk_use_session_cb_func and SSL_psk_client_cb_func).

I'm struggling with all of it, in particular the way the server callback
works in TLSv1.3: What I'm doing now is register a

static int psk_server_callback(SSL *ssl, const unsigned char *identity,
size_t identity_len, SSL_SESSION **sessptr);

using

SSL_CTX_set_psk_find_session_callback(cctx, psk_server_callback);

Then, inside the callback I create a SSL_SESSION* in the callback (if I
want to return a PSK) using SSL_SESSION_new(). Setting the master key
(that's the PSK, right?) using SSL_SESSION_set1_master_key and the
protocol version using SSL_SESSION_set_protocol_version is straightforward.

But what the heck am I supposed to do with SSL_SESSION_set_cipher? The
text in
https://www.openssl.org/docs/man1.1.1/man3/SSL_CTX_set_psk_find_session_callback.html
does not contain any hint on what to do in the server case and the text
provided in the client manpage is exceedingly confusing:

"Only the handshake digest associated with the ciphersuite is relevant
for the PSK (the server may go on to negotiate any ciphersuite which is
compatible with the digest). The application can use any TLSv1.3
ciphersuite."

So, wait, I can use any TLSv1.3 ciphersuite but it's not relevant
because only the MD of the suite is used, everything else is discarded?
So I return a cipher suite value, but it doesn't have to do anything
with the cipher suites that I allow, it's just a "wrapper" for a MD?

Here's what I'm doing right now in my server callback:

static int psk_server_callback(SSL *ssl, const unsigned char *identity,
size_t identity_len, SSL_SESSION **sessptr) {
	fprintf(stderr, "PSK server SSL %p identity %s len %ld sess %p\n", ssl,
identity, identity_len, *sessptr);
	SSL_SESSION *sess = SSL_SESSION_new();
	SSL_SESSION_set1_master_key(sess, (const unsigned char*)"\x00\x11\x22", 3);
	SSL_SESSION_set_cipher(sess, SSL_get_pending_cipher(ssl));
	SSL_SESSION_set_protocol_version(sess, TLS1_3_VERSION);
	*sessptr = sess;
	return 1;
}

All error checking omitted for now, this is obviously just a sample.
When I try to connect to my server on the command line using s_client:

$ openssl s_client -connect 127.0.0.1:12345 -psk_identity foo -psk 001122

The server pukes:

PSK server SSL 0x623000000100 identity foo len 3 sess (nil)
139933268309760:error:141F906E:SSL routines:tls_parse_ctos_psk:bad
extension:../ssl/statem/extensions_srvr.c:1267:

And I have no idea what that's supposed to mean.

I'm willing to update the documentation/manpage and create a PR, but I
don't understand it as-it right now. So any help getting me up to speed
would be greatly appreciated. Examples would be also extremely useful
for this.

All the best,
Johannes


More information about the openssl-users mailing list