enable DTLS negotiation

David Woodhouse dwmw2 at infradead.org
Fri Sep 16 08:30:48 PDT 2016


On Fri, 2016-09-16 at 15:07 +0200, Nikos Mavrogiannopoulos wrote:
> 
> Ok. For openconnect client it would be fairly easy to handle this,
> only send an extension with fairly static data, as it only sends a
> username. However, there is a catch, we should do that for both
> openssl and gnutls. Ocserv would require to be able to parse the TLS
> client hello since the extension data are in variable positions,
> however that shouldn't be really hard. I could do the ocserv part and
> the gnutls part if you do the openssl part :)

Have I got the actual payload of the extension right? I've done it as
an ASN.1 SEQUENCE containing one or more (in our case just one) ASN.1
OCTET-STRINGs each with an identity.

(I note that TLS1.3 is different here, and each PskIdentity contains
also a PskKeyExchangeMode and a PskAuthenticationMode. Is that likely
to end up in the draft for 1.2 before it becomes final?)

I have hex-printed the identity since it's often going to be treated as
a printable string. The existing PSK callback for OpenSSL, for example,
assumes that it's a string. As does gnutls_psk_set_cient_credentials().

I need to check that the server returns the correct identity too. That
one would just be the OCTET-STRING with no SEQUENCE since there can be
only one?

diff --git a/openssl-dtls.c b/openssl-dtls.c
index 84682a4..b3922fb 100644
--- a/openssl-dtls.c
+++ b/openssl-dtls.c
@@ -182,15 +182,54 @@ static unsigned int psk_callback(SSL *ssl, const char *hint, char *identity,
 				 unsigned int max_psk_len)
 {
 	struct openconnect_info *vpninfo = SSL_get_app_data(ssl);
-
-	if (!vpninfo || max_identity_len < 4 || max_psk_len < PSK_KEY_SIZE)
+	int i;
+	if (!vpninfo || max_identity_len <= sizeof(vpninfo->dtls_session_id) * 2 || max_psk_len < PSK_KEY_SIZE)
 		return 0;
 	vpn_progress(vpninfo, PRG_TRACE, _("PSK callback\n"));
 
-	snprintf(identity, max_psk_len, "psk");
+	for (i = 0; i < sizeof(vpninfo->dtls_session_id); i++)
+		sprintf(identity + (i*2), "%02x", vpninfo->dtls_session_id[i]);
+
 	memcpy(psk, vpninfo->dtls_secret, PSK_KEY_SIZE);
 	return PSK_KEY_SIZE;
 }
+
+static int pskident_add(SSL *s, unsigned int ext_type, const unsigned char **out, size_t *outlen,
+			int *al, void *add_arg)
+{
+	struct openconnect_info *vpninfo = add_arg;
+	unsigned char *buf;
+	int i;
+	buf = malloc(sizeof(vpninfo->dtls_session_id) * 2 + 5);
+	if (!buf) {
+		vpn_progress(vpninfo, PRG_ERR,
+			     _("Failed to create identity extension for OpenSSL\n"));
+		return 0;
+	}
+	buf[0] = 0x30;					   /* SEQUENCE	      */
+	buf[1] = sizeof(vpninfo->dtls_session_id) * 2 + 2; /* length	      */
+	buf[2] = 0x04;					   /*    OCTET-STRING */
+	buf[3] = sizeof(vpninfo->dtls_session_id) * 2;	   /*    length	      */
+	for (i = 0; i < sizeof(vpninfo->dtls_session_id); i++)
+		sprintf((char *)buf + 4 + (i*2), "%02x", vpninfo->dtls_session_id[i]);
+
+	*out = buf;
+	*outlen = sizeof(vpninfo->dtls_session_id) * 2 + 4;
+
+	return 1;
+}
+
+static void pskident_free(SSL *s, unsigned int ext_type, const unsigned char *out, void *add_arg)
+{
+	free((void *)out);
+}
+
+static int pskident_parse(SSL *s, unsigned int ext_type, const unsigned char *in, size_t inlen,
+			  int *al, void *parse_arg)
+{
+	return 1;
+}
+
 #endif
 
 int start_dtls_handshake(struct openconnect_info *vpninfo, int dtls_fd)
@@ -268,6 +307,9 @@ int start_dtls_handshake(struct openconnect_info *vpninfo, int dtls_fd)
 				vpninfo->dtls_attempt_period = 0;
 				return -EINVAL;
 			}
+			SSL_CTX_add_client_custom_ext(vpninfo->dtls_ctx, 10015,
+						      pskident_add, pskident_free, vpninfo,
+						      pskident_parse, vpninfo);
 			/* For SSL_CTX_set_cipher_list() */
 			cipher = "PSK";
 #endif
 
-- 
dwmw2
-------------- next part --------------
A non-text attachment was scrubbed...
Name: smime.p7s
Type: application/x-pkcs7-signature
Size: 5760 bytes
Desc: not available
URL: <http://lists.infradead.org/pipermail/openconnect-devel/attachments/20160916/15351e95/attachment-0001.bin>


More information about the openconnect-devel mailing list