예제 #1
0
파일: idlist.c 프로젝트: FabrizioFabbe/silc
void silc_idlist_del_data(void *entry)
{
  SilcIDListData idata = (SilcIDListData)entry;

  if (idata->hash)
    silc_hash_free(idata->hash);

  idata->hash = NULL;
  idata->public_key = NULL;
}
예제 #2
0
파일: mybot.c 프로젝트: FabrizioFabbe/silc
static void
silc_command_reply(SilcClient client, SilcClientConnection conn,
		   SilcCommand command, SilcStatus status,
		   SilcStatus error, va_list ap)
{
  /* If error occurred in client library with our command, print the error */
  if (status != SILC_STATUS_OK)
    fprintf(stderr, "MyBot: COMMAND REPLY %s: %s\n",
	    silc_get_command_name(command),
	    silc_get_status_message(status));

  /* Check for successful JOIN.  See
     http://silcnet.org/docs/toolkit/command_reply_args.html for the
     different arguments the client library returns. */
  if (command == SILC_COMMAND_JOIN) {
    SilcChannelEntry channel;
    SilcHash sha1hash;

    (void)va_arg(ap, SilcClientEntry);
    channel = va_arg(ap, SilcChannelEntry);

    fprintf(stdout, "MyBot: Joined '%s' channel\n", channel->channel_name);

    /* Now send the "hello" to the channel */
    silc_client_send_channel_message(client, conn, channel, NULL, 0, NULL,
				     "hello", strlen("hello"));
    fprintf(stdout, "MyBot: Sent 'hello' to channel\n");

    /* Now send digitally signed "hello" to the channel.  We have to allocate
       hash function for the signature process. */
    silc_hash_alloc("sha1", &sha1hash);
    silc_client_send_channel_message(client, conn, channel, NULL,
				     SILC_MESSAGE_FLAG_SIGNED, sha1hash,
				     "hello, with signature",
				     strlen("hello, with signature"));
    silc_hash_free(sha1hash);
    fprintf(stdout, "MyBot: Sent 'hello, with signature' to channel\n");
  }
}
예제 #3
0
int main(int argc, char **argv)
{
  SilcBool success = FALSE;
  unsigned char digest[32], tmp[4096], digest2[32];
  SilcUInt32 tmp_len;
  SilcHash sha256;
  
  if (argc > 1 && !strcmp(argv[1], "-d")) {
    silc_log_debug(TRUE);
    silc_log_debug_hexdump(TRUE);
    silc_log_set_debug_string("*crypt*,*hash*,*sha256*");
  }

  SILC_LOG_DEBUG(("Registering builtin hash functions"));
  silc_hash_register_default();

  SILC_LOG_DEBUG(("Allocating sha256 hash function"));
  if (!silc_hash_alloc("sha256", &sha256)) {
    SILC_LOG_DEBUG(("Allocating sha256 hash function failed"));
    goto err;
  }

  SilcUInt64 t1, t2;
  silc_timer_synchronize(&timer);

  /* First test vector */
  SILC_LOG_DEBUG(("First test vector"));
  silc_hash_init(sha256);
  silc_hash_update(sha256, data1, strlen(data1));
  memset(digest, 0, sizeof(digest));
  t1 = silc_timer_tick(&timer, FALSE);
  silc_hash_final(sha256, digest);
  t2 = silc_timer_tick(&timer, TRUE);
  SILC_LOG_DEBUG(("cycles: %d", t2 - t1));
  SILC_LOG_HEXDUMP(("Message"), (unsigned char *)data1, strlen(data1));
  SILC_LOG_HEXDUMP(("Digest"), digest, sizeof(digest));
  SILC_LOG_HEXDUMP(("Expected digest"), (unsigned char *)data1_digest,
		   sizeof(digest));
  if (memcmp(digest, data1_digest, sizeof(digest))) {
    SILC_LOG_DEBUG(("Hash failed"));
    goto err;
  }
  SILC_LOG_DEBUG(("Hash is successful"));
  
  /* Second test vector */
  SILC_LOG_DEBUG(("Second test vector"));
  silc_hash_init(sha256);
  silc_hash_update(sha256, data2, strlen(data2));
  silc_hash_final(sha256, digest);
  SILC_LOG_HEXDUMP(("Message"), (unsigned char *)data2, strlen(data2));
  SILC_LOG_HEXDUMP(("Digest"), digest, sizeof(digest));
  SILC_LOG_HEXDUMP(("Expected digest"), (unsigned char *)data2_digest,
		   sizeof(digest));
  if (memcmp(digest, data2_digest, sizeof(digest))) {
    SILC_LOG_DEBUG(("Hash failed"));
    goto err;
  }
  SILC_LOG_DEBUG(("Hash is successful"));
  
  /* Third test vector */
  SILC_LOG_DEBUG(("Third test vector"));
  silc_hash_init(sha256);
  silc_hex2data(data3, tmp, sizeof(tmp), &tmp_len);
  silc_hash_update(sha256, tmp, tmp_len);
  silc_hash_final(sha256, digest);
  SILC_LOG_HEXDUMP(("Message"), tmp, tmp_len);
  SILC_LOG_HEXDUMP(("Digest"), digest, sizeof(digest));
  silc_hex2data(data3_digest, digest2, sizeof(digest2), NULL);
  SILC_LOG_HEXDUMP(("Expected digest"), (unsigned char *)digest2,
		   sizeof(digest));
  if (memcmp(digest, digest2, sizeof(digest))) {
    SILC_LOG_DEBUG(("Hash failed"));
    goto err;
  }
  SILC_LOG_DEBUG(("Hash is successful"));
  
  success = TRUE;
  
 err:
  SILC_LOG_DEBUG(("Testing was %s", success ? "SUCCESS" : "FAILURE"));
  fprintf(stderr, "Testing was %s\n", success ? "SUCCESS" : "FAILURE");

  silc_hash_free(sha256);
  silc_hash_unregister_all();
  return success;
}
예제 #4
0
파일: client.c 프로젝트: TabTwo/silc-client
void silc_client_del_connection(SilcClient client, SilcClientConnection conn)
{
  SilcList list;
  SilcIDCacheEntry entry;
  SilcFSMThread thread;

  SILC_LOG_DEBUG(("Freeing connection %p", conn));

  silc_schedule_task_del_by_context(conn->internal->schedule, conn);

  /* Free all cache entries */
  if (conn->internal->server_cache) {
    if (silc_idcache_get_all(conn->internal->server_cache, &list)) {
      silc_list_start(list);
      while ((entry = silc_list_get(list)))
	silc_client_del_server(client, conn, entry->context);
    }
  }
  if (conn->internal->channel_cache) {
    if (silc_idcache_get_all(conn->internal->channel_cache, &list)) {
      silc_list_start(list);
      while ((entry = silc_list_get(list))) {
	silc_client_empty_channel(client, conn, entry->context);
	silc_client_del_channel(client, conn, entry->context);
      }
    }
  }
  if (conn->internal->client_cache) {
    if (silc_idcache_get_all(conn->internal->client_cache, &list)) {
      silc_list_start(list);
      while ((entry = silc_list_get(list)))
	silc_client_del_client(client, conn, entry->context);
    }
  }

  /* Free ID caches */
  if (conn->internal->client_cache)
    silc_idcache_free(conn->internal->client_cache);
  if (conn->internal->channel_cache)
    silc_idcache_free(conn->internal->channel_cache);
  if (conn->internal->server_cache)
    silc_idcache_free(conn->internal->server_cache);

  /* Free thread pool */
  silc_list_start(conn->internal->thread_pool);
  while ((thread = silc_list_get(conn->internal->thread_pool)))
    silc_fsm_free(thread);

  silc_free(conn->remote_host);
  silc_buffer_free(conn->internal->local_idp);
  silc_buffer_free(conn->internal->remote_idp);
  silc_mutex_free(conn->internal->lock);
  if (conn->internal->hash)
    silc_hash_free(conn->internal->hash);
  if (conn->internal->sha1hash)
    silc_hash_free(conn->internal->sha1hash);
  silc_atomic_uninit16(&conn->internal->cmd_ident);
  silc_free(conn->internal->away_message);
  if (conn->internal->rekey)
    silc_ske_free_rekey_material(conn->internal->rekey);
  if (conn->internal->cop)
    silc_async_free(conn->internal->cop);

  silc_free(conn->internal);
  memset(conn, 'F', sizeof(*conn));
  silc_free(conn);
}
예제 #5
0
int main(int argc, char **argv)
{
  SilcBool success = FALSE;
  SilcMessagePayload message;
  SilcBuffer buf;
  const char *msg = "FOOBAR MESSAGE";
  unsigned char *data, tmp[1023], *tmp2;
  SilcUInt32 data_len;
  SilcUInt16 flags;
  int i, n;

  if (argc > 1 && !strcmp(argv[1], "-d")) {
    silc_log_debug(TRUE);
    silc_log_debug_hexdump(TRUE);
    silc_log_set_debug_string("*message*");
  }

  silc_cipher_register_default();
  silc_hash_register_default();
  silc_hmac_register_default();
  silc_pkcs_register_default();

  SILC_LOG_DEBUG(("Load keypair"));
  if (!silc_load_key_pair("pubkey.pub", "privkey.prv", "",
			  &public_key, &private_key)) {
    SILC_LOG_DEBUG(("Create keypair"));
    if (!silc_create_key_pair("rsa", 2048, "pubkey.pub", "privkey.prv",
			      NULL, "", &public_key, &private_key, FALSE))
      goto err;
  }

  SILC_LOG_DEBUG(("Alloc RNG"));
  rng = silc_rng_alloc();
  silc_rng_init(rng);

  SILC_LOG_DEBUG(("Alloc AES"));
  if (!silc_cipher_alloc("aes-128-cbc", &key))
    goto err;

  SILC_LOG_DEBUG(("Alloc SHA-256"));
  if (!silc_hash_alloc("sha256", &hash))
    goto err;

  SILC_LOG_DEBUG(("Alloc HMAC"));
  if (!silc_hmac_alloc("hmac-sha256-96", hash, &hmac))
    goto err;

  SILC_LOG_DEBUG(("Set static key: '1234567890123456'"));
  if (!silc_cipher_set_key(key, "1234567890123456", 16 * 8))
    goto err;
  SILC_LOG_DEBUG(("Set HMAC key: '1234567890123456'"));
  silc_hmac_set_key(hmac, "1234567890123456", 16);

  /* Simple private message */
  SILC_LOG_DEBUG(("Encoding private message len %d (static key)",
		  strlen(msg)));
  buf = silc_message_payload_encode(SILC_MESSAGE_FLAG_ACTION |
				    SILC_MESSAGE_FLAG_UTF8 |
				    SILC_MESSAGE_FLAG_ACK,
				    msg, strlen(msg), TRUE, TRUE,
				    key, hmac, rng, NULL, NULL, NULL, NULL);
  if (!buf)
    goto err;
  SILC_LOG_HEXDUMP(("message"), buf->data, silc_buffer_len(buf));
  SILC_LOG_DEBUG(("Parsing private messsage (static key)"));
  message = silc_message_payload_parse(silc_buffer_data(buf),
				       silc_buffer_len(buf), TRUE, TRUE,
				       key, hmac, NULL, FALSE, NULL);
  if (!message)
    goto err;
  flags = silc_message_get_flags(message);
  SILC_LOG_DEBUG(("Flags: %x", flags));
  if (!(flags & SILC_MESSAGE_FLAG_ACTION))
    goto err;
  if (!(flags & SILC_MESSAGE_FLAG_UTF8))
    goto err;
  if (!(flags & SILC_MESSAGE_FLAG_ACK))
    goto err;
  data = silc_message_get_data(message, &data_len);
  SILC_LOG_HEXDUMP(("Data"), data, data_len);
  if (data_len != strlen(msg) || memcmp(data, msg, strlen(msg)))
    goto err;
  SILC_LOG_HEXDUMP(("MAC"), silc_message_get_mac(message),
		   silc_hmac_len(hmac));
  silc_message_payload_free(message);

  /* Simple private message */
  n = 10;
  SILC_LOG_DEBUG(("Encoding private message len %d (static key)", n));
  buf = silc_message_payload_encode(SILC_MESSAGE_FLAG_ACTION |
				    SILC_MESSAGE_FLAG_UTF8 |
				    SILC_MESSAGE_FLAG_ACK,
				    msg, n, TRUE, TRUE,
				    key, hmac, rng, NULL, NULL, NULL, buf);
  if (!buf)
    goto err;
  SILC_LOG_HEXDUMP(("message"), buf->data, silc_buffer_len(buf));
  SILC_LOG_DEBUG(("Parsing private messsage (static key)"));
  message = silc_message_payload_parse(silc_buffer_data(buf),
				       silc_buffer_len(buf), TRUE, TRUE,
				       key, hmac, NULL, FALSE, NULL);
  if (!message)
    goto err;
  flags = silc_message_get_flags(message);
  SILC_LOG_DEBUG(("Flags: %x", flags));
  if (!(flags & SILC_MESSAGE_FLAG_ACTION))
    goto err;
  if (!(flags & SILC_MESSAGE_FLAG_UTF8))
    goto err;
  if (!(flags & SILC_MESSAGE_FLAG_ACK))
    goto err;
  data = silc_message_get_data(message, &data_len);
  SILC_LOG_HEXDUMP(("Data"), data, data_len);
  if (data_len != n || memcmp(data, msg, n))
    goto err;
  SILC_LOG_HEXDUMP(("MAC"), silc_message_get_mac(message),
		   silc_hmac_len(hmac));
  silc_message_payload_free(message);

  /* Simple private message */
  n = 1;
  SILC_LOG_DEBUG(("Encoding private message len %d (static key)", n));
  buf = silc_message_payload_encode(SILC_MESSAGE_FLAG_ACTION |
				    SILC_MESSAGE_FLAG_UTF8 |
				    SILC_MESSAGE_FLAG_ACK,
				    msg, n, TRUE, TRUE,
				    key, hmac, rng, NULL, NULL, NULL, buf);
  if (!buf)
    goto err;
  SILC_LOG_HEXDUMP(("message"), buf->data, silc_buffer_len(buf));
  SILC_LOG_DEBUG(("Parsing private messsage (static key)"));
  message = silc_message_payload_parse(silc_buffer_data(buf),
				       silc_buffer_len(buf), TRUE, TRUE,
				       key, hmac, NULL, FALSE, NULL);
  if (!message)
    goto err;
  flags = silc_message_get_flags(message);
  SILC_LOG_DEBUG(("Flags: %x", flags));
  if (!(flags & SILC_MESSAGE_FLAG_ACTION))
    goto err;
  if (!(flags & SILC_MESSAGE_FLAG_UTF8))
    goto err;
  if (!(flags & SILC_MESSAGE_FLAG_ACK))
    goto err;
  data = silc_message_get_data(message, &data_len);
  SILC_LOG_HEXDUMP(("Data"), data, data_len);
  if (data_len != n || memcmp(data, msg, n))
    goto err;
  SILC_LOG_HEXDUMP(("MAC"), silc_message_get_mac(message),
		   silc_hmac_len(hmac));
  silc_message_payload_free(message);

  /* Simple private message */
  for (i = 0; i < sizeof(tmp); i++)
    tmp[i] = (32 + i) & 127;
  SILC_LOG_DEBUG(("Encoding private message len %d (static key)",
		  sizeof(tmp)));
  buf = silc_message_payload_encode(SILC_MESSAGE_FLAG_ACTION |
				    SILC_MESSAGE_FLAG_UTF8 |
				    SILC_MESSAGE_FLAG_ACK,
				    tmp, sizeof(tmp), TRUE, TRUE,
				    key, hmac, rng, NULL, NULL, NULL, buf);
  if (!buf)
    goto err;
  SILC_LOG_HEXDUMP(("message"), buf->data, silc_buffer_len(buf));
  SILC_LOG_DEBUG(("Parsing private messsage (static key)"));
  message = silc_message_payload_parse(silc_buffer_data(buf),
				       silc_buffer_len(buf), TRUE, TRUE,
				       key, hmac, NULL, FALSE, NULL);
  if (!message)
    goto err;
  flags = silc_message_get_flags(message);
  SILC_LOG_DEBUG(("Flags: %x", flags));
  if (!(flags & SILC_MESSAGE_FLAG_ACTION))
    goto err;
  if (!(flags & SILC_MESSAGE_FLAG_UTF8))
    goto err;
  if (!(flags & SILC_MESSAGE_FLAG_ACK))
    goto err;
  data = silc_message_get_data(message, &data_len);
  SILC_LOG_HEXDUMP(("Data"), data, data_len);
  if (data_len != sizeof(tmp) || memcmp(data, tmp, sizeof(tmp)))
    goto err;
  SILC_LOG_HEXDUMP(("MAC"), silc_message_get_mac(message),
		   silc_hmac_len(hmac));
  silc_message_payload_free(message);

  /* Digitally signed private message */
  for (i = 0; i < sizeof(tmp); i++)
    tmp[i] = (32 + i) & 127;
  SILC_LOG_DEBUG(("Encoding private message len %d (static key) SIGNED",
		  sizeof(tmp)));
  buf = silc_message_payload_encode(SILC_MESSAGE_FLAG_ACTION |
				    SILC_MESSAGE_FLAG_UTF8 |
				    SILC_MESSAGE_FLAG_ACK |
				    SILC_MESSAGE_FLAG_SIGNED,
				    tmp, sizeof(tmp), TRUE, TRUE,
				    key, hmac, rng,
				    public_key, private_key, hash, buf);
  if (!buf)
    goto err;
  SILC_LOG_HEXDUMP(("message"), buf->data, silc_buffer_len(buf));
  SILC_LOG_DEBUG(("Parsing private messsage (static key)"));
  message = silc_message_payload_parse(silc_buffer_data(buf),
				       silc_buffer_len(buf), TRUE, TRUE,
				       key, hmac, NULL, FALSE, NULL);
  if (!message)
    goto err;
  flags = silc_message_get_flags(message);
  SILC_LOG_DEBUG(("Flags: %x", flags));
  if (!(flags & SILC_MESSAGE_FLAG_ACTION))
    goto err;
  if (!(flags & SILC_MESSAGE_FLAG_UTF8))
    goto err;
  if (!(flags & SILC_MESSAGE_FLAG_ACK))
    goto err;
  if (!(flags & SILC_MESSAGE_FLAG_SIGNED))
    goto err;
  data = silc_message_get_data(message, &data_len);
  SILC_LOG_HEXDUMP(("Data"), data, data_len);
  if (data_len != sizeof(tmp) || memcmp(data, tmp, sizeof(tmp)))
    goto err;
  SILC_LOG_HEXDUMP(("MAC"), silc_message_get_mac(message),
		   silc_hmac_len(hmac));
  SILC_LOG_DEBUG(("Verifying signature"));
  if (silc_message_signed_verify(message, public_key, hash) !=
      SILC_AUTH_OK)
    goto err;
  SILC_LOG_DEBUG(("Signature Ok"));
  SILC_LOG_DEBUG(("Get public key"));
  pk2 = silc_message_signed_get_public_key(message, NULL, NULL);
  if (!pk2)
    goto err;
  SILC_LOG_DEBUG(("Verify public key"));
  if (!silc_pkcs_public_key_compare(public_key, pk2))
    goto err;
  SILC_LOG_DEBUG(("Public key Ok"));
  silc_pkcs_public_key_free(pk2);
  silc_message_payload_free(message);

  /* Digitally signed channel message */
  for (i = 0; i < sizeof(tmp) / 2; i++)
    tmp[i] = (32 + i) & 127;
  SILC_LOG_DEBUG(("Encoding channel message len %d (static key) SIGNED",
		  sizeof(tmp) / 2));
  buf = silc_message_payload_encode(SILC_MESSAGE_FLAG_ACTION |
				    SILC_MESSAGE_FLAG_UTF8 |
				    SILC_MESSAGE_FLAG_ACK |
				    SILC_MESSAGE_FLAG_SIGNED,
				    tmp, sizeof(tmp) / 2, TRUE, FALSE,
				    key, hmac, rng,
				    public_key, private_key, hash, buf);
  if (!buf)
    goto err;
  SILC_LOG_HEXDUMP(("message"), buf->data, silc_buffer_len(buf));
  SILC_LOG_DEBUG(("Parsing channel messsage (static key)"));
  message = silc_message_payload_parse(silc_buffer_data(buf),
				       silc_buffer_len(buf), FALSE, TRUE,
				       key, hmac, NULL, FALSE, NULL);
  if (!message)
    goto err;
  flags = silc_message_get_flags(message);
  SILC_LOG_DEBUG(("Flags: %x", flags));
  if (!(flags & SILC_MESSAGE_FLAG_ACTION))
    goto err;
  if (!(flags & SILC_MESSAGE_FLAG_UTF8))
    goto err;
  if (!(flags & SILC_MESSAGE_FLAG_ACK))
    goto err;
  if (!(flags & SILC_MESSAGE_FLAG_SIGNED))
    goto err;
  data = silc_message_get_data(message, &data_len);
  SILC_LOG_HEXDUMP(("Data"), data, data_len);
  if (data_len != sizeof(tmp) / 2 || memcmp(data, tmp, sizeof(tmp) / 2))
    goto err;
  SILC_LOG_HEXDUMP(("MAC"), silc_message_get_mac(message),
		   silc_hmac_len(hmac));
  SILC_LOG_DEBUG(("Verifying signature"));
  if (silc_message_signed_verify(message, public_key, hash) !=
      SILC_AUTH_OK)
    goto err;
  SILC_LOG_DEBUG(("Signature Ok"));
  SILC_LOG_DEBUG(("Get public key"));
  pk2 = silc_message_signed_get_public_key(message, NULL, NULL);
  if (!pk2)
    goto err;
  SILC_LOG_DEBUG(("Verify public key"));
  if (!silc_pkcs_public_key_compare(public_key, pk2))
    goto err;
  SILC_LOG_DEBUG(("Public key Ok"));
  silc_pkcs_public_key_free(pk2);
  silc_message_payload_free(message);

  /* Digitally signed private message (no encryption) */
  for (i = 0; i < sizeof(tmp) / 2; i++)
    tmp[i] = (32 + i) & 127;
  SILC_LOG_DEBUG(("Encoding private message len %d SIGNED",
		  sizeof(tmp) / 2));
  buf = silc_message_payload_encode(SILC_MESSAGE_FLAG_ACTION |
				    SILC_MESSAGE_FLAG_UTF8 |
				    SILC_MESSAGE_FLAG_ACK |
				    SILC_MESSAGE_FLAG_SIGNED,
				    tmp, sizeof(tmp) / 2, FALSE, TRUE,
				    NULL, NULL, rng,
				    public_key, private_key, hash, buf);
  if (!buf)
    goto err;
  SILC_LOG_HEXDUMP(("message"), buf->data, silc_buffer_len(buf));
  SILC_LOG_DEBUG(("Parsing private messsage (static key)"));
  message = silc_message_payload_parse(silc_buffer_data(buf),
				       silc_buffer_len(buf), TRUE, FALSE,
				       NULL, NULL, NULL, FALSE, NULL);
  if (!message)
    goto err;
  flags = silc_message_get_flags(message);
  SILC_LOG_DEBUG(("Flags: %x", flags));
  if (!(flags & SILC_MESSAGE_FLAG_ACTION))
    goto err;
  if (!(flags & SILC_MESSAGE_FLAG_UTF8))
    goto err;
  if (!(flags & SILC_MESSAGE_FLAG_ACK))
    goto err;
  if (!(flags & SILC_MESSAGE_FLAG_SIGNED))
    goto err;
  data = silc_message_get_data(message, &data_len);
  SILC_LOG_HEXDUMP(("Data"), data, data_len);
  if (data_len != sizeof(tmp) / 2 || memcmp(data, tmp, sizeof(tmp) / 2))
    goto err;
  SILC_LOG_DEBUG(("Verifying signature"));
  if (silc_message_signed_verify(message, public_key, hash) !=
      SILC_AUTH_OK)
    goto err;
  SILC_LOG_DEBUG(("Signature Ok"));
  SILC_LOG_DEBUG(("Get public key"));
  pk2 = silc_message_signed_get_public_key(message, NULL, NULL);
  if (!pk2)
    goto err;
  SILC_LOG_DEBUG(("Verify public key"));
  if (!silc_pkcs_public_key_compare(public_key, pk2))
    goto err;
  SILC_LOG_DEBUG(("Public key Ok"));
  silc_pkcs_public_key_free(pk2);
  silc_message_payload_free(message);

  /* Digitally signed channel message (LARGE) */
  n = 65550;
  tmp2 = silc_malloc(n);
  if (!tmp2)
    goto err;
  SILC_LOG_DEBUG(("Encoding channel message len %d (static key) SIGNED LARGE",
		  n));
  buf = silc_message_payload_encode(SILC_MESSAGE_FLAG_ACTION |
				    SILC_MESSAGE_FLAG_UTF8 |
				    SILC_MESSAGE_FLAG_ACK |
				    SILC_MESSAGE_FLAG_SIGNED,
				    tmp2, n, TRUE, FALSE,
				    key, hmac, rng,
				    public_key, private_key, hash, buf);
  if (!buf)
    goto err;
  SILC_LOG_DEBUG(("Message length: %d", silc_buffer_len(buf)));
  if (silc_buffer_len(buf) > SILC_PACKET_MAX_LEN)
    goto err;
  SILC_LOG_DEBUG(("Parsing channel messsage (static key)"));
  message = silc_message_payload_parse(silc_buffer_data(buf),
				       silc_buffer_len(buf), FALSE, TRUE,
				       key, hmac, NULL, FALSE, NULL);
  if (!message)
    goto err;
  flags = silc_message_get_flags(message);
  SILC_LOG_DEBUG(("Flags: %x", flags));
  if (!(flags & SILC_MESSAGE_FLAG_ACTION))
    goto err;
  if (!(flags & SILC_MESSAGE_FLAG_UTF8))
    goto err;
  if (!(flags & SILC_MESSAGE_FLAG_ACK))
    goto err;
  if (!(flags & SILC_MESSAGE_FLAG_SIGNED))
    goto err;
  data = silc_message_get_data(message, &data_len);
  SILC_LOG_DEBUG(("Data len: %d", data_len));
  if (silc_buffer_len(buf) > SILC_PACKET_MAX_LEN)
    goto err;
  SILC_LOG_HEXDUMP(("MAC"), silc_message_get_mac(message),
		   silc_hmac_len(hmac));
  SILC_LOG_DEBUG(("Verifying signature"));
  if (silc_message_signed_verify(message, public_key, hash) !=
      SILC_AUTH_OK)
    goto err;
  SILC_LOG_DEBUG(("Signature Ok"));
  SILC_LOG_DEBUG(("Get public key"));
  pk2 = silc_message_signed_get_public_key(message, NULL, NULL);
  if (!pk2)
    goto err;
  SILC_LOG_DEBUG(("Verify public key"));
  if (!silc_pkcs_public_key_compare(public_key, pk2))
    goto err;
  SILC_LOG_DEBUG(("Public key Ok"));
  silc_pkcs_public_key_free(pk2);
  silc_message_payload_free(message);
  silc_free(tmp2);


  success = TRUE;
  SILC_LOG_DEBUG(("Cleanup"));
  silc_pkcs_public_key_free(public_key);
  silc_pkcs_private_key_free(private_key);
  silc_cipher_free(key);
  silc_hash_free(hash);
  silc_rng_free(rng);

 err:
  silc_cipher_unregister_all();
  silc_hash_unregister_all();
  silc_hmac_unregister_all();
  silc_pkcs_unregister_all();

  SILC_LOG_DEBUG(("Testing was %s", success ? "SUCCESS" : "FAILURE"));
  fprintf(stderr, "Testing was %s\n", success ? "SUCCESS" : "FAILURE");

  return success;
}
예제 #6
0
SilcBool silc_pkcs1_verify(void *public_key,
			   unsigned char *signature,
			   SilcUInt32 signature_len,
			   unsigned char *data,
			   SilcUInt32 data_len,
			   SilcHash hash)
{
  RsaPublicKey *key = public_key;
  SilcBool ret = FALSE;
  SilcMPInt mp_tmp2;
  SilcMPInt mp_dst;
  unsigned char *verify, unpadded[2048 + 1], hashr[SILC_HASH_MAXLEN];
  SilcUInt32 verify_len, len = (key->bits + 7) / 8;
  SilcBufferStruct di, ldi;
  SilcHash ihash = NULL;
  SilcAsn1 asn1 = NULL;
  char *oid;

  SILC_LOG_DEBUG(("Verify signature"));

  asn1 = silc_asn1_alloc();
  if (!asn1)
    return FALSE;

  silc_mp_init(&mp_tmp2);
  silc_mp_init(&mp_dst);

  /* Format the signature into MP int */
  silc_mp_bin2mp(signature, signature_len, &mp_tmp2);

  /* Verify */
  silc_rsa_public_operation(key, &mp_tmp2, &mp_dst);

  /* MP to data */
  verify = silc_mp_mp2bin(&mp_dst, len, &verify_len);

  /* Unpad data */
  if (!silc_pkcs1_decode(SILC_PKCS1_BT_PRV1, verify, verify_len,
			 unpadded, sizeof(unpadded), &len))
    goto err;
  silc_buffer_set(&di, unpadded, len);

  /* If hash isn't given, allocate the one given in digest info */
  if (!hash) {
    /* Decode digest info */
    if (!silc_asn1_decode(asn1, &di,
			  SILC_ASN1_OPTS(SILC_ASN1_ACCUMUL),
			  SILC_ASN1_SEQUENCE,
			    SILC_ASN1_SEQUENCE,
			      SILC_ASN1_OID(&oid),
			    SILC_ASN1_END,
			  SILC_ASN1_END, SILC_ASN1_END))
      goto err;

    if (!silc_hash_alloc_by_oid(oid, &ihash)) {
      SILC_LOG_DEBUG(("Unknown OID %s", oid));
      goto err;
    }
    hash = ihash;
  }

  /* Hash the data */
  silc_hash_make(hash, data, data_len, hashr);
  data = hashr;
  data_len = silc_hash_len(hash);
  oid = (char *)silc_hash_get_oid(hash);

  /* Encode digest info for comparison */
  memset(&ldi, 0, sizeof(ldi));
  if (!silc_asn1_encode(asn1, &ldi,
			SILC_ASN1_OPTS(SILC_ASN1_ACCUMUL),
			SILC_ASN1_SEQUENCE,
			  SILC_ASN1_SEQUENCE,
			    SILC_ASN1_OID(oid),
			    SILC_ASN1_NULL,
			  SILC_ASN1_END,
			  SILC_ASN1_OCTET_STRING(data, data_len),
			SILC_ASN1_END, SILC_ASN1_END))
    goto err;

  SILC_LOG_HEXDUMP(("DigestInfo remote"), silc_buffer_data(&di),
		   silc_buffer_len(&di));
  SILC_LOG_HEXDUMP(("DigestInfo local"), silc_buffer_data(&ldi),
		   silc_buffer_len(&ldi));

  /* Compare */
  if (silc_buffer_len(&di) == silc_buffer_len(&ldi) &&
      !memcmp(silc_buffer_data(&di), silc_buffer_data(&ldi),
	      silc_buffer_len(&ldi)))
    ret = TRUE;

  memset(verify, 0, verify_len);
  memset(unpadded, 0, sizeof(unpadded));
  silc_free(verify);
  silc_mp_uninit(&mp_tmp2);
  silc_mp_uninit(&mp_dst);
  if (hash)
    memset(hashr, 0, sizeof(hashr));
  if (ihash)
    silc_hash_free(ihash);
  silc_asn1_free(asn1);

  return ret;

 err:
  memset(verify, 0, verify_len);
  silc_free(verify);
  silc_mp_uninit(&mp_tmp2);
  silc_mp_uninit(&mp_dst);
  if (ihash)
    silc_hash_free(ihash);
  silc_asn1_free(asn1);
  return FALSE;
}