updates
[silc.git] / lib / silcske / silcske.c
index cacdb3d66d1b43be2f9d5e82cbe54210b425a3a2..612abd81dea4f09920e12746caf2d11b85e7f47e 100644 (file)
@@ -72,8 +72,7 @@ void silc_ske_free(SilcSKE ske)
 
     /* Free rest */
     if (ske->prop) {
-      if (ske->prop->group)
-       silc_free(ske->prop->group);
+      silc_free(ske->prop->group);
       if (ske->prop->pkcs)
        silc_pkcs_free(ske->prop->pkcs);
       if (ske->prop->cipher)
@@ -94,8 +93,8 @@ void silc_ske_free(SilcSKE ske)
       silc_mp_uninit(ske->KEY);
       silc_free(ske->KEY);
     }
-    if (ske->hash)
-      silc_free(ske->hash);
+    silc_free(ske->hash);
+    silc_free(ske->callbacks);
     silc_free(ske);
   }
 }
@@ -229,6 +228,18 @@ SilcSKEStatus silc_ske_initiator_phase_1(SilcSKE ske,
     return status;
   }
 
+  /* Check version string */
+  if (ske->callbacks->check_version) {
+    status = ske->callbacks->check_version(ske, payload->version, 
+                                          payload->version_len,
+                                          ske->callbacks->context);
+    if (status != SILC_SKE_STATUS_OK) {
+      ske->status = status;
+      silc_ske_payload_start_free(ske->start_payload);
+      return status;
+    }
+  }
+
   /* Free our KE Start Payload context, we don't need it anymore. */
   silc_ske_payload_start_free(ske->start_payload);
 
@@ -650,6 +661,8 @@ SilcSKEStatus silc_ske_responder_start(SilcSKE ske, SilcRng rng,
   if (ske->callbacks->payload_receive)
     (*ske->callbacks->payload_receive)(ske, ske->callbacks->context);
 
+  silc_ske_payload_start_free(remote_payload);
+
   return status;
 
  err:
@@ -720,7 +733,7 @@ SilcSKEStatus silc_ske_responder_phase_1(SilcSKE ske,
   /* Send the packet. */
   if (ske->callbacks->send_packet)
     (*ske->callbacks->send_packet)(ske, payload_buf, SILC_PACKET_KEY_EXCHANGE, 
-                                 ske->callbacks->context);
+                                  ske->callbacks->context);
 
   silc_buffer_free(payload_buf);
 
@@ -1573,22 +1586,64 @@ SilcSKEStatus silc_ske_make_hash(SilcSKE ske,
     f = silc_mp_mp2bin(&ske->ke2_payload->x, 0, &f_len);
     KEY = silc_mp_mp2bin(ske->KEY, 0, &KEY_len);
     
-    buf = silc_buffer_alloc(ske->start_payload_copy->len + 
-                           ske->ke2_payload->pk_len + e_len + 
-                           f_len + KEY_len);
-    silc_buffer_pull_tail(buf, SILC_BUFFER_END(buf));
-
     /* Format the buffer used to compute the hash value */
-    ret = 
-      silc_buffer_format(buf,
-                        SILC_STR_UI_XNSTRING(ske->start_payload_copy->data,
-                                             ske->start_payload_copy->len),
-                        SILC_STR_UI_XNSTRING(ske->ke2_payload->pk_data, 
-                                             ske->ke2_payload->pk_len),
-                        SILC_STR_UI_XNSTRING(e, e_len),
-                        SILC_STR_UI_XNSTRING(f, f_len),
-                        SILC_STR_UI_XNSTRING(KEY, KEY_len),
-                        SILC_STR_END);
+    /* XXX Backward support for 0.6.1 */
+    if (ske->backward_version == 1) {
+      SILC_LOG_DEBUG(("*********** Using old KE payload"));
+      buf = silc_buffer_alloc(ske->start_payload_copy->len + 
+                             ske->ke2_payload->pk_len + e_len + 
+                             f_len + KEY_len);
+      silc_buffer_pull_tail(buf, SILC_BUFFER_END(buf));
+
+      ret = 
+       silc_buffer_format(buf,
+                          SILC_STR_UI_XNSTRING(ske->start_payload_copy->data,
+                                               ske->start_payload_copy->len),
+                          SILC_STR_UI_XNSTRING(ske->ke2_payload->pk_data, 
+                                               ske->ke2_payload->pk_len),
+                          SILC_STR_UI_XNSTRING(e, e_len),
+                          SILC_STR_UI_XNSTRING(f, f_len),
+                          SILC_STR_UI_XNSTRING(KEY, KEY_len),
+                          SILC_STR_END);
+    } else {
+      /* Initiator is not required to send its public key */
+      SILC_LOG_DEBUG(("*********** Using new KE payload"));
+      buf = silc_buffer_alloc(ske->start_payload_copy->len + 
+                             ske->ke2_payload->pk_len + 
+                             ske->ke1_payload->pk_len + 
+                             e_len + f_len + KEY_len);
+      silc_buffer_pull_tail(buf, SILC_BUFFER_END(buf));
+
+      if (!ske->ke1_payload->pk_data) {
+       ret = 
+         silc_buffer_format(buf,
+                            SILC_STR_UI_XNSTRING(ske->start_payload_copy->
+                                                 data,
+                                                 ske->start_payload_copy->
+                                                 len),
+                            SILC_STR_UI_XNSTRING(ske->ke2_payload->pk_data, 
+                                                 ske->ke2_payload->pk_len),
+                            SILC_STR_UI_XNSTRING(e, e_len),
+                            SILC_STR_UI_XNSTRING(f, f_len),
+                            SILC_STR_UI_XNSTRING(KEY, KEY_len),
+                            SILC_STR_END);
+      } else {
+       ret = 
+         silc_buffer_format(buf,
+                            SILC_STR_UI_XNSTRING(ske->start_payload_copy->
+                                                 data,
+                                                 ske->start_payload_copy->
+                                                 len),
+                            SILC_STR_UI_XNSTRING(ske->ke2_payload->pk_data, 
+                                                 ske->ke2_payload->pk_len),
+                            SILC_STR_UI_XNSTRING(ske->ke1_payload->pk_data, 
+                                                 ske->ke1_payload->pk_len),
+                            SILC_STR_UI_XNSTRING(e, e_len),
+                            SILC_STR_UI_XNSTRING(f, f_len),
+                            SILC_STR_UI_XNSTRING(KEY, KEY_len),
+                            SILC_STR_END);
+      }
+    }
     if (ret == -1) {
       silc_buffer_free(buf);
       memset(e, 0, e_len);
@@ -1813,13 +1868,19 @@ silc_ske_process_key_material_data(unsigned char *data,
     key->enc_key_len = req_enc_key_len;
   }
 
-  /* Take HMAC key */
+  /* Take HMAC keys */
   memset(hashd, 0, sizeof(hashd));
   buf->data[0] = 4;
   silc_hash_make(hash, buf->data, buf->len, hashd);
-  key->hmac_key = silc_calloc(req_hmac_key_len, sizeof(unsigned char));
-  memcpy(key->hmac_key, hashd, req_hmac_key_len);
+  key->send_hmac_key = silc_calloc(req_hmac_key_len, sizeof(unsigned char));
+  memcpy(key->send_hmac_key, hashd, req_hmac_key_len);
+  memset(hashd, 0, sizeof(hashd));
+  buf->data[0] = 5;
+  silc_hash_make(hash, buf->data, buf->len, hashd);
+  key->receive_hmac_key = silc_calloc(req_hmac_key_len, sizeof(unsigned char));
+  memcpy(key->receive_hmac_key, hashd, req_hmac_key_len);
   key->hmac_key_len = req_hmac_key_len;
+  memset(hashd, 0, sizeof(hashd));
 
   silc_buffer_free(buf);
 
@@ -1882,9 +1943,13 @@ void silc_ske_free_key_material(SilcSKEKeyMaterial *key)
     memset(key->receive_enc_key, 0, key->enc_key_len / 8);
     silc_free(key->receive_enc_key);
   }
-  if (key->hmac_key) {
-    memset(key->hmac_key, 0, key->hmac_key_len);
-    silc_free(key->hmac_key);
+  if (key->send_hmac_key) {
+    memset(key->send_hmac_key, 0, key->hmac_key_len);
+    silc_free(key->send_hmac_key);
+  }
+  if (key->receive_hmac_key) {
+    memset(key->receive_hmac_key, 0, key->hmac_key_len);
+    silc_free(key->receive_hmac_key);
   }
   silc_free(key);
 }