From 646723dd495657a184d1f7e439f4958a72bee1df Mon Sep 17 00:00:00 2001 From: "Schanzenbach, Martin" Date: Fri, 2 Dec 2016 17:29:08 +0100 Subject: [PATCH] - add verify and issue to cli --- src/credential/Makefile.am | 1 + src/credential/credential_api.c | 45 ++++++ src/credential/gnunet-credential.c | 139 ++++++++++++++++--- src/credential/plugin_gnsrecord_credential.c | 10 +- src/include/gnunet_credential_service.h | 22 +-- 5 files changed, 173 insertions(+), 44 deletions(-) diff --git a/src/credential/Makefile.am b/src/credential/Makefile.am index 6469895e3..e85c3cc2d 100644 --- a/src/credential/Makefile.am +++ b/src/credential/Makefile.am @@ -57,6 +57,7 @@ gnunet_credential_SOURCES = \ gnunet_credential_LDADD = \ libgnunetcredential.la \ $(top_builddir)/src/util/libgnunetutil.la \ + $(top_builddir)/src/gnsrecord/libgnunetgnsrecord.la \ $(top_builddir)/src/identity/libgnunetidentity.la \ $(GN_LIBINTL) diff --git a/src/credential/credential_api.c b/src/credential/credential_api.c index 8ff66c574..8d3c96ca8 100644 --- a/src/credential/credential_api.c +++ b/src/credential/credential_api.c @@ -28,6 +28,7 @@ #include "gnunet_arm_service.h" #include "gnunet_hello_lib.h" #include "gnunet_protocols.h" +#include "gnunet_signatures.h" #include "credential.h" #include "gnunet_credential_service.h" #include "gnunet_identity_service.h" @@ -406,5 +407,49 @@ GNUNET_CREDENTIAL_verify (struct GNUNET_CREDENTIAL_Handle *handle, return vr; } +/** + * Issue an attribute to a subject + * + * @param handle handle to the Credential service + * @param issuer the ego that should be used to issue the attribute + * @param subject the subject of the attribute + * @param attribute the name of the attribute + * @return handle to the queued request + */ +struct GNUNET_CREDENTIAL_CredentialRecordData * +GNUNET_CREDENTIAL_issue (struct GNUNET_CREDENTIAL_Handle *handle, + const struct GNUNET_CRYPTO_EcdsaPrivateKey *issuer, + struct GNUNET_CRYPTO_EcdsaPublicKey *subject, + const char *attribute) +{ + struct GNUNET_CREDENTIAL_CredentialRecordData *crd; + + crd = GNUNET_malloc (sizeof (struct GNUNET_CREDENTIAL_CredentialRecordData) + strlen (attribute) + 1); + + crd->purpose.size = htonl (strlen (attribute) + 1 + + sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey) + + sizeof (struct GNUNET_CRYPTO_EccSignaturePurpose) + + sizeof (struct GNUNET_TIME_AbsoluteNBO)); + crd->purpose.purpose = htonl (GNUNET_SIGNATURE_PURPOSE_CREDENTIAL); + GNUNET_CRYPTO_ecdsa_key_get_public (issuer, + &crd->issuer_key); + + GNUNET_memcpy (&crd[1], + attribute, + strlen (attribute)); + if (GNUNET_OK != + GNUNET_CRYPTO_ecdsa_sign (issuer, + &crd->purpose, + &crd->sig)) + { + GNUNET_break (0); + GNUNET_free (crd); + return NULL; + } + return crd; +} + + + /* end of credential_api.c */ diff --git a/src/credential/gnunet-credential.c b/src/credential/gnunet-credential.c index bfd4223ba..eaad6d5cf 100644 --- a/src/credential/gnunet-credential.c +++ b/src/credential/gnunet-credential.c @@ -25,12 +25,18 @@ #include "platform.h" #include #include +#include /** * Configuration we are using. */ static const struct GNUNET_CONFIGURATION_Handle *cfg; +/** + * EgoLookup + */ +static struct GNUNET_IDENTITY_EgoLookup *el; + /** * Handle to Credential service. */ @@ -61,16 +67,42 @@ static char *subject_key; */ static char *subject_credential; +/** + * Subject key + */ +struct GNUNET_CRYPTO_EcdsaPublicKey subject_pkey; + +/** + * Issuer key + */ +struct GNUNET_CRYPTO_EcdsaPublicKey issuer_pkey; + + /** * Issuer pubkey string */ static char *issuer_key; +/** + * Issuer ego + */ +static char *issuer_ego_name; + /** * Issuer attribute */ static char *issuer_attr; +/** + * Verify mode + */ +static uint32_t verify; + +/** + * Issue mode + */ +static uint32_t create_cred; + /** * Task run on shutdown. Cleans up everything. @@ -135,6 +167,45 @@ handle_verify_result (void *cls, GNUNET_SCHEDULER_shutdown (); } +/** + * Callback invoked from identity service with ego information. + * An @a ego of NULL means the ego was not found. + * + * @param cls closure with the configuration + * @param ego an ego known to identity service, or NULL + */ +static void +identity_cb (void *cls, + const struct GNUNET_IDENTITY_Ego *ego) +{ + const struct GNUNET_CRYPTO_EcdsaPrivateKey *privkey; + struct GNUNET_CREDENTIAL_CredentialRecordData *crd; + + el = NULL; + if (NULL == ego) + { + if (NULL != issuer_ego_name) + { + fprintf (stderr, + _("Ego `%s' not known to identity service\n"), + issuer_ego_name); + } + GNUNET_SCHEDULER_shutdown (); + return; + } + privkey = GNUNET_IDENTITY_ego_get_private_key (ego); + GNUNET_free_non_null (issuer_ego_name); + issuer_ego_name = NULL; + crd = GNUNET_CREDENTIAL_issue (credential, + privkey, + &subject_pkey, + issuer_attr); + printf ("Success.\n"); + printf (GNUNET_GNSRECORD_value_to_string (GNUNET_GNSRECORD_TYPE_CREDENTIAL, + crd, + sizeof (crd) + strlen (issuer_attr) + 1)); +} + @@ -162,39 +233,53 @@ run (void *cls, _("Failed to connect to CREDENTIAL\n")); return; } + + + tt = GNUNET_SCHEDULER_add_delayed (timeout, &do_timeout, NULL); GNUNET_SCHEDULER_add_shutdown (&do_shutdown, NULL); - struct GNUNET_CRYPTO_EcdsaPublicKey subject_pkey; - struct GNUNET_CRYPTO_EcdsaPublicKey issuer_pkey; + if (NULL == subject_key) + { + fprintf (stderr, + _("Subject public key needed\n")); + GNUNET_SCHEDULER_shutdown (); + return; - if (NULL != subject_key && NULL != issuer_key) + } + if (GNUNET_OK != + GNUNET_CRYPTO_ecdsa_public_key_from_string (subject_key, + strlen (subject_key), + &subject_pkey)) { - if (GNUNET_OK != - GNUNET_CRYPTO_ecdsa_public_key_from_string (subject_key, - strlen (subject_key), - &subject_pkey)) + fprintf (stderr, + _("Subject public key `%s' is not well-formed\n"), + subject_key); + GNUNET_SCHEDULER_shutdown (); + return; + } + + if (GNUNET_YES == verify) { + if (NULL == issuer_key) { fprintf (stderr, - _("Subject public key `%s' is not well-formed\n"), - subject_key); + _("Issuer public key not well-formed\n")); GNUNET_SCHEDULER_shutdown (); return; - } + } if (GNUNET_OK != GNUNET_CRYPTO_ecdsa_public_key_from_string (issuer_key, strlen (issuer_key), &issuer_pkey)) { fprintf (stderr, - _("Authority public key `%s' is not well-formed\n"), + _("Issuer public key `%s' is not well-formed\n"), issuer_key); GNUNET_SCHEDULER_shutdown (); - return; } verify_request = GNUNET_CREDENTIAL_verify(credential, @@ -204,15 +289,26 @@ run (void *cls, subject_credential, &handle_verify_result, NULL); + } else if (GNUNET_YES == create_cred) { + if (NULL == issuer_ego_name) + { + fprintf (stderr, + _("Issuer ego required\n")); + GNUNET_SCHEDULER_shutdown (); + return; + + } + el = GNUNET_IDENTITY_ego_lookup (cfg, + issuer_ego_name, + &identity_cb, + (void *) cfg); return; - } - else - { + } else { fprintf (stderr, _("Please specify name to lookup, subject key and issuer key!\n")); GNUNET_SCHEDULER_shutdown (); - return; } + return; } @@ -227,6 +323,12 @@ int main (int argc, char *const *argv) { static const struct GNUNET_GETOPT_CommandLineOption options[] = { + {'I', "issue", NULL, + gettext_noop ("create credential"), 0, + &GNUNET_GETOPT_set_one, &create_cred}, + {'V', "verify", NULL, + gettext_noop ("verify credential against attribute"), 0, + &GNUNET_GETOPT_set_one, &verify}, {'s', "subject", "PKEY", gettext_noop ("The public key of the subject to lookup the credential for"), 1, &GNUNET_GETOPT_set_string, &subject_key}, @@ -236,8 +338,11 @@ main (int argc, char *const *argv) {'i', "issuer", "PKEY", gettext_noop ("The public key of the authority to verify the credential against"), 1, &GNUNET_GETOPT_set_string, &issuer_key}, + {'e', "ego", "EGO", + gettext_noop ("The ego to use to issue"), 1, + &GNUNET_GETOPT_set_string, &issuer_ego_name}, {'a', "attribute", "ATTR", - gettext_noop ("The issuer attribute to verify against"), 1, + gettext_noop ("The issuer attribute to verify against or to issue"), 1, &GNUNET_GETOPT_set_string, &issuer_attr}, GNUNET_GETOPT_OPTION_END }; diff --git a/src/credential/plugin_gnsrecord_credential.c b/src/credential/plugin_gnsrecord_credential.c index d321a43a4..c7cbb8bdd 100644 --- a/src/credential/plugin_gnsrecord_credential.c +++ b/src/credential/plugin_gnsrecord_credential.c @@ -77,7 +77,6 @@ credential_value_to_string (void *cls, char *cred_str; char *subject_pkey; char *issuer_pkey; - uint32_t cf; // Credential flags if (data_size < sizeof (struct GNUNET_CREDENTIAL_CredentialRecordData)) return NULL; /* malformed */ memcpy (&cred, @@ -86,13 +85,11 @@ credential_value_to_string (void *cls, cdata = data; subject_pkey = GNUNET_CRYPTO_ecdsa_public_key_to_string (&cred.subject_key); issuer_pkey = GNUNET_CRYPTO_ecdsa_public_key_to_string (&cred.issuer_key); - cf = ntohl (cred.credential_flags); GNUNET_asprintf (&cred_str, - "%s %s %u %s", + "%s %s %s", subject_pkey, issuer_pkey, - (unsigned int) cf, &cdata[sizeof (cred)]); GNUNET_free (subject_pkey); GNUNET_free (issuer_pkey); @@ -132,7 +129,6 @@ credential_string_to_value (void *cls, case GNUNET_GNSRECORD_TYPE_CREDENTIAL: { struct GNUNET_CREDENTIAL_CredentialRecordData *cred; - unsigned int cf; // credential flags size_t enclen = (sizeof (struct GNUNET_CRYPTO_EcdsaPublicKey)) * 8; if (enclen % 5 > 0) @@ -143,10 +139,9 @@ credential_string_to_value (void *cls, char name[253 + 1]; if (5 != SSCANF (s, - "%52s %52s %u %253s", + "%52s %52s %253s", subject_pkey, issuer_pkey, - &cf, name)) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, @@ -162,7 +157,6 @@ credential_string_to_value (void *cls, GNUNET_CRYPTO_ecdsa_public_key_from_string (issuer_pkey, strlen (issuer_pkey), &cred->issuer_key); - cred->credential_flags = htonl (cf); GNUNET_memcpy (&cred[1], name, strlen (name)); diff --git a/src/include/gnunet_credential_service.h b/src/include/gnunet_credential_service.h index b996b77db..088d0c75e 100644 --- a/src/include/gnunet_credential_service.h +++ b/src/include/gnunet_credential_service.h @@ -99,11 +99,6 @@ struct GNUNET_CREDENTIAL_CredentialRecordData { */ struct GNUNET_CRYPTO_EcdsaPublicKey subject_key; - /** - * Flags for this credential - */ - uint32_t credential_flags GNUNET_PACKED; - /** * Expiration time of this credential */ @@ -168,15 +163,6 @@ typedef void (*GNUNET_CREDENTIAL_VerifyResultProcessor) (void *cls, struct GNUNET_CRYPTO_EcdsaPublicKey *issuer, uint32_t result); -/** - * Iterator called on obtained result for an attribute issuance. - * - * @param cls closure - * @param result the record data that can be handed to the subject - */ -typedef void (*GNUNET_CREDENTIAL_IssueResultProcessor) (void *cls, - struct GNUNET_CREDENTIAL_AttributeRecordData *data); - /** * Iterator called on obtained result for an attribute delegation. * @@ -271,13 +257,11 @@ GNUNET_CREDENTIAL_remove_delegation (struct GNUNET_CREDENTIAL_Handle *handle, * @param attribute the name of the attribute * @return handle to the queued request */ -struct GNUNET_CREDENTIAL_Request * +struct GNUNET_CREDENTIAL_CredentialRecordData * GNUNET_CREDENTIAL_issue (struct GNUNET_CREDENTIAL_Handle *handle, - struct GNUNET_IDENTITY_Ego *issuer, + const struct GNUNET_CRYPTO_EcdsaPrivateKey *issuer, struct GNUNET_CRYPTO_EcdsaPublicKey *subject, - const char *attribute, - GNUNET_CREDENTIAL_IssueResultProcessor proc, - void *proc_cls); + const char *attribute); /** -- 2.25.1