为该死的 Android 编译新版本的 OpenSSL 库

不知道从什么时候起,大家都喜欢把简单的事情复杂化,好像越难用就越牛逼一样。装逼的倒是无所谓,等到要用的时候就傻了。以上是题外话。手机上的 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 源码目录下执行:

代码
1
2
3
4
# For ARM Cortex
./Configure android-armv7 -DL_ENDIAN
# For x86
./Configure android-x86 -DL_ENDIAN

然后:

代码
1
2
3
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 的机器有:

代码
1
2
3
4
5
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 支持):

代码
1
2
3
4
5
6
7
8
9
10
11
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 :

代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
--- 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 :

代码
1
patch -p1 < jsse.patch

有些地方会合并失败,需要参照 rej 文件手动 merge 。这个 patch 会提供 Android 需要的一些附加函数。

打开 crypto/bf/blowfish.h ,删除开头的以下内容:

代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
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 源码目录下输入:

代码
1
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 卡中:

代码
1
2
3
adb push libs/armeabi/libcrypto.so /sdcard/
adb push libs/armeabi/libssl.so /sdcard/
adb push libs/armeabi/openssl /sdcard/

第四步,输入 adb shell ,启动手机上的终端。在里面键入以下命令:

代码
1
2
3
4
5
6
7
8
9
10
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 的备份了:

代码
1
2
3
4
5
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 编译新版本的 OpenSSL 库》上的5个想法

  1. 尤其注意需要打开 engine 这个是什么意思,怎么打开? 我在编译的时候碰到这块 头文件找不到的问题,但是文件明明在那,求解答。。。。

回复 yinchonging 取消回复

您的电子邮箱地址不会被公开。 必填项已用*标注

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据