Added version detection support to SKE. Minor bugfixes.
[silc.git] / lib / silcske / silcske.c
index 99be72b4b7e4fa881d7e93b67e039c4573b89fcb..2ee18f78f51bc2beb4e78c30adb20b368e117c76 100644 (file)
 /*
  * $Id$
  * $Log$
+ * Revision 1.6  2000/07/19 07:04:37  priikone
+ *     Added version detection support to SKE. Minor bugfixes.
+ *
+ * Revision 1.5  2000/07/10 05:34:22  priikone
+ *     Added mp binary encoding as protocols defines.
+ *
  * Revision 1.4  2000/07/07 06:46:43  priikone
  *     Removed ske_verify_public_key function as it is not needed
  *     anymore. Added support to the public key verification as callback
@@ -226,6 +232,7 @@ SilcSKEStatus silc_ske_initiator_phase_1(SilcSKE ske,
    Key Exchange 1 Payload. */
 
 SilcSKEStatus silc_ske_initiator_phase_2(SilcSKE ske,
+                                        SilcPublicKey public_key,
                                         SilcSKESendPacketCb send_packet,
                                         void *context)
 {
@@ -233,6 +240,7 @@ SilcSKEStatus silc_ske_initiator_phase_2(SilcSKE ske,
   SilcBuffer payload_buf;
   SilcInt x, e;
   SilcSKEOnePayload *payload;
+  unsigned int pk_len;
 
   SILC_LOG_DEBUG(("Start"));
 
@@ -257,6 +265,9 @@ SilcSKEStatus silc_ske_initiator_phase_2(SilcSKE ske,
   /* Encode the result to Key Exchange 1 Payload. */
   payload = silc_calloc(1, sizeof(*payload));
   payload->e = e;
+  payload->pk_data = silc_pkcs_public_key_encode(public_key, &pk_len);
+  payload->pk_len = pk_len;
+  payload->pk_type = SILC_SKE_PK_TYPE_SILC;
   status = silc_ske_payload_one_encode(ske, payload, &payload_buf);
   if (status != SILC_SKE_STATUS_OK) {
     silc_mp_clear(&x);
@@ -392,6 +403,7 @@ SilcSKEStatus silc_ske_initiator_finish(SilcSKE ske,
 
 SilcSKEStatus silc_ske_responder_start(SilcSKE ske, SilcRng rng,
                                       SilcSocketConnection sock,
+                                      char *version,
                                       SilcBuffer start_payload,
                                       SilcSKECb callback,
                                       void *context)
@@ -415,7 +427,8 @@ SilcSKEStatus silc_ske_responder_start(SilcSKE ske, SilcRng rng,
 
   /* Parse and select the security properties from the payload */
   payload = silc_calloc(1, sizeof(*payload));
-  status = silc_ske_select_security_properties(ske, payload, remote_payload);
+  status = silc_ske_select_security_properties(ske, version,
+                                              payload, remote_payload);
   if (status != SILC_SKE_STATUS_OK)
     goto err;
 
@@ -711,6 +724,7 @@ SilcSKEStatus silc_ske_abort(SilcSKE ske, SilcSKEStatus status,
 
 SilcSKEStatus 
 silc_ske_assemble_security_properties(SilcSKE ske,
+                                     char *version,
                                      SilcSKEStartPayload **return_payload)
 {
   SilcSKEStartPayload *rp;
@@ -729,6 +743,10 @@ silc_ske_assemble_security_properties(SilcSKE ske,
   rp->cookie_len = SILC_SKE_COOKIE_LEN;
   memcpy(rp->cookie, "1234567890123456", SILC_SKE_COOKIE_LEN);
 
+  /* Put version */
+  rp->version = strdup(version);
+  rp->version_len = strlen(version);
+
   /* Get supported Key Exhange groups */
   rp->ke_grp_list = silc_ske_get_supported_groups();
   rp->ke_grp_len = strlen(rp->ke_grp_list);
@@ -751,6 +769,7 @@ silc_ske_assemble_security_properties(SilcSKE ske,
   rp->comp_alg_len = 0;
 
   rp->len = 1 + 1 + 2 + SILC_SKE_COOKIE_LEN + 
+    2 + rp->version_len +
     2 + rp->ke_grp_len + 2 + rp->pkcs_alg_len + 
     2 + rp->enc_alg_len + 2 + rp->hash_alg_len + 
     2 + rp->comp_alg_len;
@@ -765,6 +784,7 @@ silc_ske_assemble_security_properties(SilcSKE ske,
 
 SilcSKEStatus 
 silc_ske_select_security_properties(SilcSKE ske,
+                                   char *version,
                                    SilcSKEStartPayload *payload,
                                    SilcSKEStartPayload *remote_payload)
 {
@@ -779,11 +799,17 @@ silc_ske_select_security_properties(SilcSKE ske,
   /* Flags are returned unchanged. */
   payload->flags = rp->flags;
 
-  /* XXX Cookie check?? */
+  /* Take cookie */
   payload->cookie = silc_calloc(SILC_SKE_COOKIE_LEN, sizeof(unsigned char));
   payload->cookie_len = SILC_SKE_COOKIE_LEN;
   memcpy(payload->cookie, rp->cookie, SILC_SKE_COOKIE_LEN);
 
+  /* XXX Do version check */
+
+  /* Put our version to our reply */
+  payload->version = strdup(version);
+  payload->version_len = strlen(version);
+
   /* Get supported Key Exchange groups */
   cp = rp->ke_grp_list;
   if (cp && strchr(cp, ',')) {
@@ -1042,6 +1068,7 @@ silc_ske_select_security_properties(SilcSKE ske,
 #endif
 
   payload->len = 1 + 1 + 2 + SILC_SKE_COOKIE_LEN + 
+    2 + payload->version_len + 
     2 + payload->ke_grp_len + 2 + payload->pkcs_alg_len + 
     2 + payload->enc_alg_len + 2 + payload->hash_alg_len + 
     2 + payload->comp_alg_len;
@@ -1062,10 +1089,10 @@ SilcSKEStatus silc_ske_create_rnd(SilcSKE ske, SilcInt n,
   SILC_LOG_DEBUG(("Creating random number"));
 
   /* Get the random number as string */
-  string = silc_rng_get_rn_string(ske->rng, (len / 8));
+  string = silc_rng_get_rn_data(ske->rng, (len / 8));
 
   /* Decode the string into a MP integer */
-  silc_mp_set_str(rnd, string, 16);
+  silc_mp_bin2mp(string, (len / 8), rnd);
   silc_mp_mod_2exp(rnd, rnd, len);
 
   /* Checks */
@@ -1094,17 +1121,9 @@ SilcSKEStatus silc_ske_make_hash(SilcSKE ske,
 
   SILC_LOG_DEBUG(("Start"));
 
-  e_len = silc_mp_sizeinbase(&ske->ke1_payload->e, 16);
-  e = silc_calloc(e_len + 1, sizeof(unsigned char));
-  silc_mp_get_str(e, 16, &ske->ke1_payload->e);
-
-  f_len = silc_mp_sizeinbase(&ske->ke2_payload->f, 16);
-  f = silc_calloc(f_len + 1, sizeof(unsigned char));
-  silc_mp_get_str(f, 16, &ske->ke2_payload->f);
-
-  KEY_len = silc_mp_sizeinbase(&ske->KEY, 16);
-  KEY = silc_calloc(KEY_len + 1, sizeof(unsigned char));
-  silc_mp_get_str(KEY, 16, &ske->KEY);
+  e = silc_mp_mp2bin(&ske->ke1_payload->e, &e_len);
+  f = silc_mp_mp2bin(&ske->ke2_payload->f, &f_len);
+  KEY = silc_mp_mp2bin(&ske->KEY, &KEY_len);
 
   buf = silc_buffer_alloc(ske->start_payload_copy->len + 
                          ske->pk_len + e_len + f_len + KEY_len);
@@ -1150,9 +1169,8 @@ SilcSKEStatus silc_ske_process_key_material(SilcSKE ske,
                                            unsigned int req_hmac_key_len,
                                            SilcSKEKeyMaterial *key)
 {
-  int i, klen;
+  int klen;
   SilcBuffer buf;
-  SilcInt tmp;
   unsigned char *tmpbuf;
   unsigned char hash[32];
   unsigned int hash_len = ske->prop->hash->hash->hash_len;
@@ -1160,19 +1178,10 @@ SilcSKEStatus silc_ske_process_key_material(SilcSKE ske,
 
   SILC_LOG_DEBUG(("Start"));
 
-  silc_mp_init_set(&tmp, &ske->KEY);
-
-  klen = silc_mp_size(&tmp);
-
-  /* Format the KEY material into binary data */
-  tmpbuf = silc_calloc(klen, sizeof(unsigned char));
-  for (i = klen; i > 0; i--) {
-    tmpbuf[i - 1] = (unsigned char)(silc_mp_get_ui(&tmp) & 0xff);
-    silc_mp_fdiv_q_2exp(&tmp, &tmp, 8);
-  }
+  /* Encode KEY to binary data */
+  tmpbuf = silc_mp_mp2bin(&ske->KEY, &klen);
 
   buf = silc_buffer_alloc(1 + klen + hash_len);
-
   silc_buffer_pull_tail(buf, SILC_BUFFER_END(buf));
   silc_buffer_format(buf,
                     SILC_STR_UI_CHAR(0),