Fix compilation warnings
[silc.git] / lib / silcske / silcske.c
index 36d36ac8d5e395c80b3a2fa8b54b23793ba8063b..ea2aa9ca5d961ce8c0a13a33e687d81b86cf4d54 100644 (file)
@@ -864,7 +864,8 @@ silc_ske_make_rekey_material(SilcSKE ske, SilcSKEKeyMaterial keymat)
 static SilcSKEStartPayload
 silc_ske_assemble_security_properties(SilcSKE ske,
                                      SilcSKESecurityPropertyFlag flags,
-                                     const char *version)
+                                     const char *version,
+                                     SilcBool small_proposal)
 {
   SilcSKEStartPayload rp;
   int i;
@@ -899,34 +900,48 @@ silc_ske_assemble_security_properties(SilcSKE ske,
     rp->version_len = strlen(version);
 
   /* Get supported Key Exhange groups */
-  rp->ke_grp_list = silc_ske_get_supported_groups();
+  rp->ke_grp_list = silc_ske_get_supported_groups(small_proposal);
   if (rp->ke_grp_list)
     rp->ke_grp_len = strlen(rp->ke_grp_list);
 
   /* Get supported PKCS algorithms */
-  rp->pkcs_alg_list = silc_pkcs_get_supported();
+  if (small_proposal)
+    rp->pkcs_alg_list = strdup(silc_default_pkcs_alg[0].name);
+  else
+    rp->pkcs_alg_list = silc_pkcs_get_supported();
   if (rp->pkcs_alg_list)
     rp->pkcs_alg_len = strlen(rp->pkcs_alg_list);
 
   /* Get supported encryption algorithms */
-  rp->enc_alg_list = silc_cipher_get_supported();
+  if (small_proposal)
+    rp->enc_alg_list = strdup(silc_default_ciphers[0].name);
+  else
+    rp->enc_alg_list = silc_cipher_get_supported();
   if (rp->enc_alg_list)
     rp->enc_alg_len = strlen(rp->enc_alg_list);
 
   /* Get supported hash algorithms */
-  rp->hash_alg_list = silc_hash_get_supported();
+  if (small_proposal)
+    rp->hash_alg_list = strdup(silc_default_hash[0].name);
+  else
+    rp->hash_alg_list = silc_hash_get_supported();
   if (rp->hash_alg_list)
     rp->hash_alg_len = strlen(rp->hash_alg_list);
 
   /* Get supported HMACs */
-  rp->hmac_alg_list = silc_hmac_get_supported();
+  if (small_proposal)
+    rp->hmac_alg_list = strdup(silc_default_hmacs[0].name);
+  else
+    rp->hmac_alg_list = silc_hmac_get_supported();
   if (rp->hmac_alg_list)
     rp->hmac_alg_len = strlen(rp->hmac_alg_list);
 
-  /* XXX */
-  /* Get supported compression algorithms */
-  rp->comp_alg_list = strdup("none");
-  rp->comp_alg_len = strlen("none");
+  if (!small_proposal) {
+    /* XXX */
+    /* Get supported compression algorithms */
+    rp->comp_alg_list = strdup("none");
+    rp->comp_alg_len = strlen("none");
+  }
 
   rp->len = 1 + 1 + 2 + SILC_SKE_COOKIE_LEN +
     2 + rp->version_len +
@@ -951,7 +966,7 @@ SILC_TASK_CALLBACK(silc_ske_packet_send_retry)
     silc_free(ske->retrans.data);
     ske->retrans.data = NULL;
     ske->status = SILC_SKE_STATUS_TIMEOUT;
-        silc_ske_notify_failure(ske);
+    silc_ske_notify_failure(ske);
     silc_fsm_continue_sync(&ske->fsm);
     return;
   }
@@ -963,10 +978,10 @@ SILC_TASK_CALLBACK(silc_ske_packet_send_retry)
 
 /* Install retransmission timer */
 
-static void silc_ske_install_retransmission(SilcSKE ske)
+static SilcBool silc_ske_install_retransmission(SilcSKE ske)
 {
   if (!silc_packet_stream_is_udp(ske->stream))
-    return;
+    return FALSE;
 
   if (ske->retrans.data) {
     SILC_LOG_DEBUG(("Installing retransmission timer %d secs",
@@ -976,6 +991,7 @@ static void silc_ske_install_retransmission(SilcSKE ske)
   }
   ske->retry_timer = ((ske->retry_timer * SILC_SKE_RETRY_MUL) +
                      (silc_rng_get_rn16(ske->rng) % SILC_SKE_RETRY_RAND));
+  return TRUE;
 }
 
 /* Sends SILC packet.  Handles retransmissions with UDP streams. */
@@ -1046,6 +1062,21 @@ SILC_TASK_CALLBACK(silc_ske_timeout)
   silc_fsm_continue_sync(&ske->fsm);
 }
 
+/* Key exchange timeout task callback */
+
+SILC_TASK_CALLBACK(silc_ske_probe_timeout)
+{
+  SilcSKE ske = context;
+
+  SILC_LOG_DEBUG(("Probe timeout"));
+
+  ske->packet = NULL;
+  ske->status = SILC_SKE_STATUS_PROBE_TIMEOUT;
+  silc_ske_notify_failure(ske);
+
+  silc_fsm_continue_sync(&ske->fsm);
+}
+
 /******************************* Protocol API *******************************/
 
 /* Allocates new SKE object. */
@@ -1229,10 +1260,6 @@ SILC_FSM_STATE(silc_ske_st_initiator_start)
     return SILC_FSM_CONTINUE;
   }
 
-  /* Add key exchange timeout */
-  silc_schedule_task_add_timeout(ske->schedule, silc_ske_timeout,
-                                ske, ske->timeout, 0);
-
   /** Wait for responder proposal */
   SILC_LOG_DEBUG(("Waiting for responder proposal"));
   silc_fsm_next(fsm, silc_ske_st_initiator_phase1);
@@ -1257,12 +1284,21 @@ SILC_FSM_STATE(silc_ske_st_initiator_phase1)
 
   if (ske->packet->type != SILC_PACKET_KEY_EXCHANGE) {
     SILC_LOG_DEBUG(("Remote retransmitted an old packet"));
-    silc_ske_install_retransmission(ske);
-    silc_packet_free(ske->packet);
-    ske->packet = NULL;
-    return SILC_FSM_WAIT;
+    if (silc_ske_install_retransmission(ske)) {
+      silc_packet_free(ske->packet);
+      ske->packet = NULL;
+      return SILC_FSM_WAIT;
+    } else {
+      silc_packet_free(ske->packet);
+      ske->packet = NULL;
+      ske->status = SILC_SKE_STATUS_ERROR;
+      silc_fsm_next(fsm, silc_ske_st_initiator_error);
+      return SILC_FSM_CONTINUE;
+    }
   }
 
+  silc_schedule_task_del_by_all(ske->schedule, 0, silc_ske_probe_timeout, ske);
+
   /* Decode the payload */
   status = silc_ske_payload_start_decode(ske, packet_buf, &payload);
   if (status != SILC_SKE_STATUS_OK) {
@@ -1275,7 +1311,9 @@ SILC_FSM_STATE(silc_ske_st_initiator_phase1)
   }
 
   /* Get remote ID and set it to stream */
-  if (ske->packet->src_id_len) {
+  if (ske->packet->src_id_len &&
+      (ske->packet->src_id_type == SILC_ID_SERVER ||
+       ske->packet->src_id_type == SILC_ID_CLIENT)) {
     silc_id_str2id(ske->packet->src_id, ske->packet->src_id_len,
                   ske->packet->src_id_type,
                   (ske->packet->src_id_type == SILC_ID_SERVER ?
@@ -1552,10 +1590,17 @@ SILC_FSM_STATE(silc_ske_st_initiator_phase3)
 
   if (ske->packet->type != SILC_PACKET_KEY_EXCHANGE_2) {
     SILC_LOG_DEBUG(("Remote retransmitted an old packet"));
-    silc_ske_install_retransmission(ske);
-    silc_packet_free(ske->packet);
-    ske->packet = NULL;
-    return SILC_FSM_WAIT;
+    if (silc_ske_install_retransmission(ske)) {
+      silc_packet_free(ske->packet);
+      ske->packet = NULL;
+      return SILC_FSM_WAIT;
+    } else {
+      silc_packet_free(ske->packet);
+      ske->packet = NULL;
+      ske->status = SILC_SKE_STATUS_ERROR;
+      silc_fsm_next(fsm, silc_ske_st_initiator_error);
+      return SILC_FSM_CONTINUE;
+    }
   }
 
   /* Decode the payload */
@@ -1663,7 +1708,7 @@ SILC_FSM_STATE(silc_ske_st_initiator_phase4)
   SilcSKEStatus status;
   SilcSKEKEPayload payload;
   unsigned char hash[SILC_HASH_MAXLEN];
-  SilcUInt32 hash_len;
+  SilcUInt32 hash_len = 0;
   int key_len, block_len;
 
   if (ske->aborted) {
@@ -1732,20 +1777,26 @@ SILC_FSM_STATE(silc_ske_st_initiator_phase4)
     goto err;
   }
 
-  /* Send SUCCESS packet */
-  SILC_PUT32_MSB((SilcUInt32)SILC_SKE_STATUS_OK, hash);
-  if (!silc_ske_packet_send(ske, SILC_PACKET_SUCCESS, 0, hash, 4)) {
-    /** Error sending packet */
-    SILC_LOG_DEBUG(("Error sending packet"));
-    ske->status = SILC_SKE_STATUS_ERROR;
-    silc_fsm_next(fsm, silc_ske_st_initiator_error);
+  if (!ske->no_acks) {
+    /* Send SUCCESS packet */
+    SILC_PUT32_MSB((SilcUInt32)SILC_SKE_STATUS_OK, hash);
+    if (!silc_ske_packet_send(ske, SILC_PACKET_SUCCESS, 0, hash, 4)) {
+      /** Error sending packet */
+      SILC_LOG_DEBUG(("Error sending packet"));
+      ske->status = SILC_SKE_STATUS_ERROR;
+      silc_fsm_next(fsm, silc_ske_st_initiator_error);
+      return SILC_FSM_CONTINUE;
+    }
+
+    /** Waiting completion */
+    silc_fsm_next(fsm, silc_ske_st_initiator_end);
+    return SILC_FSM_WAIT;
+  } else {
+    /** Complete protocol */
+    silc_fsm_next(fsm, silc_ske_st_initiator_end);
     return SILC_FSM_CONTINUE;
   }
 
-  /** Waiting completion */
-  silc_fsm_next(fsm, silc_ske_st_initiator_end);
-  return SILC_FSM_WAIT;
-
  err:
   memset(hash, 'F', sizeof(hash));
   silc_ske_payload_ke_free(payload);
@@ -1778,17 +1829,25 @@ SILC_FSM_STATE(silc_ske_st_initiator_end)
 
   SILC_LOG_DEBUG(("Start"));
 
-  if (ske->packet->type != SILC_PACKET_SUCCESS) {
+  if (!ske->no_acks && ske->packet->type != SILC_PACKET_SUCCESS) {
     SILC_LOG_DEBUG(("Remote retransmitted an old packet"));
-    silc_ske_install_retransmission(ske);
-    silc_packet_free(ske->packet);
-    ske->packet = NULL;
-    return SILC_FSM_WAIT;
+    if (silc_ske_install_retransmission(ske)) {
+      silc_packet_free(ske->packet);
+      ske->packet = NULL;
+      return SILC_FSM_WAIT;
+    } else {
+      silc_packet_free(ske->packet);
+      ske->packet = NULL;
+      ske->status = SILC_SKE_STATUS_ERROR;
+      silc_fsm_next(fsm, silc_ske_st_initiator_error);
+      return SILC_FSM_CONTINUE;
+    }
   }
 
   SILC_LOG_DEBUG(("Key exchange completed successfully"));
 
-  silc_packet_free(ske->packet);
+  if (ske->packet)
+    silc_packet_free(ske->packet);
   ske->packet = NULL;
   silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
   silc_schedule_task_del_by_context(ske->schedule, ske);
@@ -1826,7 +1885,7 @@ SILC_FSM_STATE(silc_ske_st_initiator_aborted)
 SILC_FSM_STATE(silc_ske_st_initiator_error)
 {
   SilcSKE ske = fsm_context;
-  SilcSKEStatus status;
+  SilcUInt32 status;
   unsigned char data[4];
 
   SILC_LOG_DEBUG(("Error %s (%d) occurred during key exchange",
@@ -1837,7 +1896,7 @@ SILC_FSM_STATE(silc_ske_st_initiator_error)
     status = SILC_SKE_STATUS_ERROR;
 
   /* Send FAILURE packet */
-  SILC_PUT32_MSB((SilcUInt32)status, data);
+  SILC_PUT32_MSB(status, data);
   silc_ske_packet_send(ske, SILC_PACKET_FAILURE, 0, data, 4);
 
   silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
@@ -1854,13 +1913,15 @@ SILC_FSM_STATE(silc_ske_st_initiator_error)
 SILC_FSM_STATE(silc_ske_st_initiator_failure)
 {
   SilcSKE ske = fsm_context;
-  SilcUInt32 error = SILC_SKE_STATUS_ERROR;
+  SilcUInt32 error = ske->status;
 
   if (ske->packet && silc_buffer_len(&ske->packet->buffer) == 4) {
     SILC_GET32_MSB(error, ske->packet->buffer.data);
     silc_packet_free(ske->packet);
     ske->packet = NULL;
   }
+  if (error == SILC_SKE_STATUS_OK)
+    error = SILC_SKE_STATUS_ERROR;
   ske->status = error;
 
   SILC_LOG_DEBUG(("Error %s (%d) received during key exchange",
@@ -1898,17 +1959,22 @@ SilcAsyncOperation silc_ske_initiator(SilcSKE ske,
     ske->session_port = params->session_port;
 
   /* Generate security properties if not provided */
-  if (!start_payload) {
-    start_payload = silc_ske_assemble_security_properties(ske,
-                                                         params->flags,
-                                                         params->version);
+  if (!start_payload && !params->prop) {
+    start_payload =
+      silc_ske_assemble_security_properties(ske, params->flags,
+                                           params->version,
+                                           params->small_proposal);
     if (!start_payload)
       return NULL;
   }
 
   ske->timeout = params->timeout_secs ? params->timeout_secs : 30;
+  ske->probe_timeout = (params->probe_timeout_secs ?
+                       params->probe_timeout_secs : 30);
   ske->start_payload = start_payload;
+  ske->prop = params->prop;
   ske->version = params->version;
+  ske->no_acks = params->no_acks;
   ++ske->refcnt;
 
   /* Link to packet stream to get key exchange packets */
@@ -1919,8 +1985,18 @@ SilcAsyncOperation silc_ske_initiator(SilcSKE ske,
                          SILC_PACKET_SUCCESS,
                          SILC_PACKET_FAILURE, -1);
 
+  /* Add key exchange timeout */
+  silc_schedule_task_add_timeout(ske->schedule, silc_ske_timeout,
+                                ske, ske->timeout, 0);
+  if (ske->timeout != ske->probe_timeout)
+    silc_schedule_task_add_timeout(ske->schedule, silc_ske_probe_timeout,
+                                  ske, ske->probe_timeout, 0);
+
   /* Start SKE as initiator */
-  silc_fsm_start(&ske->fsm, silc_ske_st_initiator_start);
+  if (!ske->prop)
+    silc_fsm_start(&ske->fsm, silc_ske_st_initiator_start);
+  else
+    silc_fsm_start(&ske->fsm, silc_ske_st_initiator_phase2);
 
   return &ske->op;
 }
@@ -1941,12 +2017,11 @@ SILC_FSM_STATE(silc_ske_st_responder_start)
     return SILC_FSM_CONTINUE;
   }
 
-  /* Add key exchange timeout */
-  silc_schedule_task_add_timeout(ske->schedule, silc_ske_timeout,
-                                ske, ske->timeout, 0);
-
   /** Wait for initiator */
-  silc_fsm_next(fsm, silc_ske_st_responder_phase1);
+  if (!ske->prop)
+    silc_fsm_next(fsm, silc_ske_st_responder_phase1);
+  else
+    silc_fsm_next(fsm, silc_ske_st_responder_phase2);
   return SILC_FSM_WAIT;
 }
 
@@ -1975,7 +2050,9 @@ SILC_FSM_STATE(silc_ske_st_responder_phase1)
   }
 
   /* Get remote ID and set it to stream */
-  if (ske->packet->src_id_len) {
+  if (ske->packet->src_id_len &&
+      (ske->packet->src_id_type == SILC_ID_SERVER ||
+       ske->packet->src_id_type == SILC_ID_CLIENT)) {
     silc_id_str2id(ske->packet->src_id, ske->packet->src_id_len,
                   ske->packet->src_id_type,
                   (ske->packet->src_id_type == SILC_ID_SERVER ?
@@ -2085,10 +2162,17 @@ SILC_FSM_STATE(silc_ske_st_responder_phase2)
 
   if (ske->packet->type != SILC_PACKET_KEY_EXCHANGE_1) {
     SILC_LOG_DEBUG(("Remote retransmitted an old packet"));
-    silc_ske_install_retransmission(ske);
-    silc_packet_free(ske->packet);
-    ske->packet = NULL;
-    return SILC_FSM_WAIT;
+    if (silc_ske_install_retransmission(ske)) {
+      silc_packet_free(ske->packet);
+      ske->packet = NULL;
+      return SILC_FSM_WAIT;
+    } else {
+      silc_packet_free(ske->packet);
+      ske->packet = NULL;
+      ske->status = SILC_SKE_STATUS_ERROR;
+      silc_fsm_next(fsm, silc_ske_st_responder_error);
+      return SILC_FSM_CONTINUE;
+    }
   }
 
   /* Decode Key Exchange Payload */
@@ -2194,8 +2278,9 @@ SILC_FSM_STATE(silc_ske_st_responder_phase4)
 
   /* The public key verification was performed only if the Mutual
      Authentication flag is set. */
-  if (ske->start_payload &&
-      ske->start_payload->flags & SILC_SKE_SP_FLAG_MUTUAL) {
+  if ((ske->start_payload &&
+       ske->start_payload->flags & SILC_SKE_SP_FLAG_MUTUAL) ||
+      ske->prop->flags & SILC_SKE_SP_FLAG_MUTUAL) {
     unsigned char hash[SILC_HASH_MAXLEN];
     SilcUInt32 hash_len;
 
@@ -2385,9 +2470,15 @@ SILC_FSM_STATE(silc_ske_st_responder_phase5)
     return SILC_FSM_CONTINUE;
   }
 
-  /** Waiting completion */
-  silc_fsm_next(fsm, silc_ske_st_responder_end);
-  return SILC_FSM_WAIT;
+  if (!ske->no_acks) {
+    /** Waiting completion */
+    silc_fsm_next(fsm, silc_ske_st_responder_end);
+    return SILC_FSM_WAIT;
+  } else {
+    /** Complete protocol */
+    silc_fsm_next(fsm, silc_ske_st_responder_end);
+    return SILC_FSM_CONTINUE;
+  }
 }
 
 /* Protocol completed */
@@ -2398,14 +2489,22 @@ SILC_FSM_STATE(silc_ske_st_responder_end)
   unsigned char tmp[4];
   SilcUInt32 hash_len, key_len, block_len;
 
-  if (ske->packet->type != SILC_PACKET_SUCCESS) {
+  if (!ske->no_acks && ske->packet->type != SILC_PACKET_SUCCESS) {
     SILC_LOG_DEBUG(("Remote retransmitted an old packet"));
-    silc_ske_install_retransmission(ske);
-    silc_packet_free(ske->packet);
-    ske->packet = NULL;
-    return SILC_FSM_WAIT;
+    if (silc_ske_install_retransmission(ske)) {
+      silc_packet_free(ske->packet);
+      ske->packet = NULL;
+      return SILC_FSM_WAIT;
+    } else {
+      silc_packet_free(ske->packet);
+      ske->packet = NULL;
+      ske->status = SILC_SKE_STATUS_ERROR;
+      silc_fsm_next(fsm, silc_ske_st_responder_error);
+      return SILC_FSM_CONTINUE;
+    }
   }
-  silc_packet_free(ske->packet);
+  if (ske->packet)
+    silc_packet_free(ske->packet);
   ske->packet = NULL;
 
   /* Process key material */
@@ -2422,9 +2521,11 @@ SILC_FSM_STATE(silc_ske_st_responder_end)
     return SILC_FSM_CONTINUE;
   }
 
-  /* Send SUCCESS packet */
-  SILC_PUT32_MSB(SILC_SKE_STATUS_OK, tmp);
-  silc_ske_packet_send(ske, SILC_PACKET_SUCCESS, 0, tmp, 4);
+  if (!ske->no_acks) {
+    /* Send SUCCESS packet */
+    SILC_PUT32_MSB(SILC_SKE_STATUS_OK, tmp);
+    silc_ske_packet_send(ske, SILC_PACKET_SUCCESS, 0, tmp, 4);
+  }
 
   silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
   silc_schedule_task_del_by_context(ske->schedule, ske);
@@ -2462,7 +2563,7 @@ SILC_FSM_STATE(silc_ske_st_responder_aborted)
 SILC_FSM_STATE(silc_ske_st_responder_failure)
 {
   SilcSKE ske = fsm_context;
-  SilcUInt32 error = SILC_SKE_STATUS_ERROR;
+  SilcUInt32 error = ske->status;
 
   SILC_LOG_DEBUG(("Key exchange protocol failed"));
 
@@ -2471,9 +2572,9 @@ SILC_FSM_STATE(silc_ske_st_responder_failure)
     silc_packet_free(ske->packet);
     ske->packet = NULL;
   }
+  if (error == SILC_SKE_STATUS_OK)
+    error = SILC_SKE_STATUS_ERROR;
   ske->status = error;
-  if (ske->status == SILC_SKE_STATUS_OK)
-    ske->status = SILC_SKE_STATUS_ERROR;
 
   silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
   silc_schedule_task_del_by_context(ske->schedule, ske);
@@ -2490,16 +2591,16 @@ SILC_FSM_STATE(silc_ske_st_responder_error)
 {
   SilcSKE ske = fsm_context;
   unsigned char tmp[4];
+  SilcUInt32 status;
 
   SILC_LOG_DEBUG(("Error %d (%s) during key exchange protocol",
                  ske->status, silc_ske_map_status(ske->status)));
 
   /* Send FAILURE packet */
-  if (ske->status == SILC_SKE_STATUS_OUT_OF_MEMORY)
-    ske->status = SILC_SKE_STATUS_ERROR;
-  else if (ske->status > SILC_SKE_STATUS_INVALID_COOKIE)
-    ske->status = SILC_SKE_STATUS_BAD_PAYLOAD;
-  SILC_PUT32_MSB(ske->status, tmp);
+  status = ske->status;
+  if (status > SILC_SKE_STATUS_INVALID_COOKIE)
+    status = SILC_SKE_STATUS_ERROR;
+  SILC_PUT32_MSB(status, tmp);
   silc_ske_packet_send(ske, SILC_PACKET_FAILURE, 0, tmp, 4);
 
   silc_packet_stream_unlink(ske->stream, &silc_ske_stream_cbs, ske);
@@ -2534,6 +2635,8 @@ SilcAsyncOperation silc_ske_responder(SilcSKE ske,
   if (ske->flags & SILC_SKE_SP_FLAG_IV_INCLUDED)
     ske->session_port = params->session_port;
   ske->version = params->version;
+  ske->no_acks = params->no_acks;
+  ske->prop = params->prop;
   if (!ske->version)
     return NULL;
   ++ske->refcnt;
@@ -2546,6 +2649,10 @@ SilcAsyncOperation silc_ske_responder(SilcSKE ske,
                          SILC_PACKET_SUCCESS,
                          SILC_PACKET_FAILURE, -1);
 
+  /* Add key exchange timeout */
+  silc_schedule_task_add_timeout(ske->schedule, silc_ske_timeout,
+                                ske, ske->timeout, 0);
+
   /* Start SKE as responder */
   silc_fsm_start(&ske->fsm, silc_ske_st_responder_start);
 
@@ -3627,7 +3734,7 @@ const char *silc_ske_status_string[] =
   "Unsupported PKCS",
   "Unsupported hash function",
   "Unsupported HMAC",
-  "Unsupported public key (or certificate)",
+  "Public key not accepted",
   "Incorrect signature",
   "Bad or unsupported version",
   "Invalid cookie",
@@ -3639,6 +3746,7 @@ const char *silc_ske_status_string[] =
   "Error computing signature",
   "System out of memory",
   "Key exchange timeout",
+  "Key exchange timeout",
 
   NULL
 };