摘要算法:AIX 5.3 使用 openssl 实现 md5 等
环境:
$ uname -a
AIX aix68112 3 5 00F7CAA94C00
查看 openssl 库:
$ ll /usr/lib/*ssl*
lrwxrwxrwx 1 root system 41 Jul 24 2017 /usr/lib/libgsk7ssl_64.so -> /usr/opt/ibm/gsksa/lib64/libgsk7ssl_64.so
-r-xr-xr-x 1 root system 8595301 May 19 02:09 /usr/lib/libssl.a
-r-xr-xr-x 1 root system 3400639 May 19 02:09 /usr/lib/libssl_compat.a
注意:此处 openssl 在 AIX 5.3 中是以静态库形式存在的。
代码:
$ cat main.c
#include <stdio.h>
#include <string.h>
#include <openssl/evp.h>
int main(int argc, char *argv[])
{
EVP_MD_CTX mdctx;
const EVP_MD *md;
unsigned char md_value[EVP_MAX_MD_SIZE];
int md_len, i;
OpenSSL_add_all_digests();
/*********************************************************************/
char *algorithm = "md5";
char *msg = "0123456789abcdef";
md = EVP_get_digestbyname(algorithm);
if(!md) {
fprintf(stderr, "Unknown message digest %s\n", algorithm);
exit(1);
}
EVP_MD_CTX_init(&mdctx);
EVP_DigestInit_ex(&mdctx, md, NULL);
EVP_DigestUpdate(&mdctx, msg, strlen(msg));
EVP_DigestFinal_ex(&mdctx, md_value, &md_len);
EVP_MD_CTX_cleanup(&mdctx);
for(i = 0; i < md_len; i++) {
fprintf(stdout, "%02x", md_value[i]);
}
fprintf(stdout, "\n");
return 0;
}
编译 && 链接:
$ xlc -o main main.c -lssl
"main.c", line 26.46: 1506-280 (W) Function argument assignment between types "unsigned int*" and "int*" is not allowed.
ld: 0711-317 ERROR: Undefined symbol: .OpenSSL_add_all_digests
ld: 0711-317 ERROR: Undefined symbol: .EVP_get_digestbyname
ld: 0711-317 ERROR: Undefined symbol: .EVP_MD_CTX_init
ld: 0711-317 ERROR: Undefined symbol: .EVP_DigestInit_ex
ld: 0711-317 ERROR: Undefined symbol: .EVP_DigestUpdate
ld: 0711-317 ERROR: Undefined symbol: .EVP_DigestFinal_ex
ld: 0711-317 ERROR: Undefined symbol: .EVP_MD_CTX_cleanup
ld: 0711-345 Use the -bloadmap or -bnoquiet option to obtain more information.
问题:找不到符号定义(函数)。
尝试从 libssl.a 中查找 EVP_get_digestbyname 的符号定义:
$ nm /usr/lib/libssl.a | grep OpenSSL_add_all_digests
$
确实没有此函数的全局符号定义。
AIX 5.3 中的 openssl 命令是如何工作的呢?
$ ldd `which openssl`
/usr/bin/openssl needs:
/usr/lib/libc.a(shr.o)
/usr/lib/libcrypto.a(libcrypto.so.1.0.0)
/usr/lib/libssl.a(libssl.so.1.0.0)
/unix
/usr/lib/libcrypt.a(shr.o)
查看到一个特殊的库:libcrypto.a。
尝试添加 -lcrypto 库进行编译链接:
$ xlc -o main main.c -lssl -lcrypto
"main.c", line 26.46: 1506-280 (W) Function argument assignment between types "unsigned int*" and "int*" is not allowed.
$ ./main
4032af8d61035123906e58e067140cc5
编译、链接、执行成功!
我们看看 libcrypto.a 库是否有 OpenSSL_add_all_digests 符号定义:
$ nm /usr/lib/libcrypto.a | grep OpenSSL_add_all_digests
.OpenSSL_add_all_digests T 269522904
OpenSSL_add_all_digests D 536987800 12
.OpenSSL_add_all_digests T 269522904
OpenSSL_add_all_digests D 536987800 12
.OpenSSL_add_all_digests T 269125248
OpenSSL_add_all_digests D 536979844 12
.OpenSSL_add_all_digests T 269522904
OpenSSL_add_all_digests D 536987800 12
既然 libssl.a 中没有此函数定义,而 libcrypto.a 中有此函数定义,尝试单独使用 libcrypto.a 链接:
$ xlc -o main main.c -lcrypto
"main.c", line 26.46: 1506-280 (W) Function argument assignment between types "unsigned int*" and "int*" is not allowed.
$ ./main
4032af8d61035123906e58e067140cc5
OK!!!
AIX 5.3 中使用 openssl 实现相关算法时在链接处需要指明 libcrypto.a 静态库。否则将找不到符号定义。