From ad989721684818bee9a0a1f81d5fb085241959ab Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Sun, 6 Oct 2013 07:41:21 +0000 Subject: -implementing revocation library --- src/include/gnunet_revocation_service.h | 3 +- src/revocation/gnunet-service-revocation.c | 16 +-- src/revocation/revocation.h | 24 +++- src/revocation/revocation_api.c | 196 ++++++++++++++++++++++++++++- 4 files changed, 223 insertions(+), 16 deletions(-) diff --git a/src/include/gnunet_revocation_service.h b/src/include/gnunet_revocation_service.h index 1df44b066..7758ec97e 100644 --- a/src/include/gnunet_revocation_service.h +++ b/src/include/gnunet_revocation_service.h @@ -54,7 +54,8 @@ struct GNUNET_REVOCATION_Query; * * @param cls closure * @param is_valid #GNUNET_NO of the key is/was revoked, - * #GNUNET_YES if the key is still valid + * #GNUNET_YES if the key is still valid, + * #GNUNET_SYSERR if we had trouble querying the service * */ typedef void (*GNUNET_REVOCATION_Callback) (void *cls, diff --git a/src/revocation/gnunet-service-revocation.c b/src/revocation/gnunet-service-revocation.c index f310429d3..168f8c6ef 100644 --- a/src/revocation/gnunet-service-revocation.c +++ b/src/revocation/gnunet-service-revocation.c @@ -125,7 +125,7 @@ static unsigned long long revocation_work_required; * #GNUNET_NO if the key/signature don't verify */ static int -verify_revoke_message (const struct GNUNET_REVOCATION_RevokeMessage *rm) +verify_revoke_message (const struct RevokeMessage *rm) { if (GNUNET_YES != GNUNET_REVOCATION_check_pow (&rm->public_key, @@ -183,11 +183,11 @@ handle_revoke_message (void *cls, struct GNUNET_SERVER_Client *client, const struct GNUNET_MessageHeader *message) { - const struct GNUNET_REVOCATION_RevokeMessage *rm; + const struct RevokeMessage *rm; GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received REVOKE message from client\n"); - rm = (const struct GNUNET_REVOCATION_RevokeMessage *) message; + rm = (const struct RevokeMessage *) message; if (GNUNET_OK != verify_revoke_message (rm)) { @@ -211,12 +211,12 @@ handle_p2p_revoke_message (void *cls, const struct GNUNET_PeerIdentity *peer, const struct GNUNET_MessageHeader *message) { - const struct GNUNET_REVOCATION_RevokeMessage *rm; + const struct RevokeMessage *rm; GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received REVOKE message from peer\n"); - rm = (const struct GNUNET_REVOCATION_RevokeMessage *) message; + rm = (const struct RevokeMessage *) message; if (GNUNET_OK != verify_revoke_message (rm)) { @@ -375,14 +375,14 @@ run (void *cls, { static const struct GNUNET_SERVER_MessageHandler handlers[] = { {&handle_query_message, NULL, GNUNET_MESSAGE_TYPE_REVOCATION_QUERY, - sizeof (struct GNUNET_REVOCATION_QueryMessage)}, + sizeof (struct QueryMessage)}, {&handle_revoke_message, NULL, GNUNET_MESSAGE_TYPE_REVOCATION_REVOKE, - sizeof (struct GNUNET_REVOCATION_RevokeMessage)}, + sizeof (struct RevokeMessage)}, {NULL, NULL, 0, 0} }; static const struct GNUNET_CORE_MessageHandler core_handlers[] = { {&handle_p2p_revoke_message, GNUNET_MESSAGE_TYPE_REVOCATION_REVOKE, - sizeof (struct GNUNET_REVOCATION_RevokeMessage)}, + sizeof (struct RevokeMessage)}, {NULL, 0, 0} }; diff --git a/src/revocation/revocation.h b/src/revocation/revocation.h index c6c5d5e76..29235aeee 100644 --- a/src/revocation/revocation.h +++ b/src/revocation/revocation.h @@ -33,7 +33,7 @@ GNUNET_NETWORK_STRUCT_BEGIN /** * Query key revocation status. */ -struct GNUNET_REVOCATION_QueryMessage +struct QueryMessage { /** * Type: #GNUNET_MESSAGE_TYPE_REVOCATION_QUERY @@ -56,7 +56,7 @@ struct GNUNET_REVOCATION_QueryMessage /** * Key revocation response. */ -struct GNUNET_REVOCATION_QueryResponseMessage +struct QueryResponseMessage { /** * Type: #GNUNET_MESSAGE_TYPE_REVOCATION_QUERY_RESPONSE @@ -78,7 +78,7 @@ struct GNUNET_REVOCATION_QueryResponseMessage * #GNUNET_MESSAGE_TYPE_REVOCATION_REVOKE_RESPONSE (which is just * in a `struct GNUNET_MessageHeader`. */ -struct GNUNET_REVOCATION_RevokeMessage +struct RevokeMessage { /** * Type: #GNUNET_MESSAGE_TYPE_REVOCATION_REVOKE @@ -114,6 +114,24 @@ struct GNUNET_REVOCATION_RevokeMessage }; +/** + * Key revocation response. + */ +struct RevocationResponseMessage +{ + /** + * Type: #GNUNET_MESSAGE_TYPE_REVOKE_RESPONSE + */ + struct GNUNET_MessageHeader header; + + /** + * #GNUNET_NO if revoked, #GNUNET_YES if valid. + */ + uint32_t is_valid GNUNET_PACKED; + +}; + + GNUNET_NETWORK_STRUCT_END diff --git a/src/revocation/revocation_api.c b/src/revocation/revocation_api.c index 109d4afc5..858649bbd 100644 --- a/src/revocation/revocation_api.c +++ b/src/revocation/revocation_api.c @@ -60,9 +60,81 @@ 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. * @@ -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,9 +232,86 @@ 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. * @@ -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) + -- cgit v1.2.3