static int
testSignPerformance ()
{
  struct GNUNET_CRYPTO_RsaPrivateKey *hostkey;
  struct GNUNET_CRYPTO_RsaSignaturePurpose purp;
  struct GNUNET_CRYPTO_RsaSignature sig;
  struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded pkey;
  int i;
  struct GNUNET_TIME_Absolute start;
  int ok = GNUNET_OK;

  purp.size = htonl (sizeof (struct GNUNET_CRYPTO_RsaSignaturePurpose));
  purp.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_TEST);
  FPRINTF (stderr, "%s",  "W");
  hostkey = GNUNET_CRYPTO_rsa_key_create ();
  GNUNET_CRYPTO_rsa_key_get_public (hostkey, &pkey);
  start = GNUNET_TIME_absolute_get ();
  for (i = 0; i < ITER; i++)
  {
    FPRINTF (stderr, "%s",  ".");
    if (GNUNET_SYSERR == GNUNET_CRYPTO_rsa_sign (hostkey, &purp, &sig))
    {
      FPRINTF (stderr, "%s",  "GNUNET_CRYPTO_rsa_sign returned SYSERR\n");
      ok = GNUNET_SYSERR;
      continue;
    }
  }
  printf ("%d RSA sign operations %llu ms\n", ITER,
          (unsigned long long)
          GNUNET_TIME_absolute_get_duration (start).rel_value);
  GNUNET_CRYPTO_rsa_key_free (hostkey);
  return ok;
}
Beispiel #2
0
/**
 * Transmit a send-message request to the chat service.
 *
 * @param cls closure, pointer to the 'struct GNUNET_CHAT_SendMessageContext'
 * @param size number of bytes available in buf
 * @param buf where the callee should write the message
 * @return number of bytes written to buf
 */
static size_t
transmit_send_request (void *cls, size_t size, void *buf)
{
  struct GNUNET_CHAT_SendMessageContext *smc = cls;
  struct TransmitRequestMessage *msg_to_send;
  size_t msg_size;

  if (NULL == buf)
  {
#if DEBUG_CHAT
    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Could not transmit a chat message\n");
#endif
    return 0;
  }
#if DEBUG_CHAT
  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
              "Transmitting a chat message to the service\n");
#endif
  msg_size = strlen (smc->message) + sizeof (struct TransmitRequestMessage);
  GNUNET_assert (size >= msg_size);
  msg_to_send = buf;
  msg_to_send->header.size = htons (msg_size);
  msg_to_send->header.type = htons (GNUNET_MESSAGE_TYPE_CHAT_TRANSMIT_REQUEST);
  msg_to_send->msg_options = htonl (smc->options);
  msg_to_send->sequence_number = htonl (smc->sequence_number);
  msg_to_send->timestamp =
      GNUNET_TIME_absolute_hton (GNUNET_TIME_absolute_get ());
  msg_to_send->reserved = htonl (0);
  if (NULL == smc->receiver)
    memset (&msg_to_send->target, 0, sizeof (GNUNET_HashCode));
  else
    GNUNET_CRYPTO_hash (smc->receiver,
                        sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded),
                        &msg_to_send->target);
  memcpy (&msg_to_send[1], smc->message, strlen (smc->message));
  /**
   * Client don't encode private messages since public keys of other members are
   * stored on the service side.
   */
  if (smc->options & GNUNET_CHAT_MSG_AUTHENTICATED)
  {
    msg_to_send->purpose.purpose =
        htonl (GNUNET_SIGNATURE_PURPOSE_CHAT_MESSAGE);
    msg_to_send->purpose.size =
        htonl (msg_size - sizeof (struct GNUNET_MessageHeader) -
               sizeof (struct GNUNET_CRYPTO_RsaSignature));
    GNUNET_assert (GNUNET_OK ==
                   GNUNET_CRYPTO_rsa_sign (smc->chat_room->my_private_key,
                                           &msg_to_send->purpose,
                                           &msg_to_send->signature));
  }
  GNUNET_free (smc->message);
  GNUNET_free (smc);
  return msg_size;
}
/**
 * Sign name and records
 *
 * @param key the private key
 * @param expire block expiration
 * @param name the name
 * @param rd record data
 * @param rd_count number of records
 *
 * @return the signature
 */
struct GNUNET_CRYPTO_RsaSignature *
GNUNET_NAMESTORE_create_signature (const struct GNUNET_CRYPTO_RsaPrivateKey *key,
				   struct GNUNET_TIME_Absolute expire,
				   const char *name,
				   const struct GNUNET_NAMESTORE_RecordData *rd,
				   unsigned int rd_count)
{
  struct GNUNET_CRYPTO_RsaSignature *sig;
  struct GNUNET_CRYPTO_RsaSignaturePurpose *sig_purpose;
  struct GNUNET_TIME_AbsoluteNBO expire_nbo;
  size_t rd_ser_len;
  size_t name_len;
  struct GNUNET_TIME_AbsoluteNBO *expire_tmp;
  char * name_tmp;
  char * rd_tmp;
  int res;
  uint32_t sig_len;

  if (NULL == name)
  {
    GNUNET_break (0);
    return NULL;
  }
  sig = GNUNET_malloc (sizeof (struct GNUNET_CRYPTO_RsaSignature));
  name_len = strlen (name) + 1;
  expire_nbo = GNUNET_TIME_absolute_hton (expire);
  rd_ser_len = GNUNET_NAMESTORE_records_get_size (rd_count, rd);
  {
    char rd_ser[rd_ser_len];

    GNUNET_assert (rd_ser_len ==
		   GNUNET_NAMESTORE_records_serialize (rd_count, rd, rd_ser_len, rd_ser));
    sig_len = sizeof (struct GNUNET_CRYPTO_RsaSignaturePurpose) + sizeof (struct GNUNET_TIME_AbsoluteNBO) + rd_ser_len + name_len;
    sig_purpose = GNUNET_malloc (sig_len);
    sig_purpose->size = htonl (sig_len);
    sig_purpose->purpose = htonl (GNUNET_SIGNATURE_PURPOSE_GNS_RECORD_SIGN);
    expire_tmp = (struct GNUNET_TIME_AbsoluteNBO *) &sig_purpose[1];
    memcpy (expire_tmp, &expire_nbo, sizeof (struct GNUNET_TIME_AbsoluteNBO));
    name_tmp = (char *) &expire_tmp[1];
    memcpy (name_tmp, name, name_len);
    rd_tmp = &name_tmp[name_len];
    memcpy (rd_tmp, rd_ser, rd_ser_len);
    res = GNUNET_CRYPTO_rsa_sign (key, sig_purpose, sig);
    GNUNET_free (sig_purpose);
  }
  if (GNUNET_OK != res)
  {
    GNUNET_break (0);
    GNUNET_free (sig);
    return NULL;
  }
  return sig;
}
Beispiel #4
0
/**
 * Transmit a confirmation receipt to the chat service.
 *
 * @param cls closure, pointer to the 'struct GNUNET_CHAT_SendReceiptContext'
 * @param size number of bytes available in buf
 * @param buf where the callee should write the message
 * @return number of bytes written to buf
 */
static size_t
transmit_acknowledge_request (void *cls, size_t size, void *buf)
{
  struct GNUNET_CHAT_SendReceiptContext *src = cls;
  struct ConfirmationReceiptMessage *receipt;
  struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded pub_key;
  uint16_t msg_len;
  size_t msg_size;

  if (NULL == buf)
  {
    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
                _("Could not transmit confirmation receipt\n"));
    return 0;
  }
#if DEBUG_CHAT
  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
              "Transmitting confirmation receipt to the service\n");
#endif
  msg_size = sizeof (struct ConfirmationReceiptMessage);
  GNUNET_assert (size >= msg_size);
  receipt = buf;
  receipt->header.size = htons (msg_size);
  receipt->header.type = htons (GNUNET_MESSAGE_TYPE_CHAT_CONFIRMATION_RECEIPT);
  receipt->reserved = htonl (0);
  receipt->sequence_number = src->received_msg->sequence_number;
  receipt->reserved2 = htonl (0);
  receipt->timestamp = GNUNET_TIME_absolute_hton (GNUNET_TIME_absolute_get ());
  GNUNET_CRYPTO_rsa_key_get_public (src->chat_room->my_private_key, &pub_key);
  GNUNET_CRYPTO_hash (&pub_key,
                      sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded),
                      &receipt->target);
  receipt->author = src->received_msg->sender;
  receipt->purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_CHAT_RECEIPT);
  receipt->purpose.size =
      htonl (msg_size - sizeof (struct GNUNET_MessageHeader) -
             sizeof (uint32_t) - sizeof (struct GNUNET_CRYPTO_RsaSignature));
  msg_len =
      ntohs (src->received_msg->header.size) -
      sizeof (struct ReceiveNotificationMessage);
  GNUNET_CRYPTO_hash (&src->received_msg[1], msg_len, &receipt->content);
  GNUNET_assert (GNUNET_OK ==
                 GNUNET_CRYPTO_rsa_sign (src->chat_room->my_private_key,
                                         &receipt->purpose,
                                         &receipt->signature));
  GNUNET_free (src->received_msg);
  GNUNET_free (src);
  return msg_size;
}
/**
 * Continuation of "GNUNET_FS_publish_ksk" that performs the actual
 * publishing operation (iterating over all of the keywords).
 *
 * @param cls closure of type "struct GNUNET_FS_PublishKskContext*"
 * @param tc unused
 */
static void
publish_ksk_cont (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
{
  struct GNUNET_FS_PublishKskContext *pkc = cls;
  const char *keyword;
  GNUNET_HashCode key;
  GNUNET_HashCode query;
  struct GNUNET_CRYPTO_AesSessionKey skey;
  struct GNUNET_CRYPTO_AesInitializationVector iv;
  struct GNUNET_CRYPTO_RsaPrivateKey *pk;

  pkc->ksk_task = GNUNET_SCHEDULER_NO_TASK;
  if ((pkc->i == pkc->ksk_uri->data.ksk.keywordCount) || (NULL == pkc->dsh))
  {
    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "KSK PUT operation complete\n");
    pkc->cont (pkc->cont_cls, pkc->ksk_uri, NULL);
    GNUNET_FS_publish_ksk_cancel (pkc);
    return;
  }
  keyword = pkc->ksk_uri->data.ksk.keywords[pkc->i++];
  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Publishing under keyword `%s'\n",
              &keyword[1]);
  /* first character of keyword indicates if it is
   * mandatory or not -- ignore for hashing */
  GNUNET_CRYPTO_hash (&keyword[1], strlen (&keyword[1]), &key);
  GNUNET_CRYPTO_hash_to_aes_key (&key, &skey, &iv);
  GNUNET_CRYPTO_aes_encrypt (&pkc->kb[1], pkc->slen + pkc->mdsize, &skey, &iv,
                             &pkc->cpy[1]);
  pk = GNUNET_CRYPTO_rsa_key_create_from_hash (&key);
  GNUNET_assert (NULL != pk);
  GNUNET_CRYPTO_rsa_key_get_public (pk, &pkc->cpy->keyspace);
  GNUNET_CRYPTO_hash (&pkc->cpy->keyspace,
                      sizeof (struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded),
                      &query);
  GNUNET_assert (GNUNET_OK ==
                 GNUNET_CRYPTO_rsa_sign (pk, &pkc->cpy->purpose,
                                         &pkc->cpy->signature));
  GNUNET_CRYPTO_rsa_key_free (pk);
  pkc->qre =
      GNUNET_DATASTORE_put (pkc->dsh, 0, &query,
                            pkc->mdsize + sizeof (struct KBlock) + pkc->slen,
                            pkc->cpy, GNUNET_BLOCK_TYPE_FS_KBLOCK,
                            pkc->bo.content_priority, pkc->bo.anonymity_level,
                            pkc->bo.replication_level, pkc->bo.expiration_time,
                            -2, 1, GNUNET_CONSTANTS_SERVICE_TIMEOUT,
                            &kb_put_cont, pkc);
}
Beispiel #6
0
/**
 * Run actual test queries.
 *
 * @return 0 on success
 */
static int
run_queries (PGconn *conn)
{
  struct GNUNET_CRYPTO_rsa_PublicKey *pub;
  struct GNUNET_CRYPTO_rsa_PublicKey *pub2 = NULL;
  struct GNUNET_CRYPTO_rsa_Signature *sig;
  struct GNUNET_CRYPTO_rsa_Signature *sig2 = NULL;
  struct GNUNET_TIME_Absolute abs_time = GNUNET_TIME_absolute_get ();
  struct GNUNET_TIME_Absolute abs_time2;
  struct GNUNET_TIME_Absolute forever = GNUNET_TIME_UNIT_FOREVER_ABS;
  struct GNUNET_TIME_Absolute forever2;
  struct GNUNET_HashCode hc;
  struct GNUNET_HashCode hc2;
  PGresult *result;
  int ret;
  struct GNUNET_CRYPTO_rsa_PrivateKey *priv;
  char msg[] = "Hello";
  void *msg2;
  size_t msg2_len;
  uint16_t u16;
  uint16_t u162;
  uint32_t u32;
  uint32_t u322;
  uint64_t u64;
  uint64_t u642;

  priv = GNUNET_CRYPTO_rsa_private_key_create (1024);
  pub = GNUNET_CRYPTO_rsa_private_key_get_public (priv);
  sig = GNUNET_CRYPTO_rsa_sign (priv,
				msg,
				sizeof (msg));
  u16 = 16;
  u32 = 32;
  u64 = 64;
  /* FIXME: test GNUNET_PQ_result_spec_variable_size */
  {
    struct GNUNET_PQ_QueryParam params_insert[] = {
      GNUNET_PQ_query_param_rsa_public_key (pub),
      GNUNET_PQ_query_param_rsa_signature (sig),
      GNUNET_PQ_query_param_absolute_time (&abs_time),
      GNUNET_PQ_query_param_absolute_time (&forever),
      GNUNET_PQ_query_param_auto_from_type (&hc),
      GNUNET_PQ_query_param_fixed_size (msg, strlen (msg)),
      GNUNET_PQ_query_param_uint16 (&u16),
      GNUNET_PQ_query_param_uint32 (&u32),
      GNUNET_PQ_query_param_uint64 (&u64),
      GNUNET_PQ_query_param_end
    };
    struct GNUNET_PQ_QueryParam params_select[] = {
      GNUNET_PQ_query_param_end
    };
    struct GNUNET_PQ_ResultSpec results_select[] = {
      GNUNET_PQ_result_spec_rsa_public_key ("pub", &pub2),
      GNUNET_PQ_result_spec_rsa_signature ("sig", &sig2),
      GNUNET_PQ_result_spec_absolute_time ("abs_time", &abs_time2),
      GNUNET_PQ_result_spec_absolute_time ("forever", &forever2),
      GNUNET_PQ_result_spec_auto_from_type ("hash", &hc2),
      GNUNET_PQ_result_spec_variable_size ("vsize", &msg2, &msg2_len),
      GNUNET_PQ_result_spec_uint16 ("u16", &u162),
      GNUNET_PQ_result_spec_uint32 ("u32", &u322),
      GNUNET_PQ_result_spec_uint64 ("u64", &u642),
      GNUNET_PQ_result_spec_end
    };

    result = GNUNET_PQ_exec_prepared (conn,
				     "test_insert",
				     params_insert);
    if (PGRES_COMMAND_OK != PQresultStatus (result))
    {
      GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
		  "Database failure: %s\n",
		  PQresultErrorMessage (result));
      PQclear (result);
      GNUNET_CRYPTO_rsa_signature_free (sig);
      GNUNET_CRYPTO_rsa_private_key_free (priv);
      GNUNET_CRYPTO_rsa_public_key_free (pub);
      return 1;
    }

    PQclear (result);
    result = GNUNET_PQ_exec_prepared (conn,
				      "test_select",
				      params_select);
    if (1 !=
	PQntuples (result))
    {
      GNUNET_break (0);
      PQclear (result);
      GNUNET_CRYPTO_rsa_signature_free (sig);
      GNUNET_CRYPTO_rsa_private_key_free (priv);
      GNUNET_CRYPTO_rsa_public_key_free (pub);
      return 1;
    }
    ret = GNUNET_PQ_extract_result (result,
				   results_select,
				   0);
    GNUNET_break (GNUNET_YES == ret);
    GNUNET_break (abs_time.abs_value_us == abs_time2.abs_value_us);
    GNUNET_break (forever.abs_value_us == forever2.abs_value_us);
    GNUNET_break (0 ==
		  memcmp (&hc,
			  &hc2,
			  sizeof (struct GNUNET_HashCode)));
    GNUNET_break (0 ==
		  GNUNET_CRYPTO_rsa_signature_cmp (sig,
						   sig2));
    GNUNET_break (0 ==
		  GNUNET_CRYPTO_rsa_public_key_cmp (pub,
						    pub2));
    GNUNET_break (strlen (msg) == msg2_len);
    GNUNET_break (0 ==
		  strncmp (msg,
			   msg2,
			   msg2_len));
    GNUNET_break (16 == u162);
    GNUNET_break (32 == u322);
    GNUNET_break (64 == u642);
    GNUNET_PQ_cleanup_result (results_select);
    PQclear (result);
  }
  GNUNET_CRYPTO_rsa_signature_free (sig);
  GNUNET_CRYPTO_rsa_private_key_free (priv);
  GNUNET_CRYPTO_rsa_public_key_free (pub);
  if (GNUNET_OK != ret)
    return 1;

  return 0;
}
/**
 * We've received a PING.  If appropriate, generate a PONG.
 *
 * @param sender peer sending the PING
 * @param hdr the PING
 * @param sender_address the sender address as we got it
 * @param session session we got the PING from
 */
void
GST_validation_handle_ping (const struct GNUNET_PeerIdentity *sender,
                            const struct GNUNET_MessageHeader *hdr,
                            const struct GNUNET_HELLO_Address *sender_address,
                            struct Session *session)
{
  const struct TransportPingMessage *ping;
  struct TransportPongMessage *pong;
  struct GNUNET_TRANSPORT_PluginFunctions *papi;
  struct GNUNET_CRYPTO_RsaSignature *sig_cache;
  struct GNUNET_TIME_Absolute *sig_cache_exp;
  const char *addr;
  const char *addrend;
  size_t alen;
  size_t slen;
  ssize_t ret;
  struct GNUNET_HELLO_Address address;

  if (ntohs (hdr->size) < sizeof (struct TransportPingMessage))
  {
    GNUNET_break_op (0);
    return;
  }
  ping = (const struct TransportPingMessage *) hdr;
  if (0 !=
      memcmp (&ping->target, &GST_my_identity,
              sizeof (struct GNUNET_PeerIdentity)))
  {
    GNUNET_STATISTICS_update (GST_stats,
                              gettext_noop
                              ("# PING message for different peer received"), 1,
                              GNUNET_NO);
    return;
  }
  GNUNET_STATISTICS_update (GST_stats,
                            gettext_noop ("# PING messages received"), 1,
                            GNUNET_NO);
  addr = (const char *) &ping[1];
  alen = ntohs (hdr->size) - sizeof (struct TransportPingMessage);
  /* peer wants to confirm that this is one of our addresses, this is what is
   * used for address validation */

  sig_cache = NULL;
  sig_cache_exp = NULL;

  if (0 < alen)
  {
    addrend = memchr (addr, '\0', alen);
    if (NULL == addrend)
    {
      GNUNET_break_op (0);
      return;
    }
    addrend++;
    slen = strlen (addr) + 1;
    alen -= slen;
    address.address = addrend;
    address.address_length = alen;
    address.transport_name = addr;
    address.peer = *sender;
    if (GNUNET_YES !=
        GST_hello_test_address (&address, &sig_cache, &sig_cache_exp))
    {
      GNUNET_log (GNUNET_ERROR_TYPE_INFO,
                  _
                  ("Not confirming PING with address `%s' since I cannot confirm having this address.\n"),
                  GST_plugins_a2s (&address));
      return;
    }
  }
  else
  {
    addrend = NULL;             /* make gcc happy */
    slen = 0;
    static struct GNUNET_CRYPTO_RsaSignature no_address_signature;
    static struct GNUNET_TIME_Absolute no_address_signature_expiration;

    sig_cache = &no_address_signature;
    sig_cache_exp = &no_address_signature_expiration;
  }

  pong = GNUNET_malloc (sizeof (struct TransportPongMessage) + alen + slen);
  pong->header.size =
      htons (sizeof (struct TransportPongMessage) + alen + slen);
  pong->header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_PONG);
  pong->purpose.size =
      htonl (sizeof (struct GNUNET_CRYPTO_RsaSignaturePurpose) +
             sizeof (uint32_t) + sizeof (struct GNUNET_TIME_AbsoluteNBO) +
             alen + slen);
  pong->purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_TRANSPORT_PONG_OWN);
  pong->challenge = ping->challenge;
  pong->addrlen = htonl (alen + slen);
  memcpy (&pong[1], addr, slen);
  memcpy (&((char *) &pong[1])[slen], addrend, alen);
  if (GNUNET_TIME_absolute_get_remaining (*sig_cache_exp).rel_value <
      PONG_SIGNATURE_LIFETIME.rel_value / 4)
  {
    /* create / update cached sig */
    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
                "Creating PONG signature to indicate ownership.\n");
    *sig_cache_exp = GNUNET_TIME_relative_to_absolute (PONG_SIGNATURE_LIFETIME);
    pong->expiration = GNUNET_TIME_absolute_hton (*sig_cache_exp);
    GNUNET_assert (GNUNET_OK ==
                   GNUNET_CRYPTO_rsa_sign (GST_my_private_key, &pong->purpose,
                                           sig_cache));
  }
  else
  {
    pong->expiration = GNUNET_TIME_absolute_hton (*sig_cache_exp);
  }
  pong->signature = *sig_cache;

  GNUNET_assert (sender_address != NULL);

  /* first see if the session we got this PING from can be used to transmit
   * a response reliably */
  papi = GST_plugins_find (sender_address->transport_name);
  if (papi == NULL)
    ret = -1;
  else
  {
    GNUNET_assert (papi->send != NULL);
    GNUNET_assert (papi->get_session != NULL);

    if (session == NULL)
    {
      session = papi->get_session (papi->cls, sender_address);
    }
    if (session == NULL)
    {
      GNUNET_break (0);
      ret = -1;
    }
    else
    {
      ret = papi->send (papi->cls, session,
                        (const char *) pong, ntohs (pong->header.size),
                        PONG_PRIORITY, ACCEPTABLE_PING_DELAY,
                        NULL, NULL);
    }
  }
  if (ret != -1)
  {
    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
                "Transmitted PONG to `%s' via reliable mechanism\n",
                GNUNET_i2s (sender));
    /* done! */
    GNUNET_STATISTICS_update (GST_stats,
                              gettext_noop
                              ("# PONGs unicast via reliable transport"), 1,
                              GNUNET_NO);
    GNUNET_free (pong);
    return;
  }

  /* no reliable method found, try transmission via all known addresses */
  GNUNET_STATISTICS_update (GST_stats,
                            gettext_noop
                            ("# PONGs multicast to all available addresses"), 1,
                            GNUNET_NO);
  GST_validation_get_addresses (sender, &multicast_pong, pong);
  GNUNET_free (pong);
}