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

  FPRINTF (stderr, "%s",  "W");
  hostkey = GNUNET_CRYPTO_rsa_key_create ();
  GNUNET_CRYPTO_rsa_key_get_public (hostkey, &pkey);
  start = GNUNET_TIME_absolute_get ();
  purp.size = htonl (sizeof (struct GNUNET_CRYPTO_RsaSignaturePurpose));
  purp.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_TEST);

  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;
    }
    if (GNUNET_SYSERR ==
        GNUNET_CRYPTO_rsa_verify (GNUNET_SIGNATURE_PURPOSE_TEST, &purp, &sig,
                                  &pkey))
    {
      printf ("GNUNET_CRYPTO_rsa_verify failed!\n");
      ok = GNUNET_SYSERR;
      continue;
    }
    if (GNUNET_SYSERR !=
        GNUNET_CRYPTO_rsa_verify (GNUNET_SIGNATURE_PURPOSE_TRANSPORT_PONG_OWN,
                                  &purp, &sig, &pkey))
    {
      printf ("GNUNET_CRYPTO_rsa_verify failed to fail!\n");
      ok = GNUNET_SYSERR;
      continue;
    }
  }
  printf ("%d RSA sign/verify operations %llums\n", ITER,
          (unsigned long long)
          GNUNET_TIME_absolute_get_duration (start).rel_value);
  GNUNET_CRYPTO_rsa_key_free (hostkey);
  return ok;
}
/**
 * Check if a signature is valid.  This API is used by the GNS Block
 * to validate signatures received from the network.
 *
 * @param public_key public key of the zone
 * @param expire block expiration
 * @param name name that is being mapped (at most 255 characters long)
 * @param rd_count number of entries in 'rd' array
 * @param rd array of records with data to store
 * @param signature signature for all the records in the zone under the given name
 * @return GNUNET_OK if the signature is valid
 */
int
GNUNET_NAMESTORE_verify_signature (const struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded *public_key,
                                   const struct GNUNET_TIME_Absolute expire,
				   const char *name,
				   unsigned int rd_count,
				   const struct GNUNET_NAMESTORE_RecordData *rd,
				   const struct GNUNET_CRYPTO_RsaSignature *signature)
{
  int res = GNUNET_SYSERR;
  size_t rd_ser_len = 0;
  size_t name_len = 0;
  char * name_tmp;
  char * rd_tmp;
  struct GNUNET_CRYPTO_RsaSignaturePurpose *sig_purpose;
  struct GNUNET_TIME_AbsoluteNBO *expire_tmp;
  struct GNUNET_TIME_AbsoluteNBO expire_nbo = GNUNET_TIME_absolute_hton(expire);

  GNUNET_assert (public_key != NULL);
  GNUNET_assert (name != NULL);
  GNUNET_assert (rd != NULL);
  GNUNET_assert (signature != NULL);


  rd_ser_len = GNUNET_NAMESTORE_records_get_size(rd_count, rd);
  char rd_ser[rd_ser_len];
  GNUNET_NAMESTORE_records_serialize(rd_count, rd, rd_ser_len, rd_ser);

  name_len = strlen (name) + 1;
  if (name_len > 256)
  {
    GNUNET_break (0);
    return GNUNET_SYSERR;
  }

  sig_purpose = GNUNET_malloc(sizeof (struct GNUNET_CRYPTO_RsaSignaturePurpose) + sizeof (struct GNUNET_TIME_AbsoluteNBO) + rd_ser_len + name_len);
  sig_purpose->size = htonl (sizeof (struct GNUNET_CRYPTO_RsaSignaturePurpose)+ rd_ser_len + name_len);
  sig_purpose->purpose = htonl (GNUNET_SIGNATURE_PURPOSE_GNS_RECORD_SIGN);
  expire_tmp = (struct GNUNET_TIME_AbsoluteNBO *) &sig_purpose[1];
  name_tmp = (char *) &expire_tmp[1];
  rd_tmp = &name_tmp[name_len];
  memcpy (expire_tmp, &expire_nbo, sizeof (struct GNUNET_TIME_AbsoluteNBO));
  memcpy (name_tmp, name, name_len);
  memcpy (rd_tmp, rd_ser, rd_ser_len);

  res = GNUNET_CRYPTO_rsa_verify(GNUNET_SIGNATURE_PURPOSE_GNS_RECORD_SIGN, sig_purpose, signature, public_key);

  GNUNET_free (sig_purpose);

  return res;
}
Exemple #3
0
/**
 * Evaluate RSA performance.
 *
 * @param len keylength to evaluate with
 */
static void
eval (unsigned int len)
{
  struct GNUNET_TIME_Absolute start;
  struct GNUNET_CRYPTO_RsaSignature *sig;
  struct GNUNET_CRYPTO_RsaSignature *rsig;
  struct GNUNET_CRYPTO_RsaPublicKey *public_key;
  struct GNUNET_CRYPTO_RsaPrivateKey *private_key;
  struct GNUNET_CRYPTO_RsaBlindingKeySecret bsec[10];
  unsigned int i;
  char sbuf[128];
  char *bbuf;
  size_t bbuf_len;
  struct GNUNET_HashCode hc;

  start = GNUNET_TIME_absolute_get ();
  for (i=0;i<10;i++)
  {
    private_key = GNUNET_CRYPTO_rsa_private_key_create (len);
    GNUNET_CRYPTO_rsa_private_key_free (private_key);
  }
  printf ("10x %u-key generation took %s\n",
          len,
          GNUNET_STRINGS_relative_time_to_string (GNUNET_TIME_absolute_get_duration (start),
                                                  GNUNET_YES));
  GNUNET_snprintf (sbuf,
                   sizeof (sbuf),
                   "RSA %u-key generation",
                   len);
  GAUGER ("UTIL", sbuf,
          64 * 1024 / (1 +
                       GNUNET_TIME_absolute_get_duration
                       (start).rel_value_us / 1000LL), "keys/ms");
  private_key = GNUNET_CRYPTO_rsa_private_key_create (len);
  public_key = GNUNET_CRYPTO_rsa_private_key_get_public (private_key);
  for (i=0;i<10;i++)
    GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_WEAK,
			        &bsec[i], sizeof (bsec[0]));
  /*
  start = GNUNET_TIME_absolute_get ();
  for (i=0;i<10;i++)
    rsa_blinding_key_derive(public_key, &bsec[i]);
  printf ("10x %u-blinding key generation took %s\n",
          len,
          GNUNET_STRINGS_relative_time_to_string (GNUNET_TIME_absolute_get_duration (start),
                                                  GNUNET_YES));
  GNUNET_snprintf (sbuf,
                   sizeof (sbuf),
                   "RSA %u-blinding key generation",
                   len);
  GAUGER ("UTIL", sbuf,
          64 * 1024 / (1 +
                       GNUNET_TIME_absolute_get_duration
                       (start).rel_value_us / 1000LL), "keys/ms");
  */
  start = GNUNET_TIME_absolute_get ();
  GNUNET_CRYPTO_hash ("test", 4, &hc);
  for (i=0;i<10;i++)
  {
    GNUNET_CRYPTO_rsa_blind (&hc,
                             &bsec[i],
                             public_key,
                             &bbuf, &bbuf_len);
    GNUNET_free (bbuf);
  }
  printf ("10x %u-blinding took %s\n",
          len,
          GNUNET_STRINGS_relative_time_to_string (GNUNET_TIME_absolute_get_duration (start),
						  GNUNET_YES));
  GNUNET_snprintf (sbuf,
                   sizeof (sbuf),
                   "RSA %u-blinding",
                   len);
  GAUGER ("UTIL",
          sbuf,
          64 * 1024 / (1 +
		       GNUNET_TIME_absolute_get_duration
		       (start).rel_value_us / 1000LL), "ops/ms");
  GNUNET_CRYPTO_rsa_blind (&hc,
                           &bsec[0],
                           public_key,
                           &bbuf, &bbuf_len);
  start = GNUNET_TIME_absolute_get ();
  for (i=0;i<10;i++)
  {
    sig = GNUNET_CRYPTO_rsa_sign_blinded (private_key,
                                          bbuf, bbuf_len);
    GNUNET_CRYPTO_rsa_signature_free (sig);
  }
  printf ("10x %u-signing took %s\n",
          len,
          GNUNET_STRINGS_relative_time_to_string (GNUNET_TIME_absolute_get_duration (start),
						  GNUNET_YES));
  GNUNET_snprintf (sbuf,
                   sizeof (sbuf),
                   "RSA %u-signing",
                   len);
  GAUGER ("UTIL",
          sbuf,
          64 * 1024 / (1 +
		       GNUNET_TIME_absolute_get_duration
		       (start).rel_value_us / 1000LL), "ops/ms");
  sig = GNUNET_CRYPTO_rsa_sign_blinded (private_key,
                                        bbuf,
                                        bbuf_len);
  start = GNUNET_TIME_absolute_get ();
  for (i=0;i<10;i++)
  {
    rsig = GNUNET_CRYPTO_rsa_unblind (sig,
                                      &bsec[0],
                                      public_key);
    GNUNET_CRYPTO_rsa_signature_free (rsig);
  }
  printf ("10x %u-unblinding took %s\n",
          len,
          GNUNET_STRINGS_relative_time_to_string (GNUNET_TIME_absolute_get_duration (start),
						  GNUNET_YES));
  GNUNET_snprintf (sbuf,
                   sizeof (sbuf),
                   "RSA %u-unblinding",
                   len);
  GAUGER ("UTIL",
          sbuf,
          64 * 1024 / (1 +
		       GNUNET_TIME_absolute_get_duration
		       (start).rel_value_us / 1000LL), "ops/ms");
  rsig = GNUNET_CRYPTO_rsa_unblind (sig,
                                    &bsec[0],
                                    public_key);
  start = GNUNET_TIME_absolute_get ();
  for (i=0;i<10;i++)
  {
    GNUNET_assert (GNUNET_OK ==
                   GNUNET_CRYPTO_rsa_verify (&hc,
                                             rsig,
                                             public_key));
  }
  printf ("10x %u-verifying took %s\n",
          len,
          GNUNET_STRINGS_relative_time_to_string (GNUNET_TIME_absolute_get_duration (start),
						  GNUNET_YES));
  GNUNET_snprintf (sbuf,
                   sizeof (sbuf),
                   "RSA %u-verification",
                   len);
  GAUGER ("UTIL",
          sbuf,
          64 * 1024 / (1 +
		       GNUNET_TIME_absolute_get_duration
		       (start).rel_value_us / 1000LL), "ops/ms");
  GNUNET_CRYPTO_rsa_signature_free (sig);
  GNUNET_CRYPTO_rsa_public_key_free (public_key);
  GNUNET_CRYPTO_rsa_private_key_free (private_key);
  GNUNET_free (bbuf);
}
/**
 * We've received a PONG.  Check if it matches a pending PING and
 * mark the respective address as confirmed.
 *
 * @param sender peer sending the PONG
 * @param hdr the PONG
 */
void
GST_validation_handle_pong (const struct GNUNET_PeerIdentity *sender,
                            const struct GNUNET_MessageHeader *hdr)
{
  const struct TransportPongMessage *pong;
  struct ValidationEntry *ve;
  const char *tname;
  const char *addr;
  size_t addrlen;
  size_t slen;
  size_t size;
  struct GNUNET_HELLO_Message *hello;
  struct GNUNET_HELLO_Address address;

  if (ntohs (hdr->size) < sizeof (struct TransportPongMessage))
  {
    GNUNET_break_op (0);
    return;
  }
  GNUNET_STATISTICS_update (GST_stats,
                            gettext_noop ("# PONG messages received"), 1,
                            GNUNET_NO);

  pong = (const struct TransportPongMessage *) hdr;
  tname = (const char *) &pong[1];
  size = ntohs (hdr->size) - sizeof (struct TransportPongMessage);
  addr = memchr (tname, '\0', size);
  if (NULL == addr)
  {
    GNUNET_break_op (0);
    return;
  }
  addr++;
  slen = strlen (tname) + 1;
  addrlen = size - slen;
  address.peer = *sender;
  address.address = addr;
  address.address_length = addrlen;
  address.transport_name = tname;
  ve = find_validation_entry (NULL, &address);
  if ((NULL == ve) || (ve->expecting_pong == GNUNET_NO))
  {
    GNUNET_STATISTICS_update (GST_stats,
                              gettext_noop
                              ("# PONGs dropped, no matching pending validation"),
                              1, GNUNET_NO);
    return;
  }
  /* now check that PONG is well-formed */
  if (0 != memcmp (&ve->pid, sender, sizeof (struct GNUNET_PeerIdentity)))
  {
    GNUNET_break_op (0);
    return;
  }

  if (GNUNET_OK !=
      GNUNET_CRYPTO_rsa_verify (GNUNET_SIGNATURE_PURPOSE_TRANSPORT_PONG_OWN,
                                &pong->purpose, &pong->signature,
                                &ve->public_key))
  {
    GNUNET_break_op (0);
    return;
  }

  if (GNUNET_TIME_absolute_get_remaining
      (GNUNET_TIME_absolute_ntoh (pong->expiration)).rel_value == 0)
  {
    GNUNET_STATISTICS_update (GST_stats,
                              gettext_noop
                              ("# PONGs dropped, signature expired"), 1,
                              GNUNET_NO);
    return;
  }
  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
              "Address validated for peer `%s' with plugin `%s': `%s'\n",

              GNUNET_i2s (sender), tname, GST_plugins_a2s (ve->address));
  /* validity achieved, remember it! */
  ve->expecting_pong = GNUNET_NO;
  ve->valid_until = GNUNET_TIME_relative_to_absolute (HELLO_ADDRESS_EXPIRATION);
  ve->latency = GNUNET_TIME_absolute_get_duration (ve->send_time);
  {
    struct GNUNET_ATS_Information ats;

    ats.type = htonl (GNUNET_ATS_QUALITY_NET_DELAY);
    ats.value = htonl ((uint32_t) ve->latency.rel_value);
    GNUNET_ATS_address_update (GST_ats, ve->address, NULL, &ats, 1);
  }
  /* build HELLO to store in PEERINFO */
  ve->copied = GNUNET_NO;
  hello = GNUNET_HELLO_create (&ve->public_key, &add_valid_peer_address, ve);
  GNUNET_PEERINFO_add_peer (GST_peerinfo, hello, NULL, NULL);
  GNUNET_free (hello);
}