ssl_client2: Add cmd line options to configure use of CID extension
diff --git a/programs/ssl/ssl_client2.c b/programs/ssl/ssl_client2.c
index 894a8e0..43d3b0c 100644
--- a/programs/ssl/ssl_client2.c
+++ b/programs/ssl/ssl_client2.c
@@ -113,6 +113,8 @@
 #define DFL_DHMLEN              -1
 #define DFL_RECONNECT           0
 #define DFL_RECO_DELAY          0
+#define DFL_CID_ENABLED         0
+#define DFL_CID_VALUE           ""
 #define DFL_RECONNECT_HARD      0
 #define DFL_TICKETS             MBEDTLS_SSL_SESSION_TICKETS_ENABLED
 #define DFL_ALPN_STRING         NULL
@@ -166,6 +168,16 @@
 #define USAGE_KEY_OPAQUE ""
 #endif
 
+#if defined(MBEDTLS_SSL_CID)
+#define USAGE_CID \
+    "    cid=%%d             Disable (0) or enable (1) the use of the DTLS Connection ID extension.\n" \
+    "                       default: 0 (disabled)\n"     \
+    "    cid_val=%%s          The CID to use for incoming messages (in hex, without 0x).\n"  \
+    "                        default: \"\"\n"
+#else /* MBEDTLS_SSL_CID */
+#define USAGE_CID ""
+#endif /* MBEDTLS_SSL_CID */
+
 #if defined(MBEDTLS_KEY_EXCHANGE__SOME__PSK_ENABLED)
 #define USAGE_PSK_RAW                                               \
     "    psk=%%s              default: \"\" (in hex, without 0x)\n" \
@@ -337,6 +349,7 @@
     "    max_resend=%%d       default: 0 (no resend on timeout)\n" \
     "\n"                                                    \
     USAGE_DTLS                                              \
+    USAGE_CID                                               \
     "\n"                                                    \
     "    auth_mode=%%s        default: (library default: none)\n" \
     "                        options: none, optional, required\n" \
@@ -457,6 +470,8 @@
     int etm;                    /* negotiate encrypt then mac?              */
     int context_crt_cb;         /* use context-specific CRT verify callback */
     int eap_tls;                /* derive EAP-TLS keying material?          */
+    int cid_enabled;            /* whether to use the CID extension or not  */
+    const char *cid_val;        /* the CID to use for incoming messages     */
 } opt;
 
 int query_config( const char *config );
@@ -710,7 +725,7 @@
 
 /* Unhexify `hex` into `dst`. `dst` must have
  * size at least `strlen( hex ) / 2`. */
-int unhexify( unsigned char const *hex, unsigned char *dst )
+int unhexify( char const *hex, unsigned char *dst )
 {
     unsigned char c;
     size_t j;
@@ -758,6 +773,12 @@
     unsigned char psk[MBEDTLS_PSK_MAX_LEN];
     size_t psk_len = 0;
 #endif
+
+#if defined(MBEDTLS_SSL_CID)
+    unsigned char cid[MBEDTLS_SSL_CID_IN_LEN_MAX];
+    size_t cid_len = 0;
+#endif
+
 #if defined(MBEDTLS_SSL_ALPN)
     const char *alpn_list[ALPN_LIST_SIZE];
 #endif
@@ -858,6 +879,8 @@
     opt.server_addr         = DFL_SERVER_ADDR;
     opt.server_port         = DFL_SERVER_PORT;
     opt.debug_level         = DFL_DEBUG_LEVEL;
+    opt.cid_enabled         = DFL_CID_ENABLED;
+    opt.cid_val             = DFL_CID_VALUE;
     opt.nbio                = DFL_NBIO;
     opt.event               = DFL_EVENT;
     opt.context_crt_cb      = DFL_CONTEXT_CRT_CB;
@@ -986,6 +1009,18 @@
         else if( strcmp( p, "key_opaque" ) == 0 )
             opt.key_opaque = atoi( q );
 #endif
+#if defined(MBEDTLS_SSL_CID)
+        else if( strcmp( p, "cid" ) == 0 )
+        {
+            opt.cid_enabled = atoi( q );
+            if( opt.cid_enabled != 0 && opt.cid_enabled != 1 )
+                goto usage;
+        }
+        else if( strcmp( p, "cid_val" ) == 0 )
+        {
+            opt.cid_val = q;
+        }
+#endif /* MBEDTLS_SSL_CID */
         else if( strcmp( p, "psk" ) == 0 )
             opt.psk = q;
 #if defined(MBEDTLS_USE_PSA_CRYPTO)
@@ -1381,6 +1416,7 @@
             opt.arc4 = MBEDTLS_SSL_ARC4_ENABLED;
         }
 
+
 #if defined(MBEDTLS_USE_PSA_CRYPTO)
         if( opt.psk_opaque != 0 )
         {
@@ -1406,6 +1442,24 @@
 #endif /* MBEDTLS_USE_PSA_CRYPTO */
     }
 
+#if defined(MBEDTLS_SSL_CID)
+   if( strlen( opt.cid_val ) )
+   {
+       cid_len = strlen( opt.cid_val ) / 2;
+       if( cid_len > sizeof( cid ) )
+       {
+           mbedtls_printf( "CID too long\n" );
+           goto exit;
+       }
+
+       if( unhexify( opt.cid_val, cid ) != 0 )
+       {
+           mbedtls_printf( "CID not valid hex\n" );
+           goto exit;
+       }
+   }
+#endif /* MBEDTLS_SSL_CID */
+
 #if defined(MBEDTLS_ECP_C)
     if( opt.curves != NULL )
     {
@@ -1907,6 +1961,19 @@
                              mbedtls_net_send, mbedtls_net_recv,
                              opt.nbio == 0 ? mbedtls_net_recv_timeout : NULL );
 
+#if defined(MBEDTLS_SSL_CID)
+    if( opt.transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
+    {
+        if( ( ret = mbedtls_ssl_set_cid( &ssl, opt.cid_enabled,
+                                         cid, cid_len ) ) != 0 )
+        {
+            mbedtls_printf( " failed\n  ! mbedtls_ssl_set_cid returned %d\n\n",
+                            ret );
+            goto exit;
+        }
+    }
+#endif /* MBEDTLS_SSL_CID */
+
 #if defined(MBEDTLS_SSL_PROTO_DTLS)
     if( opt.dtls_mtu != DFL_DTLS_MTU )
         mbedtls_ssl_set_mtu( &ssl, opt.dtls_mtu );
@@ -2081,6 +2148,37 @@
     mbedtls_printf( "%s\n", peer_crt_info );
 #endif /* MBEDTLS_X509_CRT_PARSE_C */
 
+#if defined(MBEDTLS_SSL_CID)
+    if( opt.transport == MBEDTLS_SSL_TRANSPORT_DATAGRAM )
+    {
+        unsigned char peer_cid[ MBEDTLS_SSL_CID_OUT_LEN_MAX ];
+        size_t peer_cid_len;
+        int cid_negotiated;
+
+        /* Check if the use of a CID has been negotiated */
+        ret = mbedtls_ssl_get_peer_cid( &ssl, &cid_negotiated,
+                                        peer_cid, &peer_cid_len );
+        if( ret != 0 )
+        {
+            mbedtls_printf( " failed\n  ! mbedtls_ssl_get_peer_cid returned -0x%x\n\n",
+                            -ret );
+            goto exit;
+        }
+
+        if( cid_negotiated == MBEDTLS_SSL_CID_DISABLED )
+        {
+            if( opt.cid_enabled == MBEDTLS_SSL_CID_ENABLED )
+            {
+                mbedtls_printf( "Use of Connection ID was rejected by the server.\n" );
+            }
+        }
+        else
+        {
+            mbedtls_printf( "Use of Connection ID has been negotiated.\n" );
+        }
+    }
+#endif /* MBEDTLS_SSL_CID */
+
 #if defined(MBEDTLS_SSL_RENEGOTIATION)
     if( opt.renegotiate )
     {