help-gnunet
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Help with hashing and signatures


From: Schanzenbach, Martin
Subject: Re: Help with hashing and signatures
Date: Tue, 4 Aug 2020 16:21:54 +0200

Hi Alessio,

it is difficult helping without all of the code.
However, from what you posted is not clear at all where the error could be.
There is not necessarily anything wrong with your use of the crypto.

Questions I would ask are:

- Have you verified that the public key is still the same key in the 
verification step as it was in the signing step?
- If yes, is the signature the same string that you "sent"?

If any of the above is not true, your (de)serialization functions are buggy 
(extract_sig/key or the equivalend encoding functions).

BR

> On 4. Aug 2020, at 15:13, Alessio Vanni <vannilla@firemail.cc> wrote:
> 
> Hello,
> 
> I have a function used to sign some data and embed it in a larger
> structure, defined like so:
> 
>     int
>     sign_data(container, public_key, private_key) { ... }
> 
> (the type of the arguments are not included because they are not
> important; the keys are the GNUnet structs used by egos.)
> 
> The function hashes the data inside the container using GNUnet's hashing
> contexts and then signs the hash with the ECDSA signing functions.  The
> problem is that when I do the reverse, i.e. verifying the signature, I'm
> always getting a bad signature error.
> 
> The verify function is defined as:
> 
>     int
>     verify_signature(container) { ... }
> 
> in which `container' contains the signature and the public key of the
> signing entity.
> 
> Both functions hash the data using the following snippet (`msg' is the
> formal name of `container' in the actual function.)
> 
>     #define MAXBYTES 8192
>     struct SignatureData *sd = GNUNET_new(struct SignatureData);
> 
>     size_t segments = (msg->data_size / MAXBYTES) + 1;
>     struct GNUNET_HashContext *hc = GNUNET_CRYPTO_hash_context_start();
> 
>     if (1 == segments) {
>         GNUNET_CRYPTO_hash_context_read(hc, msg->data, msg->data_size);
>     } else {
>         size_t cursor = 0;
>         for (size_t i=0; i<segments; ++i) {
>              size_t mult = i * MAXBYTES;
>              size_t sz = (msg->data_size - mult > MAXBYTES) ?
>                   MAXBYTES :
>                   msg->data_size - mult;
> 
>              GNUNET_CRYPTO_hash_context_read(hc, msg->data+cursor, sz);
>              cursor += sz;
>         }
>     }
> 
>     GNUNET_CRYPTO_hash_context_finish(hc, &sd->hash);
> 
>     sd->purpose.size = htonl(sizeof(struct SignatureData));
>     sd->purpose.purpose = htonl(SIGN_PURPOSE);
> 
> where `struct SignatureData' is defined as such:
> 
>     struct SignatureData {
>          struct GNUNET_CRYPTO_EccSignaturePurpose purpose;
>          struct GNUNET_HashCode hash;
>     };
> 
> After hashing the data, the signing function does this:
> 
>     struct GNUNET_CRYPTO_EcdsaSignature sig;
>     GNUNET_CRYPTO_ecdsa_sign(private_key, sd, &sig);
>     char *sstr = GNUNET_STRINGS_data_to_string_alloc(&sig, sizeof(sig));
> 
> `sstr' is then embedded in the container as explained earlier.
> 
> The verifying function first extracts the public key and the signature
> from the container, like so:
> 
>     struct GNUNET_CRYPTO_EcdsaPublicKey pk;
>     char *pkstr = extract_key(msg);
>     size_t pklen = strlen(pkstr);
>     GNUNET_CRYPTO_ecdsa_public_key_from_string(pkstr, pklen, &pk);
> 
>     struct GNUNET_CRYPTO_EcdsaSignature sig;
>     char *sigstr = extract_sig(msg);
>     size_t siglen = strlen(sigstr);
>     GNUNET_STRINGS_string_to_data(sigstr, siglen, &sig, sizeof(sig));
> 
> After that it hashes the data with the same code as above and then
> executes these statements:
> 
>     if (GNUNET_OK != GNUNET_CRYPTO_ecdsa_verify(SIGN_PURPOSE,
>                                                sd,
>                                                &sig,
>                                                &pk)) {
>         ERRLOG(_("Message not verified!\n"));
>         GNUNET_free(sd);
>         return GNUNET_NO;
>     }
> 
> The error happens here, as I'm always getting the error message and a
> return value of GNUNET_NO.
> 
> I don't really know what I'm doing wrong here and the documentation
> unfortunately isn't helpful at all, as the comments before the
> `GNUNET_CRYPTO_ecdsa_verify' function isn't even about that function
> (they list arguments that the function doesn't use.)  I'd really
> appreciate some guidance here.
> 
> Thank you,
> A.V.
> 

Attachment: signature.asc
Description: Message signed with OpenPGP


reply via email to

[Prev in Thread] Current Thread [Next in Thread]