>       From: owner-openssl-us...@openssl.org On Behalf Of krishnamurthy
santhanam
>       Sent: Saturday, 06 August, 2011 15:13

>       Thanks for your suggestion. Let me explain in what i am doing. 
> I have GT.M(MUMPS) calls to C language(external calls) routines that 
> has to generate RSA key pairs and send it to the GT.M(same server).
        
>       DO &security.rsakey(char *pubkey,char *privatekey)

>       GT.M stores the key pairs in database and shares the public key
only. 
> GTM will accept only strings and characters. hence i had tried to 
> i2d/d2i methods to right the keys to database.

*If* those are C strings, DER by itself cannot be a C string.
Interlanguage calls sometimes use other kinds of strings, some of 
which can handle binary data. I'll assume a C string. There are 
several ways of encoding DER (or other binary data) to make it 
a printable string and easily manipulable in C and other tools 
designed for printable strings; I'll assume that includes GT.M.

You'll need to use whatever method GT.M requires (or allows).
PEM and base64, the two you have (nearly) coded, are two related 
and popular ways, but not the only ways. Do you know this is 
what GT.M wants?
        
>       I had tried below program but it is giving error. i had 
> created RSA keys and the tried to extract the public key 
> using i2d_RSApublickey then tried to encode the keys using 
> EVP_Encodeinit()...Am i doing wrong? any help would be great

See below. (So far you're only trying to encode one key, the 
publickey; from your description you will also need to do 
the privatekey, but one step at a time.)

<code trimmed>
>           unsigned char *next;
>           RSA *key;
>         int outlen,status,len, total = 0;
>         /* EVP_Encode*() Base64 */
>         EVP_ENCODE_CTX ectx;
>         EVP_CIPHER_CTX ctx;
>           EVP_PKEY *pkey;
>               pkey = EVP_PKEY_new();
>               next=buf;
>                       printf("generating key...\n");
>                       key =  RSA_generate_key(1024,RSA_F4, NULL, NULL);

As I said before, check for failure (null) before using.

>               EVP_PKEY_assign_RSA(pkey,key);
>           if (RSA_check_key(key)==1)

This is redundant: if RSA_generate_key succeeded, the key is good.
RSA_check_key is useful where you get a keypair from somewhere else, 
like storage or a comm partner, who might have screwed it up 
(either accidentally, or an adversary deliberately interfering).

>           {
>               fp=fopen("public.pem","w");   <snip>
>               PEM_write_PUBKEY(fp,pkey);
>                   fclose(fp);
>                   len=i2d_RSAPublicKey(key, &next);
>               printf("length=%d",len);       <snip>len=140
>           }

There are both subtle and obvious differences here.
PEM_write_PUBKEY encodes the pubkey part in a generic 
DER format defined by X.509 called SubjectPublicKeyInfo, 
then encodes to PEM (which is base64 + fold + labels).
i2d_RSAPublicKey() encodes to *PKCS1* DER format, which 
is slightly different. If you want (that is, GT.M wants) 
KeyInfo DER, instead use i2d_RSA_PUBKEY or just i2d_PUBKEY.

>         /* Base64 using EVP */
>         printf("\nEncoding RSA string...");
>         EVP_EncodeInit(&ectx);
>         EVP_EncodeUpdate(&ectx, b64buf, &len, buf, outlen);
>         total += len;

Here's your immediate error. You have the DER in buf for len,
so 'inl' should be len, and 'outl' should be &outlen and then 
you add outlen to total. (Actually here you know total is 0 
so you can just assign instead, but add is more general.)

>         EVP_EncodeFinal(&ectx, b64buf + len, &len);
>         total += len;

Similarly these should be outlen. Actually b64buf+len could be 
either b64buf+outlen (from prev call) or b64buf+total; they're 
actually the same here but the latter is more logical.
        
>         printf("\nBase64 encoded length string: %d,%d\n",total,len);  
> ----------------->outcome is 0,0
>         printf("\nBase64 encoded string: %s\n",b64buf);       
> -------------------------------->  see the below outcome
>         EVP_CIPHER_CTX_cleanup(&ctx);

You didn't init ctx (or use it at all), so it's not safe 
to clean it, and in fact you got a glibc fault (snipped).

You certainly don't want to encrypt your publickey; 
publickeys are public. Whether, and how, you want to 
encrypt your privatekey depends on what GT.M wants.
If he's storing it in a database, it may reasonably 
depend on what control he has over that database.

For clear RSA privatekey there is one DER standard (PKCS1) 
which i2d_RSAPrivateKey implements. But for encrypted 
there are several standards, which differ both on the 
encoding and the encryption, plus proprietary schemes.



______________________________________________________________________
OpenSSL Project                                 http://www.openssl.org
User Support Mailing List                    openssl-users@openssl.org
Automated List Manager                           majord...@openssl.org

Reply via email to