Search code examples
copensslrsabignum

Why does the BN_bn2bin and BN_bin2bn not give me the same result if applied to an RSA key?


I m trying to create an RSA key (has type BIGNUM) and then turn it into a char* in order to send it over a client-server channel and then turn it again into a BIGNUM again. The problem is, when I do the double cast I do not get the original result. I have tried to simulate the problem with another BIGNUM created by me, but it seems to have the problem only with the RSA key. Here is the code I used for the tests

RSA *rsa;

rsa = RSA_generate_key(2048, 65535, NULL, NULL);
if (RSA_check_key(rsa) != 1)
{
    printf("error");
}
const BIGNUM    *rsa_n = BN_new(), // modulul
    *rsa_e = BN_new(), // exponentul public
    *rsa_d = BN_new(); // exponentul privat
RSA_get0_key(rsa, &rsa_n, &rsa_e, &rsa_d);

//TEST 1
unsigned char* rsa_n_char = (unsigned char*)malloc(BN_num_bytes(rsa_n));
BN_bn2bin(rsa_n, rsa_n_char);
BIGNUM *rsa_n2=BN_new();
BN_bin2bn(rsa_n_char, strlen((char*)rsa_n_char) + 1, rsa_n2);
printf("%d\n", BN_cmp(rsa_n2, rsa_n)); // output -1 -> not equal

//TEST 2
unsigned char*test1_char = (unsigned char*)malloc(6);
test1_char = (unsigned char*)"apple";
BIGNUM *test1 = BN_new(), *test2 = BN_new();
BN_bin2bn(test1_char, strlen((char*)test1_char)+1, test1);

unsigned char*test2_char = (unsigned char*)malloc(BN_num_bytes(test1));
BN_bn2bin(test1, test2_char);
BN_bin2bn(test2_char, strlen((char*)test2_char)+1, test2);
printf("%d\n", BN_cmp(test1, test2)); // output 0 ->  equal

Solution

  • You have a problem here:

    BN_bin2bn(rsa_n_char, strlen((char*)rsa_n_char) + 1, rsa_n2);
    

    The function strlen finds the length of a printable string by looking for a NUL terminator (0 byte). The data held in the buffer pointed to by rsa_n_char is not a printable string and is not NUL terminated. It is binary data - and may even contain the NUL (0) byte within it. You cannot use strlen for such data.

    It happens to work in your second test because the binary data you are working with happens to also be a printable string.