GNUnet  0.10.x
revocation_api.c
Go to the documentation of this file.
1 /*
2  This file is part of GNUnet
3  Copyright (C) 2013, 2016 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  */
25 #include "platform.h"
27 #include "gnunet_signatures.h"
28 #include "gnunet_protocols.h"
29 #include "revocation.h"
30 #include <gcrypt.h>
31 
32 
41 
46 
50  void *func_cls;
51 };
52 
53 
63 static void
65  enum GNUNET_MQ_Error error)
66 {
67  struct GNUNET_REVOCATION_Query *q = cls;
68 
70  "Revocation query MQ error\n");
71  q->func(q->func_cls,
74 }
75 
76 
83 static void
85  const struct QueryResponseMessage *qrm)
86 {
87  struct GNUNET_REVOCATION_Query *q = cls;
88 
90  "Revocation query result: %d\n",
91  (uint32_t)ntohl(qrm->is_valid));
92  q->func(q->func_cls,
93  ntohl(qrm->is_valid));
95 }
96 
97 
109  const struct GNUNET_CRYPTO_EcdsaPublicKey *key,
111  void *func_cls)
112 {
113  struct GNUNET_REVOCATION_Query *q
115  struct GNUNET_MQ_MessageHandler handlers[] = {
116  GNUNET_MQ_hd_fixed_size(revocation_query_response,
118  struct QueryResponseMessage,
119  q),
121  };
122  struct QueryMessage *qm;
123  struct GNUNET_MQ_Envelope *env;
124 
125  q->mq = GNUNET_CLIENT_connect(cfg,
126  "revocation",
127  handlers,
129  q);
130  if (NULL == q->mq)
131  {
132  GNUNET_free(q);
133  return NULL;
134  }
135  q->func = func;
136  q->func_cls = func_cls;
137  env = GNUNET_MQ_msg(qm,
139  qm->reserved = htonl(0);
140  qm->key = *key;
141  GNUNET_MQ_send(q->mq,
142  env);
143  return q;
144 }
145 
146 
152 void
154 {
155  if (NULL != q->mq)
156  {
157  GNUNET_MQ_destroy(q->mq);
158  q->mq = NULL;
159  }
160  GNUNET_free(q);
161 }
162 
163 
172 
177 
181  void *func_cls;
182 };
183 
184 
194 static void
196  enum GNUNET_MQ_Error error)
197 {
198  struct GNUNET_REVOCATION_Handle *h = cls;
199 
201  "Revocation MQ error\n");
202  h->func(h->func_cls,
203  GNUNET_SYSERR);
205 }
206 
207 
214 static void
216  const struct RevocationResponseMessage *rrm)
217 {
218  struct GNUNET_REVOCATION_Handle *h = cls;
219 
221  "Revocation transmission result: %d\n",
222  (uint32_t)ntohl(rrm->is_valid));
223  h->func(h->func_cls,
224  ntohl(rrm->is_valid));
226 }
227 
228 
246  const struct GNUNET_CRYPTO_EcdsaPublicKey *key,
247  const struct GNUNET_CRYPTO_EcdsaSignature *sig,
248  uint64_t pow,
250  void *func_cls)
251 {
254  struct GNUNET_MQ_MessageHandler handlers[] = {
255  GNUNET_MQ_hd_fixed_size(revocation_response,
258  h),
260  };
261  unsigned long long matching_bits;
262  struct RevokeMessage *rm;
263  struct GNUNET_MQ_Envelope *env;
264 
265  if ((GNUNET_OK ==
267  "REVOCATION",
268  "WORKBITS",
269  &matching_bits)) &&
270  (GNUNET_YES !=
272  pow,
273  (unsigned int)matching_bits)))
274  {
275  GNUNET_break(0);
276  GNUNET_free(h);
277  return NULL;
278  }
279 
280  h->mq = GNUNET_CLIENT_connect(cfg,
281  "revocation",
282  handlers,
284  h);
285  if (NULL == h->mq)
286  {
287  GNUNET_free(h);
288  return NULL;
289  }
290  h->func = func;
291  h->func_cls = func_cls;
292  env = GNUNET_MQ_msg(rm,
294  rm->reserved = htonl(0);
295  rm->proof_of_work = pow;
297  rm->purpose.size = htonl(sizeof(struct GNUNET_CRYPTO_EccSignaturePurpose) +
298  sizeof(struct GNUNET_CRYPTO_EcdsaPublicKey));
299  rm->public_key = *key;
300  rm->signature = *sig;
301  GNUNET_MQ_send(h->mq,
302  env);
303  return h;
304 }
305 
306 
312 void
314 {
315  if (NULL != h->mq)
316  {
317  GNUNET_MQ_destroy(h->mq);
318  h->mq = NULL;
319  }
320  GNUNET_free(h);
321 }
322 
323 
331 static void
332 pow_hash(const void *buf,
333  size_t buf_len,
334  struct GNUNET_HashCode *result)
335 {
336  GNUNET_break(0 ==
337  gcry_kdf_derive(buf, buf_len,
338  GCRY_KDF_SCRYPT,
339  1 /* subalgo */,
340  "gnunet-revocation-proof-of-work",
341  strlen("gnunet-revocation-proof-of-work"),
342  2 /* iterations; keep cost of individual op small */,
343  sizeof(struct GNUNET_HashCode), result));
344 }
345 
346 
353 static unsigned int
355 {
356  unsigned int hash_count;
357 
358  hash_count = 0;
359  while ((0 == GNUNET_CRYPTO_hash_get_bit(hash, hash_count)))
360  hash_count++;
361  return hash_count;
362 }
363 
364 
374 int
376  uint64_t pow,
377  unsigned int matching_bits)
378 {
379  char buf[sizeof(struct GNUNET_CRYPTO_EcdsaPublicKey) +
380  sizeof(pow)] GNUNET_ALIGN;
381  struct GNUNET_HashCode result;
382 
383  GNUNET_memcpy(buf, &pow, sizeof(pow));
384  GNUNET_memcpy(&buf[sizeof(pow)], key,
385  sizeof(struct GNUNET_CRYPTO_EcdsaPublicKey));
386  pow_hash(buf, sizeof(buf), &result);
387  return (count_leading_zeroes(&result) >=
388  matching_bits) ? GNUNET_YES : GNUNET_NO;
389 }
390 
391 
398 void
400  struct GNUNET_CRYPTO_EcdsaSignature *sig)
401 {
402  struct RevokeMessage rm;
403 
405  rm.purpose.size = htonl(sizeof(struct GNUNET_CRYPTO_EccSignaturePurpose) +
406  sizeof(struct GNUNET_CRYPTO_EcdsaPublicKey));
410  &rm.purpose,
411  sig));
412 }
413 
414 
415 /* end of revocation_api.c */
#define GNUNET_MESSAGE_TYPE_REVOCATION_QUERY
Client to service: was this key revoked?
void GNUNET_REVOCATION_query_cancel(struct GNUNET_REVOCATION_Query *q)
Cancel key revocation check.
struct GNUNET_CRYPTO_EcdsaSignature signature
Signature confirming revocation.
Definition: revocation.h:96
int GNUNET_CONFIGURATION_get_value_number(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option, unsigned long long *number)
Get a configuration value that should be a number.
struct GNUNET_MQ_Handle * mq
Message queue to the service.
struct GNUNET_REVOCATION_Handle * GNUNET_REVOCATION_revoke(const struct GNUNET_CONFIGURATION_Handle *cfg, const struct GNUNET_CRYPTO_EcdsaPublicKey *key, const struct GNUNET_CRYPTO_EcdsaSignature *sig, uint64_t pow, GNUNET_REVOCATION_Callback func, void *func_cls)
Perform key revocation.
struct GNUNET_MQ_Handle * GNUNET_CLIENT_connect(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *service_name, const struct GNUNET_MQ_MessageHandler *handlers, GNUNET_MQ_ErrorHandler error_handler, void *error_handler_cls)
Create a message queue to connect to a GNUnet service.
Definition: client.c:900
uint32_t purpose
What does this signature vouch for? This must contain a GNUNET_SIGNATURE_PURPOSE_XXX constant (from g...
static void revocation_mq_error_handler(void *cls, enum GNUNET_MQ_Error error)
Generic error handler, called with the appropriate error code and the same closure specified at the c...
GNUNET_MQ_Error
Error codes for the queue.
struct GNUNET_MQ_Handle * mq
Message queue to the service.
void GNUNET_REVOCATION_sign_revocation(const struct GNUNET_CRYPTO_EcdsaPrivateKey *key, struct GNUNET_CRYPTO_EcdsaSignature *sig)
Create a revocation signature.
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
struct GNUNET_CRYPTO_EccSignaturePurpose purpose
Must have purpose GNUNET_SIGNATURE_PURPOSE_REVOCATION, size expands over the public key...
Definition: revocation.h:102
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
#define GNUNET_MQ_hd_fixed_size(name, code, str, ctx)
#define GNUNET_MQ_msg(mvar, type)
Allocate a GNUNET_MQ_Envelope.
Definition: gnunet_mq_lib.h:67
#define GNUNET_NO
Definition: gnunet_common.h:78
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:75
#define GNUNET_new(type)
Allocate a struct or union of the given type.
Private ECC key encoded for transmission.
Query key revocation status.
Definition: revocation.h:36
#define GNUNET_MESSAGE_TYPE_REVOCATION_REVOKE
Client to service OR peer-to-peer: revoke this key!
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
static struct GNUNET_ARM_Handle * h
Connection with ARM.
Definition: gnunet-arm.c:94
static unsigned int count_leading_zeroes(const struct GNUNET_HashCode *hash)
Count the leading zeroes in hash.
header of what an ECC signature signs this must be followed by "size - 8" bytes of the actual signed ...
int GNUNET_CRYPTO_ecdsa_sign(const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv, const struct GNUNET_CRYPTO_EccSignaturePurpose *purpose, struct GNUNET_CRYPTO_EcdsaSignature *sig)
ECDSA Sign a given block.
Definition: crypto_ecc.c:931
void * func_cls
Closure for func.
#define GNUNET_MESSAGE_TYPE_REVOCATION_QUERY_RESPONSE
Service to client: answer if key was revoked!
Revoke key.
Definition: revocation.h:77
Key revocation response.
Definition: revocation.h:57
static void handle_revocation_response(void *cls, const struct RevocationResponseMessage *rrm)
Handle response to our revocation query.
#define GNUNET_MESSAGE_TYPE_REVOCATION_REVOKE_RESPONSE
Service to client: revocation confirmed.
messages for key revocation
an ECC signature using ECDSA
static char buf[2048]
static int result
Global testing status.
uint64_t proof_of_work
Number that causes a hash collision with the public_key.
Definition: revocation.h:91
void * func_cls
Closure for func.
uint32_t size
How many bytes does this signature sign? (including this purpose header); in network byte order (!)...
A 512-bit hashcode.
static void handle_revocation_query_response(void *cls, const struct QueryResponseMessage *qrm)
Handle response to our revocation query.
Message handler for a specific message type.
static struct GNUNET_REVOCATION_Query * q
Handle for revocation query.
static struct GNUNET_CONFIGURATION_Handle * cfg
Our configuration.
Definition: gnunet-arm.c:104
uint32_t is_valid
GNUNET_NO if revoked, GNUNET_YES if valid.
Definition: revocation.h:66
#define GNUNET_SIGNATURE_PURPOSE_REVOCATION
Signature for confirming a key revocation.
struct GNUNET_HashCode key
The key used in the DHT.
void(* GNUNET_REVOCATION_Callback)(void *cls, int is_valid)
Callback to call with the result of a key revocation query.
#define GNUNET_SYSERR
Definition: gnunet_common.h:76
void GNUNET_CRYPTO_ecdsa_key_get_public(const struct GNUNET_CRYPTO_EcdsaPrivateKey *priv, struct GNUNET_CRYPTO_EcdsaPublicKey *pub)
Extract the public key for the given private key.
Definition: crypto_ecc.c:241
uint32_t reserved
For alignment.
Definition: revocation.h:45
int GNUNET_CRYPTO_hash_get_bit(const struct GNUNET_HashCode *code, unsigned int bit)
Obtain a bit from a hashcode.
Definition: crypto_hash.c:236
struct GNUNET_MQ_Envelope * env
Definition: 005.c:1
Handle for the key revocation query.
Key revocation response.
Definition: revocation.h:114
Handle to a message queue.
Definition: mq.c:84
struct GNUNET_CRYPTO_EcdsaPublicKey key
Key to check.
Definition: revocation.h:50
configuration data
Definition: configuration.c:83
Public ECC key (always for Curve25519) encoded in a format suitable for network transmission and ECDS...
static void query_mq_error_handler(void *cls, enum GNUNET_MQ_Error error)
Generic error handler, called with the appropriate error code and the same closure specified at the c...
#define GNUNET_log(kind,...)
struct GNUNET_REVOCATION_Query * GNUNET_REVOCATION_query(const struct GNUNET_CONFIGURATION_Handle *cfg, const struct GNUNET_CRYPTO_EcdsaPublicKey *key, GNUNET_REVOCATION_Callback func, void *func_cls)
Check if a key was revoked.
Handle for the key revocation operation.
static void pow_hash(const void *buf, size_t buf_len, struct GNUNET_HashCode *result)
Calculate the &#39;proof-of-work&#39; hash (an expensive hash).
GNUNET_REVOCATION_Callback func
Function to call with the result.
struct GNUNET_CRYPTO_EcdsaPublicKey public_key
Key to revoke.
Definition: revocation.h:107
void GNUNET_MQ_destroy(struct GNUNET_MQ_Handle *mq)
Destroy the message queue.
Definition: mq.c:821
GNUNET_REVOCATION_Callback func
Function to call once we are done.
#define GNUNET_YES
Definition: gnunet_common.h:77
void GNUNET_MQ_send(struct GNUNET_MQ_Handle *mq, struct GNUNET_MQ_Envelope *ev)
Send a message with the given message queue.
Definition: mq.c:351
uint32_t is_valid
GNUNET_NO if revocation failed for internal reasons (e.g.
Definition: revocation.h:124
void GNUNET_REVOCATION_revoke_cancel(struct GNUNET_REVOCATION_Handle *h)
Cancel key revocation.
static unsigned long long matching_bits
Number of matching bits required for revocation.
#define GNUNET_MQ_handler_end()
End-marker for the handlers array.
#define GNUNET_free(ptr)
Wrapper around free.
int GNUNET_REVOCATION_check_pow(const struct GNUNET_CRYPTO_EcdsaPublicKey *key, uint64_t pow, unsigned int matching_bits)
Check if the given proof-of-work value would be acceptable for revoking the given key...
uint32_t reserved
For alignment.
Definition: revocation.h:86