Search code examples
c++openssl

Check if given keypair is valid C++


I want to check if the given key pair is valid, I had found solution, but it didn't work because object of the RSA class doesn't have parameter n.

#include <openssl/rsa.h>
#include <openssl/pem.h>

int main() {

    RSA *pubkey = PEM_read_RSA_PUBKEY(...);
    RSA *privkey = PEM_read_RSAPrivateKey(...);

    if (!BN_cmp(pubkey->n, privkey->n)) {
        // same modulus, so the keys match
    }

    return 0;
}

How to solve my problem, or is there another way to test if the key pair is valid?


Solution

  • OpenSSL 3.x

    OpenSSL 3.x provides EVP_PKEY_get_bn_param. It can be used like this (error handling for reading the keys etc. has to be added accordingly of course):

    #include <openssl/rsa.h>
    #include <openssl/pem.h>
    #include <openssl/evp.h>
    #include <openssl/core_names.h>
    ...
        EVP_PKEY *priv_key= NULL, *pub_key= NULL;
        BIGNUM *rsa_pub_n = NULL, *rsa_priv_n = NULL;
    ...
        PEM_read_PUBKEY(fp_pub, &pub_key, NULL, NULL)
        PEM_read_PrivateKey(fp_priv, &priv_key, NULL, NULL)
    ...
        //extract n with EVP_PKEY_get_bn_param for the keys...
        if (EVP_PKEY_is_a(priv_key, "RSA")) {
            if (!EVP_PKEY_get_bn_param(priv_key, OSSL_PKEY_PARAM_RSA_N, &rsa_priv_n)) {
                //error message and exit
        }
        //finally compare with BN_cmp
    
    

    See documentation here: https://www.openssl.org/docs/man3.0/man3/EVP_PKEY_get_bn_param.html

    OpenSSL 1.x

    For OpenSSL 1.x the function RSA_get0_key can be used. Please note that this function is marked as deprecated in OpenSSL 3.x.

    #include <openssl/rsa.h>
    #include <openssl/pem.h>
    ...
        BIGNUM *rsa_pub_n = NULL, *rsa_priv_n = NULL;
    ...
        RSA *pub = RSA_new();
        PEM_read_RSA_PUBKEY(fp_pub, &pub, NULL, NULL)
        RSA *priv = RSA_new();
        PEM_read_RSAPrivateKey(fp_priv, &priv, NULL, NULL)
    ...
        RSA_get0_key(pub, &rsa_pub_n, NULL, NULL);
        RSA_get0_key(priv, &rsa_priv_n, NULL, NULL);
        ...
        //finally compare with BN_cmp
    

    Make sure to check the return codes for each function and add proper error handling.

    More information here: https://www.openssl.org/docs/manmaster/man3/RSA_get0_key.html