123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198 |
- /*
- This file is part of GNUnet.
- Copyright (C) 2018 GNUnet e.V.
- GNUnet is free software: you can redistribute it and/or modify it
- under the terms of the GNU Affero General Public License as published
- by the Free Software Foundation, either version 3 of the License,
- or (at your option) any later version.
- GNUnet is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Affero General Public License for more details.
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
- SPDX-License-Identifier: AGPL3.0-or-later
- */
- /**
- * @file hello/hello-ng.c
- * @brief helper library for handling HELLOs
- * @author Christian Grothoff
- */
- #include "platform.h"
- #include "gnunet_signatures.h"
- #include "gnunet_hello_lib.h"
- #include "gnunet_protocols.h"
- #include "gnunet_util_lib.h"
- #include "gnunet_ats_service.h"
- /**
- * Binary block we sign when we sign an address.
- */
- struct SignedAddress
- {
- /**
- * Purpose must be #GNUNET_SIGNATURE_PURPOSE_TRANSPORT_ADDRESS
- */
- struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
- /**
- * When was the address generated.
- */
- struct GNUNET_TIME_AbsoluteNBO mono_time;
- /**
- * Hash of the address.
- */
- struct GNUNET_HashCode h_addr;
- };
- /**
- * Build address record by signing raw information with private key.
- *
- * @param address text address at @a communicator to sign
- * @param nt network type of @a address
- * @param mono_time monotonic time at which @a address was valid
- * @param private_key signing key to use
- * @param result[out] where to write address record (allocated)
- * @param result_size[out] set to size of @a result
- */
- void
- GNUNET_HELLO_sign_address (
- const char *address,
- enum GNUNET_NetworkType nt,
- struct GNUNET_TIME_Absolute mono_time,
- const struct GNUNET_CRYPTO_EddsaPrivateKey *private_key,
- void **result,
- size_t *result_size)
- {
- struct SignedAddress sa;
- struct GNUNET_CRYPTO_EddsaSignature sig;
- char *sig_str;
- sa.purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_TRANSPORT_ADDRESS);
- sa.purpose.size = htonl (sizeof(sa));
- sa.mono_time = GNUNET_TIME_absolute_hton (mono_time);
- GNUNET_CRYPTO_hash (address, strlen (address), &sa.h_addr);
- GNUNET_CRYPTO_eddsa_sign (private_key, &sa, &sig);
- sig_str = NULL;
- (void) GNUNET_STRINGS_base64_encode (&sig, sizeof(sig), &sig_str);
- *result_size =
- 1 + GNUNET_asprintf ((char **) result,
- "%s;%llu;%u;%s",
- sig_str,
- (unsigned long long) mono_time.abs_value_us,
- (unsigned int) nt,
- address);
- GNUNET_free (sig_str);
- }
- /**
- * Check signature and extract address record.
- *
- * @param raw raw signed address
- * @param raw_size size of @a raw
- * @param pid public key to use for signature verification
- * @param nt[out] set to network type
- * @param mono_time[out] when was the address generated
- * @return NULL on error, otherwise the address
- */
- char *
- GNUNET_HELLO_extract_address (const void *raw,
- size_t raw_size,
- const struct GNUNET_PeerIdentity *pid,
- enum GNUNET_NetworkType *nt,
- struct GNUNET_TIME_Absolute *mono_time)
- {
- const struct GNUNET_CRYPTO_EddsaPublicKey *public_key = &pid->public_key;
- const char *raws = raw;
- unsigned long long raw_us;
- unsigned int raw_nt;
- const char *sc;
- const char *sc2;
- const char *sc3;
- const char *raw_addr;
- struct GNUNET_TIME_Absolute raw_mono_time;
- struct SignedAddress sa;
- struct GNUNET_CRYPTO_EddsaSignature *sig;
- if ('\0' != raws[raw_size])
- {
- GNUNET_break_op (0);
- return NULL;
- }
- if (NULL == (sc = strchr (raws, ';')))
- {
- GNUNET_break_op (0);
- return NULL;
- }
- if (NULL == (sc2 = strchr (sc + 1, ';')))
- {
- GNUNET_break_op (0);
- return NULL;
- }
- if (NULL == (sc3 = strchr (sc2 + 1, ';')))
- {
- GNUNET_break_op (0);
- return NULL;
- }
- if (1 != sscanf (sc + 1, "%llu;%u;", &raw_us, &raw_nt))
- {
- GNUNET_break_op (0);
- return NULL;
- }
- raw_mono_time.abs_value_us = raw_us;
- sig = NULL;
- if (sizeof(struct GNUNET_CRYPTO_EddsaSignature) !=
- GNUNET_STRINGS_base64_decode (raws, sc - raws, (void **) &sig))
- {
- GNUNET_break_op (0);
- GNUNET_free (sig);
- return NULL;
- }
- raw_addr = sc3 + 1;
- sa.purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_TRANSPORT_ADDRESS);
- sa.purpose.size = htonl (sizeof(sa));
- sa.mono_time = GNUNET_TIME_absolute_hton (raw_mono_time);
- GNUNET_CRYPTO_hash (raw_addr, strlen (raw_addr), &sa.h_addr);
- if (GNUNET_YES !=
- GNUNET_CRYPTO_eddsa_verify (GNUNET_SIGNATURE_PURPOSE_TRANSPORT_ADDRESS,
- &sa,
- sig,
- public_key))
- {
- GNUNET_break_op (0);
- GNUNET_free (sig);
- return NULL;
- }
- GNUNET_free (sig);
- *mono_time = raw_mono_time;
- *nt = (enum GNUNET_NetworkType) raw_nt;
- return GNUNET_strdup (raw_addr);
- }
- /**
- * Given an address as a string, extract the prefix that identifies
- * the communicator offering transmissions to that address.
- *
- * @param address a peer's address
- * @return NULL if the address is mal-formed, otherwise the prefix
- */
- char *
- GNUNET_HELLO_address_to_prefix (const char *address)
- {
- const char *dash;
- dash = strchr (address, '-');
- if (NULL == dash)
- return NULL;
- return GNUNET_strndup (address, dash - address);
- }
|