> From: [email protected] On Behalf Of Luca Costantino
> Sent: Saturday, 12 December, 2009 17:14

> i'm having some troubles with this (simple) code...
> 
> #include
> #include
> #include
> #include
> #include
> #include
> #include
> #include
> #include
> #include
> #include
> #include
> #include
> #include
> #include
> #include
> #include
> #include
> 
I assume those are actually #include <header> and just got 
stripped by some HTML or pseudo-HTML (or XML) mailing process. 

> #define PUB_KEY "../chiave/pubkey.pem"
> #define PRIV_KEY "../chiave/keynopwd.pem"
> 
> int cifra_messaggio(char* messaggio_in_chiaro, char* 
> messaggio_cifrato) {
>       FILE* fdpub = fopen(PUB_KEY, "r");
>       RSA* chiave_pubblica = RSA_new();
>       PEM_read_RSA_PUBKEY(fdpub, &chiave_pubblica, NULL, NULL);
>       messaggio_cifrato = malloc(RSA_size(chiave_pubblica));
> 
This sets the pointer *in cifra_ only* see below. 
 
>       printf("Info:\tPubkey successfully loaded\n");
>       printf("Info:\tMessage length is %d byte\n", 
> strlen(messaggio_in_chiaro));
> 
>       int n_byte_cifrati = 
> RSA_public_encrypt(strlen(messaggio_in_chiaro) +
> 1, messaggio_in_chiaro, messaggio_cifrato, chiave_pubblica,
> RSA_PKCS1_OAEP_PADDING);
>       if(n_byte_cifrati == 0 || n_byte_cifrati == -1) {
>               printf("Err :\tUnable to encrypt\n");

Here you ought to display the error(stack) in the same way 
you do below in decifra_ . 

>               errore_non_recuperabile();
>               exit(-1);
>       }
>       
>       printf("Info:\tText successfully encrypted\n");
>       printf("Info:\t%d byte encrypted\n", n_byte_cifrati);
>       RSA_free(chiave_pubblica);
>       fclose(fdpub);
>       
>       return n_byte_cifrati;
> }
> 
> int decifra_messaggio(char* messaggio_cifrato, char* 
> messaggio_decifrato) {
>       FILE* fdpriv = fopen(PRIV_KEY, "r");
>       RSA* chiave_privata;
> 
>       chiave_privata = PEM_read_RSAPrivateKey(fdpriv, NULL, 
> NULL, NULL);

In cifra_ you preallocated pubkey and used the second argument; 
here you let OpenSSL allocate and use the return value.
Both are legal, but it's confusing to be inconsistent.

>       messaggio_decifrato = malloc(RSA_size(chiave_privata));
> 

This sets the pointer *in decifra_ only* see below.

>       printf("Info:\tPrivkey successfully loaded\n");
> 
>       int n_byte_decifrati = RSA_private_decrypt(512, 
> messaggio_cifrato,
> messaggio_decifrato, chiave_privata, RSA_PKCS1_OAEP_PADDING);

Even if _cifrato were valid (see below), 512 is the correct length 
only for a 4Kbit key. Which is possible but rare. cifra_ should 
return both the pointer and count, the caller (main) should save 
both and pass both in to decifra_ which should use them.

>       if(n_byte_decifrati == 0 || n_byte_decifrati == -1) {
>               printf("Err :\tUnable to decrypt\n");
>               
>               char* errore = malloc(1024);
>               bzero(errore, 1024);
>               printf("%s\n", 
> ERR_error_string(ERR_get_error(), errore));
>               

Minor points: no need to use malloc() here, much less bzero();
just declare a local array.  There can be more than one item 
in the error stack; best to loop until ERR_get_error() returns 
zero, which requires you put it (temporarily) in a variable.  
If you just want output to a file, as here (stdout), 
ERR_print_errors_fp is easier to use.  See below about strings.

>               errore_non_recuperabile();
>               exit(-1);
>               
>       }
> 
>       printf("Info:\tText successfully decripted\n");
> 
>       RSA_free(chiave_privata);
>       fclose(fdpriv);
> 
>       return n_byte_decifrati;
> }
> 
> int main(int argc, char* argv[]) {
>       char* messaggio = "Questo รจ un messaggio di prova lungo qualche
> decina di caratteri...";
>       char* cifrato;
>       char* decifrato;
> 
Only the first pointer is initialized here; the others are garbage 
(and are NOT set by the calls below).

>       cifra_messaggio(messaggio, cifrato);

This does the encryption, but throws away (leaks) the pointer 
to malloc'ed storage, and also the length.

>       decifra_messaggio(cifrato, decifrato);
> 
This attempts to decrypt some random memory, and in the very 
unlikely case it succeeds, throws away (leaks) the result.

>       printf("Plaintext\t%s\n", messaggio);
>       printf("Cyphertext\t%s\n", decifrato);
>       
Once the other bugs are fixed that label is misleading: the 
result of deciphering is plaintext again, not ciphertext.
(And if you do want to display 'cifrato', printf %s won't 
come even close; it's not printable nor null-terminated.)

>       if(strncmp(messaggio, decifrato, 512) != 0) {
>               printf("Info:\tMessages are different\n");
>               errore_non_recuperabile();
>               exit(-1);
>       }
>       
>       printf("Info:\tMessages are equal\n");
> 
>       return 1;
> }
> 
Aside: Unix programs conventionally exit with 0 for success, 
and a value >0 (not negative) for error.

> i got this error
> 
> error:0407A079:lib(4):func(122):reason(121)
> 
> and i'm not able to understand why...
> 
1) You got the error because of the bugs above.

2) You got an unhelpful *display* of the error because you 
didn't load errorstrings before using ERR_error_string .
Easiest is to call ERR_load_crypto_strings() at startup. 
There are other possibilities for very constrained systems.

3) Having gotten the unhelpful display, you can decode it 
with the commandline utility 'errstr'; in this case:
>openssl errstr 0407A079
error:0407A079:rsa routines:RSA_padding_check_PKCS1_OAEP:oaep decoding error

4) 2 and 3 are FAQs: http://www.openssl.org/support/faq.html#PROG7 

Also, in general you should always check the return values 
from fopen(), malloc(), *_new and other allocating routines 
e.g. PEM_read*(,NULL...) for null before using them.



______________________________________________________________________
OpenSSL Project                                 http://www.openssl.org
Development Mailing List                       [email protected]
Automated List Manager                           [email protected]

Reply via email to