从官网下载openssl源码和 libcurl源码。OpenSSL顺利交叉编译通过。
版本:OpenSSL openssl-1.1.0c.tar.gz版本
curl版本 curl-7.57.0.tar.gz
tar -axvf .....
准备开始交叉编译OpenSSL
在openssl解压目录下,使用config命令
CC=arm-linux-gcc ./config no-asm shared --prefix=/home/linux/arm/openssl --openssldir=/home/linux/arm/openssl/ssl
生成了Makefile
然后就是make和make install
之后会在安装目录下生成lib文件
再编译libcurl时编译没问题,但链接时出现问题,如下:
CCLD curl /home/yang/b503/ctools/gcc-linaro-arm-linux-gnueabihf-4.9-2014.09_linux/bin/../lib/gcc/arm-linux-gnueabihf/4.9.2/../../../../arm-linux-gnueabihf/bin/ld: warning: libssl.so.1.1, needed by ../lib/.libs/libcurl.so, not found (try using -rpath or -rpath-link) /home/yang/b503/ctools/gcc-linaro-arm-linux-gnueabihf-4.9-2014.09_linux/bin/../lib/gcc/arm-linux-gnueabihf/4.9.2/../../../../arm-linux-gnueabihf/bin/ld: warning: libcrypto.so.1.1, needed by ../lib/.libs/libcurl.so, not found (try using -rpath or -rpath-link) ../lib/.libs/libcurl.so: undefined reference to `X509_EXTENSION_get_object@OPENSSL_1_1_0' ../lib/.libs/libcurl.so: undefined reference to `SHA256_Final@OPENSSL_1_1_0' ../lib/.libs/libcurl.so: undefined reference to `SSL_get_peer_cert_chain@OPENSSL_1_1_0' ../lib/.libs/libcurl.so: undefined reference to `OPENSSL_load_builtin_modules@OPENSSL_1_1_0' ../lib/.libs/libcurl.so: undefined reference to `PKCS12_parse@OPENSSL_1_1_0' ../lib/.libs/libcurl.so: undefined reference to `ASN1_TIME_print@OPENSSL_1_1_0' ../lib/.libs/libcurl.so: undefined reference to `SSL_shutdown@OPENSSL_1_1_0' ../lib/.libs/libcurl.so: undefined reference to `CONF_modules_load_file@OPENSSL_1_1_0'
但是我的configure的配置明明已经指定了OpenSSL库的位置啊,OpenSSL库也是已经编译成功了的。为什么链接时还是报找不到openssl库呢?
我的openssl库编译完成后,位置位于 /home/linux/arm/openssl/lib
我的configure配置如下:
CPPFLAGS="-I/home/linux/arm/openssl/ -I/home/linux/arm/openssl/include" LDFLAGS="-L/home/linux/arm/openssl/lib" LIBS="-ldl" ./configure --host=arm-linux CC=arm-linux-gnueabihf-gcc CXX=arm-linux-gnueabihf-g++ --with-ssl --enable-shared --enable-static --disable-dict --disable-ftp --disable-imap --disable-ldap --disable-ldaps --disable-pop3 --disable-proxy --disable-rtsp --disable-smtp --disable-telnet --disable-tftp --disable-zlib --without-ca-bundle --without-gnutls --without-libidn --without-librtmp --without-libssh2 --without-nss --without-zlib --prefix=/home/linux/arm/curl
这里 LDFLAGS="-L/home/linux/arm/openssl/lib"已经指定了的,链接查找的路径。但是就是找不到。
看了下自动生成的Makefile,没发现有什么问题,
最后打开libtool文件,发现链接查找的路径里没有这个/home/linux/arm/openssl/lib。最后干脆把OpenSSL库拷贝到工具链查找的路径下,最后链接通过了。
但是原因是什么呢?
最后,改 LIBS="-ldl -lssl -lcrypto" ,加上去了 lssl和 lcrypto,顺利编译通过。原因或许就出在这里。
添加了LDFLAGS,相当于扩展了工具链的搜索路径,但是 链接时,得指定下 链接什么,
原来的LIBS="-ldl",没有指定 链接 ssl,
是否就是这个原因引起的?欢迎指正
编译参数 :
root@yang-vir:/home/yang/test/curl-7.57.0# setarch i386 ./configure --host=arm-linux CC=arm-linux-gnueabihf-gcc CXX=arm-linux-gnueabihf-g++ CPPFLAGS="-I/home/linux/arm/openssl/ -I/home/linux/arm/openssl/include" LDFLAGS="-L/home/linux/arm/openssl/lib" LIBS="-ldl -lssl -lcrypto" --with-ssl --enable-shared --enable-static --disable-dict --disable-ftp --disable-imap --disable-ldap --disable-ldaps --disable-pop3 --disable-proxy --disable-rtsp --disable-smtp --disable-telnet --disable-tftp --disable-zlib --without-ca-bundle --without-gnutls --without-libidn --without-librtmp --without-libssh2 --without-nss --without-zlib --prefix=/home/linux/arm/curl openssl1.1.0h 编译参数: CC=arm-linux-gnueabihf-gcc setarch i386 ./config no-asm shared -DOPENSSL_NO_HEARTBEATS --prefix=/home/linux/arm/openssl --openssldir=/home/linux/arm/openssl/ssl
遇到一个问题,咱还没解决,同样的测试,在电脑上OK,在ARM板子上报错,如下
curl https://xxx.xxx.xxx.xxx:xxxx-v --cacert ./UP.pem -k -H 'User-Agent: Donjin Http 0.1' -H 'Content-Type: x-ISO-TPDU/x-auth' -H 'Cache-Control: no-cache' -H 'Content-Length: 93' --data-binary @aaa.bin * Rebuilt URL to: https://xxx.xxx.xxx.xxx * Trying xxx.xxx.xxx.xxx... * TCP_NODELAY set * Connected to xxx.xxx.xxx.xxx(140.xx.xx.xx) port xxxx (#0) * ALPN, offering http/1.1 * successfully set certificate verify locations: * CAfile: ./UP.pem CApath: none * TLSv1.2 (OUT), TLS handshake, Client hello (1): * TLSv1.2 (IN), TLS handshake, Server hello (2): * TLSv1.2 (IN), TLS handshake, Certificate (11): * TLSv1.2 (IN), TLS handshake, Server finished (14): * error:0306E06C:bignum routines:BN_mod_inverse:no inverse * Closing connection 0 curl: (35) error:0306E06C:bignum routines:BN_mod_inverse:no inverse
最后,问题已解决。原因不明确。用从github上下载的官方稳定版 1.1-stable版,重新编译。
暂未出现上述问题。难道之前下载的版本有bug?
2018.4.26日记:
好消息,有重大发现,之前不一定是这个原因导致的!!!!!
因为我把https加进我的应用后,让我的应用发起https请求总是会崩,报segment falut,连个日志和堆栈信息都看不到。
一度怀疑 是openssl不支持多线程的原因。折腾了几天仍找不到解决办法。想到用 进程间通信暂时解决吧,
但是呢,测试了下,效率太低了,联机银联双免交易速度7~9秒,太长了。让应用的报文通过 进程间通信的
消息队列的方式,发给单独的进程去发起https请求。 又想进一步改为 共享内存的形式看能否提高交易速度。
正准备尝试呢,突然想到,为什么不去做个demo,抛开我的应用,去测测 到底OpenSSL支不支持多线程。
写了个demo,结果发现无论我怎么试,都没有崩。于是乎,,,问题可能出现应用上,但会是哪里呢?
我的测试验证方法如下,把 gcc编译参数 搞成一致,编译后运行看会不会崩。结果不会崩。
在把所有链接的动态库也加上去,虽然没用到,但是至少链接进去不影响什么。结果,,,,你猜怎么?
崩啦,于是我高兴了,定位到问题了,就是链接了某个库导致的,但具体是哪个呢?于是开始挨个试,
最后竟发现,是支付宝二维码的脱机认证库惹的祸。把它去掉,别链接进去。试了下,我的应用也不在崩啦!!
于是乎想看看这libposoffline.so里面到底有什么。咋影响了我的openssl.。
结果,测试如下,果然有影响:看这里面的函数,在openssl里也有。这导致了我的应用只要访问https就崩。
strings libposoffline.so __gmon_start__ _fini _ITM_deregisterTMCloneTable _ITM_registerTMCloneTable __cxa_finalize _Jv_RegisterClasses tolower strlen memcpy memset sprintf __fpclassify floor strcpy strchr strncmp strcat strrchr atoi strcmp get_qrcode_info init_pos_verify verify_qrcode_v2 verify_qrcode get_key_id strncpy EC_KEY_new_by_curve_name SHA1_Init SHA1_Update SHA1_Final OPENSSL_cleanse EC_KEY_generate_key EC_KEY_get0_group EC_KEY_get0_private_key EC_KEY_get0_public_key BN_bn2hex EC_POINT_point2hex EC_KEY_free CRYPTO_free EC_POINT_new EC_POINT_hex2point EC_KEY_set_public_key ECDSA_verify EC_POINT_free BN_new BN_hex2bn EC_KEY_set_private_key ECDSA_sign BN_free EVP_md5 HMAC_CTX_init HMAC_Init_ex HMAC_Update HMAC_Final HMAC_CTX_cleanup CRYPTO_set_mem_functions OPENSSL_init CRYPTO_set_mem_ex_functions CRYPTO_set_locked_mem_functions CRYPTO_set_locked_mem_ex_functions CRYPTO_set_mem_debug_functions CRYPTO_get_mem_functions CRYPTO_get_mem_ex_functions CRYPTO_get_locked_mem_functions CRYPTO_get_locked_mem_ex_functions CRYPTO_get_mem_debug_functions CRYPTO_malloc_locked cleanse_ctr CRYPTO_free_locked CRYPTO_malloc CRYPTO_strdup CRYPTO_realloc CRYPTO_realloc_clean CRYPTO_remalloc CRYPTO_set_mem_debug_options CRYPTO_get_mem_debug_options memchr SHA1_Transform SHA1_version EVP_MD_block_size EVP_DigestInit_ex EVP_DigestUpdate EVP_DigestFinal_ex OpenSSLDie EVP_MD_CTX_copy_ex EVP_MD_CTX_init HMAC_Init HMAC_CTX_copy EVP_MD_CTX_copy EVP_MD_CTX_cleanup HMAC_CTX_set_flags EVP_MD_CTX_set_flags ERR_put_error BN_set_params BN_get_params BN_value_one BN_num_bits_word BN_num_bits BN_clear_free BN_init bn_expand2 BN_copy BN_dup bn_dup_expand BN_swap BN_clear BN_get_word BN_set_word BN_bin2bn BN_bn2bin BN_ucmp BN_cmp BN_set_bit BN_clear_bit BN_is_bit_set BN_mask_bits BN_set_negative bn_cmp_words bn_cmp_part_words BN_consttime_swap BN_version BN_bn2dec BN_div_word BIO_snprintf __ctype_b_loc BN_dec2bn BN_mul_word BN_add_word BN_asc2bn BN_print BIO_write BN_print_fp BIO_s_file BIO_new BIO_ctrl BIO_free BN_options BN_mod_word BN_lshift bn_div_words BN_sub_word bn_mul_words bn_mul_add_words bn_sqr_words bn_add_words bn_sub_words bn_mul_comba8 bn_mul_comba4 bn_sqr_comba8 bn_sqr_comba4 bn_mul_mont EC_GROUP_new EC_GROUP_method_of EC_METHOD_get_field_type EC_GROUP_get0_generator EC_GROUP_get_mont_data EC_GROUP_get_order EC_GROUP_get_cofactor EC_GROUP_set_curve_name EC_GROUP_get_curve_name EC_GROUP_set_asn1_flag EC_GROUP_get_asn1_flag EC_GROUP_set_point_conversion_form EC_GROUP_get_point_conversion_form EC_GROUP_set_seed EC_GROUP_get0_seed EC_GROUP_get_seed_len EC_GROUP_set_curve_GFp EC_GROUP_get_curve_GFp EC_GROUP_set_curve_GF2m EC_GROUP_get_curve_GF2m EC_GROUP_get_degree EC_GROUP_check_discriminant EC_EX_DATA_set_data EC_EX_DATA_get_data EC_EX_DATA_free_data EC_EX_DATA_clear_free_data EC_EX_DATA_free_all_data EC_EX_DATA_clear_free_all_data EC_GROUP_free BN_MONT_CTX_free EC_POINT_clear_free EC_GROUP_clear_free EC_POINT_copy EC_GROUP_copy BN_MONT_CTX_copy BN_MONT_CTX_new EC_GROUP_dup EC_POINT_dup EC_POINT_method_of EC_POINT_set_to_infinity EC_POINT_set_Jprojective_coordinates_GFp EC_POINT_get_Jprojective_coordinates_GFp EC_POINT_set_affine_coordinates_GFp EC_POINT_set_affine_coordinates_GF2m EC_POINT_get_affine_coordinates_GFp EC_POINT_get_affine_coordinates_GF2m EC_POINT_add EC_POINT_dbl EC_POINT_invert EC_POINT_is_at_infinity EC_POINT_is_on_curve EC_POINT_cmp EC_GROUP_cmp BN_CTX_start BN_CTX_get BN_CTX_end BN_CTX_free BN_CTX_new EC_POINT_make_affine EC_POINTs_make_affine EC_POINTs_mul ec_wNAF_mul EC_POINT_mul EC_GROUP_precompute_mult ec_wNAF_precompute_mult EC_GROUP_have_precompute_mult ec_wNAF_have_precompute_mult ec_precompute_mont_data BN_MONT_CTX_set EC_GROUP_set_generator EC_version CRYPTO_add_lock EC_POINT_point2bn EC_POINT_point2oct EC_POINT_bn2point EC_POINT_oct2point EC_KEY_new EC_GROUP_new_by_curve_name EC_KEY_copy EC_KEY_dup EC_KEY_up_ref BN_rand_range EC_KEY_check_key EC_KEY_set_group EC_KEY_set_public_key_affine_coordinates EC_KEY_get_enc_flags EC_KEY_set_enc_flags EC_KEY_get_conv_form EC_KEY_set_conv_form EC_KEY_get_key_method_data CRYPTO_lock EC_KEY_insert_key_method_data EC_KEY_set_asn1_flag EC_KEY_precompute_mult EC_KEY_get_flags EC_KEY_set_flags EC_KEY_clear_flags EC_POINT_set_compressed_coordinates_GFp ec_GF2m_simple_set_compressed_coordinates ec_GFp_simple_set_compressed_coordinates EC_POINT_set_compressed_coordinates_GF2m ec_GF2m_simple_point2oct ec_GFp_simple_point2oct ec_GF2m_simple_oct2point ec_GFp_simple_oct2point ECDSA_do_sign_ex ecdsa_check ECDSA_do_sign ECDSA_sign_ex RAND_seed i2d_ECDSA_SIG ECDSA_SIG_free ECDSA_sign_setup ECDSA_do_verify ECDSA_SIG_new d2i_ECDSA_SIG BIO_set CRYPTO_new_ex_data CRYPTO_free_ex_data BIO_vfree BIO_clear_flags BIO_test_flags BIO_set_flags BIO_get_callback BIO_set_callback BIO_set_callback_arg BIO_get_callback_arg BIO_method_name BIO_method_type BIO_read BIO_puts BIO_gets BIO_indent BIO_int_ctrl =========>>>catch signal 11 <<<========= Dump stack start... backtrace() returned 0 addresses Dump stack end... readData..162..exit..connect..error.. modemDeamon.c...readerLoop...close..client_fd = 4 Segmentation fault root@b503_lcd:/app/city_app/bin# ./b503_app1 root@b503_lcd:/app# ./test task1 run... =================================>>thread tid = 1976562784 start... thread begin post: data:00,5b postlen:147 ->begin send: * Rebuilt URL to: https://xx.207.168.xx:xxxxx0/ * Trying xxx.xxx.xx.xx... * TCP_NODELAY set * Connected to xxx.xxx.xxx.xxxx (xxx.xxx.xxx.xxx) port xxxxx (#0) Segmentation fault
到此为止,这个问题可以结贴了。不要怀疑openssl了。且官网查看说明,openssl1.09之后的版本都内建支持多线程。
之前的版本需要hook进去锁。
因此也总结了一种解决这类问题的方法,写个demo尽最大限度的去模拟,看能否复现问题。排除应用里复杂代码和逻辑等的影响。如果能复现问题,原因就明朗了。
今天又发现一问题,收获满满,在多线程程序中,请慎用类似memcpy等的拷贝。这类涉及内存操作的要尤其谨慎。
今天遇到的新问题,最后定位到原因是memcpy.最后自己写了个拷贝函数解决了。