aboutsummaryrefslogtreecommitdiff
path: root/src/lib/hello/hello-ng.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/hello/hello-ng.c')
-rw-r--r--src/lib/hello/hello-ng.c198
1 files changed, 198 insertions, 0 deletions
diff --git a/src/lib/hello/hello-ng.c b/src/lib/hello/hello-ng.c
new file mode 100644
index 000000000..9c255b361
--- /dev/null
+++ b/src/lib/hello/hello-ng.c
@@ -0,0 +1,198 @@
1/*
2 This file is part of GNUnet.
3 Copyright (C) 2018 GNUnet e.V.
4
5 GNUnet is free software: you can redistribute it and/or modify it
6 under the terms of the GNU Affero General Public License as published
7 by the Free Software Foundation, either version 3 of the License,
8 or (at your option) any later version.
9
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Affero General Public License for more details.
14
15 You should have received a copy of the GNU Affero General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17
18 SPDX-License-Identifier: AGPL3.0-or-later
19 */
20
21/**
22 * @file hello/hello-ng.c
23 * @brief helper library for handling HELLOs
24 * @author Christian Grothoff
25 */
26#include "platform.h"
27#include "gnunet_signatures.h"
28#include "gnunet_hello_lib.h"
29#include "gnunet_protocols.h"
30#include "gnunet_util_lib.h"
31
32GNUNET_NETWORK_STRUCT_BEGIN
33/**
34 * Binary block we sign when we sign an address.
35 */
36struct SignedAddress
37{
38 /**
39 * Purpose must be #GNUNET_SIGNATURE_PURPOSE_TRANSPORT_ADDRESS
40 */
41 struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
42
43 /**
44 * When was the address generated.
45 */
46 struct GNUNET_TIME_AbsoluteNBO mono_time;
47
48 /**
49 * Hash of the address.
50 */
51 struct GNUNET_HashCode addr_hash GNUNET_PACKED;
52};
53GNUNET_NETWORK_STRUCT_END
54
55/**
56 * Build address record by signing raw information with private key.
57 *
58 * @param address text address at @a communicator to sign
59 * @param nt network type of @a address
60 * @param mono_time monotonic time at which @a address was valid
61 * @param private_key signing key to use
62 * @param[out] result where to write address record (allocated)
63 * @param[out] result_size set to size of @a result
64 */
65void
66GNUNET_HELLO_sign_address (
67 const char *address,
68 enum GNUNET_NetworkType nt,
69 struct GNUNET_TIME_Absolute mono_time,
70 const struct GNUNET_CRYPTO_EddsaPrivateKey *private_key,
71 void **result,
72 size_t *result_size)
73{
74 struct SignedAddress sa;
75 struct GNUNET_CRYPTO_EddsaSignature sig;
76 char *sig_str;
77
78 sa.purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_TRANSPORT_ADDRESS);
79 sa.purpose.size = htonl (sizeof(sa));
80 sa.mono_time = GNUNET_TIME_absolute_hton (mono_time);
81 GNUNET_CRYPTO_hash (address, strlen (address), &sa.addr_hash);
82 GNUNET_CRYPTO_eddsa_sign (private_key, &sa, &sig);
83 sig_str = NULL;
84 (void) GNUNET_STRINGS_base64_encode (&sig, sizeof(sig), &sig_str);
85 *result_size =
86 1 + GNUNET_asprintf ((char **) result,
87 "%s;%llu;%u;%s",
88 sig_str,
89 (unsigned long long) mono_time.abs_value_us,
90 (unsigned int) nt,
91 address);
92 GNUNET_free (sig_str);
93}
94
95
96/**
97 * Check signature and extract address record.
98 *
99 * @param raw raw signed address
100 * @param raw_size size of @a raw
101 * @param pid public key to use for signature verification
102 * @param nt[out] set to network type
103 * @param mono_time[out] when was the address generated
104 * @return NULL on error, otherwise the address
105 */
106char *
107GNUNET_HELLO_extract_address (const void *raw,
108 size_t raw_size,
109 const struct GNUNET_PeerIdentity *pid,
110 enum GNUNET_NetworkType *nt,
111 struct GNUNET_TIME_Absolute *mono_time)
112{
113 const struct GNUNET_CRYPTO_EddsaPublicKey *public_key = &pid->public_key;
114 const char *raws = raw;
115 unsigned long long raw_us = 0;
116 unsigned int raw_nt = 0;
117 const char *sc;
118 const char *sc2;
119 const char *sc3;
120 const char *raw_addr;
121 char *data = NULL;
122 struct GNUNET_TIME_Absolute raw_mono_time;
123 struct SignedAddress sa;
124 struct GNUNET_CRYPTO_EddsaSignature *sig;
125
126 if ('\0' != raws[raw_size-1])
127 {
128 GNUNET_break_op (0);
129 return NULL;
130 }
131 if (NULL == (sc = strchr (raws, ';')))
132 {
133 GNUNET_break_op (0);
134 return NULL;
135 }
136 if (NULL == (sc2 = strchr (sc + 1, ';')))
137 {
138 GNUNET_break_op (0);
139 return NULL;
140 }
141 if (NULL == (sc3 = strchr (sc2 + 1, ';')))
142 {
143 GNUNET_break_op (0);
144 return NULL;
145 }
146 if (2 != sscanf (sc + 1, "%llu;%u;%*s", &raw_us, &raw_nt))
147 {
148 GNUNET_break_op (0);
149 return NULL;
150 }
151 raw_addr = sc3 + 1;
152 raw_mono_time.abs_value_us = raw_us;
153 if (sizeof(struct GNUNET_CRYPTO_EddsaSignature) !=
154 GNUNET_STRINGS_base64_decode (raws, sc - raws, (void **) &data))
155 {
156 GNUNET_break_op (0);
157 GNUNET_free (data);
158 return NULL;
159 }
160 sig = (struct GNUNET_CRYPTO_EddsaSignature*) data;
161 sa.purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_TRANSPORT_ADDRESS);
162 sa.purpose.size = htonl (sizeof(sa));
163 sa.mono_time = GNUNET_TIME_absolute_hton (raw_mono_time);
164 GNUNET_CRYPTO_hash (raw_addr, strlen (raw_addr), &sa.addr_hash);
165 if (GNUNET_YES !=
166 GNUNET_CRYPTO_eddsa_verify (GNUNET_SIGNATURE_PURPOSE_TRANSPORT_ADDRESS,
167 &sa,
168 sig,
169 public_key))
170 {
171 GNUNET_free (data);
172 GNUNET_break_op (0);
173 return NULL;
174 }
175 GNUNET_free (data);
176 *mono_time = raw_mono_time;
177 *nt = raw_nt;
178 return GNUNET_strdup (raw_addr);
179}
180
181
182/**
183 * Given an address as a string, extract the prefix that identifies
184 * the communicator offering transmissions to that address.
185 *
186 * @param address a peer's address
187 * @return NULL if the address is mal-formed, otherwise the prefix
188 */
189char *
190GNUNET_HELLO_address_to_prefix (const char *address)
191{
192 const char *dash;
193
194 dash = strchr (address, '-');
195 if (NULL == dash)
196 return NULL;
197 return GNUNET_strndup (address, dash - address);
198}