Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to load RSA key pair without p, q, etc

Tags:

c++

c

openssl

I'm trying to find a way of loading RSA key pair to Openssl using only n, e, d. According to the openssl documentation for the RSA those components (p, q, etc) can be NULL, but the only function for loading keys I managed to find is i2d_RSAPrivateKey / i2d_RSAPublicKey. Unfortunally these functions work only with keys in DER format.

So is there any way to load my keys (n, e, d) except coping them directly into the RSA structure?

like image 210
SkySurfer Avatar asked Nov 01 '22 14:11

SkySurfer


1 Answers

... these functions work only with keys in DER format.

OpenSSL's app.c has the code the utility uses to load keys from a file (for practical purposes, there's no difference between file or memory because you can use a different BIO). Its reproduced below, and it offers a number of formats.

So is there any way to load my keys (n, e, d) except coping them directly into the RSA structure?

What format are your keys in?


EVP_PKEY *load_key(BIO *err, const char *file, int format, int maybe_stdin,
                   const char *pass, ENGINE *e, const char *key_descrip)
{
    BIO *key=NULL;
    EVP_PKEY *pkey=NULL;
    PW_CB_DATA cb_data;

    cb_data.password = pass;
    cb_data.prompt_info = file;

    if (file == NULL && (!maybe_stdin || format == FORMAT_ENGINE))
    {
        BIO_printf(err,"no keyfile specified\n");
        goto end;
    }
#ifndef OPENSSL_NO_ENGINE
    if (format == FORMAT_ENGINE)
    {
        if (!e)
            BIO_printf(err,"no engine specified\n");
        else
        {
            pkey = ENGINE_load_private_key(e, file,
                                           ui_method, &cb_data);
            if (!pkey)
            {
                BIO_printf(err,"cannot load %s from engine\n",key_descrip);
                ERR_print_errors(err);
            }
        }
        goto end;
    }
#endif
    key=BIO_new(BIO_s_file());
    if (key == NULL)
    {
        ERR_print_errors(err);
        goto end;
    }
    if (file == NULL && maybe_stdin)
    {
#ifdef _IONBF
# ifndef OPENSSL_NO_SETVBUF_IONBF
        setvbuf(stdin, NULL, _IONBF, 0);
# endif /* ndef OPENSSL_NO_SETVBUF_IONBF */
#endif
        BIO_set_fp(key,stdin,BIO_NOCLOSE);
    }
    else
        if (BIO_read_filename(key,file) <= 0)
        {
            BIO_printf(err, "Error opening %s %s\n",
                       key_descrip, file);
            ERR_print_errors(err);
            goto end;
        }
    if (format == FORMAT_ASN1)
    {
        pkey=d2i_PrivateKey_bio(key, NULL);
    }
    else if (format == FORMAT_PEM)
    {
        pkey=PEM_read_bio_PrivateKey(key,NULL,
                                     (pem_password_cb *)password_callback, &cb_data);
    }
#if !defined(OPENSSL_NO_RC4) && !defined(OPENSSL_NO_RSA)
    else if (format == FORMAT_NETSCAPE || format == FORMAT_IISSGC)
        pkey = load_netscape_key(err, key, file, key_descrip, format);
#endif
    else if (format == FORMAT_PKCS12)
    {
        if (!load_pkcs12(err, key, key_descrip,
                         (pem_password_cb *)password_callback, &cb_data,
                         &pkey, NULL, NULL))
            goto end;
    }
#if !defined(OPENSSL_NO_RSA) && !defined(OPENSSL_NO_DSA) && !defined (OPENSSL_NO_RC4)
    else if (format == FORMAT_MSBLOB)
        pkey = b2i_PrivateKey_bio(key);
    else if (format == FORMAT_PVK)
        pkey = b2i_PVK_bio(key, (pem_password_cb *)password_callback,
                           &cb_data);
#endif
    else
    {
        BIO_printf(err,"bad input format specified for key file\n");
        goto end;
    }
end:
    if (key != NULL) BIO_free(key);
    if (pkey == NULL)
    {
        BIO_printf(err,"unable to load %s\n", key_descrip);
        ERR_print_errors(err);
    }
    return(pkey);
}
like image 94
jww Avatar answered Nov 14 '22 11:11

jww