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; }
/** * 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); }