不知道从什么时候起,大家都喜欢把简单的事情复杂化,好像越难用就越牛逼一样。装逼的倒是无所谓,等到要用的时候就傻了。以上是题外话。手机上的 Android ICS 的 OpenSSL 库版本较旧( 1.0.0e ),在神奇的地方使用容易出现一些问题,因此打算用新版本的替换掉,看看能不能解决在兲朝时不时出现的 SSL 错误(手机上特有的现象)。另外安装 openssl 命令行工具也可以用于手机处理器性能的 benchmark 。
整个工作的基础是 http://crrrazzzy.blogspot.co.il/p/steps-for-porting-openssl-for-android.html ,但是必须跳过第六步——这一步会导致诸多麻烦。最后得到的 SSL 库是为应用设计的,并不能替代系统的 SSL 库,因此还需要修改。
源码修改
首先,去 http://developer.android.com/tools/sdk/ndk/index.html 下载最新的 Android NDK ,去 http://www.openssl.org/source/ 下载 OpenSSL 的最新源码。解压这两个包。
接着,在 OpenSSL 源码目录下执行:
# For ARM Cortex ./Configure android-armv7 -DL_ENDIAN # For x86 ./Configure android-x86 -DL_ENDIAN
然后:
cp LICENSE NOTICE touch MODULE_LICENSE_BSD_LIKE rm -f AndroidManifest.xml
接下来,查看 Makefile 里的 CFLAG 和 DEPFLAG ,接着创建如下的 android-config.mk :
# From CLFAG (Please replace) LOCAL_CFLAGS += -DOPENSSL_THREADS -D_REENTRANT -DDSO_DLFCN -DHAVE_DLFCN_H \ -DL_ENDIAN -O3 -fomit-frame-pointer -Wall # From DEPFLAG (Please replace) LOCAL_CFLAGS += -DOPENSSL_NO_EC_NISTP_64_GCC_128 -DOPENSSL_NO_SCTP \ -DOPENSSL_NO_CAMELLIA -DOPENSSL_NO_CAPIENG -DOPENSSL_NO_CAST \ -DOPENSSL_NO_CMS -DOPENSSL_NO_GMP -DOPENSSL_NO_IDEA \ -DOPENSSL_NO_JPAKE -DOPENSSL_NO_MD2 -DOPENSSL_NO_MDC2 \ -DOPENSSL_NO_RC5 -DOPENSSL_NO_SHA0 -DOPENSSL_NO_RFC3779 \ -DOPENSSL_NO_SEED -DOPENSSL_NO_STORE -DOPENSSL_NO_WHIRLPOOL # Extra LOCAL_CFLAGS += -DZLIB -DOPENSSL_NO_HW -DOPENSSL_NO_GOST
然后还需要一大票 Android.mk (老老实实用 Makefile 能死人吗?):
jni/Application.mk (目录需自行创建):
APP_PROJECT_PATH := $(shell pwd) APP_BUILD_SCRIPT := $(APP_PROJECT_PATH)/Android.mk
Android.mk :
LOCAL_PATH := $(call my-dir) subdirs := $(addprefix $(LOCAL_PATH)/,$(addsuffix /Android.mk, \ crypto \ ssl \ apps \ )) include $(subdirs)
apps/Android.mk :
LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) LOCAL_SRC_FILES:= \ app_rand.c \ apps.c \ asn1pars.c \ ca.c \ ciphers.c \ crl.c \ crl2p7.c \ dgst.c \ dh.c \ dhparam.c \ dsa.c \ dsaparam.c \ ecparam.c \ ec.c \ enc.c \ engine.c \ errstr.c \ gendh.c \ gendsa.c \ genpkey.c \ genrsa.c \ nseq.c \ ocsp.c \ openssl.c \ passwd.c \ pkcs12.c \ pkcs7.c \ pkcs8.c \ pkey.c \ pkeyparam.c \ pkeyutl.c \ prime.c \ rand.c \ req.c \ rsa.c \ rsautl.c \ s_cb.c \ s_client.c \ s_server.c \ s_socket.c \ s_time.c \ sess_id.c \ smime.c \ speed.c \ spkac.c \ srp.c \ verify.c \ version.c \ x509.c LOCAL_SHARED_LIBRARIES := \ libssl \ libcrypto LOCAL_C_INCLUDES := \ $(NDK_PROJECT_PATH) \ $(NDK_PROJECT_PATH)/include \ $(NDK_PROJECT_PATH)/../include LOCAL_CFLAGS := -DMONOLITH include $(LOCAL_PATH)/../android-config.mk LOCAL_CFLAGS += -DOPENSSL_NO_DTLS1 LOCAL_MODULE:= openssl LOCAL_MODULE_TAGS := tests include $(BUILD_EXECUTABLE)
crypto/Android.mk (尤其注意需要打开 engine ):
LOCAL_PATH:= $(call my-dir) arm_cflags := -DOPENSSL_BN_ASM_MONT -DAES_ASM -DSHA1_ASM -DSHA256_ASM -DSHA512_ASM arm_src_files := \ aes/asm/aes-armv4.S \ bn/asm/armv4-mont.S \ sha/asm/sha1-armv4-large.S \ sha/asm/sha256-armv4.S \ sha/asm/sha512-armv4.S non_arm_src_files := aes/aes_core.c local_src_files := \ cryptlib.c \ mem.c \ mem_clr.c \ mem_dbg.c \ cversion.c \ ex_data.c \ cpt_err.c \ ebcdic.c \ uid.c \ o_time.c \ o_str.c \ o_dir.c \ o_fips.c \ o_init.c \ fips_ers.c \ aes/aes_cbc.c \ aes/aes_cfb.c \ aes/aes_ctr.c \ aes/aes_ecb.c \ aes/aes_ige.c \ aes/aes_misc.c \ aes/aes_ofb.c \ aes/aes_wrap.c \ asn1/a_bitstr.c \ asn1/a_bool.c \ asn1/a_bytes.c \ asn1/a_d2i_fp.c \ asn1/a_digest.c \ asn1/a_dup.c \ asn1/a_enum.c \ asn1/a_gentm.c \ asn1/a_i2d_fp.c \ asn1/a_int.c \ asn1/a_mbstr.c \ asn1/a_object.c \ asn1/a_octet.c \ asn1/a_print.c \ asn1/a_set.c \ asn1/a_sign.c \ asn1/a_strex.c \ asn1/a_strnid.c \ asn1/a_time.c \ asn1/a_type.c \ asn1/a_utctm.c \ asn1/a_utf8.c \ asn1/a_verify.c \ asn1/ameth_lib.c \ asn1/asn1_err.c \ asn1/asn1_gen.c \ asn1/asn1_lib.c \ asn1/asn1_par.c \ asn1/asn_mime.c \ asn1/asn_moid.c \ asn1/asn_pack.c \ asn1/bio_asn1.c \ asn1/bio_ndef.c \ asn1/d2i_pr.c \ asn1/d2i_pu.c \ asn1/evp_asn1.c \ asn1/f_enum.c \ asn1/f_int.c \ asn1/f_string.c \ asn1/i2d_pr.c \ asn1/i2d_pu.c \ asn1/n_pkey.c \ asn1/nsseq.c \ asn1/p5_pbe.c \ asn1/p5_pbev2.c \ asn1/p8_pkey.c \ asn1/t_bitst.c \ asn1/t_crl.c \ asn1/t_pkey.c \ asn1/t_req.c \ asn1/t_spki.c \ asn1/t_x509.c \ asn1/t_x509a.c \ asn1/tasn_dec.c \ asn1/tasn_enc.c \ asn1/tasn_fre.c \ asn1/tasn_new.c \ asn1/tasn_prn.c \ asn1/tasn_typ.c \ asn1/tasn_utl.c \ asn1/x_algor.c \ asn1/x_attrib.c \ asn1/x_bignum.c \ asn1/x_crl.c \ asn1/x_exten.c \ asn1/x_info.c \ asn1/x_long.c \ asn1/x_name.c \ asn1/x_nx509.c \ asn1/x_pkey.c \ asn1/x_pubkey.c \ asn1/x_req.c \ asn1/x_sig.c \ asn1/x_spki.c \ asn1/x_val.c \ asn1/x_x509.c \ asn1/x_x509a.c \ bf/bf_cfb64.c \ bf/bf_ecb.c \ bf/bf_enc.c \ bf/bf_ofb64.c \ bf/bf_skey.c \ bio/b_dump.c \ bio/b_print.c \ bio/b_sock.c \ bio/bf_buff.c \ bio/bf_nbio.c \ bio/bf_null.c \ bio/bio_cb.c \ bio/bio_err.c \ bio/bio_lib.c \ bio/bss_acpt.c \ bio/bss_bio.c \ bio/bss_conn.c \ bio/bss_dgram.c \ bio/bss_fd.c \ bio/bss_file.c \ bio/bss_log.c \ bio/bss_mem.c \ bio/bss_null.c \ bio/bss_sock.c \ bn/bn_add.c \ bn/bn_asm.c \ bn/bn_blind.c \ bn/bn_const.c \ bn/bn_ctx.c \ bn/bn_depr.c \ bn/bn_div.c \ bn/bn_err.c \ bn/bn_exp.c \ bn/bn_exp2.c \ bn/bn_gcd.c \ bn/bn_gf2m.c \ bn/bn_kron.c \ bn/bn_lib.c \ bn/bn_mod.c \ bn/bn_mont.c \ bn/bn_mpi.c \ bn/bn_mul.c \ bn/bn_nist.c \ bn/bn_prime.c \ bn/bn_print.c \ bn/bn_rand.c \ bn/bn_recp.c \ bn/bn_shift.c \ bn/bn_sqr.c \ bn/bn_sqrt.c \ bn/bn_word.c \ bn/bn_x931p.c \ buffer/buf_err.c \ buffer/buf_str.c \ buffer/buffer.c \ cmac/cmac.c \ cmac/cm_ameth.c \ cmac/cm_pmeth.c \ comp/c_rle.c \ comp/c_zlib.c \ comp/comp_err.c \ comp/comp_lib.c \ conf/conf_api.c \ conf/conf_def.c \ conf/conf_err.c \ conf/conf_lib.c \ conf/conf_mall.c \ conf/conf_mod.c \ conf/conf_sap.c \ des/cbc_cksm.c \ des/cbc_enc.c \ des/cfb64ede.c \ des/cfb64enc.c \ des/cfb_enc.c \ des/des_enc.c \ des/des_old.c \ des/des_old2.c \ des/ecb3_enc.c \ des/ecb_enc.c \ des/ede_cbcm_enc.c \ des/enc_read.c \ des/enc_writ.c \ des/fcrypt.c \ des/fcrypt_b.c \ des/ofb64ede.c \ des/ofb64enc.c \ des/ofb_enc.c \ des/pcbc_enc.c \ des/qud_cksm.c \ des/rand_key.c \ des/read2pwd.c \ des/rpc_enc.c \ des/set_key.c \ des/str2key.c \ des/xcbc_enc.c \ dh/dh_ameth.c \ dh/dh_asn1.c \ dh/dh_check.c \ dh/dh_depr.c \ dh/dh_err.c \ dh/dh_gen.c \ dh/dh_key.c \ dh/dh_lib.c \ dh/dh_pmeth.c \ dh/dh_prn.c \ dsa/dsa_ameth.c \ dsa/dsa_asn1.c \ dsa/dsa_depr.c \ dsa/dsa_err.c \ dsa/dsa_gen.c \ dsa/dsa_key.c \ dsa/dsa_lib.c \ dsa/dsa_ossl.c \ dsa/dsa_pmeth.c \ dsa/dsa_prn.c \ dsa/dsa_sign.c \ dsa/dsa_vrf.c \ dso/dso_dl.c \ dso/dso_dlfcn.c \ dso/dso_err.c \ dso/dso_lib.c \ dso/dso_null.c \ dso/dso_openssl.c \ dso/dso_vms.c \ dso/dso_win32.c \ dso/dso_beos.c \ ec/ec2_mult.c \ ec/ec2_smpl.c \ ec/ec_ameth.c \ ec/ec_asn1.c \ ec/ec_check.c \ ec/ec_curve.c \ ec/ec_cvt.c \ ec/ec_err.c \ ec/ec_key.c \ ec/ec_lib.c \ ec/ec_mult.c \ ec/ec_pmeth.c \ ec/ec_print.c \ ec/eck_prn.c \ ec/ecp_mont.c \ ec/ecp_nist.c \ ec/ecp_smpl.c \ ec/ecp_nistp224.c \ ec/ecp_nistp256.c \ ec/ecp_nistp521.c \ ec/ecp_nistputil.c \ ec/ecp_oct.c \ ec/ec2_oct.c \ ec/ec_oct.c \ ecdh/ech_err.c \ ecdh/ech_key.c \ ecdh/ech_lib.c \ ecdh/ech_ossl.c \ ecdsa/ecs_asn1.c \ ecdsa/ecs_err.c \ ecdsa/ecs_lib.c \ ecdsa/ecs_ossl.c \ ecdsa/ecs_sign.c \ ecdsa/ecs_vrf.c \ err/err.c \ err/err_all.c \ err/err_prn.c \ evp/bio_b64.c \ evp/bio_enc.c \ evp/bio_md.c \ evp/bio_ok.c \ evp/c_all.c \ evp/c_allc.c \ evp/c_alld.c \ evp/digest.c \ evp/e_aes.c \ evp/e_bf.c \ evp/e_des.c \ evp/e_des3.c \ evp/e_null.c \ evp/e_old.c \ evp/e_rc2.c \ evp/e_rc4.c \ evp/e_rc5.c \ evp/e_xcbc_d.c \ evp/encode.c \ evp/evp_acnf.c \ evp/evp_enc.c \ evp/evp_err.c \ evp/evp_key.c \ evp/evp_lib.c \ evp/evp_pbe.c \ evp/evp_pkey.c \ evp/m_dss.c \ evp/m_dss1.c \ evp/m_ecdsa.c \ evp/m_md4.c \ evp/m_md5.c \ evp/m_mdc2.c \ evp/m_null.c \ evp/m_ripemd.c \ evp/m_sha1.c \ evp/m_sigver.c \ evp/m_wp.c \ evp/names.c \ evp/p5_crpt.c \ evp/p5_crpt2.c \ evp/p_dec.c \ evp/p_enc.c \ evp/p_lib.c \ evp/p_open.c \ evp/p_seal.c \ evp/p_sign.c \ evp/p_verify.c \ evp/pmeth_fn.c \ evp/pmeth_gn.c \ evp/pmeth_lib.c \ evp/e_idea.c \ evp/e_camellia.c \ evp/e_seed.c \ evp/e_cast.c \ evp/m_md2.c \ evp/m_sha.c \ evp/evp_fips.c \ evp/e_aes_cbc_hmac_sha1.c \ evp/e_rc4_hmac_md5.c \ hmac/hm_ameth.c \ hmac/hm_pmeth.c \ hmac/hmac.c \ krb5/krb5_asn.c \ lhash/lh_stats.c \ lhash/lhash.c \ md4/md4_dgst.c \ md4/md4_one.c \ md5/md5_dgst.c \ md5/md5_one.c \ modes/cbc128.c \ modes/ctr128.c \ modes/cts128.c \ modes/cfb128.c \ modes/ofb128.c \ modes/gcm128.c \ modes/ccm128.c \ modes/xts128.c \ objects/o_names.c \ objects/obj_dat.c \ objects/obj_err.c \ objects/obj_lib.c \ objects/obj_xref.c \ ocsp/ocsp_asn.c \ ocsp/ocsp_cl.c \ ocsp/ocsp_err.c \ ocsp/ocsp_ext.c \ ocsp/ocsp_ht.c \ ocsp/ocsp_lib.c \ ocsp/ocsp_prn.c \ ocsp/ocsp_srv.c \ ocsp/ocsp_vfy.c \ pem/pem_all.c \ pem/pem_err.c \ pem/pem_info.c \ pem/pem_lib.c \ pem/pem_oth.c \ pem/pem_pk8.c \ pem/pem_pkey.c \ pem/pem_seal.c \ pem/pem_sign.c \ pem/pem_x509.c \ pem/pem_xaux.c \ pem/pvkfmt.c \ pkcs12/p12_add.c \ pkcs12/p12_asn.c \ pkcs12/p12_attr.c \ pkcs12/p12_crpt.c \ pkcs12/p12_crt.c \ pkcs12/p12_decr.c \ pkcs12/p12_init.c \ pkcs12/p12_key.c \ pkcs12/p12_kiss.c \ pkcs12/p12_mutl.c \ pkcs12/p12_npas.c \ pkcs12/p12_p8d.c \ pkcs12/p12_p8e.c \ pkcs12/p12_utl.c \ pkcs12/pk12err.c \ pkcs7/pk7_asn1.c \ pkcs7/pk7_attr.c \ pkcs7/pk7_doit.c \ pkcs7/pk7_lib.c \ pkcs7/pk7_mime.c \ pkcs7/pk7_smime.c \ pkcs7/pkcs7err.c \ pkcs7/bio_pk7.c \ pqueue/pqueue.c \ rand/md_rand.c \ rand/rand_egd.c \ rand/rand_err.c \ rand/rand_lib.c \ rand/rand_unix.c \ rand/randfile.c \ rc2/rc2_cbc.c \ rc2/rc2_ecb.c \ rc2/rc2_skey.c \ rc2/rc2cfb64.c \ rc2/rc2ofb64.c \ rc4/rc4_enc.c \ rc4/rc4_skey.c \ rc4/rc4_utl.c \ ripemd/rmd_dgst.c \ ripemd/rmd_one.c \ rsa/rsa_ameth.c \ rsa/rsa_asn1.c \ rsa/rsa_chk.c \ rsa/rsa_eay.c \ rsa/rsa_err.c \ rsa/rsa_gen.c \ rsa/rsa_lib.c \ rsa/rsa_none.c \ rsa/rsa_null.c \ rsa/rsa_oaep.c \ rsa/rsa_pk1.c \ rsa/rsa_pmeth.c \ rsa/rsa_prn.c \ rsa/rsa_pss.c \ rsa/rsa_saos.c \ rsa/rsa_sign.c \ rsa/rsa_ssl.c \ rsa/rsa_x931.c \ rsa/rsa_depr.c \ rsa/rsa_crpt.c \ sha/sha1_one.c \ sha/sha1dgst.c \ sha/sha256.c \ sha/sha512.c \ sha/sha_dgst.c \ sha/sha_one.c \ srp/srp_lib.c \ srp/srp_vfy.c \ stack/stack.c \ ts/ts_err.c \ txt_db/txt_db.c \ ui/ui_compat.c \ ui/ui_err.c \ ui/ui_lib.c \ ui/ui_openssl.c \ ui/ui_util.c \ x509/by_dir.c \ x509/by_file.c \ x509/x509_att.c \ x509/x509_cmp.c \ x509/x509_d2.c \ x509/x509_def.c \ x509/x509_err.c \ x509/x509_ext.c \ x509/x509_lu.c \ x509/x509_obj.c \ x509/x509_r2x.c \ x509/x509_req.c \ x509/x509_set.c \ x509/x509_trs.c \ x509/x509_txt.c \ x509/x509_v3.c \ x509/x509_vfy.c \ x509/x509_vpm.c \ x509/x509cset.c \ x509/x509name.c \ x509/x509rset.c \ x509/x509spki.c \ x509/x509type.c \ x509/x_all.c \ x509v3/pcy_cache.c \ x509v3/pcy_data.c \ x509v3/pcy_lib.c \ x509v3/pcy_map.c \ x509v3/pcy_node.c \ x509v3/pcy_tree.c \ x509v3/v3_akey.c \ x509v3/v3_akeya.c \ x509v3/v3_alt.c \ x509v3/v3_asid.c \ x509v3/v3_addr.c \ x509v3/v3_bcons.c \ x509v3/v3_bitst.c \ x509v3/v3_conf.c \ x509v3/v3_cpols.c \ x509v3/v3_crld.c \ x509v3/v3_enum.c \ x509v3/v3_extku.c \ x509v3/v3_genn.c \ x509v3/v3_ia5.c \ x509v3/v3_info.c \ x509v3/v3_int.c \ x509v3/v3_lib.c \ x509v3/v3_ncons.c \ x509v3/v3_ocsp.c \ x509v3/v3_pci.c \ x509v3/v3_pcia.c \ x509v3/v3_pcons.c \ x509v3/v3_pku.c \ x509v3/v3_pmaps.c \ x509v3/v3_prn.c \ x509v3/v3_purp.c \ x509v3/v3_skey.c \ x509v3/v3_sxnet.c \ x509v3/v3_utl.c \ x509v3/v3err.c \ engine/eng_err.c \ engine/eng_lib.c \ engine/eng_list.c \ engine/eng_init.c \ engine/eng_ctrl.c \ engine/eng_table.c \ engine/eng_pkey.c \ engine/eng_fat.c \ engine/tb_rsa.c \ engine/tb_dsa.c \ engine/tb_ecdsa.c \ engine/tb_dh.c \ engine/tb_ecdh.c \ engine/tb_rand.c \ engine/tb_store.c \ engine/tb_cipher.c \ engine/tb_digest.c \ engine/tb_pkmeth.c \ engine/tb_asnmth.c \ engine/eng_openssl.c \ engine/eng_cnf.c \ engine/eng_dyn.c \ engine/eng_cryptodev.c \ engine/eng_rsax.c \ engine/eng_rdrand.c \ engine/eng_all.c \ fakewapi.c local_c_includes := \ $(NDK_PROJECT_PATH) \ $(NDK_PROJECT_PATH)/crypto/asn1 \ $(NDK_PROJECT_PATH)/crypto/evp \ $(NDK_PROJECT_PATH)/include \ $(NDK_PROJECT_PATH)/include/openssl \ $(NDK_PROJECT_PATH)/../include local_c_flags := -DNO_WINDOWS_BRAINDEATH include $(CLEAR_VARS) include $(LOCAL_PATH)/../android-config.mk LOCAL_SRC_FILES += $(local_src_files) LOCAL_CFLAGS += $(local_c_flags) LOCAL_C_INCLUDES += $(local_c_includes) LOCAL_LDLIBS += -lz ifeq ($(TARGET_ARCH),arm) LOCAL_SRC_FILES += $(arm_src_files) LOCAL_CFLAGS += $(arm_cflags) else LOCAL_SRC_FILES += $(non_arm_src_files) endif ifeq ($(TARGET_SIMULATOR),true) # Make valgrind happy. LOCAL_CFLAGS += -DPURIFY LOCAL_LDLIBS += -ldl endif LOCAL_MODULE_TAGS := optional LOCAL_MODULE:= libcrypto include $(BUILD_SHARED_LIBRARY) ifeq ($(WITH_HOST_DALVIK),true) include $(CLEAR_VARS) include $(LOCAL_PATH)/../android-config.mk LOCAL_SRC_FILES += $(local_src_files) LOCAL_CFLAGS += $(local_c_flags) -DPURIFY LOCAL_C_INCLUDES += $(local_c_includes) LOCAL_SRC_FILES += $(non_arm_src_files) LOCAL_LDLIBS += -ldl LOCAL_MODULE_TAGS := optional LOCAL_MODULE:= libcrypto include $(BUILD_SHARED_LIBRARY) endif include $(CLEAR_VARS) include $(LOCAL_PATH)/../android-config.mk LOCAL_SRC_FILES += $(local_src_files) LOCAL_CFLAGS += $(local_c_flags) -DPURIFY LOCAL_C_INCLUDES += $(local_c_includes) LOCAL_SRC_FILES += $(non_arm_src_files) LOCAL_LDLIBS += -ldl LOCAL_MODULE_TAGS := optional LOCAL_MODULE:= libcrypto_static include $(BUILD_STATIC_LIBRARY)
ssl/Android.mk :
LOCAL_PATH:= $(call my-dir) local_c_includes := \ $(NDK_PROJECT_PATH) \ $(NDK_PROJECT_PATH)/include \ $(NDK_PROJECT_PATH)/crypto \ $(NDK_PROJECT_PATH)/../include local_src_files:= \ s2_meth.c \ s2_srvr.c \ s2_clnt.c \ s2_lib.c \ s2_enc.c \ s2_pkt.c \ s3_meth.c \ s3_srvr.c \ s3_clnt.c \ s3_lib.c \ s3_enc.c \ s3_pkt.c \ s3_both.c \ s23_meth.c \ s23_srvr.c \ s23_clnt.c \ s23_lib.c \ s23_pkt.c \ t1_meth.c \ t1_srvr.c \ t1_clnt.c \ t1_lib.c \ t1_enc.c \ t1_reneg.c \ d1_meth.c \ d1_srvr.c \ d1_clnt.c \ d1_lib.c \ d1_pkt.c \ d1_both.c \ d1_enc.c \ d1_srtp.c \ ssl_lib.c \ ssl_err2.c \ ssl_cert.c \ ssl_sess.c \ ssl_ciph.c \ ssl_stat.c \ ssl_rsa.c \ ssl_asn1.c \ ssl_txt.c \ ssl_algs.c \ bio_ssl.c \ ssl_err.c \ kssl.c \ tls_srp.c include $(CLEAR_VARS) include $(LOCAL_PATH)/../android-config.mk LOCAL_SRC_FILES += $(local_src_files) LOCAL_C_INCLUDES += $(local_c_includes) LOCAL_SHARED_LIBRARIES += libcrypto LOCAL_MODULE_TAGS := optional LOCAL_MODULE:= libssl include $(BUILD_SHARED_LIBRARY) ifeq ($(WITH_HOST_DALVIK),true) include $(CLEAR_VARS) include $(LOCAL_PATH)/../android-config.mk LOCAL_SRC_FILES += $(local_src_files) LOCAL_C_INCLUDES += $(local_c_includes) LOCAL_SHARED_LIBRARIES += libcrypto LOCAL_MODULE_TAGS := optional LOCAL_MODULE:= libssl include $(BUILD_SHARED_LIBRARY) endif include $(CLEAR_VARS) include $(LOCAL_PATH)/../android-config.mk LOCAL_SRC_FILES:= ssltest.c LOCAL_C_INCLUDES += $(local_c_includes) LOCAL_SHARED_LIBRARIES := libssl libcrypto LOCAL_MODULE:= ssltest LOCAL_MODULE_TAGS := optional include $(BUILD_EXECUTABLE)
接着,生成 libcrypto 的一票子汇编代码。对于 ARM 的机器有:
perl crypto/aes/asm/aes-armv4.pl > crypto/aes/asm/aes-armv4.S perl crypto/bn/asm/armv4-mont.pl > crypto/bn/asm/armv4-mont.S perl crypto/sha/asm/sha1-armv4-large.pl > crypto/sha/asm/sha1-armv4-large.S perl crypto/sha/asm/sha256-armv4.pl > crypto/sha/asm/sha256-armv4.S perl crypto/sha/asm/sha512-armv4.pl > crypto/sha/asm/sha512-armv4.S
新建 crypto/fakewapi.c ,用一些 dummy 填充某些支持 WAPI 的机器上 wpa_supplicant 所需的一些函数(源码没找到,这将废掉 WAPI 支持):
int i2o_ECPrivateKey(int i, ...) { return 0; } int i2o_ECDSA_SIG(int i, ...) { return 0; } int o2i_ECDSA_SIG(int i, ...) { return 0; }
保存下面这个 patch 到 jsse.patch :
--- openssl-1.0.0b.orig/ssl/ssl.h 2010-11-30 00:03:46.000000000 +0000 +++ openssl-1.0.0b/ssl/ssl.h 2010-11-30 00:03:47.000000000 +0000 @@ -1133,6 +1133,9 @@ struct ssl_st /* This can also be in the session once a session is established */ SSL_SESSION *session; + /* This can be disabled to prevent the use of uncached sessions */ + int session_creation_enabled; + /* Default generate session ID callback. */ GEN_SESSION_CB generate_session_id; @@ -1546,6 +1549,7 @@ const SSL_CIPHER *SSL_get_current_cipher int SSL_CIPHER_get_bits(const SSL_CIPHER *c,int *alg_bits); char * SSL_CIPHER_get_version(const SSL_CIPHER *c); const char * SSL_CIPHER_get_name(const SSL_CIPHER *c); +const char * SSL_CIPHER_authentication_method(const SSL_CIPHER *c); int SSL_get_fd(const SSL *s); int SSL_get_rfd(const SSL *s); @@ -1554,6 +1558,7 @@ const char * SSL_get_cipher_list(const char * SSL_get_shared_ciphers(const SSL *s, char *buf, int len); int SSL_get_read_ahead(const SSL * s); int SSL_pending(const SSL *s); +const char * SSL_authentication_method(const SSL *c); #ifndef OPENSSL_NO_SOCK int SSL_set_fd(SSL *s, int fd); int SSL_set_rfd(SSL *s, int fd); @@ -1565,6 +1570,7 @@ BIO * SSL_get_rbio(const SSL *s); BIO * SSL_get_wbio(const SSL *s); #endif int SSL_set_cipher_list(SSL *s, const char *str); +int SSL_set_cipher_lists(SSL *s, STACK_OF(SSL_CIPHER) *sk); void SSL_set_read_ahead(SSL *s, int yes); int SSL_get_verify_mode(const SSL *s); int SSL_get_verify_depth(const SSL *s); @@ -1580,6 +1586,8 @@ int SSL_use_PrivateKey(SSL *ssl, EVP_PKE int SSL_use_PrivateKey_ASN1(int pk,SSL *ssl, const unsigned char *d, long len); int SSL_use_certificate(SSL *ssl, X509 *x); int SSL_use_certificate_ASN1(SSL *ssl, const unsigned char *d, int len); +int SSL_use_certificate_chain(SSL *ssl, STACK_OF(X509) *cert_chain); +STACK_OF(X509) * SSL_get_certificate_chain(SSL *ssl, X509 *x); #ifndef OPENSSL_NO_STDIO int SSL_use_RSAPrivateKey_file(SSL *ssl, const char *file, int type); @@ -1615,6 +1623,7 @@ void SSL_copy_session_id(SSL *to,const S SSL_SESSION *SSL_SESSION_new(void); const unsigned char *SSL_SESSION_get_id(const SSL_SESSION *s, unsigned int *len); +const char * SSL_SESSION_get_version(const SSL_SESSION *s); #ifndef OPENSSL_NO_FP_API int SSL_SESSION_print_fp(FILE *fp,const SSL_SESSION *ses); #endif @@ -1624,6 +1633,7 @@ int SSL_SESSION_print(BIO *fp,const SSL_ void SSL_SESSION_free(SSL_SESSION *ses); int i2d_SSL_SESSION(SSL_SESSION *in,unsigned char **pp); int SSL_set_session(SSL *to, SSL_SESSION *session); +void SSL_set_session_creation_enabled(SSL *, int); int SSL_CTX_add_session(SSL_CTX *s, SSL_SESSION *c); int SSL_CTX_remove_session(SSL_CTX *,SSL_SESSION *c); int SSL_CTX_set_generate_session_id(SSL_CTX *, GEN_SESSION_CB); @@ -2066,6 +2076,7 @@ void ERR_load_SSL_strings(void); #define SSL_F_SSL_UNDEFINED_VOID_FUNCTION 244 #define SSL_F_SSL_USE_CERTIFICATE 198 #define SSL_F_SSL_USE_CERTIFICATE_ASN1 199 +#define SSL_F_SSL_USE_CERTIFICATE_CHAIN 2000 #define SSL_F_SSL_USE_CERTIFICATE_FILE 200 #define SSL_F_SSL_USE_PRIVATEKEY 201 #define SSL_F_SSL_USE_PRIVATEKEY_ASN1 202 @@ -2272,6 +2283,7 @@ void ERR_load_SSL_strings(void); #define SSL_R_SCSV_RECEIVED_WHEN_RENEGOTIATING 345 #define SSL_R_SERVERHELLO_TLSEXT 275 #define SSL_R_SESSION_ID_CONTEXT_UNINITIALIZED 277 +#define SSL_R_SESSION_MAY_NOT_BE_CREATED 2000 #define SSL_R_SHORT_READ 219 #define SSL_R_SIGNATURE_FOR_NON_SIGNING_CERTIFICATE 220 #define SSL_R_SSL23_DOING_SESSION_ID_REUSE 221 --- openssl-1.0.0b.orig/ssl/d1_clnt.c 2010-01-26 19:46:29.000000000 +0000 +++ openssl-1.0.0b/ssl/d1_clnt.c 2010-11-30 00:03:47.000000000 +0000 @@ -613,6 +613,12 @@ int dtls1_client_hello(SSL *s) #endif (s->session->not_resumable)) { + if (!s->session_creation_enabled) + { + ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_HANDSHAKE_FAILURE); + SSLerr(SSL_F_DTLS1_CLIENT_HELLO,SSL_R_SESSION_MAY_NOT_BE_CREATED); + goto err; + } if (!ssl_get_new_session(s,0)) goto err; } --- openssl-1.0.0b.orig/ssl/s23_clnt.c 2010-02-16 14:20:40.000000000 +0000 +++ openssl-1.0.0b/ssl/s23_clnt.c 2010-11-30 00:03:47.000000000 +0000 @@ -687,6 +687,13 @@ static int ssl23_get_server_hello(SSL *s /* Since, if we are sending a ssl23 client hello, we are not * reusing a session-id */ + if (!s->session_creation_enabled) + { + if (!(s->client_version == SSL2_VERSION)) + ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_HANDSHAKE_FAILURE); + SSLerr(SSL_F_SSL23_GET_SERVER_HELLO,SSL_R_SESSION_MAY_NOT_BE_CREATED); + goto err; + } if (!ssl_get_new_session(s,0)) goto err; --- openssl-1.0.0b.orig/ssl/s3_both.c 2010-11-30 00:03:46.000000000 +0000 +++ openssl-1.0.0b/ssl/s3_both.c 2010-11-30 00:03:47.000000000 +0000 @@ -347,8 +347,11 @@ unsigned long ssl3_output_cert_chain(SSL unsigned long l=7; BUF_MEM *buf; int no_chain; + STACK_OF(X509) *cert_chain; - if ((s->mode & SSL_MODE_NO_AUTO_CHAIN) || s->ctx->extra_certs) + cert_chain = SSL_get_certificate_chain(s, x); + + if ((s->mode & SSL_MODE_NO_AUTO_CHAIN) || s->ctx->extra_certs || cert_chain) no_chain = 1; else no_chain = 0; @@ -400,6 +403,10 @@ unsigned long ssl3_output_cert_chain(SSL return(0); } + for (i=0; i<sk_X509_num(cert_chain); i++) + if (ssl3_add_cert_to_buf(buf, &l, sk_X509_value(cert_chain,i))) + return(0); + l-=7; p=(unsigned char *)&(buf->data[4]); l2n3(l,p); --- openssl-1.0.0b.orig/ssl/s3_clnt.c 2010-11-30 00:03:46.000000000 +0000 +++ openssl-1.0.0b/ssl/s3_clnt.c 2010-11-30 00:03:47.000000000 +0000 @@ -686,6 +686,12 @@ int ssl3_client_hello(SSL *s) #endif (sess->not_resumable)) { + if (!s->session_creation_enabled) + { + ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_HANDSHAKE_FAILURE); + SSLerr(SSL_F_SSL3_CLIENT_HELLO,SSL_R_SESSION_MAY_NOT_BE_CREATED); + goto err; + } if (!ssl_get_new_session(s,0)) goto err; } @@ -894,6 +900,12 @@ int ssl3_get_server_hello(SSL *s) s->hit=0; if (s->session->session_id_length > 0) { + if (!s->session_creation_enabled) + { + ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_HANDSHAKE_FAILURE); + SSLerr(SSL_F_SSL3_GET_SERVER_HELLO,SSL_R_SESSION_MAY_NOT_BE_CREATED); + goto err; + } if (!ssl_get_new_session(s,0)) { al=SSL_AD_INTERNAL_ERROR; --- openssl-1.0.0b.orig/ssl/s3_srvr.c 2010-11-30 00:03:46.000000000 +0000 +++ openssl-1.0.0b/ssl/s3_srvr.c 2010-11-30 00:03:47.000000000 +0000 @@ -902,6 +902,12 @@ int ssl3_get_client_hello(SSL *s) */ if ((s->new_session && (s->options & SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION))) { + if (!s->session_creation_enabled) + { + ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_HANDSHAKE_FAILURE); + SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO,SSL_R_SESSION_MAY_NOT_BE_CREATED); + goto err; + } if (!ssl_get_new_session(s,1)) goto err; } @@ -916,6 +922,12 @@ int ssl3_get_client_hello(SSL *s) goto err; else /* i == 0 */ { + if (!s->session_creation_enabled) + { + ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_HANDSHAKE_FAILURE); + SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO,SSL_R_SESSION_MAY_NOT_BE_CREATED); + goto err; + } if (!ssl_get_new_session(s,1)) goto err; } --- openssl-1.0.0b.orig/ssl/ssl_ciph.c 2010-06-15 17:25:14.000000000 +0000 +++ openssl-1.0.0b/ssl/ssl_ciph.c 2010-11-30 00:03:47.000000000 +0000 @@ -1652,6 +1652,52 @@ int SSL_CIPHER_get_bits(const SSL_CIPHER return(ret); } +/* return string version of key exchange algorithm */ +const char* SSL_CIPHER_authentication_method(const SSL_CIPHER* cipher) + { + switch (cipher->algorithm_mkey) + { + case SSL_kRSA: + return SSL_TXT_RSA; + case SSL_kDHr: + return SSL_TXT_DH "_" SSL_TXT_RSA; + case SSL_kDHd: + return SSL_TXT_DH "_" SSL_TXT_DSS; + case SSL_kEDH: + switch (cipher->algorithm_auth) + { + case SSL_aDSS: + return "DHE_" SSL_TXT_DSS; + case SSL_aRSA: + return "DHE_" SSL_TXT_RSA; + case SSL_aNULL: + return SSL_TXT_DH "_anon"; + default: + return "UNKNOWN"; + } + case SSL_kKRB5: + return SSL_TXT_KRB5; + case SSL_kECDHr: + return SSL_TXT_ECDH "_" SSL_TXT_RSA; + case SSL_kECDHe: + return SSL_TXT_ECDH "_" SSL_TXT_ECDSA; + case SSL_kEECDH: + switch (cipher->algorithm_auth) + { + case SSL_aECDSA: + return "ECDHE_" SSL_TXT_ECDSA; + case SSL_aRSA: + return "ECDHE_" SSL_TXT_RSA; + case SSL_aNULL: + return SSL_TXT_ECDH "_anon"; + default: + return "UNKNOWN"; + } + default: + return "UNKNOWN"; + } + } + SSL_COMP *ssl3_comp_find(STACK_OF(SSL_COMP) *sk, int n) { SSL_COMP *ctmp; --- openssl-1.0.0b.orig/ssl/ssl_err.c 2010-11-30 00:03:46.000000000 +0000 +++ openssl-1.0.0b/ssl/ssl_err.c 2010-11-30 00:03:47.000000000 +0000 @@ -465,6 +465,7 @@ static ERR_STRING_DATA SSL_str_reasons[] {ERR_REASON(SSL_R_SCSV_RECEIVED_WHEN_RENEGOTIATING),"scsv received when renegotiating"}, {ERR_REASON(SSL_R_SERVERHELLO_TLSEXT) ,"serverhello tlsext"}, {ERR_REASON(SSL_R_SESSION_ID_CONTEXT_UNINITIALIZED),"session id context uninitialized"}, +{ERR_REASON(SSL_R_SESSION_MAY_NOT_BE_CREATED),"session may not be created"}, {ERR_REASON(SSL_R_SHORT_READ) ,"short read"}, {ERR_REASON(SSL_R_SIGNATURE_FOR_NON_SIGNING_CERTIFICATE),"signature for non signing certificate"}, {ERR_REASON(SSL_R_SSL23_DOING_SESSION_ID_REUSE),"ssl23 doing session id reuse"}, --- openssl-1.0.0b.orig/ssl/ssl_lib.c 2010-11-30 00:03:46.000000000 +0000 +++ openssl-1.0.0b/ssl/ssl_lib.c 2010-11-30 00:03:47.000000000 +0000 @@ -326,6 +326,7 @@ SSL *SSL_new(SSL_CTX *ctx) OPENSSL_assert(s->sid_ctx_length <= sizeof s->sid_ctx); memcpy(&s->sid_ctx,&ctx->sid_ctx,sizeof(s->sid_ctx)); s->verify_callback=ctx->default_verify_callback; + s->session_creation_enabled=1; s->generate_session_id=ctx->generate_session_id; s->param = X509_VERIFY_PARAM_new(); @@ -1311,6 +1312,32 @@ int SSL_set_cipher_list(SSL *s,const cha return 1; } +/** specify the ciphers to be used by the SSL */ +int SSL_set_cipher_lists(SSL *s,STACK_OF(SSL_CIPHER) *sk) + { + STACK_OF(SSL_CIPHER) *tmp_cipher_list; + + if (sk == NULL) + return 0; + + /* Based on end of ssl_create_cipher_list */ + tmp_cipher_list = sk_SSL_CIPHER_dup(sk); + if (tmp_cipher_list == NULL) + { + return 0; + } + if (s->cipher_list != NULL) + sk_SSL_CIPHER_free(s->cipher_list); + s->cipher_list = sk; + if (s->cipher_list_by_id != NULL) + sk_SSL_CIPHER_free(s->cipher_list_by_id); + s->cipher_list_by_id = tmp_cipher_list; + (void)sk_SSL_CIPHER_set_cmp_func(s->cipher_list_by_id,ssl_cipher_ptr_id_cmp); + + sk_SSL_CIPHER_sort(s->cipher_list_by_id); + return 1; + } + /* works well for SSLv2, not so good for SSLv3 */ char *SSL_get_shared_ciphers(const SSL *s,char *buf,int len) { @@ -2551,18 +2578,45 @@ SSL_METHOD *ssl_bad_method(int ver) return(NULL); } -const char *SSL_get_version(const SSL *s) +static const char *ssl_get_version(int version) { - if (s->version == TLS1_VERSION) + if (version == TLS1_VERSION) return("TLSv1"); - else if (s->version == SSL3_VERSION) + else if (version == SSL3_VERSION) return("SSLv3"); - else if (s->version == SSL2_VERSION) + else if (version == SSL2_VERSION) return("SSLv2"); else return("unknown"); } +const char *SSL_get_version(const SSL *s) + { + return ssl_get_version(s->version); + } + +const char *SSL_SESSION_get_version(const SSL_SESSION *s) + { + return ssl_get_version(s->ssl_version); + } + +const char* SSL_authentication_method(const SSL* ssl) + { + if (ssl->cert != NULL && ssl->cert->rsa_tmp != NULL) + return SSL_TXT_RSA "_" SSL_TXT_EXPORT; + switch (ssl->version) + { + case SSL2_VERSION: + return SSL_TXT_RSA; + case SSL3_VERSION: + case TLS1_VERSION: + case DTLS1_VERSION: + return SSL_CIPHER_authentication_method(ssl->s3->tmp.new_cipher); + default: + return "UNKNOWN"; + } + } + SSL *SSL_dup(SSL *s) { STACK_OF(X509_NAME) *sk; --- openssl-1.0.0b.orig/ssl/ssl_locl.h 2010-11-30 00:03:46.000000000 +0000 +++ openssl-1.0.0b/ssl/ssl_locl.h 2010-11-30 00:03:47.000000000 +0000 @@ -456,6 +456,7 @@ typedef struct cert_pkey_st { X509 *x509; + STACK_OF(X509) *cert_chain; EVP_PKEY *privatekey; } CERT_PKEY; --- openssl-1.0.0b.orig/ssl/ssl_rsa.c 2009-09-12 23:09:26.000000000 +0000 +++ openssl-1.0.0b/ssl/ssl_rsa.c 2010-11-30 00:03:47.000000000 +0000 @@ -697,6 +697,42 @@ int SSL_CTX_use_PrivateKey_ASN1(int type } +int SSL_use_certificate_chain(SSL *ssl, STACK_OF(X509) *cert_chain) + { + if (ssl == NULL) + { + SSLerr(SSL_F_SSL_USE_CERTIFICATE_CHAIN,ERR_R_PASSED_NULL_PARAMETER); + return(0); + } + if (ssl->cert == NULL) + { + SSLerr(SSL_F_SSL_USE_CERTIFICATE_CHAIN,SSL_R_NO_CERTIFICATE_ASSIGNED); + return(0); + } + if (ssl->cert->key == NULL) + { + SSLerr(SSL_F_SSL_USE_CERTIFICATE_CHAIN,SSL_R_NO_CERTIFICATE_ASSIGNED); + return(0); + } + ssl->cert->key->cert_chain = cert_chain; + return(1); + } + +STACK_OF(X509) *SSL_get_certificate_chain(SSL *ssl, X509 *x) + { + int i; + if (x == NULL) + return NULL; + if (ssl == NULL) + return NULL; + if (ssl->cert == NULL) + return NULL; + for (i = 0; i < SSL_PKEY_NUM; i++) + if (ssl->cert->pkeys[i].x509 == x) + return ssl->cert->pkeys[i].cert_chain; + return NULL; + } + #ifndef OPENSSL_NO_STDIO /* Read a file that contains our certificate in "PEM" format, * possibly followed by a sequence of CA certificates that should be --- openssl-1.0.0b.orig/ssl/ssl_sess.c 2010-02-01 16:49:42.000000000 +0000 +++ openssl-1.0.0b/ssl/ssl_sess.c 2010-11-30 00:03:47.000000000 +0000 @@ -261,6 +261,11 @@ static int def_generate_session_id(const return 0; } +void SSL_set_session_creation_enabled (SSL *s, int creation_enabled) + { + s->session_creation_enabled = creation_enabled; + } + int ssl_get_new_session(SSL *s, int session) { /* This gets used by clients and servers. */ @@ -269,6 +274,8 @@ int ssl_get_new_session(SSL *s, int sess SSL_SESSION *ss=NULL; GEN_SESSION_CB cb = def_generate_session_id; + /* caller should check this if they can do better error handling */ + if (!s->session_creation_enabled) return(0); if ((ss=SSL_SESSION_new()) == NULL) return(0); /* If the context has a default timeout, use it */
接着应用这个 patch :
patch -p1 < jsse.patch
有些地方会合并失败,需要参照 rej 文件手动 merge 。这个 patch 会提供 Android 需要的一些附加函数。
打开 crypto/bf/blowfish.h ,删除开头的以下内容:
diff --git a/crypto/bf/blowfish.h b/crypto/bf/blowfish.h index 4b6c892..2a9ae98 100644 --- a/crypto/bf/blowfish.h +++ b/crypto/bf/blowfish.h @@ -65,10 +65,6 @@ extern "C" { #endif -#ifdef OPENSSL_NO_BF -#error BF is disabled. -#endif - #define BF_ENCRYPT 1 #define BF_DECRYPT 0
这样,源码的修改基本就完成了。
编译
编译的过程相对简单,在 OpenSSL 源码目录下输入:
NDK_PROJECT_PATH=. /path/to/android-ndk/ndk-build
稍等片刻即可。
安装
注意!由于 Android 的系统核心库需要连接 libcrypt 和 libssl ,更换缺少符号的 OpenSSL 库会导致大量程序无法启动甚至手机变砖,请确认 OpenSSL 库含有 Android 系统所需的所有符号。
安装前请确认手机已经 root 且 su 和 busybox 可用。
第一步是下载 Android SDK 或者从系统软件源里面安装 adb 。第二步就是打开手机上的 USB 调试。更换 OpenSSL 库后,在确定各个程序运行正常、手机能正常重启并使用 Wifi 之前请不要关掉 USB 调试。
第三步,用 adb 把编译好的文件传送至手机 SD 卡中:
adb push libs/armeabi/libcrypto.so /sdcard/ adb push libs/armeabi/libssl.so /sdcard/ adb push libs/armeabi/openssl /sdcard/
第四步,输入 adb shell ,启动手机上的终端。在里面键入以下命令:
busybox mount -o remount,rw /system mkdir /system/lib/old-ssl mv /system/lib/libcrypto.so /system/lib/libssl.so /system/lib/old-ssl/ cp /sdcard/libcrypto.so /system/lib/ cp /sdcard/libssl.so /system/lib/ cp /sdcard/openssl /system/xbin/ chmod 0644 /system/lib/libcrypto.so /system/lib/libssl.so chmod 0755 /system/xbin/openssl rm /sdcard/libcrypto.so /sdcard/libssl.so /sdcard/openssl busybox mount -o remount,ro /system
第五步,测试。新开一个 adb shell ,输入 su ,观察链接器是否报错。输入“ openssl version ”查看版本信息。关闭手机上的浏览器和 Wifi ,杀掉所有进程,重开 Wifi 和浏览器,访问带有 SSL 的网站,观察其工作是否正常。在此期间可以用“ adb logcat ”查看日志。
若出现工作不正常的程序,在 adb shell 里手工调用,观察链接器输出,考虑是否能 patch 代码重新编译来修复。若无法修复,就只好还原 OpenSSL 的备份了:
busybox mount -o remount,rw /system mv /system/lib/old-ssl/* /system/lib rmdir /system/lib/old-ssl rm /system/xbin/openssl busybox mount -o remount,ro /system
若测试成功,则可以“ adb reboot ”来重启手机,看看各部件是否仍然能正常工作。若手机一直停留在启动画面,则可以尝试通过 adb shell 还原原来的 OpenSSL 库。
的确是该死的Android,真他娘的,弄吧。。。。。。。。。
尤其注意需要打开 engine 这个是什么意思,怎么打开? 我在编译的时候碰到这块 头文件找不到的问题,但是文件明明在那,求解答。。。。
不贴日志我怎么知道你在说什么?
尤其注意需要打开 engine ,求怎么打开????这块报错了
engine是第三方加密库,可忽略