LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Programming (http://www.linuxquestions.org/questions/programming-9/)
-   -   OpenSSL Public Key Issue (http://www.linuxquestions.org/questions/programming-9/openssl-public-key-issue-818548/)

delite 07-07-2010 01:15 PM

OpenSSL Public Key Issue
 
Hi, i'm just starting out with OpenSSL. I've worked up a little example to generate a RSA key pair and save it into both private and public PEM files.

All seems ok, but then i'm try to use it with actual openssl and get the following error:
Code:

unable to load Public Key
I'm testing with:
Code:

openssl rsautl -encrypt -pubin -inkey pub.pem -in plain.txt -out cipher.txt
And here's my code...

Code:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <openssl/pem.h>

static void callback(int p, int n, void *arg)
{
        char c='B';

        if (p == 0) c='.';
        if (p == 1) c='+';
        if (p == 2) c='*';
        if (p == 3) c='\n';
        fputc(c,stderr);
}

int main (int argc, char *argv[])
{
        char *file_pem = "priv.pem";
        char *file_pem_pub = "pub.pem";
        FILE *fp;
       
        int bits = 512;        //        512, 1024, 2048, 4096
        unsigned long exp = RSA_F4;        //        RSA_3
       
        RSA *rsa;
       
        //        GENERATE KEY
        rsa=RSA_generate_key(bits,exp,callback,NULL);
       
        //        WRITE PRIVATE KEY
        if(!(fp = fopen(file_pem, "w"))){
                fprintf(stderr, "Error opening PEM file %s\n", file_pem);
                exit(1);
        }
       
        unsigned char *kstr = "password";
        if(!PEM_write_RSAPrivateKey(fp,rsa,EVP_des_ede3_cbc(),kstr,strlen(kstr),NULL,NULL)){
                fprintf(stderr, "Error writing PEM file %s\n", file_pem);
                exit(1);
        }
        close(fp);
       
        //        WRITE PUBLIC KEY
        if(!(fp = fopen(file_pem_pub, "w"))) {
                fprintf(stderr, "Error opening PEM file %s\n", file_pem_pub);
                exit(1);
        }
       
        if(!PEM_write_RSAPublicKey(fp, rsa)){
                fprintf(stderr, "Error writing PEM file %s\n", file_pem_pub);
                exit(1);
        }
        close(fp);
       
        RSA_free(rsa);
       
        return 0;
}

Do you know if it's the openssl command that mismatches what the code does, or if it's an error / issue with the code itself?

EDIT:
Here's a makefile...
Code:

CC=cc
CFLAGS= -g -I../../include
LIBS= -lcrypto -lssl

EXAMPLES=main

all: $(EXAMPLES)

main: main.o
        $(CC) -o run main.o $(LIBS)

clean:       
        rm -f $(EXAMPLES) *.o


delite 07-07-2010 08:46 PM

Right, I have some sort of solution...

Code:

#include <stdio.h>
#include <stdlib.h>
#include <openssl/pem.h>

static void callback(int p, int n, void *arg)
{
        char c='B';
        if (p == 0) c='.';
        if (p == 1) c='+';
        if (p == 2) c='*';
        if (p == 3) c='\n';
        fputc(c,stderr);
}

int main (int argc, char *argv[])
{
        char *file_pem = "priv.pem";
        char *file_pem_pub = "pub.pem";
        FILE *fp;
       
        int bits = 512;        //        512, 1024, 2048, 4096
        unsigned long exp = RSA_F4;        //        RSA_3
       
        RSA *rsa;
        EVP_PKEY *pkey;
       
        //        GENERATE KEY
        rsa=RSA_generate_key(bits,exp,callback,NULL);
        if(RSA_check_key(rsa)!=1){
                fprintf(stderr, "Error whilst checking key.\n");
                exit(1);
        }
       
        //        ADD KEY TO EVP
        pkey = EVP_PKEY_new();
        EVP_PKEY_assign_RSA(pkey, rsa);
       
        //        WRITE PRIVATE KEY
        if(!(fp = fopen(file_pem, "w"))) {
                fprintf(stderr, "Error opening PEM file %s\n", file_pem);
                exit(1);
        }
        if(!PEM_write_PrivateKey(fp, pkey, NULL,NULL,0,NULL,NULL)){
                fprintf(stderr, "Error writing PEM file %s\n", file_pem);
                exit(1);
        }
        close(fp);
       
        //        WRITE PUBLIC KEY
        if(!(fp = fopen(file_pem_pub, "w"))) {
                fprintf(stderr, "Error opening PEM file %s\n", file_pem_pub);
                exit(1);
        }
        if(!PEM_write_PUBKEY(fp, pkey)){
                fprintf(stderr, "Error writing PEM file %s\n", file_pem_pub);
                exit(1);
        }
        close(fp);
       
        //        FREE
        RSA_free(rsa);
       
        return 0;
}

After executing the compiled app I can run the following two commands:
Code:

openssl rsautl -encrypt -pubin -inkey pub.pem -in plain.txt -out cipher.txt
openssl rsautl -decrypt -inkey priv.pem -in cipher.txt -out plain2.txt

This works fine as long as the message is kept short, otherwise an error is thrown:
Code:

$ openssl rsautl -encrypt -pubin -inkey pub.pem -in plain.txt -out cipher.txt
RSA operation error
3503:error:0406D06E:rsa routines:RSA_padding_add_PKCS1_type_2:data too large for key size:rsa_pk1.c:151:

I feel i've read somewhere that the message should be shorter than the key length. If so, how do I get the key length or is it just the number of bits... If so a 512 bit key divided by 8 yields 64, but through testing 51 / 52 characters is the max I seem to be able to put through it. e.g.
Code:

0123456789
0123456789
0123456789
0123456789
01234567

Can anyone please explain why this maximum is so (and how it translates to larger key sizes (e.g. is it num bits minus fixed_size_x, or ???).


p.s. Maxing out with plain text shouldn't be an issue because this'll just be used for key exchange, but i'd still like to know more...


Thanks for any knowledge and experience imparted...


oooh it's late...


All times are GMT -5. The time now is 09:32 PM.