Ankit
Ankit

Reputation: 1418

PEM_write_PrivateKey() function is not storing the RSA private key in private.pem file

This is the code i am using by taking reference of stack overflow questions asked by other users from here. But when i am trying to use PEM_write_PrivateKey() function to write the private keys into the file. It is not doing it. The console screen get closed automatically after this function call. And the private.pem file doesn't contains anything.

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <openssl/evp.h>
#include <openssl/rsa.h>
#include <openssl/bio.h>
#include <openssl/pem.h>
#include <openssl/objects.h>
#include <openssl/err.h>
#include <openssl/x509.h>

int main()
{

//
// Local variables definition
//
EVP_PKEY_CTX    *evp_ctx    = NULL;
EVP_PKEY        *ppkey      = NULL;
FILE            *fpPri      = NULL;
FILE            *fpPub      = NULL;
int             retValue    = 1;

for (;;)
{
    //
    // Function allocates public key algorithm context using the algorithm
    // specified by id
    //
    evp_ctx = EVP_PKEY_CTX_new_id(EVP_PKEY_RSA, NULL);
    if (NULL == evp_ctx)
    {
        printf("RSA Public key algorithm context is not allocated\n");
        break;
    } // if
    printf("RSA Public key algoritm context allocated\n");

    //
    // Function initializes a public key algorithm context using key pkey
    // for a key genration operation
    //
    retValue = EVP_PKEY_keygen_init(evp_ctx);
    if (1 != retValue)
    {
        printf("Initialization of public key alogorithm context failed\n");
        break;
    } // if
    printf("Public key alogorithm context initialized\n");

    //
    // Setting RSA key bit to 2048
    //
    retValue = EVP_PKEY_CTX_set_rsa_keygen_bits(evp_ctx, 2048);
    if (1 != retValue)
    {
        printf("RSA key bits not set to 2048\n");
        break;
    } // if
    printf("RSA key bits set to 2048\n");

    //
    // Function performs a key generation operation
    //
    retValue = EVP_PKEY_keygen(evp_ctx, &ppkey);
    if (1 != retValue)
    {
        printf("Key generation operation failed\n");
        break;
    } // if
    printf("Key generated successfully\n");

    //
    // Creating a file to store RSA private key
    //
    fpPri = fopen("./private.pem", "w+");
    if (NULL == fpPri)
    {
        printf("File pointer of private.pem file is not opened\n");
        break;
    } // if
    printf("File pointer or private.pem file opened\n");

    retValue = PEM_write_PrivateKey(fpPri, ppkey, NULL, NULL, 0, 0, NULL);
    if (1 != retValue)
    {
        printf("Private key is not written to file private.pem\n");
        break;
    } // if
    printf("Private key written to file private.pem\n");

    //
    // Final break statement
    //
    break;
} // for

//
// Releasing all the memory allocations and the handles
//

getchar();

return 0;
 }

Upvotes: 2

Views: 4494

Answers (3)

rahul k
rahul k

Reputation: 31

use PEM_write_bio_RSAPrivateKey() insted of PEM_write_PrivateKey() for writing private key to a file

    BIO* pOut = BIO_new_file( "key.pem", "w");
    if (!pOut)
    {
        return false;
    }
    /* Write the key to disk. */
    if( !PEM_write_bio_RSAPrivateKey( pOut, pRSA, NULL, NULL, 0, NULL, NULL))
    {
        return false;
    }
    BIO_free_all( pOut );
    /* Open the PEM file for writing the certificate to disk. */
    BIO * x509file = BIO_new_file( "cer.pem", "w" );
    if (!x509file )
    {
        return false;
    }
    if (!PEM_write_bio_X509( x509file, pX509Cert ))
    {
        return false;
    }
    BIO_free_all( x509file );

Upvotes: 2

plfoley
plfoley

Reputation: 111

I'm not exactly sure this is related to your issue but I encountered a similar problem and ended up on this page while trying to figure out what the problem could be. So I thought I'd share my findings hoping it will help someone. I also saw on some other forums that people ran into the same issue I encountered.

The issue: The application exits without any error code when calling PEM_write_PrivateKey on an application compiled using Visual Studio 2015. The same application and code works fine when compiled with VS2010.

I first discovered that Microsoft did some breaking changes to the FILE handle in VS2015.

FILE Encapsulation In previous versions, the FILE type was completely defined in , so it was possible for user code to reach into a FILE and modify its internals. The stdio library has been changed to hide implementation details. As part of this, FILE as defined in is now an opaque type and its members are inaccessible from outside of the CRT itself. https://msdn.microsoft.com/en-us/library/bb531344%28v=vs.140%29.aspx?f=255&MSPPError=-2147217396

By debugging in OpenSSL I figured out that the handler "APPLINK_FSETMOD" was set to "unsupported". This led me to read on the AppLink technology implemention in OpenSSL.

This led me to discover that the solution to my problem was to add the following code in my application.

#include "openssl/applink.c" 

Important: You must put the include in one of the .exe source file because GetModuleHandle is passed NULL.

Upvotes: 3

jcoffland
jcoffland

Reputation: 5431

Perhaps it's because you never called SSL_library_init().

Also, your buffered file is probably not getting flushed before the program exits. Before the end of the program you should call:

fflush(fpPri);

Upvotes: 0

Related Questions