GNUnet  0.11.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 {
42 
47 
51  void *func_cls;
52 };
53 
54 
64 static void
66  enum GNUNET_MQ_Error error)
67 {
68  struct GNUNET_REVOCATION_Query *q = cls;
69 
71  "Revocation query MQ error\n");
72  q->func (q->func_cls,
75 }
76 
77 
84 static void
86  const struct QueryResponseMessage *qrm)
87 {
88  struct GNUNET_REVOCATION_Query *q = cls;
89 
91  "Revocation query result: %d\n",
92  (uint32_t) ntohl (qrm->is_valid));
93  q->func (q->func_cls,
94  ntohl (qrm->is_valid));
96 }
97 
98 
110  const struct GNUNET_CRYPTO_EcdsaPublicKey *key,
112  void *func_cls)
113 {
114  struct GNUNET_REVOCATION_Query *q
116  struct GNUNET_MQ_MessageHandler handlers[] = {
117  GNUNET_MQ_hd_fixed_size (revocation_query_response,
119  struct QueryResponseMessage,
120  q),
122  };
123  struct QueryMessage *qm;
124  struct GNUNET_MQ_Envelope *env;
125 
126  q->mq = GNUNET_CLIENT_connect (cfg,
127  "revocation",
128  handlers,
130  q);
131  if (NULL == q->mq)
132  {
133  GNUNET_free (q);
134  return NULL;
135  }
136  q->func = func;
137  q->func_cls = func_cls;
138  env = GNUNET_MQ_msg (qm,
140  qm->reserved = htonl (0);
141  qm->key = *key;
142  GNUNET_MQ_send (q->mq,
143  env);
144  return q;
145 }
146 
147 
153 void
155 {
156  if (NULL != q->mq)
157  {
158  GNUNET_MQ_destroy (q->mq);
159  q->mq = NULL;
160  }
161  GNUNET_free (q);
162 }
163 
164 
169 {
174 
179 
183  void *func_cls;
184 };
185 
186 
196 static void
198  enum GNUNET_MQ_Error error)
199 {
200  struct GNUNET_REVOCATION_Handle *h = cls;
201 
203  "Revocation MQ error\n");
204  h->func (h->func_cls,
205  GNUNET_SYSERR);
207 }
208 
209 
216 static void
218  const struct RevocationResponseMessage *rrm)
219 {
220  struct GNUNET_REVOCATION_Handle *h = cls;
221 
223  "Revocation transmission result: %d\n",
224  (uint32_t) ntohl (rrm->is_valid));
225  h->func (h->func_cls,
226  ntohl (rrm->is_valid));
228 }
229 
230 
248  const struct GNUNET_CRYPTO_EcdsaPublicKey *key,
249  const struct GNUNET_CRYPTO_EcdsaSignature *sig,
250  uint64_t pow,
252  void *func_cls)
253 {
256  struct GNUNET_MQ_MessageHandler handlers[] = {
257  GNUNET_MQ_hd_fixed_size (revocation_response,
260  h),
262  };
263  unsigned long long matching_bits;
264  struct RevokeMessage *rm;
265  struct GNUNET_MQ_Envelope *env;
266 
267  if ((GNUNET_OK ==
269  "REVOCATION",
270  "WORKBITS",
271  &matching_bits)) &&
272  (GNUNET_YES !=
274  pow,
275  (unsigned int) matching_bits)))
276  {
277  GNUNET_break (0);
278  GNUNET_free (h);
279  return NULL;
280  }
281 
282  h->mq = GNUNET_CLIENT_connect (cfg,
283  "revocation",
284  handlers,
286  h);
287  if (NULL == h->mq)
288  {
289  GNUNET_free (h);
290  return NULL;
291  }
292  h->func = func;
293  h->func_cls = func_cls;
294  env = GNUNET_MQ_msg (rm,
296  rm->reserved = htonl (0);
297  rm->proof_of_work = pow;
299  rm->purpose.size = htonl (sizeof(struct GNUNET_CRYPTO_EccSignaturePurpose)
300  + sizeof(struct GNUNET_CRYPTO_EcdsaPublicKey));
301  rm->public_key = *key;
302  rm->signature = *sig;
303  GNUNET_MQ_send (h->mq,
304  env);
305  return h;
306 }
307 
308 
314 void
316 {
317  if (NULL != h->mq)
318  {
319  GNUNET_MQ_destroy (h->mq);
320  h->mq = NULL;
321  }
322  GNUNET_free (h);
323 }
324 
325 
333 static void
334 pow_hash (const void *buf,
335  size_t buf_len,
336  struct GNUNET_HashCode *result)
337 {
338  GNUNET_break (0 ==
339  gcry_kdf_derive (buf, buf_len,
340  GCRY_KDF_SCRYPT,
341  1 /* subalgo */,
342  "gnunet-revocation-proof-of-work",
343  strlen ("gnunet-revocation-proof-of-work"),
344  2 /* iterations; keep cost of individual op small */,
345  sizeof(struct GNUNET_HashCode), result));
346 }
347 
348 
355 static unsigned int
357 {
358  unsigned int hash_count;
359 
360  hash_count = 0;
361  while ((0 == GNUNET_CRYPTO_hash_get_bit (hash, hash_count)))
362  hash_count++;
363  return hash_count;
364 }
365 
366 
376 int
378  uint64_t pow,
379  unsigned int matching_bits)
380 {
381  char buf[sizeof(struct GNUNET_CRYPTO_EcdsaPublicKey)
382  + sizeof(pow)] GNUNET_ALIGN;
383  struct GNUNET_HashCode result;
384 
385  GNUNET_memcpy (buf, &pow, sizeof(pow));
386  GNUNET_memcpy (&buf[sizeof(pow)], key,
387  sizeof(struct GNUNET_CRYPTO_EcdsaPublicKey));
388  pow_hash (buf, sizeof(buf), &result);
389  return (count_leading_zeroes (&result) >=
390  matching_bits) ? GNUNET_YES : GNUNET_NO;
391 }
392 
393 
400 void
403  struct GNUNET_CRYPTO_EcdsaSignature *sig)
404 {
405  struct RevokeMessage rm;
406 
408  rm.purpose.size = htonl (sizeof(struct GNUNET_CRYPTO_EccSignaturePurpose)
409  + sizeof(struct GNUNET_CRYPTO_EcdsaPublicKey));
413  &rm.purpose,
414  sig));
415 }
416 
417 
418 /* 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:99
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.
static const struct GNUNET_CONFIGURATION_Handle * cfg
Configuration we are using.
Definition: gnunet-abd.c:36
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:1057
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:105
#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:99
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:928
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:79
Key revocation response.
Definition: revocation.h:58
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:94
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.
uint32_t is_valid
GNUNET_NO if revoked, GNUNET_YES if valid.
Definition: revocation.h:68
#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:239
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:251
struct GNUNET_MQ_Envelope * env
Definition: 005.c:1
Handle for the key revocation query.
Key revocation response.
Definition: revocation.h:117
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:110
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: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:353
uint32_t is_valid
GNUNET_NO if revocation failed for internal reasons (e.g.
Definition: revocation.h:128
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:89