首页
学习
活动
专区
圈层
工具
发布
50 篇文章
1
C语言中如何实现数据帧封装与解析
2
【熟视C语言】如何快速的了解一个库函数(C语言讲解,以string.h中的部分库函数为例)
3
C语言代码封装MQTT协议报文,了解MQTT协议通信过程
4
NV12数据格式转H265编码格式实现过程
5
基于Modbus协议实现Openplc与Kingview的仿真通讯与模拟测试
6
onvif协议最新版本_接口协议测试工具
7
linux后台开发常用调试工具
8
C/C++开发人员要了解的几大著名C/C++开源库[通俗易懂]
9
适用于嵌入式环境的加速计算库
10
Linux下WebRTC框架Janus编译过程
11
探索嵌入式应用框架(EAF)
12
[C&C++]联合体union的特征及用其进行传输
13
联合体和结构体一起解析数据
14
国标GB28181协议客户端开发(四)实时视频数据传输
15
6.1 C/C++ 封装字符串操作
17
C语言进阶——自定义类型
18
干货 | 结构体、联合体嵌套使用的一些实用操作
19
C语言的面向对象编程
20
QT应用编程: 编写低功耗BLE蓝牙调试助手(Android系统APP)
21
设计模式之接口隔离原则C++实现
22
嵌入式软件开发的框架思维
23
通过面向对象设计串口协议
24
QT应用编程: 开发串口调试助手
25
一种高效的串口自定义16进制通信协议的嵌入式应用开发解决方案
26
嵌入式中状态机的几种骚操作
27
【干货】用FreeRTOS搭建Event-Driven应用框架
28
嵌入式开发基础之任务管理(线程管理)
29
SIP菜鸟如何学SIP
30
Linux下使用libuvc读取控制USB免驱摄像头
31
Linux 使用strace命令查找进程卡死原因
32
84-OOP之组合
33
如何调试多线程程序
34
GDB多线程调试分析
35
GDB多线程多进程调试
36
一个简单实用的线程基类
37
OpenThread是世界上最舒心的跨平台多线程并发库
38
OpenMiniServer是一个超迷你、 超易用的C++高并发跨平台服务器框架
39
OpenSocket是跨全平台的高性能高并发网络库
40
一个C++多线程TCP服务Demo
41
一文搞懂网络库的分层设计!
42
实现一个接收多路RTP流,输出一路RTMP流的简单MCU
43
谈谈嵌入式应用软件人机界面开发的菜单框架编写
44
union 的概念及在嵌入式编程中的应用
45
让终端支持https,移植OpenSSL和libcurl到嵌入式linux,遇到的问题总结
46
日常工作中的设计:解耦和封装
47
一种简易的嵌入式设备系统日志记录方法
48
PLC和计算机通信的数据采集方法和传输监控的实现(1)
49
C++随笔(五)三种实现串口通信的方式
50
开源一个自己写过的MQTT 客户端调试工具

让终端支持https,移植OpenSSL和libcurl到嵌入式linux,遇到的问题总结

从官网下载openssl源码和 libcurl源码。OpenSSL顺利交叉编译通过。

版本:OpenSSL openssl-1.1.0c.tar.gz版本

curl版本 curl-7.57.0.tar.gz

tar -axvf .....

准备开始交叉编译OpenSSL

在openssl解压目录下,使用config命令

代码语言:javascript
复制
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时编译没问题,但链接时出现问题,如下:

代码语言:javascript
复制
 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配置如下:

代码语言:javascript
复制
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,

是否就是这个原因引起的?欢迎指正

代码语言:javascript
复制

 编译参数 :
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板子上报错,如下

代码语言:javascript
复制
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就崩。

代码语言:javascript
复制
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.最后自己写了个拷贝函数解决了。

下一篇
举报
领券