diff options
author | Christian Grothoff <christian@grothoff.org> | 2013-10-06 07:41:21 +0000 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2013-10-06 07:41:21 +0000 |
commit | ad989721684818bee9a0a1f81d5fb085241959ab (patch) | |
tree | d3761d4e3af72e1d9c67565b682271a4801436d6 /src/revocation/revocation_api.c | |
parent | 2315ef124c25961fc88eadbf6b9d396de5d8f992 (diff) |
-implementing revocation library
Diffstat (limited to 'src/revocation/revocation_api.c')
-rw-r--r-- | src/revocation/revocation_api.c | 196 |
1 files changed, 192 insertions, 4 deletions
diff --git a/src/revocation/revocation_api.c b/src/revocation/revocation_api.c index 109d4afc50..858649bbd8 100644 --- a/src/revocation/revocation_api.c +++ b/src/revocation/revocation_api.c @@ -60,10 +60,82 @@ struct GNUNET_REVOCATION_Query * Closure for @e func. */ void *func_cls; + + /** + * Transmission handle to the service. + */ + struct GNUNET_CLIENT_TransmitHandle *th; + }; /** + * Handle response to our revocation query. + * + * @param cls our `struct GNUNET_REVOCATION_Query` handle + * @param msg response we got, NULL on disconnect + */ +static void +handle_revocation_query_response (void *cls, + const struct GNUNET_MessageHeader *msg) +{ + struct GNUNET_REVOCATION_Query *q = cls; + const struct QueryResponseMessage *qrm; + + if ( (NULL == msg) || + (sizeof (struct QueryResponseMessage) != ntohs (msg->size)) || + (GNUNET_MESSAGE_TYPE_REVOCATION_QUERY_RESPONSE != ntohs (msg->type)) ) + { + GNUNET_break (NULL == msg); + q->func (q->func_cls, GNUNET_SYSERR); + GNUNET_REVOCATION_query_cancel (q); + return; + } + qrm = (const struct QueryResponseMessage *) msg; + q->func (q->func_cls, ntohl (qrm->is_valid)); + GNUNET_REVOCATION_query_cancel (q); +} + + +/** + * Transmit our revocation query to the service. + * + * @param cls our `struct GNUNET_REVOCATION_Query` handle + * @param size number of bytes available in @a buf + * @param buf where to copy the query + * @return number of bytes copied to @a buf + */ +static size_t +send_revocation_query (void *cls, + size_t size, + void *buf) +{ + struct GNUNET_REVOCATION_Query *q = cls; + struct QueryMessage qm; + + q->th = NULL; + if ( (NULL == buf) || + (sizeof (struct QueryMessage) > size) ) + { + GNUNET_break (0); + q->func (q->func_cls, GNUNET_SYSERR); + GNUNET_REVOCATION_query_cancel (q); + return 0; + } + qm.header.size = htons (sizeof (struct QueryMessage)); + qm.header.type = htons (GNUNET_MESSAGE_TYPE_REVOCATION_QUERY); + qm.reserved = htonl (0); + qm.key = q->key; + memcpy (buf, &qm, sizeof (struct QueryMessage)); + GNUNET_CLIENT_receive (q->client, + &handle_revocation_query_response, + q, + GNUNET_TIME_UNIT_FOREVER_REL); + return sizeof (struct QueryMessage); +} + + +/** * Check if a key was revoked. * * @param cfg the configuration to use @@ -81,11 +153,22 @@ GNUNET_REVOCATION_query (const struct GNUNET_CONFIGURATION_Handle *cfg, q = GNUNET_new (struct GNUNET_REVOCATION_Query); q->client = GNUNET_CLIENT_connect ("revocation", cfg); + if (NULL == q->client) + { + GNUNET_break (0); + GNUNET_free (q); + return NULL; + } q->cfg = cfg; q->key = *key; q->func = func; q->func_cls = func_cls; - GNUNET_break (0); + q->th = GNUNET_CLIENT_notify_transmit_ready (q->client, + sizeof (struct QueryMessage), + GNUNET_TIME_UNIT_FOREVER_REL, + GNUNET_YES, + &send_revocation_query, + q); return q; } @@ -98,6 +181,11 @@ GNUNET_REVOCATION_query (const struct GNUNET_CONFIGURATION_Handle *cfg, void GNUNET_REVOCATION_query_cancel (struct GNUNET_REVOCATION_Query *q) { + if (NULL != q->th) + { + GNUNET_CLIENT_notify_transmit_ready_cancel (q->th); + q->th = NULL; + } GNUNET_CLIENT_disconnect (q->client); GNUNET_free (q); } @@ -144,10 +232,87 @@ struct GNUNET_REVOCATION_Handle */ void *func_cls; + /** + * Transmission handle to the service. + */ + struct GNUNET_CLIENT_TransmitHandle *th; + }; /** + * Handle response to our revocation query. + * + * @param cls our `struct GNUNET_REVOCATION_Handle` handle + * @param msg response we got, NULL on disconnect + */ +static void +handle_revocation_response (void *cls, + const struct GNUNET_MessageHeader *msg) +{ + struct GNUNET_REVOCATION_Handle *h = cls; + const struct RevocationResponseMessage *rrm; + + if ( (NULL == msg) || + (sizeof (struct RevocationResponseMessage) != ntohs (msg->size)) || + (GNUNET_MESSAGE_TYPE_REVOCATION_REVOKE_RESPONSE != ntohs (msg->type)) ) + { + GNUNET_break (NULL == msg); + h->func (h->func_cls, GNUNET_SYSERR); + GNUNET_REVOCATION_revoke_cancel (h); + return; + } + rrm = (const struct RevocationResponseMessage *) msg; + h->func (h->func_cls, ntohl (rrm->is_valid)); + GNUNET_REVOCATION_revoke_cancel (h); + +} + + +/** + * Transmit our revocation to the service. + * + * @param cls our `struct GNUNET_REVOCATION_Handle` handle + * @param size number of bytes available in @a buf + * @param buf where to copy the query + * @return number of bytes copied to @a buf + */ +static size_t +send_revoke (void *cls, + size_t size, + void *buf) +{ + struct GNUNET_REVOCATION_Handle *h = cls; + struct RevokeMessage rm; + + h->th = NULL; + if ( (NULL == buf) || + (sizeof (struct RevokeMessage) > size) ) + { + GNUNET_break (0); + h->func (h->func_cls, GNUNET_SYSERR); + GNUNET_REVOCATION_revoke_cancel (h); + return 0; + } + rm.header.size = htons (sizeof (struct QueryMessage)); + rm.header.type = htons (GNUNET_MESSAGE_TYPE_REVOCATION_QUERY); + rm.reserved = htonl (0); + rm.proof_of_work = h->pow; + rm.purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_REVOCATION); + rm.purpose.size = htonl (sizeof (struct GNUNET_CRYPTO_EccSignaturePurpose) + + sizeof (struct GNUNET_CRYPTO_EccPublicSignKey)); + rm.public_key = h->key; + rm.signature = h->sig; + memcpy (buf, &rm, sizeof (struct RevokeMessage)); + GNUNET_CLIENT_receive (h->client, + &handle_revocation_response, + h, + GNUNET_TIME_UNIT_FOREVER_REL); + return sizeof (struct RevokeMessage); +} + + +/** * Perform key revocation. * * @param cfg the configuration to use @@ -170,7 +335,20 @@ GNUNET_REVOCATION_revoke (const struct GNUNET_CONFIGURATION_Handle *cfg, GNUNET_REVOCATION_Callback func, void *func_cls) { struct GNUNET_REVOCATION_Handle *h; - + unsigned long long matching_bits; + + if ( (GNUNET_OK == + GNUNET_CONFIGURATION_get_value_number (cfg, + "REVOCATION", + "WORKBITS", + &matching_bits)) && + (GNUNET_YES != + GNUNET_REVOCATION_check_pow (key, pow, + (unsigned int) matching_bits)) ) + { + GNUNET_break (0); + return NULL; + } h = GNUNET_new (struct GNUNET_REVOCATION_Handle); h->client = GNUNET_CLIENT_connect ("revocation", cfg); h->cfg = cfg; @@ -179,7 +357,12 @@ GNUNET_REVOCATION_revoke (const struct GNUNET_CONFIGURATION_Handle *cfg, h->pow = pow; h->func = func; h->func_cls = func_cls; - GNUNET_break (0); + h->th = GNUNET_CLIENT_notify_transmit_ready (h->client, + sizeof (struct RevokeMessage), + GNUNET_TIME_UNIT_FOREVER_REL, + GNUNET_YES, + &send_revoke, + h); return h; } @@ -192,6 +375,11 @@ GNUNET_REVOCATION_revoke (const struct GNUNET_CONFIGURATION_Handle *cfg, void GNUNET_REVOCATION_revoke_cancel (struct GNUNET_REVOCATION_Handle *h) { + if (NULL != h->th) + { + GNUNET_CLIENT_notify_transmit_ready_cancel (h->th); + h->th = NULL; + } GNUNET_CLIENT_disconnect (h->client); GNUNET_free (h); } @@ -276,7 +464,7 @@ void GNUNET_REVOCATION_sign_revocation (const struct GNUNET_CRYPTO_EccPrivateKey *key, struct GNUNET_CRYPTO_EccSignature *sig) { - struct GNUNET_REVOCATION_RevokeMessage rm; + struct RevokeMessage rm; rm.purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_REVOCATION); rm.purpose.size = htonl (sizeof (struct GNUNET_CRYPTO_EccSignaturePurpose) + |