分析1:
我新建了一个dll A.dll,而A.dll要调用openssl的dll, 然后新建一个win32应用程序B去调用A中的导出函数,此时必须include一次且仅一次<install-root>/include/openssl/applink.c 到你的B工程里去,而不能include到A.dll工程里,或者把<install-root>/include/openssl/applink.c拷贝到B个工程里去,否则就会出现,运行时错误OPENSSL_Uplink(0098E000,07): no OPENSSL_Applink
因为openssl源码Uplink.c中是这样子 :h=GetModuleHandle(NULL)) applink=(void**(*)())GetProcAddress(h,"OPENSSL_Applink");
可以看出 openssl 通过GetModuleHandle(NULL)取得的句柄h去调用Applink()函数(Applink函数就是applink.c中的一个导出函数), Applink()函数不属于openssl的dll内部函数的一部分(通过dll分析器看出这个函数不存在),但是因为GetModuleHandle(NULL)取得的句柄会始终指向应用程序的句柄(比如上面例子中的B工程)而非dll句柄, 所以必须把applink.c文件应用程序的一部分编译.
下面是我在openssl-user mail list中的提问,和有些人给我的答复:
From: yangniancai@hotmail.com
To: openssl-users@openssl.org
Subject: RE: OPENSSL_Uplink(0099E000,07): no OPENSSL_Applink
Date: Wed, 12 Nov 2008 01:51:11 +0000
hiGer Hobbelt
thank yousoooooooomuch .
your answer 2) solve my problem well.
because there exists libeay32.dll,ssleay32.dll ,my own dll and my application. my own dll call libeay32.dlland ssleay32.dll. And my application call my own dll.
according to Ger Hobbelt's suggestion 2), firstly I used a tool to analyse the exports functions of libeay32.dll,ssleay32.dll and my own dll. I found that dll exports functions don't contain OPENSSL_Applink() function.Also I look up the source code ofUplink.c which call OPENSSL_Applink() function. Uplink.c use <h=GetModuleHandle(NULL)> to get a handle h, and then use <applink=(void**(*)())GetProcAddress(h,"OPENSSL_Applink")> to got the address of OPENSSL_Applink().when I uselibeay32.dll,ssleay32.dllin my application , this handle h will point to the applicationbut not my own dll.
So I should add applink.c to my application as a part of my application source code , never add it to my own dll source code.
Leo Yang
Best Regards
MSN:yangniancai@hotmail.com
> Date: Tue, 11 Nov 2008 17:35:03 +0100
> From: ger@hobbelt.com
> To: openssl-users@openssl.org
> Subject: Re: OPENSSL_Uplink(0099E000,07): no OPENSSL_Applink
> CC: i-zw@hotmail.com
>
> 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, 念材 杨 <yangniancai@hotmail.com> 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: ger@hobbelt.com
> mobile: +31-6-11 120 978
分享到:
相关推荐
出现以下报错,替换/usr/local/include/openssl里面的文件之后编译成功。add_assoc_name_entry’:/data/src/php-5.6.23/ext/openssl/openssl.c:664: warning: ‘ASN1_STRING_data’ is deprecated (declared at /usr...
前言本博客所写到的是我在Linux云服务器升级编译内核时所遇到的真实问题,已解决。编译内核遇到的问题太多了。问题描述 在进行内核编译的时候,提sha1加密 C语
openssl的客户端和服务器端的程序,C语言编写
Win64OpenSSL_Light-3_0_0
onenet MQTTS第三方库paho.mqtt.c-1.3.0 &openssl-OpenSSL_1_0_2q.tar
Windows平台OpenSSl_64位安装包,需配环境变量,可用于android系统签名文件生成JKS文件。...如果提示无法打开openssl配置文件:设置一下配置文件:set OPENSSL_CONF=C:\OpenSSL-Win64\bin\openssl.cfg
Win64OpenSSL_Light-1_1_1f python scrapy 爬取https需要OpenSSL
在编译curl时遇到了openssl,因为openssl 比较常用,因此将资源上传。
Win64OpenSSL_Light-1_1_1c.exe 64为下载使用,安装说明:随意安装至本地,配置环境变量\bin,重启电脑,务必重启电脑
Win64OpenSSL_Light-1_0_2o,http://slproweb.com/products/Win32OpenSSL.html被墙了,故搬运过来
php使用openssl_encrypt中的AES-128-ECB加密解密 保证的传输数据的安全性 保证了开发系统的安全性
Win64OpenSSL_Light-1_1_1b 是一个方便的证书生成工具,方便用于 HTTPS 认证上。
openssl-OpenSSL_1_1_1d.tar,用于更新低下版本,总要用于python安装
windows OpenSSL工具
webrtc owt 构建: openssl-OpenSSL_1_1_1-stable VS2019 X86 源码动态库静态库 解决 Can’t locate Win32/Console.pm in @INC (you may need to install the Win32::Console module)
win64openssl_light-1-0-2.exe OpenSSL 是一个安全套接字层密码库,囊括主要的密码算法、常用的密钥和证书封装管理功能及SSL协议,并提供丰富的应用程序供测试或其它目的使用。
Win64OpenSSL_Light-1_1_0f.exe
OpenSSL开放源代码的软件,从官网下载,亲测有效。 支持win64系统; 安装步骤,一路next,在最后需要付款按钮,全不选即可。
OpenSSL win 64位安装包,可以直接安装,安装完默认路径是C:\Program Files\OpenSSL-Win64
openssl轻量版 windows 64