Merged from silc_1_0_branch (second merge).
[silc.git] / lib / silcske / silcske.c
index 4fd34f780c840b044f56b68d95f36f7f02c30774..e00121210a4b767ab89a295318768d8251f189e3 100644 (file)
@@ -111,6 +111,8 @@ void silc_ske_free(SilcSKE ske)
     }
     silc_free(ske->hash);
     silc_free(ske->callbacks);
+
+    memset(ske, 'F', sizeof(*ske));
     silc_free(ske);
   }
 }
@@ -199,17 +201,15 @@ SilcSKEStatus silc_ske_initiator_start(SilcSKE ske, SilcRng rng,
   if (status != SILC_SKE_STATUS_OK)
     return status;
 
-  /* Take a copy of the payload buffer for future use. It is used to
-     compute the HASH value. */
-  ske->start_payload_copy = silc_buffer_copy(payload_buf);
-  ske->start_payload = start_payload;
-
   /* Send the packet. */
   if (ske->callbacks->send_packet)
     (*ske->callbacks->send_packet)(ske, payload_buf, SILC_PACKET_KEY_EXCHANGE, 
                                   ske->callbacks->context);
 
-  silc_buffer_free(payload_buf);
+  /* Save the the payload buffer for future use. It is later used to 
+     compute the HASH value. */
+  ske->start_payload_copy = payload_buf;
+  ske->start_payload = start_payload;
 
   return status;
 }
@@ -389,6 +389,7 @@ SilcSKEStatus silc_ske_initiator_phase_2(SilcSKE ske,
       silc_free(x);
       silc_mp_uninit(&payload->x);
       silc_free(payload);
+      ske->ke1_payload = NULL;
       ske->status = SILC_SKE_STATUS_OK;
       return ske->status;
     }
@@ -398,7 +399,7 @@ SilcSKEStatus silc_ske_initiator_phase_2(SilcSKE ske,
 
   /* Compute signature data if we are doing mutual authentication */
   if (private_key && ske->start_payload->flags & SILC_SKE_SP_FLAG_MUTUAL) {
-    unsigned char hash[32], sign[2048];
+    unsigned char hash[32], sign[2048 + 1];
     SilcUInt32 hash_len, sign_len;
 
     SILC_LOG_DEBUG(("We are doing mutual authentication"));
@@ -420,13 +421,13 @@ SilcSKEStatus silc_ske_initiator_phase_2(SilcSKE ske,
       silc_mp_uninit(&payload->x);
       silc_free(payload->pk_data);
       silc_free(payload);
+      ske->ke1_payload = NULL;
       ske->status = SILC_SKE_STATUS_SIGNATURE_ERROR;
       return ske->status;
     }
-    payload->sign_data = silc_calloc(sign_len, sizeof(unsigned char));
-    memcpy(payload->sign_data, sign, sign_len);
-    memset(sign, 0, sizeof(sign));
+    payload->sign_data = silc_memdup(sign, sign_len);
     payload->sign_len = sign_len;
+    memset(sign, 0, sizeof(sign));
   }
 
   status = silc_ske_payload_ke_encode(ske, payload, &payload_buf);
@@ -435,7 +436,9 @@ SilcSKEStatus silc_ske_initiator_phase_2(SilcSKE ske,
     silc_free(x);
     silc_mp_uninit(&payload->x);
     silc_free(payload->pk_data);
+    silc_free(payload->sign_data);
     silc_free(payload);
+    ske->ke1_payload = NULL;
     ske->status = status;
     return status;
   }
@@ -508,8 +511,7 @@ static void silc_ske_initiator_finish_final(SilcSKE ske,
     if (status != SILC_SKE_STATUS_OK)
       goto err;
 
-    ske->hash = silc_calloc(hash_len, sizeof(unsigned char));
-    memcpy(ske->hash, hash, hash_len);
+    ske->hash = silc_memdup(hash, hash_len);
     ske->hash_len = hash_len;
 
     SILC_LOG_DEBUG(("Verifying signature (HASH)"));
@@ -621,8 +623,8 @@ SilcSKEStatus silc_ske_initiator_finish(SilcSKE ske,
     
     ske->users++;
     (*ske->callbacks->verify_key)(ske, payload->pk_data, payload->pk_len,
-                                payload->pk_type, ske->callbacks->context,
-                                silc_ske_initiator_finish_final, NULL);
+                                 payload->pk_type, ske->callbacks->context,
+                                 silc_ske_initiator_finish_final, NULL);
     
     /* We will continue to the final state after the public key has
        been verified by the caller. */
@@ -720,8 +722,7 @@ SilcSKEStatus silc_ske_responder_start(SilcSKE ske, SilcRng rng,
  err:
   if (remote_payload)
     silc_ske_payload_start_free(remote_payload);
-  if (payload)
-    silc_free(payload);
+  silc_free(payload);
 
   if (status == SILC_SKE_STATUS_OK)
     return SILC_SKE_STATUS_ERROR;
@@ -1016,7 +1017,7 @@ SilcSKEStatus silc_ske_responder_finish(SilcSKE ske,
   SilcSKEStatus status = SILC_SKE_STATUS_OK;
   SilcBuffer payload_buf;
   SilcMPInt *KEY;
-  unsigned char hash[32], sign[2048], *pk;
+  unsigned char hash[32], sign[2048 + 1], *pk;
   SilcUInt32 hash_len, sign_len, pk_len;
 
   SILC_LOG_DEBUG(("Start"));
@@ -1050,8 +1051,7 @@ SilcSKEStatus silc_ske_responder_finish(SilcSKE ske,
     if (status != SILC_SKE_STATUS_OK)
       goto err;
 
-    ske->hash = silc_calloc(hash_len, sizeof(unsigned char));
-    memcpy(ske->hash, hash, hash_len);
+    ske->hash = silc_memdup(hash, hash_len);
     ske->hash_len = hash_len;
     
     SILC_LOG_DEBUG(("Signing HASH value"));
@@ -1064,10 +1064,9 @@ SilcSKEStatus silc_ske_responder_finish(SilcSKE ske,
       status = SILC_SKE_STATUS_SIGNATURE_ERROR;
       goto err;
     }
-    ske->ke2_payload->sign_data = silc_calloc(sign_len, sizeof(unsigned char));
-    memcpy(ske->ke2_payload->sign_data, sign, sign_len);
-    memset(sign, 0, sizeof(sign));
+    ske->ke2_payload->sign_data = silc_memdup(sign, sign_len);
     ske->ke2_payload->sign_len = sign_len;
+    memset(sign, 0, sizeof(sign));
   }
   ske->ke2_payload->pk_type = pk_type;
 
@@ -1106,23 +1105,18 @@ SilcSKEStatus silc_ske_responder_finish(SilcSKE ske,
 
 SilcSKEStatus silc_ske_end(SilcSKE ske)
 {
-  SilcBuffer packet;
+  SilcBufferStruct packet;
+  unsigned char data[4];
 
   SILC_LOG_DEBUG(("Start"));
 
-  packet = silc_buffer_alloc_size(4);
-  if (!packet)
-    return SILC_SKE_STATUS_OUT_OF_MEMORY;
-  silc_buffer_format(packet,
-                    SILC_STR_UI_INT((SilcUInt32)SILC_SKE_STATUS_OK),
-                    SILC_STR_END);
+  SILC_PUT32_MSB((SilcUInt32)SILC_SKE_STATUS_OK, data);
+  silc_buffer_set(&packet, data, 4);
 
   if (ske->callbacks->send_packet)
-    (*ske->callbacks->send_packet)(ske, packet, SILC_PACKET_SUCCESS, 
+    (*ske->callbacks->send_packet)(ske, &packet, SILC_PACKET_SUCCESS, 
                                   ske->callbacks->context);
 
-  silc_buffer_free(packet);
-
   return SILC_SKE_STATUS_OK;
 }
 
@@ -1132,26 +1126,21 @@ SilcSKEStatus silc_ske_end(SilcSKE ske)
 
 SilcSKEStatus silc_ske_abort(SilcSKE ske, SilcSKEStatus status)
 {
-  SilcBuffer packet;
+  SilcBufferStruct packet;
+  unsigned char data[4];
 
   SILC_LOG_DEBUG(("Start"));
 
   if (status > SILC_SKE_STATUS_INVALID_COOKIE)
     status = SILC_SKE_STATUS_BAD_PAYLOAD;
 
-  packet = silc_buffer_alloc_size(4);
-  if (!packet)
-    return SILC_SKE_STATUS_OUT_OF_MEMORY;
-  silc_buffer_format(packet,
-                    SILC_STR_UI_INT((SilcUInt32)status),
-                    SILC_STR_END);
+  SILC_PUT32_MSB((SilcUInt32)status, data);
+  silc_buffer_set(&packet, data, 4);
 
   if (ske->callbacks->send_packet)
-    (*ske->callbacks->send_packet)(ske, packet, SILC_PACKET_FAILURE, 
+    (*ske->callbacks->send_packet)(ske, &packet, SILC_PACKET_FAILURE, 
                                   ske->callbacks->context);
 
-  silc_buffer_free(packet);
-
   return SILC_SKE_STATUS_OK;
 }
 
@@ -1181,7 +1170,7 @@ silc_ske_assemble_security_properties(SilcSKE ske,
   /* Set random cookie */
   rp->cookie = silc_calloc(SILC_SKE_COOKIE_LEN, sizeof(*rp->cookie));
   for (i = 0; i < SILC_SKE_COOKIE_LEN; i++)
-    rp->cookie[i] = silc_rng_get_byte(ske->rng);
+    rp->cookie[i] = silc_rng_get_byte_fast(ske->rng);
   rp->cookie_len = SILC_SKE_COOKIE_LEN;
 
   /* Put version */
@@ -1210,8 +1199,8 @@ silc_ske_assemble_security_properties(SilcSKE ske,
 
   /* XXX */
   /* Get supported compression algorithms */
-  rp->comp_alg_list = strdup("");
-  rp->comp_alg_len = 0;
+  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 +
@@ -1537,9 +1526,8 @@ silc_ske_select_security_properties(SilcSKE ske,
     payload->hmac_alg_list = strdup(rp->hmac_alg_list);
   }
 
-#if 0
   /* Get supported compression algorithms */
-  cp = rp->hash_alg_list;
+  cp = rp->comp_alg_list;
   if (cp && strchr(cp, ',')) {
     while(cp) {
       char *item;
@@ -1548,15 +1536,23 @@ silc_ske_select_security_properties(SilcSKE ske,
       item = silc_calloc(len + 1, sizeof(char));
       memcpy(item, cp, len);
 
-      SILC_LOG_DEBUG(("Proposed hash alg `%s'", item));
-
-      if (silc_hash_is_supported(item) == TRUE) {
-       SILC_LOG_DEBUG(("Found hash alg `%s'", item));
+      SILC_LOG_DEBUG(("Proposed Compression `%s'", item));
 
-       payload->hash_alg_len = len;
-       payload->hash_alg_list = item;
+#if 1
+      if (!strcmp(item, "none")) {
+       SILC_LOG_DEBUG(("Found Compression `%s'", item));
+       payload->comp_alg_len = len;
+       payload->comp_alg_list = item;
+       break;
+      }
+#else
+      if (silc_hmac_is_supported(item) == TRUE) {
+       SILC_LOG_DEBUG(("Found Compression `%s'", item));
+       payload->comp_alg_len = len;
+       payload->comp_alg_list = item;
        break;
       }
+#endif
 
       cp += len;
       if (strlen(cp) == 0)
@@ -1567,20 +1563,7 @@ silc_ske_select_security_properties(SilcSKE ske,
       if (item)
        silc_free(item);
     }
-
-    if (!payload->hash_alg_len && !payload->hash_alg_list) {
-      SILC_LOG_DEBUG(("Could not find supported hash alg"));
-      silc_ske_abort(ske, SILC_SKE_STATUS_UNKNOWN_HASH_FUNCTION);
-      silc_free(payload->ke_grp_list);
-      silc_free(payload->pkcs_alg_list);
-      silc_free(payload->enc_alg_list);
-      silc_free(payload);
-      return;
-    }
-  } else {
-
   }
-#endif
 
   payload->len = 1 + 1 + 2 + SILC_SKE_COOKIE_LEN + 
     2 + payload->version_len + 
@@ -1600,16 +1583,22 @@ static SilcSKEStatus silc_ske_create_rnd(SilcSKE ske, SilcMPInt *n,
 {
   SilcSKEStatus status = SILC_SKE_STATUS_OK;
   unsigned char *string;
+  SilcUInt32 l;
+
+  if (!len)
+    return SILC_SKE_STATUS_ERROR;
 
   SILC_LOG_DEBUG(("Creating random number"));
 
+  l = ((len - 1) / 8);
+
   /* Get the random number as string */
-  string = silc_rng_get_rn_data(ske->rng, ((len - 1) / 8));
+  string = silc_rng_get_rn_data(ske->rng, l);
   if (!string)
     return SILC_SKE_STATUS_OUT_OF_MEMORY;
 
   /* Decode the string into a MP integer */
-  silc_mp_bin2mp(string, ((len - 1) / 8), rnd);
+  silc_mp_bin2mp(string, l, rnd);
   silc_mp_mod_2exp(rnd, rnd, len);
 
   /* Checks */
@@ -1618,7 +1607,7 @@ static SilcSKEStatus silc_ske_create_rnd(SilcSKE ske, SilcMPInt *n,
   if (silc_mp_cmp(rnd, n) >= 0)
     status = SILC_SKE_STATUS_ERROR;
 
-  memset(string, 'F', (len / 8));
+  memset(string, 'F', l);
   silc_free(string);
 
   return status;