Example #1
0
/* Start the MyBot, by creating the SILC Client entity by using the
   SILC Client Library API. */
int mybot_start(void)
{
  MyBot mybot;
  SilcClientParams params;

  /* Allocate the MyBot structure */
  mybot = silc_calloc(1, sizeof(*mybot));
  if (!mybot) {
    perror("Out of memory");
    return 1;
  }

  memset(&params, 0, sizeof(params));
  params.threads = TRUE;
  mybot->client = silc_client_alloc(&ops, &params, mybot, NULL);
  if (!mybot->client) {
    perror("Could not allocate SILC Client");
    return 1;
  }

  /* Now we initialize the client. */
  if (!silc_client_init(mybot->client, silc_get_username(),
			silc_net_localhost(), "I am the MyBot",
			silc_running, mybot)) {
    perror("Could not init client");
    return 1;
  }

  if (!silc_load_key_pair("mybot.pub", "mybot.prv", "",
			  &mybot->public_key,
			  &mybot->private_key)) {
    /* The keys don't exist.  Let's generate us a key pair then!  There's
       nice ready routine for that too.  Let's do 2048 bit RSA key pair. */
    fprintf(stdout, "MyBot: Key pair does not exist, generating it.\n");
    if (!silc_create_key_pair("rsa", 2048, "mybot.pub", "mybot.prv", NULL, "",
			      &mybot->public_key,
			      &mybot->private_key, FALSE)) {
      perror("Could not generated key pair");
      return 1;
    }
  }

  /* And, then we are ready to go.  Since we are really simple client we
     don't have user interface and we don't have to deal with message loops
     or interactivity.  That's why we can just hand over the execution
     to the library by calling silc_client_run.  */
  silc_client_run(mybot->client);

  /* When we get here, we have quit the client, so clean up and exit */
  silc_client_free(mybot->client);
  silc_free(mybot);
  return 0;
}
static PyObject *pysilc_create_key_pair(PyObject *mod, PyObject *args, PyObject *kwds)
{
	PyObject *passphrase_obj = Py_None;
    char *pkcs_name = NULL;
    char *pub_filename , *prv_filename;
    char *passphrase = NULL;
    char *pub_identifier = NULL;

    SilcUInt32      key_length = 2048;
    SilcPublicKey   public_key;
    SilcPrivateKey  private_key;

    static char *kwlist[] = {"public_filename", "private_filename", "identifier", "passphrase", "pkcs_name", "key_length", NULL};

    if (!PyArg_ParseTupleAndKeywords(args, kwds, "ss|sOsi", kwlist,
            &pub_filename, &prv_filename, &pub_identifier,
			&passphrase_obj, &pkcs_name, &key_length))
        return NULL;

	if (passphrase_obj == Py_None) {
		passphrase = NULL;
	}
	else if (PyString_Check(passphrase_obj)) {
		passphrase = PyString_AsString(passphrase_obj);
	}
	else {
		PyErr_SetString(PyExc_TypeError, "passphrase should either be None or String Type");
		return NULL;
	}

    bool result = silc_create_key_pair(pkcs_name, key_length, pub_filename,
                                       prv_filename, pub_identifier, passphrase,
                                       &public_key, &private_key, 0);
    if (!result) {
        PyErr_SetString(PyExc_RuntimeError, "Unable to generate keys.");
        return NULL;
    }

    return PySilcKeys_New(public_key, private_key);
}
Example #3
0
gboolean silcpurple_check_silc_dir(PurpleConnection *gc)
{
	char filename[256], file_public_key[256], file_private_key[256];
	char servfilename[256], clientfilename[256], friendsfilename[256];
	char pkd[256], prd[256];
	struct stat st;
	struct passwd *pw;
	int fd;

	pw = getpwuid(getuid());
	if (!pw) {
		purple_debug_error("silc", "silc: %s\n", g_strerror(errno));
		return FALSE;
	}

	g_snprintf(filename, sizeof(filename) - 1, "%s", silcpurple_silcdir());
	g_snprintf(servfilename, sizeof(servfilename) - 1, "%s" G_DIR_SEPARATOR_S "serverkeys",
		   silcpurple_silcdir());
	g_snprintf(clientfilename, sizeof(clientfilename) - 1, "%s" G_DIR_SEPARATOR_S "clientkeys",
		   silcpurple_silcdir());
	g_snprintf(friendsfilename, sizeof(friendsfilename) - 1, "%s" G_DIR_SEPARATOR_S "friends",
		   silcpurple_silcdir());

	if (pw->pw_uid != geteuid()) {
		purple_debug_error("silc", "Couldn't create directories due to wrong uid!\n");
		return FALSE;
	}

	/*
	 * Check ~/.silc directory
	 */
	if (g_mkdir(filename, 0755) != 0 && errno != EEXIST) {
		purple_debug_error("silc", "Couldn't create '%s' directory\n", filename);
		return FALSE;
	}

#ifndef _WIN32
	if ((g_stat(filename, &st)) == -1) {
		purple_debug_error("silc", "Couldn't stat '%s' directory, error: %s\n", filename, g_strerror(errno));
		return FALSE;
	} else {
		/* Check the owner of the dir */
		if (st.st_uid != 0 && st.st_uid != pw->pw_uid) {
			purple_debug_error("silc", "You don't seem to own '%s' directory\n",
				filename);
			return FALSE;
		}
	}
#endif

	/*
	 * Check ~./silc/serverkeys directory
	 */
	if (g_mkdir(servfilename, 0755) != 0 && errno != EEXIST) {
		purple_debug_error("silc", "Couldn't create '%s' directory\n", servfilename);
		return FALSE;
	}

	/*
	 * Check ~./silc/clientkeys directory
	 */
	if (g_mkdir(clientfilename, 0755) != 0 && errno != EEXIST) {
		purple_debug_error("silc", "Couldn't create '%s' directory\n", clientfilename);
		return FALSE;
	}

	/*
	 * Check ~./silc/friends directory
	 */
	if (g_mkdir(friendsfilename, 0755) != 0 && errno != EEXIST) {
		purple_debug_error("silc", "Couldn't create '%s' directory\n", friendsfilename);
		return FALSE;
	}

	/*
	 * Check Public and Private keys
	 */
	g_snprintf(pkd, sizeof(pkd), "%s" G_DIR_SEPARATOR_S "public_key.pub", silcpurple_silcdir());
	g_snprintf(prd, sizeof(prd), "%s" G_DIR_SEPARATOR_S "private_key.prv", silcpurple_silcdir());
	g_snprintf(file_public_key, sizeof(file_public_key) - 1, "%s",
		   purple_account_get_string(gc->account, "public-key", pkd));
	g_snprintf(file_private_key, sizeof(file_public_key) - 1, "%s",
		   purple_account_get_string(gc->account, "private-key", prd));

	if ((g_stat(file_public_key, &st)) == -1) {
		/* If file doesn't exist */
		if (errno == ENOENT) {
			purple_connection_update_progress(gc, _("Creating SILC key pair..."), 1, 5);
			if (!silc_create_key_pair(SILCPURPLE_DEF_PKCS,
						  SILCPURPLE_DEF_PKCS_LEN,
						  file_public_key,
						  file_private_key, NULL,
						  (gc->password == NULL)
						  ? "" : gc->password,
						  NULL, NULL, FALSE)) {
				purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_OTHER_ERROR,
				                             _("Unable to create SILC key pair"));
				return FALSE;
			}

			if ((g_stat(file_public_key, &st)) == -1) {
				purple_debug_error("silc", "Couldn't stat '%s' public key, error: %s\n",
						   file_public_key, g_strerror(errno));
				return FALSE;
			}
		} else {
			purple_debug_error("silc", "Couldn't stat '%s' public key, error: %s\n",
					   file_public_key, g_strerror(errno));
			return FALSE;
		}
	}

#ifndef _WIN32
	/* Check the owner of the public key */
	if (st.st_uid != 0 && st.st_uid != pw->pw_uid) {
		purple_debug_error("silc", "You don't seem to own your public key!?\n");
		return FALSE;
	}
#endif

	if ((fd = g_open(file_private_key, O_RDONLY, 0)) != -1) {
		if ((fstat(fd, &st)) == -1) {
			purple_debug_error("silc", "Couldn't stat '%s' private key, error: %s\n",
					   file_private_key, g_strerror(errno));
			close(fd);
			return FALSE;
		}
	} else {
		/* If file doesn't exist */
		if (errno == ENOENT) {
			purple_connection_update_progress(gc, _("Creating SILC key pair..."), 1, 5);
			if (!silc_create_key_pair(SILCPURPLE_DEF_PKCS,
						  SILCPURPLE_DEF_PKCS_LEN,
						  file_public_key,
						  file_private_key, NULL,
						  (gc->password == NULL)
						  ? "" : gc->password,
						  NULL, NULL, FALSE)) {
				purple_connection_error_reason(gc, PURPLE_CONNECTION_ERROR_OTHER_ERROR,
				                             _("Unable to create SILC key pair"));
				return FALSE;
			}

			if ((fd = g_open(file_private_key, O_RDONLY, 0)) != -1) {
				if ((fstat(fd, &st)) == -1) {
					purple_debug_error("silc", "Couldn't stat '%s' private key, error: %s\n",
							   file_private_key, g_strerror(errno));
					close(fd);
					return FALSE;
				}
			} else {
				purple_debug_error("silc", "Couldn't open '%s' "
					"private key, error: %s\n",
					file_private_key, g_strerror(errno));
				return FALSE;
			}
		} else {
			purple_debug_error("silc", "Couldn't open '%s' private key, error: %s\n",
					   file_private_key, g_strerror(errno));
			return FALSE;
		}
	}

#ifndef _WIN32
	/* Check the owner of the private key */
	if (st.st_uid != 0 && st.st_uid != pw->pw_uid) {
		purple_debug_error("silc", "You don't seem to own your private key!?\n");
		if (fd != -1)
			close(fd);
		return FALSE;
	}

	/* Check the permissions for the private key */
	if ((st.st_mode & 0777) != 0600) {
		purple_debug_warning("silc", "Wrong permissions in your private key file `%s'!\n"
			"Trying to change them ...\n", file_private_key);
		if ((fd == -1) || (fchmod(fd, S_IRUSR | S_IWUSR)) == -1) {
			purple_debug_error("silc",
				"Failed to change permissions for private key file!\n"
				"Permissions for your private key file must be 0600.\n");
			if (fd != -1)
				close(fd);
			return FALSE;
		}
		purple_debug_warning("silc", "Done.\n\n");
	}
#endif

	if (fd != -1)
		close(fd);

	return TRUE;
}
Example #4
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;
}