Search code examples
copenssl

Hash to Bignum - unsigned char[] to char *


I need to export the current hash value into a BIGNUM. I am using OpenSSL in C. When I try to do this operation and I print the content of h with BN_print I have 0 as output. As following the code snippet:

BIGNUM *h;
h = BN_new();
unsigned char hash[EVP_MAX_MD_SIZE];
unsigned hash_size = EVP_MAX_MD_SIZE;
EVP_DigestFinal_ex(hash_ctx, hash, &hash_size);
EVP_MD_CTX_free(hash_ctx);

// printing
for (unsigned n = 0; n < hash_size; n++) {
    printf("%02hhx", hash[n]);
}

BN_hex2bn(&h, hash);
printf("\n");
BN_print(bio_out, h);

The function BN_hex2bn(BIGNUM **a, const char *str); accepts in input a pointer to a BIGNUM and a pointer to the a const char. Do I need to convert it? If, yes, what could be the best approach?


Solution

  • BN_hex2bn takes the textual representation of the value. You must convert the hash to a textual representation in hex:

    unsigned char hash[EVP_MAX_MD_SIZE];
    unsigned hash_size = EVP_MAX_MD_SIZE;
    EVP_DigestFinal_ex(hash_ctx, hash, &hash_size);
    EVP_MD_CTX_free(hash_ctx);
    
    // hex conversion
    unsigned char hash_text[2 * EVP_MAX_MD_SIZE + 1];
    static char const hexdigits[16] = "0123456789abcdef";
    for (unsigned n = 0; n < hash_size; n++) {
        hash_text[2 * n + 0] = hexdigits[hash[n] >> 4];
        hash_text[2 * n + 1] = hexdigits[hash[n] & 15];
    }
    hash_text[2 * hash_size] = '\0';
    
    // printing
    printf("%s\n", hash_text);
    
    // BIGNUM conversion
    BIGNUM *h = BN_new();
    BN_hex2bn(&h, hash);
    BN_print(bio_out, h);
    

    You can also initialize the BIGNUM directly from big endian binary data with BN_bin2bn:

    // BIGNUM conversion
    BIGNUM *h = BN_new();
    BN_bin2bn(hash, hash_size, h);
    BN_print(bio_out, h);
    

    Or simpler:

    // BIGNUM conversion
    BIGNUM *h = BN_bin2bn(hash, hash_size, NULL);
    BN_print(bio_out, h);