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 
37 {
38 
43 
48 
52  void *func_cls;
53 
54 };
55 
56 
66 static void
68  enum GNUNET_MQ_Error error)
69 {
70  struct GNUNET_REVOCATION_Query *q = cls;
71 
73  "Revocation query MQ error\n");
74  q->func (q->func_cls,
77 }
78 
79 
86 static void
88  const struct QueryResponseMessage *qrm)
89 {
90  struct GNUNET_REVOCATION_Query *q = cls;
91 
93  "Revocation query result: %d\n",
94  (uint32_t) ntohl (qrm->is_valid));
95  q->func (q->func_cls,
96  ntohl (qrm->is_valid));
98 }
99 
100 
112  const struct GNUNET_CRYPTO_EcdsaPublicKey *key,
114  void *func_cls)
115 {
116  struct GNUNET_REVOCATION_Query *q
118  struct GNUNET_MQ_MessageHandler handlers[] = {
119  GNUNET_MQ_hd_fixed_size (revocation_query_response,
121  struct QueryResponseMessage,
122  q),
124  };
125  struct QueryMessage *qm;
126  struct GNUNET_MQ_Envelope *env;
127 
128  q->mq = GNUNET_CLIENT_connect (cfg,
129  "revocation",
130  handlers,
132  q);
133  if (NULL == q->mq)
134  {
135  GNUNET_free (q);
136  return NULL;
137  }
138  q->func = func;
139  q->func_cls = func_cls;
140  env = GNUNET_MQ_msg (qm,
142  qm->reserved = htonl (0);
143  qm->key = *key;
144  GNUNET_MQ_send (q->mq,
145  env);
146  return q;
147 }
148 
149 
155 void
157 {
158  if (NULL != q->mq)
159  {
160  GNUNET_MQ_destroy (q->mq);
161  q->mq = NULL;
162  }
163  GNUNET_free (q);
164 }
165 
166 
171 {
172 
177 
182 
186  void *func_cls;
187 
188 };
189 
190 
200 static void
202  enum GNUNET_MQ_Error error)
203 {
204  struct GNUNET_REVOCATION_Handle *h = cls;
205 
207  "Revocation MQ error\n");
208  h->func (h->func_cls,
209  GNUNET_SYSERR);
211 }
212 
213 
220 static void
222  const struct RevocationResponseMessage *rrm)
223 {
224  struct GNUNET_REVOCATION_Handle *h = cls;
225 
227  "Revocation transmission result: %d\n",
228  (uint32_t) ntohl (rrm->is_valid));
229  h->func (h->func_cls,
230  ntohl (rrm->is_valid));
232 }
233 
234 
252  const struct GNUNET_CRYPTO_EcdsaPublicKey *key,
253  const struct GNUNET_CRYPTO_EcdsaSignature *sig,
254  uint64_t pow,
256  void *func_cls)
257 {
260  struct GNUNET_MQ_MessageHandler handlers[] = {
261  GNUNET_MQ_hd_fixed_size (revocation_response,
264  h),
266  };
267  unsigned long long matching_bits;
268  struct RevokeMessage *rm;
269  struct GNUNET_MQ_Envelope *env;
270 
271  if ( (GNUNET_OK ==
273  "REVOCATION",
274  "WORKBITS",
275  &matching_bits)) &&
276  (GNUNET_YES !=
278  pow,
279  (unsigned int) matching_bits)) )
280  {
281  GNUNET_break (0);
282  GNUNET_free (h);
283  return NULL;
284  }
285 
286  h->mq = GNUNET_CLIENT_connect (cfg,
287  "revocation",
288  handlers,
290  h);
291  if (NULL == h->mq)
292  {
293  GNUNET_free (h);
294  return NULL;
295  }
296  h->func = func;
297  h->func_cls = func_cls;
298  env = GNUNET_MQ_msg (rm,
300  rm->reserved = htonl (0);
301  rm->proof_of_work = pow;
303  rm->purpose.size = htonl (sizeof (struct GNUNET_CRYPTO_EccSignaturePurpose) +
304  sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey));
305  rm->public_key = *key;
306  rm->signature = *sig;
307  GNUNET_MQ_send (h->mq,
308  env);
309  return h;
310 }
311 
312 
318 void
320 {
321  if (NULL != h->mq)
322  {
323  GNUNET_MQ_destroy (h->mq);
324  h->mq = NULL;
325  }
326  GNUNET_free (h);
327 }
328 
329 
337 static void
338 pow_hash (const void *buf,
339  size_t buf_len,
340  struct GNUNET_HashCode *result)
341 {
342  GNUNET_break (0 ==
343  gcry_kdf_derive (buf, buf_len,
344  GCRY_KDF_SCRYPT,
345  1 /* subalgo */,
346  "gnunet-revocation-proof-of-work",
347  strlen ("gnunet-revocation-proof-of-work"),
348  2 /* iterations; keep cost of individual op small */,
349  sizeof (struct GNUNET_HashCode), result));
350 }
351 
352 
359 static unsigned int
361 {
362  unsigned int hash_count;
363 
364  hash_count = 0;
365  while ((0 == GNUNET_CRYPTO_hash_get_bit (hash, hash_count)))
366  hash_count++;
367  return hash_count;
368 }
369 
370 
380 int
382  uint64_t pow,
383  unsigned int matching_bits)
384 {
385  char buf[sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey) +
386  sizeof (pow)] GNUNET_ALIGN;
387  struct GNUNET_HashCode result;
388 
389  GNUNET_memcpy (buf, &pow, sizeof (pow));
390  GNUNET_memcpy (&buf[sizeof (pow)], key,
391  sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey));
392  pow_hash (buf, sizeof (buf), &result);
393  return (count_leading_zeroes (&result) >=
394  matching_bits) ? GNUNET_YES : GNUNET_NO;
395 }
396 
397 
404 void
406  struct GNUNET_CRYPTO_EcdsaSignature *sig)
407 {
408  struct RevokeMessage rm;
409 
411  rm.purpose.size = htonl (sizeof (struct GNUNET_CRYPTO_EccSignaturePurpose) +
412  sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey));
416  &rm.purpose,
417  sig));
418 }
419 
420 
421 /* 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:101
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:901
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:107
#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:81
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:78
#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!
#define GNUNET_memcpy(dst, src, n)
Revoke key.
Definition: revocation.h:81
Key revocation response.
Definition: revocation.h:59
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:96
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:69
#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:79
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:46
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:120
Handle to a message queue.
Definition: mq.c:85
struct GNUNET_CRYPTO_EcdsaPublicKey key
Key to check.
Definition: revocation.h:51
configuration data
Definition: configuration.c:85
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:112
void GNUNET_MQ_destroy(struct GNUNET_MQ_Handle *mq)
Destroy the message queue.
Definition: mq.c:824
GNUNET_REVOCATION_Callback func
Function to call once we are done.
#define GNUNET_YES
Definition: gnunet_common.h:80
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:353
uint32_t is_valid
GNUNET_NO if revocation failed for internal reasons (e.g.
Definition: revocation.h:131
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:91