Question

I am trying the code bellow. The thing is: some times work and some times doesn't! I am using the OpenSSL library, but I believe my mistake is something simple, C related.

int test_c(string to_sign, string key)
{
    const void* key_void = (const void*)key.c_str();
    int key_size = key.size();

    const unsigned char* data_char = (const unsigned char*)to_sign.c_str();
    int data_size = to_sign.size();

    unsigned int res_f_len = data_size*8;
    unsigned char* res_f = (unsigned char*) malloc(sizeof(unsigned char)*res_f_len);

    HMAC_CTX ctx;
    HMAC_CTX_init(&ctx);
    HMAC_Init_ex(&ctx, key_void, key_size, EVP_sha256(), NULL);
    HMAC_Update(&ctx, data_char, data_size);
    HMAC_Final(&ctx, res_f, &res_f_len);
    HMAC_CTX_cleanup(&ctx);

    return strlen(res_f);
}

When I say it doesn't work, I mean, for the same data and key, different results are returned!

Était-ce utile?

La solution

Rather than return strlen(res_f); as the length of the output buffer, you need to return res_f_len.

There are three things that could happen with strlen() in your code:

  • If the HMAC message digest has a byte that equals zero, strlen will return a length that's shorter than the HMAC message digest.
  • If the HMAC message digest has no zero bytes, then strlen will read beyond the message digest, leading to one of two outcomes:
    • strlen reads through garbage in memory after the message digest, eventually stopping on a random 0. strlen returns a value that's way too large.
    • If you're exceedingly lucky, the first byte after the message digest is 0, in which case strlen returns the actual length of the message digest.

So, only in the last scenario will you get the right value. That pretty much seems wrong.

It appears tht HMAC_Final does update the length argument you pass to it. (See the example in the top-voted answer to this StackOverflow question.) That's why you pass a pointer-to-int. You should just return this updated value.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top