Hm, never used this OPENSSL_Uplink/Applink glue before... (I have my
own OpenSSL MSVC2005 projects, which I always use inside my solutions)

Anyway, a quick check leads me to two possible answers:

1) somewhere APPMACROS_ONLY was #define'd before your actual

> extern "C"
> {
> #include <openssl/applink.c>
> }

code bit.

A simple change should be able to verify if this is actually the matter:

 extern "C"
 {
#undef APPMACROS_ONLY
 #include <openssl/applink.c>
 }

as then the problem should be gone.

However, there's a chance:

2) ... that you are compiling this code into a DLL of your own (given
your description of the issue, my guess is this is what you are doing.
Correct?).

Given that the Uplink code looks at the *application module* for the
Applink export, you may not find it when it is actually exported from
a DLL instead of the EXE itself.

NOTE: the above is 'guesswork': I haven't checked.


To fix the above, moving the

> extern "C"
> {
> #include <openssl/applink.c>
> }

code snippet to the main application source code should resolve the
matter, preferrably by placing it in the same source file as your
WinMain() / main() function.



To help you see who exports what and depends on whom, you may search
the Net for a free tool called 'Dependency Walker' (
http://www.dependencywalker.com/ ) which is a very handy tool when you
need to check what is going regarding DLL/EXE dependencies and
function/data import/exports.






On Tue, Nov 11, 2008 at 11:09 AM, 念材 杨 <[EMAIL PROTECTED]> wrote:
> hi all
>
> I meet a run time error "OPENSSL_Uplink(0099E000,07): no OPENSSL_Applink"
> which feaze me several days.
> this is my project description:
> I had download openssl-0.9.8i. then build it and install it correctly
> following the INSTALL.WIN32 instruction.
> I use vs2005 to develop my project
> and I had set vs2005 environment such as "MultiThread Debug DLL" etc.
> Because it works well in my other projects.
> this project is a bit different because the below function is called by a
> dll project. but the function is the same in dll project and application
> project.
> [source code]
> // "MyCryptlib.cpp"
> #include "stdafx.h"
> #include <openssl/ssl.h>
> #include "MyCryptlib.h"
> #include <iostream>
> using namespace std;
> extern "C"
> {
> #include <openssl/applink.c>
> }
> CONF *config=NULL;
> BIO *bio_err=NULL;
> // encrypt data
> #define RSA_SIGN  1
> #define RSA_VERIFY  2
> #define RSA_ENCRYPT  3
> #define RSA_DECRYPT  4
> #define KEY_PRIVKEY 1
> #define KEY_PUBKEY 2
> #define KEY_CERT 3
> //int EncryptData()
> int EncryptData(unsigned char* indata, unsigned char* outdata, char*
> pubkeyfile, int& len)
> {
>
>
> ENGINE *e = NULL;
>  BIO *in = NULL, *out = NULL;
>  char *infile = NULL, *outfile = NULL;
> #ifndef OPENSSL_NO_ENGINE
>  char *engine = NULL;
> #endif
>  char *keyfile = NULL;
>  char rsa_mode = RSA_VERIFY, key_type = KEY_PRIVKEY;
>  int keyform = FORMAT_PEM;
>  char need_priv = 0, badarg = 0, rev = 0;
>  char hexdump = 0, asn1parse = 0;
>  X509 *x;
>  EVP_PKEY *pkey = NULL;
>  RSA *rsa = NULL;
>  unsigned char *rsa_in = NULL, *rsa_out = NULL, pad;
>  char *passargin = NULL, *passin = NULL;
>  int rsa_inlen, rsa_outlen = 0;
>  int keysize;
>  int ret = 1;
>
> CRYPTO_malloc_init();
> SSL_library_init();
>  if(!bio_err) bio_err = BIO_new_fp(stderr, BIO_NOCLOSE);
>  if (!load_config(bio_err, NULL))
>   goto end;
>  ERR_load_crypto_strings();
>  OpenSSL_add_all_algorithms();
>  pad = RSA_PKCS1_PADDING;
>
>
> rsa_mode = RSA_ENCRYPT;
> key_type = KEY_PUBKEY;
> keyfile = pubkeyfile;
> //infile = "data.txt";
> //outfile = "data.ssl";
> //cerr <<"just for testing BIO_printf\n" << endl;
>
>  if(need_priv && (key_type != KEY_PRIVKEY)) {
>   BIO_printf(bio_err, "A private key is needed for this operation\n");
>   goto end;
>  }
> #ifndef OPENSSL_NO_ENGINE
>         e = setup_engine(bio_err, engine, 0);
> #endif
>  if(!app_passwd(bio_err, passargin, NULL, &passin, NULL)) {
>   BIO_printf(bio_err, "Error getting password\n");
>   goto end;
>  }
> /* FIXME: seed PRNG only if needed */
>  app_RAND_load_file(NULL, bio_err, 0);
>
>  switch(key_type) {
>   case KEY_PRIVKEY:
>   pkey = load_key(bio_err, keyfile, keyform, 0,
>    passin, e, "Private Key");
>   break;
>   case KEY_PUBKEY:
>   pkey = load_pubkey(bio_err, keyfile, keyform, 0,
>    NULL, e, "Public Key");
>   break;
>   case KEY_CERT:
>   x = load_cert(bio_err, keyfile, keyform,
>    NULL, e, "Certificate");
>   if(x) {
>    pkey = X509_get_pubkey(x);
>    X509_free(x);
>   }
>   break;
>  }
>  if(!pkey) {
>   return 1;
>  }
>  rsa = EVP_PKEY_get1_RSA(pkey);
>  EVP_PKEY_free(pkey);
>  if(!rsa) {
>   BIO_printf(bio_err, "Error getting RSA key\n");
>   ERR_print_errors(bio_err);
>   goto end;
>  }
>
>  if(infile) {
>   if(!(in = BIO_new_file(infile, "rb"))) {
>    BIO_printf(bio_err, "Error Reading Input File\n");
>    ERR_print_errors(bio_err);
>    goto end;
>   }
>  } else in = BIO_new_fp(stdin, BIO_NOCLOSE);
>  if(outfile) {
>   if(!(out = BIO_new_file(outfile, "wb"))) {
>    BIO_printf(bio_err, "Error Reading Output File\n");
>    ERR_print_errors(bio_err);
>    goto end;
>   }
>  } else {
>   out = BIO_new_fp(stdout, BIO_NOCLOSE);
> #ifdef OPENSSL_SYS_VMS
>   {
>       BIO *tmpbio = BIO_new(BIO_f_linebuffer());
>       out = BIO_push(tmpbio, out);
>   }
> #endif
>  }
>  keysize = RSA_size(rsa);
>  rsa_in = (unsigned char *)OPENSSL_malloc(keysize * 2);
>  rsa_out = (unsigned char *)OPENSSL_malloc(keysize);
>  /* Read the input data */
>  //rsa_inlen = BIO_read(in, rsa_in, keysize * 2);
>  rsa_inlen = strlen((char *)indata);
>     strcpy((char*)rsa_in, (char*)indata);
>  if(rsa_inlen <= 0) {
>   BIO_printf(bio_err, "Error reading input Data\n");
>   exit(1);
>  }
>
>  if(rev) {
>   int i;
>   unsigned char ctmp;
>   for(i = 0; i < rsa_inlen/2; i++) {
>    ctmp = rsa_in[i];
>    rsa_in[i] = rsa_in[rsa_inlen - 1 - i];
>    rsa_in[rsa_inlen - 1 - i] = ctmp;
>   }
>  }
>  switch(rsa_mode) {
>   case RSA_VERIFY:
>    rsa_outlen  = RSA_public_decrypt(rsa_inlen, rsa_in, rsa_out, rsa, pad);
>   break;
>   case RSA_SIGN:
>    rsa_outlen  = RSA_private_encrypt(rsa_inlen, rsa_in, rsa_out, rsa, pad);
>   break;
>   case RSA_ENCRYPT:
>    rsa_outlen  = RSA_public_encrypt(rsa_inlen, rsa_in, rsa_out, rsa, pad);
>   break;
>   case RSA_DECRYPT:
>    rsa_outlen  = RSA_private_decrypt(rsa_inlen, rsa_in, rsa_out, rsa, pad);
>   break;
>  }
>
>  if(rsa_outlen <= 0) {
>   BIO_printf(bio_err, "RSA operation error\n");
>   ERR_print_errors(bio_err);
>   goto end;
>  }
> memcpy(outdata, rsa_out, rsa_outlen);
> outdata[rsa_outlen] = 0;
> len = rsa_outlen;
> //cout<<"%%%%%%%%%%len%%%%%%%%%"<<len<<endl;
> ret = 0;
>  if(asn1parse) {
>   if(!ASN1_parse_dump(out, rsa_out, rsa_outlen, 1, -1)) {
>    ERR_print_errors(bio_err);
>   }
>  } else if(hexdump) BIO_dump(out, (char *)rsa_out, rsa_outlen);
>  else BIO_write(out, rsa_out, rsa_outlen);
>  end:
>  RSA_free(rsa);
>  BIO_free(in);
>  BIO_free_all(out);
>  if(rsa_in) OPENSSL_free(rsa_in);
>  if(rsa_out) OPENSSL_free(rsa_out);
>  if(passin) OPENSSL_free(passin);
>  return ret;
> }
>
> this function use a pass in a buffer (indata) , and expect a buffer
> (outdata)  out. outdata contains encrypted data.
>
> please help me ! thank you for your kind in advance.
>
> by the way, I wirte above EncryptData function referring to rsa source code.
>
>
>
>
>
>
>
> ________________________________
> Invite your mail contacts to join your friends list with Windows Live
> Spaces. It's easy! Try it!



-- 
Met vriendelijke groeten / Best regards,

Ger Hobbelt

--------------------------------------------------
web:    http://www.hobbelt.com/
        http://www.hebbut.net/
mail:   [EMAIL PROTECTED]
mobile: +31-6-11 120 978
--------------------------------------------------

Reply via email to