Error while using API PEM_read_bio_RSAPrivateKey

classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view
|

Error while using API PEM_read_bio_RSAPrivateKey

sajalmalhotra
This post has NOT been accepted by the mailing list yet.
Hi,

In our application, we have been using openssl 0.9.8 and trying to move to openssl-1.0.1j. we have application to generate RSA key using below set of API in openssl 0.9.8.
1. RSA_generate_key(2048,65537,NULL,NULL)
2. EVP_PKEY_assign_RSA
3. PEM_write_bio_PrivateKey [To get EVP_PKEY  output]
4. PEM_read_bio_PrivateKey[as output we get EVP_PKEY, which is further used in CMP IR request]
After these API our application get RSA private key.

Same sets of API called in openssl-1.0.1, but output of private key is not RSA.

I have some modification in API calling of our application.

First Apporach:-
1. RSA_generate_key(2048,65537,NULL,NULL)
2. EVP_PKEY_set1_RSA
3. PEM_write_bio_PrivateKey[To get EVP_PKEY  output]
But still private key is not RSA type.
Sample program:-
#include<stdio.h>
#include"/home/amit_cmp/openssl/include/openssl/rsa.h"
#include<string.h>
#include<stdbool.h>
int main()
{
        char *plain="Sample text"; //Sample text (plain text) to Encrypt/Decrypt
        char *ciphertext;
        const int kBits = 1024;
        const int kExp = 3;
        FILE *fp = NULL;
        fp = fopen("/home/amit_cmp/openssl/include/test.txt", "a+");
        time_t now;
        time(&now);
        if (fp != NULL)
        {
                fprintf(fp, "funs[%s] :: Line[%d] ::Time %s \n", __func__, __LINE__, ctime(&now));
                fflush(fp);
        }
        long keylen;
        char *pem_key;
        printf("%s\n",plain);
        RSA *rsa1= RSA_generate_key(2048,65537,NULL,NULL);
        if(rsa1==NULL)
                printf("NO RSA!\n");
        else
        {
                printf("RSA OK!\n");
                ciphertext = (char *)malloc(RSA_size(rsa1));
                printf("rsa key = %d\n",rsa1);
                printf("RSA size = %d\n",RSA_size(rsa1));

                EVP_PKEY *pKey = EVP_PKEY_new();
                if(pKey)
                {
                        printf("EVP_PKEY_NEW SUCCESS\n");
                        EVP_PKEY_set1_RSA(pKey,rsa1);

                        BIO *bio = BIO_new(BIO_s_mem());
                        if(bio)
                        {
                                printf("BIO_new SUCCESS\n");
                                bool success = false;
                                success = PEM_write_bio_PrivateKey(bio, pKey, NULL, NULL, 0, 0, NULL);
                                if(success)
                                {
                                        printf("PEM_write_bio_PrivateKey SUCCESS\n");
                                        char *pKeyMem = NULL;
                                        long base64KeyLength = BIO_get_mem_data(bio, &pKeyMem);
                                        printf("base64KeyLength[%lu]\n", base64KeyLength);

                                        char *pem_key;
                                        int keylen = BIO_pending(bio);
                                        pem_key = calloc(keylen+1, 1); /* Null-terminate */
                                        BIO_read(bio, pem_key, keylen);

                                        printf("%s", pem_key);
                                        printf("%d\n", keylen);
                                }
                                else
                                {
                                        printf("PEM_write_bio_PrivateKey ERROR\n");
                                }
                        }
                        else
                        {
                                printf("BIO_new error\n");
                        }
                }
                else
                {
                        printf("EVP_PKEY_NEW error\n");
                }
        }
        RSA_free(rsa1);
}


Second Apporach:-
Now we try to use PEM_write_bio_RSAPrivateKey API in our application, and private key is generated is RSA type.
But in our application, we calling API PEM_read_bio_PrivateKey()[as we need output of EVP_PKEY type, which is further used in CMP IR request], but we getting error at following function.
PEM_read_bio_PrivateKey[File Name  - pem_pkey.c]-> PEM_bytes_read_bio[File Name  - pem_lib.c]
for (;;)
        {
        if (!PEM_read_bio(bp,&nm,&header,&data,&len)) {
            if(ERR_GET_REASON(ERR_peek_error()) ==
                PEM_R_NO_START_LINE)
                ERR_add_error_data(2, "Expecting: ", name);
            return 0;
        }

Also try to use PEM_read_bio_RSAPrivateKey, getting error at same point.

Sample program:-
#include<stdio.h>
#include"/home/amit_cmp/openssl/include/openssl/rsa.h"
#include<string.h>
#include<stdbool.h>
int main()
{
        char *plain="Sample text"; //Sample text (plain text) to Encrypt/Decrypt
        char *ciphertext;
        const int kBits = 1024;
        const int kExp = 3;
        long keylen;
        printf("%s\n",plain);
        RSA *rsa1= RSA_generate_key(2048,65537,NULL,NULL);
        if(rsa1==NULL)
                printf("NO RSA!\n");
        else
        {
                printf("RSA OK!\n");
                ciphertext = (char *)malloc(RSA_size(rsa1));
                printf("rsa key = %d\n",rsa1);
                printf("RSA size = %d\n",RSA_size(rsa1));

                printf("RSA_NEW SUCCESS\n");

                BIO *bio = BIO_new(BIO_s_mem());
                if(bio)
                {
                        printf("BIO_new SUCCESS\n");
                        bool success = false;
                        success = PEM_write_bio_RSAPrivateKey(bio, rsa1, NULL, NULL, 0, NULL, NULL);
                        if(success)
                        {
                                printf("PEM_write_bio_PrivateKey SUCCESS\n");
                                char *pKeyMem = NULL;
                                long base64KeyLength = BIO_get_mem_data(bio, &pKeyMem);

                                char *pem_key;
                              int keylen = BIO_pending(bio);
                              pem_key = calloc(keylen+1, 1); /* Null-terminate */
                              BIO_read(bio, pem_key, keylen);
                              printf("%s", pem_key);
                              printf("%d\n", keylen);
                                if (base64KeyLength >0)
                                {
                                        printf("base64KeyLength[%lu]\n", base64KeyLength);
                                        printf("[%d]\n", BIO_pending(bio));
                                        RSA *pktmp;
                                        printf("[%d]\n", BIO_pending(bio));
                                        pktmp = PEM_read_bio_PrivateKey(bio, NULL, NULL, NULL);
                                        if(pktmp)
                                        {
                                                printf("PEM_read_bio_PrivateKey SUCCESS\n");
                                        }
                                        else
                                        {
                                                printf("PEM_read_bio_PrivateKey ERROR[%d]\n", BIO_pending(bio));
                                        }

                                }
                                else
                                {
                                        printf("base64KeyLength ERROR\n");
                                }
                        }
                        else
                        {
                                printf("PEM_write_bio_PrivateKey ERROR\n");
                        }
                }
                else
                {
                        printf("BIO_new error\n");
                }
        }
        RSA_free(rsa1);
}

We want to know, how to read privatekey using “PEM_read_bio_PrivateKey()”.
Thank you in advance and hoping to get reply soon.

Thanks
Sajal Malhotra