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