Hi Dave,

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.

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

#include <stdio.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 buf[2000];   ------> i shoud not use malloc thats why used
buffers
  unsigned char b64buf[3000];
    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);
        EVP_PKEY_assign_RSA(pkey,key);
    if (RSA_check_key(key)==1)
    {
        fp=fopen("public.pem","w");                    ------------------>
it is writing pem files
        PEM_write_PUBKEY(fp,pkey);
            fclose(fp);
            len=i2d_RSAPublicKey(key, &next);
        printf("length=%d",len);
---------------------->len=140
    }
  /* Base64 using EVP */
  printf("\nEncoding RSA string...");
  EVP_EncodeInit(&ectx);
  EVP_EncodeUpdate(&ectx, b64buf, &len, buf, outlen);
  total += len;
  EVP_EncodeFinal(&ectx, b64buf + len, &len);
  total += len;

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

  return 1;
}

generating key...
length=140
Encoding RSA string...
Base64 encoded length string: 0,0

Base64 encoded string:
*** glibc detected *** ./rsaencrypt: free(): invalid pointer: 0x002e2ff4 ***
======= Backtrace: =========
/lib/tls/i686/cmov/libc.so.6(+0x6b591)[0xc7f591]
/lib/tls/i686/cmov/libc.so.6(+0x6cde8)[0xc80de8]
/lib/tls/i686/cmov/libc.so.6(cfree+0x6d)[0xc83ecd]
/lib/i686/cmov/libcrypto.so.0.9.8(CRYPTO_free+0x3a)[0x14f03a]
/lib/i686/cmov/libcrypto.so.0.9.8(EVP_CIPHER_CTX_cleanup+0x5e)[0x1c51ce]
./rsaencrypt[0x8048a80]
/lib/tls/i686/cmov/libc.so.6(__libc_start_main+0xe6)[0xc2abd6]
./rsaencrypt[0x8048821]
======= Memory map: ========
00110000-00248000 r-xp 00000000 08:03 1321372
/lib/i686/cmov/libcrypto.so.0.9.8
00248000-00250000 r--p 00137000 08:03 1321372
/lib/i686/cmov/libcrypto.so.0.9.8
00250000-0025e000 rw-p 0013f000 08:03 1321372
/lib/i686/cmov/libcrypto.so.0.9.8
0025e000-00262000 rw-p 00000000 00:00 0
00262000-00264000 r-xp 00000000 08:03 1310623    /lib/tls/i686/cmov/
libdl-2.11.1.so
00264000-00265000 r--p 00001000 08:03 1310623    /lib/tls/i686/cmov/
libdl-2.11.1.so
00265000-00266000 rw-p 00002000 08:03 1310623    /lib/tls/i686/cmov/
libdl-2.11.1.so
002c7000-002e2000 r-xp 00000000 08:03 1308339    /lib/ld-2.11.1.so
002e2000-002e3000 r--p 0001a000 08:03 1308339    /lib/ld-2.11.1.so
002e3000-002e4000 rw-p 0001b000 08:03 1308339    /lib/ld-2.11.1.so
00712000-00713000 r-xp 00000000 00:00 0          [vdso]
00c14000-00d67000 r-xp 00000000 08:03 1310609    /lib/tls/i686/cmov/
libc-2.11.1.so
00d67000-00d68000 ---p 00153000 08:03 1310609    /lib/tls/i686/cmov/
libc-2.11.1.so
00d68000-00d6a000 r--p 00153000 08:03 1310609    /lib/tls/i686/cmov/
libc-2.11.1.so
00d6a000-00d6b000 rw-p 00155000 08:03 1310609    /lib/tls/i686/cmov/
libc-2.11.1.so
00d6b000-00d6e000 rw-p 00000000 00:00 0
00efc000-00f19000 r-xp 00000000 08:03 1310643    /lib/libgcc_s.so.1
00f19000-00f1a000 r--p 0001c000 08:03 1310643    /lib/libgcc_s.so.1
00f1a000-00f1b000 rw-p 0001d000 08:03 1310643    /lib/libgcc_s.so.1
00f9c000-00faf000 r-xp 00000000 08:03 1310758    /lib/libz.so.1.2.3.3
00faf000-00fb0000 r--p 00012000 08:03 1310758    /lib/libz.so.1.2.3.3
00fb0000-00fb1000 rw-p 00013000 08:03 1310758    /lib/libz.so.1.2.3.3
08048000-08049000 r-xp 00000000 08:03 1580777
/home/kicha/openssl/rsaencrypt
08049000-0804a000 r--p 00000000 08:03 1580777
/home/kicha/openssl/rsaencrypt
0804a000-0804b000 rw-p 00001000 08:03 1580777
/home/kicha/openssl/rsaencrypt
09221000-09242000 rw-p 00000000 00:00 0          [heap]
b7700000-b7721000 rw-p 00000000 00:00 0
b7721000-b7800000 ---p 00000000 00:00 0
b78a9000-b78ab000 rw-p 00000000 00:00 0
b78ba000-b78bd000 rw-p 00000000 00:00 0
bfdce000-bfde3000 rw-p 00000000 00:00 0          [stack]
Aborted





On Sat, Aug 6, 2011 at 2:24 AM, Dave Thompson <dthomp...@prinpay.com> wrote:

> >       From: owner-openssl-us...@openssl.org On Behalf Of krishnamurthy
> santhanam
> >       Sent: Friday, 05 August, 2011 08:09
>
> >       I have to write back rsa public/private key to calling function,
> > i have tried below program using i2d_RSAPrivatekey().
> >       My application will not accept RSA * structure, it will accept only
> char
> > or strings to be return as s key.
>
> It's not clear what you're trying to do.  Your code is actually operating
> on a private key but your label says pubkey. You talk about 'encrypting
> the message' but RSA_private_encrypt is a misnomer, it actually provides
> integrity protection (signing) NOT confidentiality (encryption).
>
> >       #include <stdio.h>
> >       #include <string.h>
> >       #include <openssl/rsa.h>
> >       typedef struct {
> >               unsigned char cl_priv[1000];
> >       } DER_RSA;
>
> If you change to a keysize that is actually secure, this will be
> too small for a private key (at least an OpenSSL private key,
> which has all the CRT components). It will be big enough for
> a public key if that's what you actually want and do.
>
> Although DER is self-delimiting, the length computation is
> nontrivial. I would keep the length explicitly in the struct.
>
> >       generate(DER_RSA *ctr)
>
> Since 1999 'implicit int' is gone from C. You must declare
> the return type of a function (and the type of a variable etc.).
> If you don't want to return a value, declare it 'void'.
>
> >       {
> >           RSA *rsa, *pub_rsa, *priv_rsa;
> >           unsigned char keybuf[512], *p;
>
> If this 512 is intended to be related to the size of the key,
> or related cryptogram(s), remember that keys (and ciphers and
> hashes etc) are in bits, while C char is a byte.
>
> >           int len;
> >       //      DER_RSA *ctr;
> >               printf("hello");
> >
> >           rsa = RSA_generate_key(512, RSA_F4,NULL,NULL);
>
> 512-bit RSA has been in range for factoring,
> and thus insecure, for about a decade now.
>
> In general you should always check for errors, here
> a returned null pointer, before using the result.
> In particular I think RSA_generate_key could fail
> for lack of entropy, though yours apparently didn't.
>
> >       /* get separated der key pair */
> >               p=ctr->cl_priv;
> >               len=i2d_RSAPrivateKey(rsa,&p);
> >               printf("\nlen=%d\n",len);
> >               return ;
> >           RSA_free(rsa);
>
> This is never executed, so you have a (small) memory leak.
>
> >       }
>
> >       int main()
> >       {
> >       int i;
> >       DER_RSA *ctr;
>
> This is an uninitialized pointer, and
>
> >       generate(ctr);
>
> this uses that pointer to try to access memory.
> That can cause many different problems.
>
> >       printf("pubkey=%s",ctr->cl_priv);
> >       }
>
> >       pubkey=(null)
>
> It looks like 'ctr' happened to be 0, which in C is the
> null pointer (except very weird systems you can ignore).
> *Many* C platforms nowadays fault for access to 0, because
> it's such a common bug; what are you running on?
>
> If you want to use a DER_RSA object (containing a buffer),
> create one and then use it.
>
> Even if this encoded to proper memory, DER (the result
> of i2d_anything) is not a C string and can't validly be
> printed with %s, or strcpy'ed, or strcmp'ed, etc.
> You need to treat it as binary data, and that's why
> you want to keep track explicitly of its length.
>
> Alternatively you can further encode it into a form that
> IS a valid string; base64 and hex are two popular ones.
> PEM is a variant of base64 builtin to OpenSSL.
>
>
> ______________________________________________________________________
> OpenSSL Project                                 http://www.openssl.org
> User Support Mailing List                    openssl-users@openssl.org
> Automated List Manager                           majord...@openssl.org
>

Reply via email to