C++ OpenSSL RSA_free give Segmentation fault if EVP_PKEY_free is also used

kel*_*aka 2 c++ openssl cryptography rsa

I'm writing a small program to test an old issue on RSA. I need to access the prime factors of the modulus. So my code is

int RSAKeyGen(int keySize) {

      EVP_PKEY *pkey  = EVP_PKEY_new();

      BIGNUM *bn = BN_new();
      BN_set_word(bn, RSA_F4);

      RSA *rsa = RSA_new();
      RSA_generate_key_ex(rsa, keySize, bn, NULL);

      EVP_PKEY_assign_RSA(pkey, rsa);

      const BIGNUM *p;
      const BIGNUM *q;

      RSA_get0_factors(rsa, &p,&q);

      BN_print_fp(stdout, p);
      puts("\n");
      BN_print_fp(stdout, q);

      RSA_free(rsa);
      EVP_PKEY_free(pkey);
      BN_free(bn);

      return 0;
}
Run Code Online (Sandbox Code Playgroud)

Having both EVP_PKEY_free(pkey); and RSA_free(rsa); gives

`Segmentation fault (core dumped)`
Run Code Online (Sandbox Code Playgroud)

commenting one of them is working fine, except may be something is not freed. Changed the order but did not worked.

  • Does only one of them is enough to work correctly?

Mat*_*ell 5

请参阅此处的文档EVP_PKEY_assign_RSA

https://www.openssl.org/docs/man1.1.1/man3/EVP_PKEY_assign_RSA.html

正如该页面所述:

EVP_PKEY_assign_RSA()、EVP_PKEY_assign_DSA()、EVP_PKEY_assign_DH()、EVP_PKEY_assign_EC_KEY()、EVP_PKEY_assign_POLY1305() 和 EVP_PKEY_assign_SIPHASH() 还将引用的密钥设置为 key,但是它们在内部使用提供的密钥,因此当父 pkey 被释放时,密钥将被释放。

换句话说,通过EVP_PKEY_assign_RSA()调用分配的密钥的所有权将转移到 EVP_PKEY。当您释放它时,EVP_PKEY它也会释放底层RSA密钥。因此,一旦成功调用,EVP_PKEY_assign_RSA()就不能调用RSA_free()底层密钥,否则可能会导致双重释放。