diff options
Diffstat (limited to 'src/service/reclaim/did_core.c')
-rw-r--r-- | src/service/reclaim/did_core.c | 270 |
1 files changed, 270 insertions, 0 deletions
diff --git a/src/service/reclaim/did_core.c b/src/service/reclaim/did_core.c new file mode 100644 index 000000000..5804a0d7e --- /dev/null +++ b/src/service/reclaim/did_core.c | |||
@@ -0,0 +1,270 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet | ||
3 | Copyright (C) 2010-2015 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 reclaim/did_core.c | ||
23 | * @brief Core functionality for DID | ||
24 | * @author Tristan Schwieren | ||
25 | */ | ||
26 | |||
27 | // TODO: DID documents do not have an expiration date. Still we add one | ||
28 | // TODO: Store DID document with empty label and own type (maybe DID-Document or JSON??) | ||
29 | |||
30 | #include "did_core.h" | ||
31 | |||
32 | struct DID_resolve_return | ||
33 | { | ||
34 | DID_resolve_callback *cb; | ||
35 | void *cls; | ||
36 | }; | ||
37 | |||
38 | struct DID_action_return | ||
39 | { | ||
40 | DID_action_callback *cb; | ||
41 | void *cls; | ||
42 | }; | ||
43 | |||
44 | // ------------------------------------------------ // | ||
45 | // -------------------- Resolve ------------------- // | ||
46 | // ------------------------------------------------ // | ||
47 | |||
48 | /** | ||
49 | * @brief GNS lookup callback. Calls the given callback function | ||
50 | * and gives it the DID Document. | ||
51 | * Fails if there is more than one DID record. | ||
52 | * | ||
53 | * @param cls closure | ||
54 | * @param rd_count number of records in rd | ||
55 | * @param rd the records in the reply | ||
56 | */ | ||
57 | static void | ||
58 | DID_resolve_gns_lookup_cb ( | ||
59 | void *cls, | ||
60 | uint32_t rd_count, | ||
61 | const struct GNUNET_GNSRECORD_Data *rd) | ||
62 | { | ||
63 | char *did_document; | ||
64 | DID_resolve_callback *cb = ((struct DID_resolve_return *) cls)->cb; | ||
65 | void *cls_did_resolve_cb = ((struct DID_resolve_return *) cls)->cls; | ||
66 | free (cls); | ||
67 | |||
68 | for (int i = 0; i < rd_count; i++) | ||
69 | { | ||
70 | if (rd[i].record_type != GNUNET_GNSRECORD_TYPE_DID_DOCUMENT) | ||
71 | continue; | ||
72 | did_document = (char *) rd[i].data; | ||
73 | cb (GNUNET_OK, did_document, cls_did_resolve_cb); | ||
74 | return; | ||
75 | } | ||
76 | cb (GNUNET_NO, "DID Document is not a DID_DOCUMENT record\n", | ||
77 | cls_did_resolve_cb); | ||
78 | } | ||
79 | |||
80 | |||
81 | /** | ||
82 | * @brief Resolve a DID. | ||
83 | * Calls the given callback function with the resolved DID Document and the given closure. | ||
84 | * If the did can not be resolved did_document is NULL. | ||
85 | * | ||
86 | * @param did DID that is resolve | ||
87 | */ | ||
88 | enum GNUNET_GenericReturnValue | ||
89 | DID_resolve (const char *did, | ||
90 | struct GNUNET_GNS_Handle *gns_handle, | ||
91 | DID_resolve_callback *cont, | ||
92 | void *cls) | ||
93 | { | ||
94 | struct GNUNET_CRYPTO_PublicKey pkey; | ||
95 | |||
96 | // did, gns_handle and cont must me set | ||
97 | if ((did == NULL) || (gns_handle == NULL) || (cont == NULL)) | ||
98 | return GNUNET_NO; | ||
99 | |||
100 | if (GNUNET_OK != DID_did_to_pkey (did, &pkey)) | ||
101 | return GNUNET_NO; | ||
102 | |||
103 | // Create closure for lookup callback | ||
104 | struct DID_resolve_return *cls_gns_lookup_cb | ||
105 | = malloc (sizeof(struct DID_resolve_return)); | ||
106 | cls_gns_lookup_cb->cb = cont; | ||
107 | cls_gns_lookup_cb->cls = cls; | ||
108 | |||
109 | GNUNET_GNS_lookup (gns_handle, | ||
110 | DID_DOCUMENT_LABEL, | ||
111 | &pkey, | ||
112 | GNUNET_GNSRECORD_TYPE_DID_DOCUMENT, | ||
113 | GNUNET_GNS_LO_DEFAULT, | ||
114 | &DID_resolve_gns_lookup_cb, | ||
115 | cls_gns_lookup_cb); | ||
116 | |||
117 | return GNUNET_OK; | ||
118 | } | ||
119 | |||
120 | |||
121 | // ------------------------------------------------ // | ||
122 | // -------------------- Create -------------------- // | ||
123 | // ------------------------------------------------ // | ||
124 | |||
125 | static void | ||
126 | DID_create_did_store_cb (void *cls, | ||
127 | enum GNUNET_ErrorCode ec) | ||
128 | { | ||
129 | DID_action_callback *cb = ((struct DID_action_return *) cls)->cb; | ||
130 | void *cls_did_create_cb = ((struct DID_action_return *) cls)->cls; | ||
131 | free (cls); | ||
132 | |||
133 | if (GNUNET_EC_NONE == ec) | ||
134 | { | ||
135 | cb (GNUNET_OK, (void *) cls_did_create_cb); | ||
136 | } | ||
137 | else | ||
138 | { | ||
139 | // TODO: Log emsg. Not writing it to STDOUT | ||
140 | printf ("%s\n", GNUNET_ErrorCode_get_hint (ec)); | ||
141 | cb (GNUNET_NO, (void *) cls_did_create_cb); | ||
142 | } | ||
143 | } | ||
144 | |||
145 | |||
146 | struct DID_create_namestore_lookup_closure | ||
147 | { | ||
148 | const char *did_document; | ||
149 | struct GNUNET_TIME_Relative expire_time; | ||
150 | struct GNUNET_NAMESTORE_Handle *namestore_handle; | ||
151 | struct DID_action_return *ret; | ||
152 | }; | ||
153 | |||
154 | static void | ||
155 | DID_create_namestore_lookup_cb (void *cls, | ||
156 | const struct | ||
157 | GNUNET_CRYPTO_PrivateKey *zone, | ||
158 | const char *label, | ||
159 | unsigned int rd_count, | ||
160 | const struct GNUNET_GNSRECORD_Data *rd) | ||
161 | { | ||
162 | struct GNUNET_GNSRECORD_Data record_data; | ||
163 | struct GNUNET_CRYPTO_PublicKey pkey; | ||
164 | |||
165 | const char *did_document | ||
166 | = ((struct DID_create_namestore_lookup_closure *) cls)->did_document; | ||
167 | |||
168 | const struct GNUNET_TIME_Relative expire_time | ||
169 | = ((struct DID_create_namestore_lookup_closure *) cls)->expire_time; | ||
170 | |||
171 | struct GNUNET_NAMESTORE_Handle *namestore_handle | ||
172 | = ((struct DID_create_namestore_lookup_closure *) cls)->namestore_handle; | ||
173 | |||
174 | struct DID_action_return *cls_record_store_cb | ||
175 | = ((struct DID_create_namestore_lookup_closure *) cls)->ret; | ||
176 | |||
177 | free (cls); | ||
178 | |||
179 | if (rd_count > 0) | ||
180 | { | ||
181 | printf ("Ego already has a DID Document. Abort.\n"); | ||
182 | cls_record_store_cb->cb (GNUNET_NO, cls_record_store_cb->cls); | ||
183 | } | ||
184 | else | ||
185 | { | ||
186 | // Get public key | ||
187 | GNUNET_CRYPTO_key_get_public (zone, &pkey); | ||
188 | |||
189 | // If no DID Document is given a default one is created | ||
190 | if (did_document != NULL) | ||
191 | printf ( | ||
192 | "DID Docuement is read from \"DID-document\" argument (EXPERIMENTAL)\n"); | ||
193 | else | ||
194 | did_document = DID_pkey_to_did_document (&pkey); | ||
195 | |||
196 | // Create record | ||
197 | record_data.data = did_document; | ||
198 | record_data.expiration_time = expire_time.rel_value_us; | ||
199 | record_data.data_size = strlen (did_document) + 1; | ||
200 | record_data.record_type = GNUNET_GNSRECORD_typename_to_number ("TXT"), | ||
201 | record_data.flags = GNUNET_GNSRECORD_RF_RELATIVE_EXPIRATION; | ||
202 | |||
203 | // Store record | ||
204 | GNUNET_NAMESTORE_record_set_store (namestore_handle, | ||
205 | zone, | ||
206 | DID_DOCUMENT_LABEL, | ||
207 | 1, // FIXME what if GNUNET_GNS_EMPTY_LABEL_AT has records | ||
208 | &record_data, | ||
209 | &DID_create_did_store_cb, | ||
210 | (void *) cls_record_store_cb); | ||
211 | } | ||
212 | } | ||
213 | |||
214 | |||
215 | /** | ||
216 | * @brief Creates a DID and saves DID Document in Namestore. | ||
217 | * | ||
218 | * @param ego ego for which the DID should be created. | ||
219 | * @param did_document did_document that should be saved in namestore. | ||
220 | * If did_document==NULL -> Default DID document is created. | ||
221 | * @param namestore_handle | ||
222 | * @param cont callback function | ||
223 | * @param cls closure | ||
224 | */ | ||
225 | enum GNUNET_GenericReturnValue | ||
226 | DID_create (const struct GNUNET_IDENTITY_Ego *ego, | ||
227 | const char *did_document, | ||
228 | const struct GNUNET_TIME_Relative *expire_time, | ||
229 | struct GNUNET_NAMESTORE_Handle *namestore_handle, | ||
230 | DID_action_callback *cont, | ||
231 | void *cls) | ||
232 | { | ||
233 | struct GNUNET_CRYPTO_PublicKey pkey; | ||
234 | |||
235 | // Ego, namestore_handle and cont must be set | ||
236 | if ((ego == NULL) || (namestore_handle == NULL) || (cont == NULL)) | ||
237 | return GNUNET_NO; | ||
238 | |||
239 | // Check if ego has EdDSA key | ||
240 | GNUNET_IDENTITY_ego_get_public_key ((struct GNUNET_IDENTITY_Ego *) ego, | ||
241 | &pkey); | ||
242 | if (ntohl (pkey.type) != GNUNET_GNSRECORD_TYPE_EDKEY) | ||
243 | { | ||
244 | printf ("The EGO has to have an EdDSA key pair\n"); | ||
245 | return GNUNET_NO; | ||
246 | } | ||
247 | |||
248 | struct DID_action_return *ret | ||
249 | = malloc (sizeof(struct DID_action_return)); | ||
250 | ret->cb = cont; | ||
251 | ret->cls = cls; | ||
252 | |||
253 | struct DID_create_namestore_lookup_closure *cls_name_store_lookup_cb | ||
254 | = malloc (sizeof(struct DID_create_namestore_lookup_closure)); | ||
255 | cls_name_store_lookup_cb->did_document = did_document; | ||
256 | cls_name_store_lookup_cb->expire_time = (*expire_time); | ||
257 | cls_name_store_lookup_cb->namestore_handle = namestore_handle; | ||
258 | cls_name_store_lookup_cb->ret = ret; | ||
259 | |||
260 | // Check if ego already has a DID Document | ||
261 | GNUNET_NAMESTORE_records_lookup (namestore_handle, | ||
262 | GNUNET_IDENTITY_ego_get_private_key (ego), | ||
263 | DID_DOCUMENT_LABEL, | ||
264 | NULL, | ||
265 | NULL, | ||
266 | DID_create_namestore_lookup_cb, | ||
267 | (void *) cls_name_store_lookup_cb); | ||
268 | |||
269 | return GNUNET_OK; | ||
270 | } | ||