从官网下载openssl源码和 libcurl源码。OpenSSL顺利交叉编译通过。
版本:OpenSSL openssl-1.1.0c.tar.gz版本
curl版本 curl-7.57.0.tar.gz
tar -axvf .....
再编译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,
是否就是这个原因引起的?欢迎指正
遇到一个问题,咱还没解决,同样的测试,在电脑上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
Segmentation fault
到此为止,这个问题可以结贴了。不要怀疑openssl了。且官网查看说明,openssl1.09之后的版本都内建支持多线程。
之前的版本需要hook进去锁。
因此也总结了一种解决这类问题的方法,写个demo尽最大限度的去模拟,看能否复现问题。排除应用里复杂代码和逻辑等的影响。如果能复现问题,原因就明朗了。
今天又发现一问题,收获满满,在多线程程序中,请慎用类似memcpy等的拷贝。这类涉及内存操作的要尤其谨慎。
今天遇到的新问题,最后定位到原因是memcpy.最后自己写了个拷贝函数解决了。