Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

How can I load a PEM key stored in a string instead from a file?

2,135 views
Skip to first unread message

Leandro Santiago

unread,
Oct 26, 2010, 12:49:54 PM10/26/10
to
Hello to all.

I'm using the openssl api in a C application.

Currently to load a private key (generated by openssl command), I do:

_privKeyFile = fopen(filename, "rt");

_privKey = PEM_read_PrivateKey(_privKeyFile, NULL, NULL, NULL);

_rsa = EVP_PKEY_get1_RSA(_privKey);

The _rsa is the object I need to decrypt my data.

But now I need do keep the private key in a database, and not in files
anymore. In database I store these keys in a common plain text format
and I can't use the filesystem.

So imagine I have key as char[]. How can I get a EVP_PKEY object from
a key that is a string?
______________________________________________________________________
OpenSSL Project http://www.openssl.org
User Support Mailing List openss...@openssl.org
Automated List Manager majo...@openssl.org

Wim Lewis

unread,
Oct 26, 2010, 1:23:34 PM10/26/10
to
PEM_read_PrivateKey() is a wrapper around PEM_ASN1_read() (which reads an arbitrary ASN.1 object from a PEM-encoded blob) and d2i_PrivateKey() (which knows how to read a private key blob specifically).

PEM_ASN1_read() simply creates a BIO from the FILE* that you give it, and calls PEM_ASN1_read_bio(). If you want, you can instead create a BIO from your string using something like BIO_new_mem_buf() and call PEM_ASN1_read_bio() yourself. (A BIO is an openssl object that's like a more general-purpose FILE*.)

BTW, if your keys are stored in a database, there's probably no need for them to be PEM-encoded; you can save a bit of space and time by storing them in DER format and calling d2i_PrivateKey() directly. (PEM format is more or less just base64-encoded DER.) There's a FAQ entry on this:
http://www.openssl.org/support/faq.html#PROG3

Leandro Santiago

unread,
Oct 26, 2010, 9:47:25 PM10/26/10
to
Sorry. I don't understand everything. Do you have any code example?
I've tried to read the source code of these functions, but
PEM_read_PrivateKey is a macro (and I hate read big macros) :-(

2010/10/26 Wim Lewis <wi...@omnigroup.com>:

Michael S. Zick

unread,
Oct 27, 2010, 8:16:54 AM10/27/10
to
On Tue October 26 2010, Leandro Santiago wrote:
> Sorry. I don't understand everything. Do you have any code example?
> I've tried to read the source code of these functions, but
> PEM_read_PrivateKey is a macro (and I hate read big macros) :-(
>

gcc -E ... >output.txt
Is your answer to that complaint.

Mike

Leandro Santiago

unread,
Oct 27, 2010, 10:42:09 AM10/27/10
to
Ok. I've found the implementation of that function:

EVP_PKEY *PEM_read_PrivateKey(FILE *fp, EVP_PKEY **x, pem_password_cb
*cb, void *u)
{
BIO *b;
EVP_PKEY *ret;

if ((b=BIO_new(BIO_s_file())) == NULL)
{
PEMerr(PEM_F_PEM_READ_PRIVATEKEY,ERR_R_BUF_LIB);
return(0);
}
BIO_set_fp(b,fp,BIO_NOCLOSE);
ret=PEM_read_bio_PrivateKey(b,x,cb,u);
BIO_free(b);
return(ret);
}

So if I need to implement a function which opens a char string as a
key I need to write something as the code above, but changing the
functions BIO_s_file() and BIO_set_fp(b,fp,BIO_NOCLOSE) to something
which load from that string instead from a FILE*?

ps: yes, I'm very noob on openssl. OpenSSL is amazing, but it's very
hard to beginners. thx

2010/10/27 Michael S. Zick <ope...@morethan.org>:

Dr. Stephen Henson

unread,
Oct 27, 2010, 10:59:53 AM10/27/10
to
On Wed, Oct 27, 2010, Leandro Santiago wrote:

> Ok. I've found the implementation of that function:
>
> EVP_PKEY *PEM_read_PrivateKey(FILE *fp, EVP_PKEY **x, pem_password_cb
> *cb, void *u)
> {
> BIO *b;
> EVP_PKEY *ret;
>
> if ((b=BIO_new(BIO_s_file())) == NULL)
> {
> PEMerr(PEM_F_PEM_READ_PRIVATEKEY,ERR_R_BUF_LIB);
> return(0);
> }
> BIO_set_fp(b,fp,BIO_NOCLOSE);
> ret=PEM_read_bio_PrivateKey(b,x,cb,u);
> BIO_free(b);
> return(ret);
> }
>
> So if I need to implement a function which opens a char string as a
> key I need to write something as the code above, but changing the
> functions BIO_s_file() and BIO_set_fp(b,fp,BIO_NOCLOSE) to something
> which load from that string instead from a FILE*?
>
> ps: yes, I'm very noob on openssl. OpenSSL is amazing, but it's very
> hard to beginners. thx
>

As others have indicated you can use PEM_read_bio_PrivateKey() instead as
this can be passed a BIO which is an OpenSSL I/O abstraction. You can create a
BIO from a character string using BIO_new_mem_buf().

Steve.
--
Dr Stephen N. Henson. OpenSSL project core developer.
Commercial tech support now available see: http://www.openssl.org

Leandro Santiago

unread,
Oct 29, 2010, 7:26:21 AM10/29/10
to
Thanks to all. I've resolved my first problem, load the PEM from a string.
I've used BIO_new_mem_buf() and PEM_read_bio_PrivateKey().

But now I've seen that it works well with PEM keys, and now I'm trying
to use a DER key, again from a string. Is there something like
DER_read_bio_PrivateKey()?

2010/10/27 Dr. Stephen Henson <st...@openssl.org>:

Erik Tkal

unread,
Oct 29, 2010, 10:12:34 AM10/29/10
to
How about using the d2i_ functions?


....................................
Erik Tkal
Juniper OAC/UAC/Pulse Development

Leandro Santiago

unread,
Oct 29, 2010, 12:48:31 PM10/29/10
to
Thank you very much!

I've used d2i_PrivateKey_bio() with the BIO I get from the key buffer.

2010/10/29 Erik Tkal <et...@juniper.net>:

0 new messages