2

Here is the code snippet I have now and it is working well

/* Generate key */
if (EVP_PKEY_keygen(ctx, &pkey) <= 0)
    goto cleanup;


// write rsa private key to file
bio_private = BIO_new_file("private_new.pem", "w+");
ret = PEM_write_bio_PrivateKey(bio_private, pkey, NULL, NULL, 0, NULL, NULL);
if (ret != 1) {
    goto cleanup;
}
BIO_flush(bio_private);

// write rsa public key to file
bio_public = BIO_new_file("public_new.pem", "w+");

ret = PEM_write_bio_PUBKEY(bio_public, pkey);
if (ret != 1) {
    goto cleanup;
}
BIO_flush(bio_public);

instead of using

PEM_write_bio_PrivateKey(bio_private, pkey, NULL, NULL, 0, NULL, NULL);

I want the generated key text to be put into a string and NOT a file. I don't want it written to disk, just to a string in memory. Is there a PEM_ function to do this? or any other way? Thanks a lot for your help

jww
  • 97,681
  • 90
  • 411
  • 885
seedhom
  • 349
  • 2
  • 6
  • 19
  • 1
    Very close to a duplicate of [How to get PEM encoded X509 certificate as C++ string using openssl?](http://stackoverflow.com/q/6877588/608639), [Convert OpenSSL x509 data to std::string](http://stackoverflow.com/q/39968558/608639), [How to get PKCS7_sign result into a char * or std::string](http://stackoverflow.com/q/38077226/608639), etc. They are using `std::strings` instead of C strings. If using C strings, then be careful of embedded NULLs. – jww Mar 14 '17 at 15:11

2 Answers2

4

Use

bio_private = BIO_new(BIO_s_mem());

instead of

bio_private = BIO_new_file("private_new.pem", "w+");

as seen here.

You can use long BIO_get_mem_data(BIO *b, char **pp) to access the data in the BIO:

BIO_get_mem_data() sets pp to a pointer to the start of the memory BIOs data and returns the total amount of data available. It is implemented as a macro.

Artjom B.
  • 61,146
  • 24
  • 125
  • 222
0

Thanks for Artjom's answer above. It worked! Here is the relevant code with the change :

/* Generate key */
if (EVP_PKEY_keygen(ctx, &pkey) <= 0)
    goto cleanup;

// write private key to memory
bio_private = BIO_new(BIO_s_mem());
ret = PEM_write_bio_PrivateKey(bio_private, pkey, NULL, NULL, 0, NULL, NULL);
if (ret != 1)
{
goto cleanup;
}
BIO_flush(bio_private);

BIO_get_mem_data(bio_private, &private_key_text);
cout << "PRIVE KEY :\n" << private_key_text << endl;
// write public key to memory
bio_public = BIO_new(BIO_s_mem());    
ret = PEM_write_bio_PUBKEY(bio_public, pkey);
if (ret != 1)
{
goto cleanup;
}
BIO_flush(bio_public);

BIO_get_mem_data(bio_public, &public_key_text);

cout << "PUBLIC KEY :\n" << public_key_text << endl;
seedhom
  • 349
  • 2
  • 6
  • 19
  • If `private_key_text` is a binary representation of the key, then you cannot simply treat it as a string. Binary data may contain `\0` which is the string end character. So, it might happen that you print an incomplete key. The same goes for the public key. – Artjom B. Mar 13 '17 at 22:12
  • you are right, but this is just to test that the code worked. I don't intend to print it out, I intend to use in-memory while the server is up and running, then re-generate it on re-start of the server. Thanks a lot! – seedhom Mar 13 '17 at 22:19