Hi Dave,

Thanks a lot for your detailed explanation. GT.M supports ASCII format also.
i believe converting base64 is better way instead of ASCII.

I had changed as per your suggestion and code worked for me. additionally i
had tested the Decode also, now everything is fine. can you please verify
the decoded pubkey and d2i_RSA_PUBKEY implemented correctly here.

#include <stdio.h>
#include <string.h>
#include <openssl/bio.h>
#include <openssl/evp.h>
#include <openssl/rsa.h>
#include <openssl/pem.h>

int main(int argc, char* argv[]) {
  /* Variables */
  unsigned char bfbuf[2000];
  unsigned char buf[2000];
  unsigned char b64buf[3000];
    unsigned char *next,*next1;
    RSA *key,*pub_key;
  FILE *fp;
  int outlen,status;
  int len,len1, total = 0;
int total1=0;
long length;
/* EVP_Encode*() Base64 */
  EVP_ENCODE_CTX ectx;
  next=buf;
  printf("generating key...\n");
  fp=fopen("public.pem","r");
 key    =(RSA *)PEM_read_RSA_PUBKEY(fp,NULL,NULL,NULL);
 printf("RSA size for key=%d\n",RSA_size(key));
           //len=i2d_RSAPublicKey(key, &next);
            len=i2d_RSA_PUBKEY(key, &next);
        fclose(fp);
        printf("DER character buffer length=%d",len);

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

  printf("\nBase64 encoded length string: %d,%d\n",total,len);
  printf("\nBase64 encoded string: %s\n",b64buf);

/* Base64 decodification */

  printf("\nDecoding string...");

  EVP_DecodeInit(&ectx);
  EVP_DecodeUpdate(&ectx, bfbuf, &len1, b64buf, strlen(b64buf));
  total1 +=len1;
  EVP_DecodeFinal(&ectx, bfbuf + len1, &len1);
  total1 +=len1;

  printf("\nBase64 decoded length string: %d,%d\n",total1,len1);
<--------- here len1 is 0, why len1 is zero here is it right?
  printf("\nBase64 decoded string:
%s\n",bfbuf);                                <------------------- i
understood this will not print

    next1=bfbuf;
    length=total1;

    pub_key=d2i_RSA_PUBKEY(NULL,(const unsigned char**)&next1, total1);
    printf("RSA size for pub_key=%d\n",RSA_size(pub_key));
  return 1;
}

kicha@kicha-laptop:~/openssl$

outcome:
-------------

RSA size for key=128
DER character buffer length=162
Encoding RSA string...
Base64 encoded length string: 390,25

Base64 encoded string:
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC9TI3eLAsOolBjnrrhGEAI7fiy
nnCgn0tzSSNEGNeMOvPcxlwXiTqt2iYZ39LoXJPRfFC6tPIDomcr1ijBXT07Tr2P
mjGq3BDS8a9CNQhIm0m3nIhkP3+hCXbvLYqfuim87voeXgjycD4aVVlqCca82SzI
fVKneZGtvJ7wtxv/uQIDAQAB


Decoding string...
Base64 decoded length string: 162,0    <------------------how this value
will be 0.

e64 e*�H�ed string: 0��0
RSA size for pub_key=128

Thanks for your time,
Krishnamurthy



On Tue, Aug 9, 2011 at 2:47 AM, Dave Thompson <dthomp...@prinpay.com> wrote:

> >       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