2

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;
 }
Community
  • 1
  • 1
Ankit
  • 1,330
  • 2
  • 11
  • 16
  • "The console screen get closed automatically" ...Are you using Windows? The problem might be unrelated to your code. – Will Jun 20 '13 at 06:58
  • Yes. I am using this code on Visual studio 2010 – Ankit Jun 20 '13 at 06:59
  • After execution of that function call PEM_write_PrivateKey() program is automatically getting closed. – Ankit Jun 20 '13 at 07:01
  • 2
    Your code works for me, the private key is written to private.pem. – Remi Gacogne Jun 21 '13 at 07:47
  • Does it print that the key is not written? Do you write to handle pointing to a file that can be written? Did you flush? (sorry, could not resist that last sentence) – Maarten Bodewes Jun 23 '13 at 17:03
  • @Remi Gacogne: Ok, ty for trying this code. It is still not working on my pc :( – Ankit Jun 26 '13 at 06:56
  • @owlstead: No it is not printing that message --> printf("Private key is not written to file private.pem\n");. The code is terminating on the statement --> retValue = PEM_write_PrivateKey(fpPri, ppkey, NULL, NULL, 0, 0, NULL); Yes my file pointer is created with mode "w+", so i believe it must write key to the file private.pem – Ankit Jun 26 '13 at 07:00

3 Answers3

3

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.

plfoley
  • 111
  • 5
2

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 );
rahul k
  • 31
  • 4
0

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);
jcoffland
  • 5,238
  • 38
  • 43
  • Ty @jcoffland for replying. Used both SSL_library_init(); and fflush(fpPri); in my code but still I am getting the same problem. – Ankit Jul 15 '13 at 05:44