summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/.gitignore1
-rw-r--r--src/BUILDING96
-rw-r--r--src/BUILDING.md100
-rw-r--r--src/LICENSE39
-rw-r--r--src/PORTING.md157
-rw-r--r--src/STYLE198
-rw-r--r--src/STYLE.md197
-rw-r--r--src/crypto/CMakeLists.txt7
-rw-r--r--src/crypto/aes/CMakeLists.txt11
-rw-r--r--src/crypto/aes/aes_test.cc102
-rwxr-xr-xsrc/crypto/aes/asm/aes-586.pl6
-rw-r--r--src/crypto/aes/asm/aes-armv4.pl2
-rw-r--r--src/crypto/aes/asm/aesv8-armx.pl2
-rw-r--r--src/crypto/aes/asm/bsaes-armv7.pl2
-rw-r--r--src/crypto/asn1/CMakeLists.txt2
-rw-r--r--src/crypto/asn1/a_bitstr.c11
-rw-r--r--src/crypto/asn1/a_bool.c2
-rw-r--r--src/crypto/asn1/a_bytes.c6
-rw-r--r--src/crypto/asn1/a_d2i_fp.c24
-rw-r--r--src/crypto/asn1/a_dup.c4
-rw-r--r--src/crypto/asn1/a_enum.c8
-rw-r--r--src/crypto/asn1/a_gentm.c2
-rw-r--r--src/crypto/asn1/a_i2d_fp.c10
-rw-r--r--src/crypto/asn1/a_int.c12
-rw-r--r--src/crypto/asn1/a_mbstr.c20
-rw-r--r--src/crypto/asn1/a_object.c22
-rw-r--r--src/crypto/asn1/a_strnid.c4
-rw-r--r--src/crypto/asn1/a_time.c4
-rw-r--r--src/crypto/asn1/a_utctm.c6
-rw-r--r--src/crypto/asn1/asn1_lib.c15
-rw-r--r--src/crypto/asn1/asn_pack.c8
-rw-r--r--src/crypto/asn1/bio_ndef.c2
-rw-r--r--src/crypto/asn1/f_enum.c8
-rw-r--r--src/crypto/asn1/f_int.c8
-rw-r--r--src/crypto/asn1/f_string.c8
-rw-r--r--src/crypto/asn1/tasn_dec.c111
-rw-r--r--src/crypto/asn1/tasn_new.c6
-rw-r--r--src/crypto/asn1/tasn_prn.c2
-rw-r--r--src/crypto/asn1/tasn_utl.c3
-rw-r--r--src/crypto/asn1/x_long.c4
-rw-r--r--src/crypto/base64/CMakeLists.txt2
-rw-r--r--src/crypto/bio/CMakeLists.txt2
-rw-r--r--src/crypto/bio/bio.c14
-rw-r--r--src/crypto/bio/bio_mem.c4
-rw-r--r--src/crypto/bio/buffer.c2
-rw-r--r--src/crypto/bio/connect.c16
-rw-r--r--src/crypto/bio/file.c21
-rw-r--r--src/crypto/bio/pair.c62
-rw-r--r--src/crypto/bio/printf.c2
-rw-r--r--src/crypto/bio/socket_helper.c5
-rw-r--r--src/crypto/bn/CMakeLists.txt3
-rw-r--r--src/crypto/bn/add.c2
-rw-r--r--src/crypto/bn/asm/armv4-mont.pl2
-rw-r--r--src/crypto/bn/bn.c20
-rw-r--r--src/crypto/bn/bn_asn1.c93
-rw-r--r--src/crypto/bn/bn_test.cc376
-rw-r--r--src/crypto/bn/convert.c178
-rw-r--r--src/crypto/bn/ctx.c6
-rw-r--r--src/crypto/bn/div.c6
-rw-r--r--src/crypto/bn/exponentiation.c30
-rw-r--r--src/crypto/bn/gcd.c32
-rw-r--r--src/crypto/bn/internal.h4
-rw-r--r--src/crypto/bn/montgomery.c6
-rw-r--r--src/crypto/bn/mul.c8
-rw-r--r--src/crypto/bn/prime.c9
-rw-r--r--src/crypto/bn/random.c14
-rw-r--r--src/crypto/bn/rsaz_exp.h68
-rw-r--r--src/crypto/bn/shift.c4
-rw-r--r--src/crypto/bn/sqrt.c24
-rw-r--r--src/crypto/buf/CMakeLists.txt2
-rw-r--r--src/crypto/buf/buf.c14
-rw-r--r--src/crypto/bytestring/CMakeLists.txt2
-rw-r--r--src/crypto/bytestring/bytestring_test.cc13
-rw-r--r--src/crypto/bytestring/cbb.c9
-rw-r--r--src/crypto/bytestring/cbs.c20
-rw-r--r--src/crypto/bytestring/internal.h8
-rw-r--r--src/crypto/chacha/CMakeLists.txt2
-rw-r--r--src/crypto/chacha/chacha_vec_arm.S2
-rw-r--r--src/crypto/chacha/chacha_vec_arm_generate.go4
-rw-r--r--src/crypto/cipher/CMakeLists.txt2
-rw-r--r--src/crypto/cipher/aead.c15
-rw-r--r--src/crypto/cipher/aead_test.cc62
-rw-r--r--src/crypto/cipher/cipher.c41
-rw-r--r--src/crypto/cipher/cipher_test.cc57
-rw-r--r--src/crypto/cipher/e_aes.c108
-rw-r--r--src/crypto/cipher/e_chacha20poly1305.c22
-rw-r--r--src/crypto/cipher/e_des.c78
-rw-r--r--src/crypto/cipher/e_rc2.c27
-rw-r--r--src/crypto/cipher/e_rc4.c22
-rw-r--r--src/crypto/cipher/e_ssl3.c56
-rw-r--r--src/crypto/cipher/e_tls.c56
-rw-r--r--src/crypto/cipher/test/aes_128_gcm_tests.txt6
-rw-r--r--src/crypto/cipher/test/cipher_test.txt60
-rw-r--r--src/crypto/cmac/CMakeLists.txt4
-rw-r--r--src/crypto/cmac/cmac_test.cc13
-rw-r--r--src/crypto/conf/CMakeLists.txt2
-rw-r--r--src/crypto/conf/conf.c64
-rw-r--r--src/crypto/conf/internal.h31
-rw-r--r--src/crypto/cpu-arm.c6
-rw-r--r--src/crypto/cpu-intel.c157
-rw-r--r--src/crypto/cpu-x86-asm.pl334
-rw-r--r--src/crypto/cpu-x86_64-asm.pl163
-rw-r--r--src/crypto/crypto.c2
-rw-r--r--src/crypto/des/CMakeLists.txt2
-rw-r--r--src/crypto/des/des.c157
-rw-r--r--src/crypto/des/internal.h10
-rw-r--r--src/crypto/dh/CMakeLists.txt2
-rw-r--r--src/crypto/dh/dh.c2
-rw-r--r--src/crypto/dh/dh_impl.c14
-rw-r--r--src/crypto/digest/CMakeLists.txt2
-rw-r--r--src/crypto/digest/digest.c32
-rw-r--r--src/crypto/digest/digests.c3
-rw-r--r--src/crypto/digest/internal.h17
-rw-r--r--src/crypto/dsa/CMakeLists.txt2
-rw-r--r--src/crypto/dsa/dsa.c2
-rw-r--r--src/crypto/dsa/dsa_asn1.c2
-rw-r--r--src/crypto/dsa/dsa_impl.c42
-rw-r--r--src/crypto/ec/CMakeLists.txt2
-rw-r--r--src/crypto/ec/ec.c127
-rw-r--r--src/crypto/ec/ec_asn1.c77
-rw-r--r--src/crypto/ec/ec_key.c32
-rw-r--r--src/crypto/ec/ec_montgomery.c12
-rw-r--r--src/crypto/ec/oct.c59
-rw-r--r--src/crypto/ec/p256-64.c26
-rw-r--r--src/crypto/ec/simple.c20
-rw-r--r--src/crypto/ec/wnaf.c58
-rw-r--r--src/crypto/ecdh/CMakeLists.txt2
-rw-r--r--src/crypto/ecdh/ecdh.c14
-rw-r--r--src/crypto/ecdsa/CMakeLists.txt2
-rw-r--r--src/crypto/ecdsa/ecdsa.c119
-rw-r--r--src/crypto/ecdsa/ecdsa_asn1.c183
-rw-r--r--src/crypto/ecdsa/ecdsa_test.cc55
-rw-r--r--src/crypto/engine/CMakeLists.txt2
-rw-r--r--src/crypto/err/CMakeLists.txt4
-rw-r--r--src/crypto/err/asn1.errordata240
-rw-r--r--src/crypto/err/bio.errordata53
-rw-r--r--src/crypto/err/bn.errordata63
-rw-r--r--src/crypto/err/buf.errordata4
-rw-r--r--src/crypto/err/cipher.errordata85
-rw-r--r--src/crypto/err/conf.errordata16
-rw-r--r--src/crypto/err/crypto.errordata4
-rw-r--r--src/crypto/err/dh.errordata12
-rw-r--r--src/crypto/err/digest.errordata4
-rw-r--r--src/crypto/err/dsa.errordata13
-rw-r--r--src/crypto/err/ec.errordata123
-rw-r--r--src/crypto/err/ecdh.errordata7
-rw-r--r--src/crypto/err/ecdsa.errordata16
-rw-r--r--src/crypto/err/engine.errordata2
-rw-r--r--src/crypto/err/err.c132
-rw-r--r--src/crypto/err/err_data_generate.go32
-rw-r--r--src/crypto/err/err_test.cc50
-rw-r--r--src/crypto/err/evp.errordata160
-rw-r--r--src/crypto/err/hkdf.errordata3
-rw-r--r--src/crypto/err/obj.errordata6
-rw-r--r--src/crypto/err/pem.errordata54
-rw-r--r--src/crypto/err/pkcs8.errordata68
-rw-r--r--src/crypto/err/rsa.errordata115
-rw-r--r--src/crypto/err/ssl.errordata604
-rw-r--r--src/crypto/err/x509.errordata133
-rw-r--r--src/crypto/err/x509v3.errordata183
-rw-r--r--src/crypto/evp/CMakeLists.txt6
-rw-r--r--src/crypto/evp/algorithm.c18
-rw-r--r--src/crypto/evp/digestsign.c72
-rw-r--r--src/crypto/evp/evp.c53
-rw-r--r--src/crypto/evp/evp_asn1.c (renamed from src/crypto/evp/asn1.c)11
-rw-r--r--src/crypto/evp/evp_ctx.c77
-rw-r--r--src/crypto/evp/evp_extra_test.cc4
-rw-r--r--src/crypto/evp/evp_test.cc64
-rw-r--r--src/crypto/evp/evp_tests.txt5
-rw-r--r--src/crypto/evp/internal.h69
-rw-r--r--src/crypto/evp/p_dsa_asn1.c44
-rw-r--r--src/crypto/evp/p_ec.c52
-rw-r--r--src/crypto/evp/p_ec_asn1.c42
-rw-r--r--src/crypto/evp/p_hmac.c223
-rw-r--r--src/crypto/evp/p_hmac_asn1.c89
-rw-r--r--src/crypto/evp/p_rsa.c49
-rw-r--r--src/crypto/evp/p_rsa_asn1.c116
-rw-r--r--src/crypto/ex_data.c31
-rw-r--r--src/crypto/hkdf/CMakeLists.txt2
-rw-r--r--src/crypto/hkdf/hkdf.c4
-rw-r--r--src/crypto/hmac/CMakeLists.txt2
-rw-r--r--src/crypto/hmac/hmac.c2
-rw-r--r--src/crypto/hmac/hmac_tests.txt3
-rw-r--r--src/crypto/internal.h8
-rw-r--r--src/crypto/lhash/CMakeLists.txt2
-rw-r--r--src/crypto/lhash/lhash.c3
-rw-r--r--src/crypto/md4/CMakeLists.txt2
-rw-r--r--src/crypto/md5/CMakeLists.txt2
-rw-r--r--src/crypto/md5/md5.c3
-rw-r--r--src/crypto/mem.c3
-rw-r--r--src/crypto/modes/CMakeLists.txt2
-rw-r--r--src/crypto/modes/asm/ghash-armv4.pl10
-rw-r--r--src/crypto/modes/asm/ghash-x86.pl2
-rw-r--r--src/crypto/modes/asm/ghash-x86_64.pl8
-rw-r--r--src/crypto/modes/asm/ghashv8-armx.pl24
-rw-r--r--src/crypto/modes/gcm.c8
-rw-r--r--src/crypto/modes/gcm_test.c16
-rw-r--r--src/crypto/modes/internal.h5
-rw-r--r--src/crypto/obj/CMakeLists.txt2
-rw-r--r--src/crypto/obj/obj.c10
-rw-r--r--src/crypto/pem/CMakeLists.txt2
-rw-r--r--src/crypto/pem/pem_info.c14
-rw-r--r--src/crypto/pem/pem_lib.c67
-rw-r--r--src/crypto/pem/pem_oth.c2
-rw-r--r--src/crypto/pem/pem_pk8.c10
-rw-r--r--src/crypto/pem/pem_pkey.c14
-rwxr-xr-xsrc/crypto/perlasm/arm-xlate.pl5
-rw-r--r--src/crypto/pkcs8/CMakeLists.txt9
-rw-r--r--src/crypto/pkcs8/internal.h9
-rw-r--r--src/crypto/pkcs8/p5_pbe.c10
-rw-r--r--src/crypto/pkcs8/p5_pbev2.c144
-rw-r--r--src/crypto/pkcs8/pkcs8.c255
-rw-r--r--src/crypto/pkcs8/pkcs8_test.cc91
-rw-r--r--src/crypto/poly1305/CMakeLists.txt11
-rw-r--r--src/crypto/poly1305/poly1305_test.cc81
-rw-r--r--src/crypto/poly1305/poly1305_test.txt52
-rw-r--r--src/crypto/rand/CMakeLists.txt2
-rw-r--r--src/crypto/rand/hwrand.c21
-rw-r--r--src/crypto/rand/internal.h10
-rw-r--r--src/crypto/rand/rand.c27
-rw-r--r--src/crypto/rand/urandom.c292
-rw-r--r--src/crypto/rc4/CMakeLists.txt2
-rw-r--r--src/crypto/rc4/asm/rc4-x86_64.pl2
-rw-r--r--src/crypto/rsa/CMakeLists.txt4
-rw-r--r--src/crypto/rsa/blinding.c24
-rw-r--r--src/crypto/rsa/internal.h34
-rw-r--r--src/crypto/rsa/padding.c110
-rw-r--r--src/crypto/rsa/rsa.c143
-rw-r--r--src/crypto/rsa/rsa_asn1.c421
-rw-r--r--src/crypto/rsa/rsa_impl.c311
-rw-r--r--src/crypto/rsa/rsa_test.c511
-rw-r--r--src/crypto/rsa/rsa_test.cc869
-rw-r--r--src/crypto/sha/CMakeLists.txt2
-rw-r--r--src/crypto/sha/asm/sha1-586.pl4
-rw-r--r--src/crypto/sha/asm/sha1-armv4-large.pl2
-rw-r--r--src/crypto/sha/asm/sha1-armv8.pl2
-rw-r--r--src/crypto/sha/asm/sha256-586.pl2
-rw-r--r--src/crypto/sha/asm/sha256-armv4.pl2
-rw-r--r--src/crypto/sha/asm/sha512-586.pl2
-rw-r--r--src/crypto/sha/asm/sha512-armv4.pl2
-rw-r--r--src/crypto/sha/asm/sha512-armv8.pl2
-rw-r--r--src/crypto/stack/CMakeLists.txt2
-rw-r--r--src/crypto/test/CMakeLists.txt1
-rw-r--r--src/crypto/test/file_test.cc1
-rw-r--r--src/crypto/test/file_test.h8
-rw-r--r--src/crypto/test/malloc.cc17
-rw-r--r--src/crypto/test/scoped_types.h5
-rw-r--r--src/crypto/test/test_util.cc30
-rw-r--r--src/crypto/test/test_util.h35
-rw-r--r--src/crypto/x509/CMakeLists.txt3
-rw-r--r--src/crypto/x509/a_digest.c2
-rw-r--r--src/crypto/x509/a_sign.c4
-rw-r--r--src/crypto/x509/a_verify.c10
-rw-r--r--src/crypto/x509/asn1_gen.c62
-rw-r--r--src/crypto/x509/by_dir.c12
-rw-r--r--src/crypto/x509/by_file.c22
-rw-r--r--src/crypto/x509/i2d_pr.c2
-rw-r--r--src/crypto/x509/pkcs7.c12
-rw-r--r--src/crypto/x509/t_crl.c2
-rw-r--r--src/crypto/x509/t_req.c246
-rw-r--r--src/crypto/x509/t_x509.c4
-rw-r--r--src/crypto/x509/x509_att.c16
-rw-r--r--src/crypto/x509/x509_cmp.c6
-rw-r--r--src/crypto/x509/x509_lu.c14
-rw-r--r--src/crypto/x509/x509_obj.c2
-rw-r--r--src/crypto/x509/x509_r2x.c2
-rw-r--r--src/crypto/x509/x509_req.c12
-rw-r--r--src/crypto/x509/x509_trs.c10
-rw-r--r--src/crypto/x509/x509_v3.c8
-rw-r--r--src/crypto/x509/x509_vfy.c54
-rw-r--r--src/crypto/x509/x509cset.c7
-rw-r--r--src/crypto/x509/x509name.c8
-rw-r--r--src/crypto/x509/x509spki.c12
-rw-r--r--src/crypto/x509/x_all.c25
-rw-r--r--src/crypto/x509/x_crl.c2
-rw-r--r--src/crypto/x509/x_info.c2
-rw-r--r--src/crypto/x509/x_name.c6
-rw-r--r--src/crypto/x509/x_pkey.c2
-rw-r--r--src/crypto/x509/x_pubkey.c20
-rw-r--r--src/crypto/x509/x_x509a.c48
-rw-r--r--src/crypto/x509v3/CMakeLists.txt6
-rw-r--r--src/crypto/x509v3/tab_test.c (renamed from src/crypto/x509v3/tabtest.c)0
-rw-r--r--src/crypto/x509v3/v3_akey.c10
-rw-r--r--src/crypto/x509v3/v3_alt.c40
-rw-r--r--src/crypto/x509v3/v3_bcons.c4
-rw-r--r--src/crypto/x509v3/v3_bitst.c6
-rw-r--r--src/crypto/x509v3/v3_conf.c26
-rw-r--r--src/crypto/x509v3/v3_cpols.c40
-rw-r--r--src/crypto/x509v3/v3_crld.c14
-rw-r--r--src/crypto/x509v3/v3_extku.c4
-rw-r--r--src/crypto/x509v3/v3_ia5.c6
-rw-r--r--src/crypto/x509v3/v3_info.c12
-rw-r--r--src/crypto/x509v3/v3_lib.c16
-rw-r--r--src/crypto/x509v3/v3_ncons.c4
-rw-r--r--src/crypto/x509v3/v3_pci.c35
-rw-r--r--src/crypto/x509v3/v3_pcons.c6
-rw-r--r--src/crypto/x509v3/v3_pmaps.c8
-rw-r--r--src/crypto/x509v3/v3_purp.c10
-rw-r--r--src/crypto/x509v3/v3_skey.c10
-rw-r--r--src/crypto/x509v3/v3_sxnet.c16
-rw-r--r--src/crypto/x509v3/v3_utl.c40
-rw-r--r--src/crypto/x509v3/v3name_test.c (renamed from src/crypto/x509v3/v3nametest.c)0
-rw-r--r--src/decrepit/CMakeLists.txt12
-rw-r--r--src/decrepit/bio/CMakeLists.txt9
-rw-r--r--src/decrepit/bio/base64_bio.c536
-rw-r--r--src/decrepit/blowfish/CMakeLists.txt2
-rw-r--r--src/decrepit/cast/CMakeLists.txt2
-rw-r--r--src/decrepit/des/CMakeLists.txt9
-rw-r--r--src/decrepit/des/cfb64ede.c242
-rw-r--r--src/decrepit/rsa/CMakeLists.txt9
-rw-r--r--src/decrepit/rsa/rsa_decrepit.c (renamed from src/ssl/ssl_algs.c)34
-rw-r--r--src/decrepit/xts/CMakeLists.txt9
-rw-r--r--src/decrepit/xts/xts.c295
l---------src/doc/doc.css1
-rw-r--r--src/include/openssl/aead.h19
-rw-r--r--src/include/openssl/aes.h2
-rw-r--r--src/include/openssl/arm_arch.h (renamed from src/crypto/arm_arch.h)2
-rw-r--r--src/include/openssl/asn1.h67
-rw-r--r--src/include/openssl/base.h37
-rw-r--r--src/include/openssl/base64.h8
-rw-r--r--src/include/openssl/bio.h43
-rw-r--r--src/include/openssl/bn.h76
-rw-r--r--src/include/openssl/buf.h5
-rw-r--r--src/include/openssl/bytestring.h40
-rw-r--r--src/include/openssl/chacha.h6
-rw-r--r--src/include/openssl/cipher.h43
-rw-r--r--src/include/openssl/conf.h4
-rw-r--r--src/include/openssl/cpu.h5
-rw-r--r--src/include/openssl/crypto.h9
-rw-r--r--src/include/openssl/des.h27
-rw-r--r--src/include/openssl/dh.h6
-rw-r--r--src/include/openssl/digest.h8
-rw-r--r--src/include/openssl/dsa.h5
-rw-r--r--src/include/openssl/ec.h71
-rw-r--r--src/include/openssl/ec_key.h6
-rw-r--r--src/include/openssl/ecdh.h1
-rw-r--r--src/include/openssl/ecdsa.h34
-rw-r--r--src/include/openssl/err.h74
-rw-r--r--src/include/openssl/evp.h119
-rw-r--r--src/include/openssl/ex_data.h6
-rw-r--r--src/include/openssl/hkdf.h1
-rw-r--r--src/include/openssl/lhash.h3
-rw-r--r--src/include/openssl/md4.h5
-rw-r--r--src/include/openssl/md5.h5
-rw-r--r--src/include/openssl/mem.h3
-rw-r--r--src/include/openssl/obj.h6
-rw-r--r--src/include/openssl/pem.h26
-rw-r--r--src/include/openssl/pkcs8.h68
-rw-r--r--src/include/openssl/poly1305.h13
-rw-r--r--src/include/openssl/rand.h51
-rw-r--r--src/include/openssl/rsa.h180
-rw-r--r--src/include/openssl/srtp.h188
-rw-r--r--src/include/openssl/ssl.h4174
-rw-r--r--src/include/openssl/ssl2.h268
-rw-r--r--src/include/openssl/ssl23.h85
-rw-r--r--src/include/openssl/ssl3.h136
-rw-r--r--src/include/openssl/stack.h9
-rw-r--r--src/include/openssl/stack_macros.h392
-rw-r--r--src/include/openssl/tls1.h47
-rw-r--r--src/include/openssl/x509.h148
-rw-r--r--src/include/openssl/x509v3.h57
-rw-r--r--src/ssl/CMakeLists.txt11
-rw-r--r--src/ssl/custom_extensions.c257
-rw-r--r--src/ssl/d1_both.c112
-rw-r--r--src/ssl/d1_clnt.c33
-rw-r--r--src/ssl/d1_lib.c25
-rw-r--r--src/ssl/d1_meth.c4
-rw-r--r--src/ssl/d1_pkt.c475
-rw-r--r--src/ssl/d1_srtp.c245
-rw-r--r--src/ssl/d1_srvr.c24
-rw-r--r--src/ssl/dtls_record.c308
-rw-r--r--src/ssl/internal.h534
-rw-r--r--src/ssl/s3_both.c146
-rw-r--r--src/ssl/s3_clnt.c811
-rw-r--r--src/ssl/s3_enc.c180
-rw-r--r--src/ssl/s3_lib.c346
-rw-r--r--src/ssl/s3_meth.c4
-rw-r--r--src/ssl/s3_pkt.c579
-rw-r--r--src/ssl/s3_srvr.c645
-rw-r--r--src/ssl/ssl_aead_ctx.c29
-rw-r--r--src/ssl/ssl_asn1.c393
-rw-r--r--src/ssl/ssl_buffer.c318
-rw-r--r--src/ssl/ssl_cert.c742
-rw-r--r--src/ssl/ssl_cipher.c239
-rw-r--r--src/ssl/ssl_file.c623
-rw-r--r--src/ssl/ssl_lib.c1992
-rw-r--r--src/ssl/ssl_rsa.c470
-rw-r--r--src/ssl/ssl_session.c (renamed from src/ssl/ssl_sess.c)660
-rw-r--r--src/ssl/ssl_stat.c114
-rw-r--r--src/ssl/ssl_test.cc276
-rw-r--r--src/ssl/ssl_txt.c8
-rw-r--r--src/ssl/t1_enc.c293
-rw-r--r--src/ssl/t1_lib.c3135
-rw-r--r--src/ssl/t1_reneg.c246
-rw-r--r--src/ssl/test/bssl_shim.cc731
-rw-r--r--src/ssl/test/runner/cipher_suites.go13
-rw-r--r--src/ssl/test/runner/common.go104
-rw-r--r--src/ssl/test/runner/conn.go117
-rw-r--r--src/ssl/test/runner/dtls.go15
-rw-r--r--src/ssl/test/runner/handshake_client.go42
-rw-r--r--src/ssl/test/runner/handshake_messages.go236
-rw-r--r--src/ssl/test/runner/handshake_server.go32
-rw-r--r--src/ssl/test/runner/runner.go2916
-rw-r--r--src/ssl/test/test_config.cc25
-rw-r--r--src/ssl/test/test_config.h22
-rw-r--r--src/ssl/tls_record.c338
-rw-r--r--src/tool/CMakeLists.txt8
-rw-r--r--src/tool/args.cc27
-rw-r--r--src/tool/client.cc42
-rw-r--r--src/tool/const.cc120
-rw-r--r--src/tool/genrsa.cc69
-rw-r--r--src/tool/internal.h14
-rw-r--r--src/tool/server.cc50
-rw-r--r--src/tool/speed.cc33
-rw-r--r--src/tool/tool.cc18
-rw-r--r--src/tool/transport_common.cc2
-rw-r--r--src/util/all_tests.go92
-rw-r--r--src/util/all_tests.json58
-rw-r--r--src/util/doc.go76
-rw-r--r--src/util/generate_build_files.py224
-rw-r--r--src/util/make_errors.go98
421 files changed, 22472 insertions, 17827 deletions
diff --git a/src/.gitignore b/src/.gitignore
index b54125f..a2e3ed2 100644
--- a/src/.gitignore
+++ b/src/.gitignore
@@ -3,3 +3,4 @@ ssl/test/runner/runner
*.swp
*.swo
doc/*.html
+doc/doc.css
diff --git a/src/BUILDING b/src/BUILDING
deleted file mode 100644
index d818f95..0000000
--- a/src/BUILDING
+++ /dev/null
@@ -1,96 +0,0 @@
-Build Prerequisites:
-
- * CMake[1] 2.8.8 or later is required.
-
- * Perl 5.6.1 or later is required. On Windows, Strawberry Perl and MSYS Perl
- have both been reported to work. If not found by CMake, it may be configured
- explicitly by setting PERL_EXECUTABLE.
-
- * On Windows you currently must use Ninja[2] to build; on other platforms,
- it is not required, but recommended, because it makes builds faster.
-
- * If you need to build Ninja from source, then a recent version of
- Python[3] is required (Python 2.7.5 works).
-
- * On Windows only, Yasm[4] is required. If not found by CMake, it may be
- configured explicitly by setting CMAKE_ASM_NASM_COMPILER.
-
- * A C compiler is required. On Windows, MSVC 12 (Visual Studio 2013) or later
- with Platform SDK 8.1 or later are supported. Recent versions of GCC and
- Clang should work on non-Windows platforms, and maybe on Windows too.
-
- * Go[5] is required. If not found by CMake, the go executable may be
- configured explicitly by setting GO_EXECUTABLE.
-
-Using Ninja (note the 'N' is capitalized in the cmake invocation):
-
- mkdir build
- cd build
- cmake -GNinja ..
- ninja
-
-Using makefiles (does not work on Windows):
-
- mkdir build
- cd build
- cmake ..
- make
-
-You usually don't need to run cmake again after changing CMakeLists.txt files
-because the build scripts will detect changes to them and rebuild themselves
-automatically.
-
-Note that the default build flags in the top-level CMakeLists.txt are for
-debugging - optimisation isn't enabled.
-
-If you want to cross-compile then there is an example toolchain file for
-32-bit Intel in util/. Wipe out the build directory, recreate it and run cmake
-like this:
-
- cmake -DCMAKE_TOOLCHAIN_FILE=../util/32-bit-toolchain.cmake -GNinja ..
-
-If you want to build as a shared library, pass -DBUILD_SHARED_LIBS=1. On
-Windows, where functions need to be tagged with "dllimport" when coming from a
-shared library, define BORINGSSL_SHARED_LIBRARY in any code which #includes the
-BoringSSL headers.
-
-
-Building for Android:
-
-It's possible to build BoringSSL with the Android NDK using CMake. This has
-been tested with version 10d of the NDK.
-
-Unpack the Android NDK somewhere and export ANDROID_NDK to point to the
-directory. Clone https://github.com/taka-no-me/android-cmake into util/.
-Then make a build directory as above and run CMake *twice* like this:
-
- cmake -DANDROID_NATIVE_API_LEVEL=android-9 \
- -DANDROID_ABI=armeabi-v7a \
- -DCMAKE_TOOLCHAIN_FILE=../util/android-cmake/android.toolchain.cmake \
- -GNinja ..
-
-Once you've run that twice, ninja should produce Android-compatible binaries.
-You can replace "armeabi-v7a" in the above with "arm64-v8a" to build aarch64
-binaries.
-
-
-Known Limitations on Windows:
-
- * Versions of cmake since 3.0.2 have a bug in its Ninja generator that causes
- yasm to output warnings "yasm: warning: can open only one input file, only
- the last file will be processed". These warnings can be safely ignored.
- The cmake bug is http://www.cmake.org/Bug/view.php?id=15253.
-
- * cmake can generate Visual Studio projects, but the generated project files
- don't have steps for assembling the assembly language source files, so they
- currently cannot be used to build BoringSSL.
-
-[1] http://www.cmake.org/download/
-
-[2] https://martine.github.io/ninja/
-
-[3] https://www.python.org/downloads/
-
-[4] http://yasm.tortall.net/
-
-[5] https://golang.org/dl/
diff --git a/src/BUILDING.md b/src/BUILDING.md
new file mode 100644
index 0000000..c75851f
--- /dev/null
+++ b/src/BUILDING.md
@@ -0,0 +1,100 @@
+# Building BoringSSL
+
+## Build Prerequisites
+
+ * [CMake] [1] 2.8.8 or later is required.
+
+ * Perl 5.6.1 or later is required. On Windows, [Strawberry Perl] [2] and MSYS
+ Perl have both been reported to work. If not found by CMake, it may be
+ configured explicitly by setting `PERL_EXECUTABLE`.
+
+ * On Windows you currently must use [Ninja] [3] to build; on other platforms,
+ it is not required, but recommended, because it makes builds faster.
+
+ * If you need to build Ninja from source, then a recent version of
+ [Python] [4] is required (Python 2.7.5 works).
+
+ * On Windows only, [Yasm] [5] is required. If not found by CMake, it may be
+ configured explicitly by setting `CMAKE_ASM_NASM_COMPILER`.
+
+ * A C compiler is required. On Windows, MSVC 12 (Visual Studio 2013) or later
+ with Platform SDK 8.1 or later are supported. Recent versions of GCC and
+ Clang should work on non-Windows platforms, and maybe on Windows too.
+
+ * [Go] [6] is required. If not found by CMake, the go executable may be
+ configured explicitly by setting `GO_EXECUTABLE`.
+
+## Building
+
+Using Ninja (note the 'N' is capitalized in the cmake invocation):
+
+ mkdir build
+ cd build
+ cmake -GNinja ..
+ ninja
+
+Using Make (does not work on Windows):
+
+ mkdir build
+ cd build
+ cmake ..
+ make
+
+You usually don't need to run `cmake` again after changing `CMakeLists.txt`
+files because the build scripts will detect changes to them and rebuild
+themselves automatically.
+
+Note that the default build flags in the top-level `CMakeLists.txt` are for
+debugging—optimisation isn't enabled.
+
+If you want to cross-compile then there is an example toolchain file for 32-bit
+Intel in `util/`. Wipe out the build directory, recreate it and run `cmake` like
+this:
+
+ cmake -DCMAKE_TOOLCHAIN_FILE=../util/32-bit-toolchain.cmake -GNinja ..
+
+If you want to build as a shared library, pass `-DBUILD_SHARED_LIBS=1`. On
+Windows, where functions need to be tagged with `dllimport` when coming from a
+shared library, define `BORINGSSL_SHARED_LIBRARY` in any code which `#include`s
+the BoringSSL headers.
+
+### Building for Android
+
+It's possible to build BoringSSL with the Android NDK using CMake. This has
+been tested with version 10d of the NDK.
+
+Unpack the Android NDK somewhere and export `ANDROID_NDK` to point to the
+directory. Clone https://github.com/taka-no-me/android-cmake into `util/`. Then
+make a build directory as above and run CMake *twice* like this:
+
+ cmake -DANDROID_NATIVE_API_LEVEL=android-9 \
+ -DANDROID_ABI=armeabi-v7a \
+ -DCMAKE_TOOLCHAIN_FILE=../util/android-cmake/android.toolchain.cmake \
+ -DANDROID_NATIVE_API_LEVEL=16 \
+ -GNinja ..
+
+Once you've run that twice, Ninja should produce Android-compatible binaries.
+You can replace `armeabi-v7a` in the above with `arm64-v8a` to build aarch64
+binaries.
+
+## Known Limitations on Windows
+
+ * Versions of CMake since 3.0.2 have a bug in its Ninja generator that causes
+ yasm to output warnings
+
+ yasm: warning: can open only one input file, only the last file will be processed
+
+ These warnings can be safely ignored. The cmake bug is
+ http://www.cmake.org/Bug/view.php?id=15253.
+
+ * CMake can generate Visual Studio projects, but the generated project files
+ don't have steps for assembling the assembly language source files, so they
+ currently cannot be used to build BoringSSL.
+
+
+ [1]: http://www.cmake.org/download/
+ [2]: http://strawberryperl.com/
+ [3]: https://martine.github.io/ninja/
+ [4]: https://www.python.org/downloads/
+ [5]: http://yasm.tortall.net/
+ [6]: https://golang.org/dl/
diff --git a/src/LICENSE b/src/LICENSE
index 8ae5e77..b242dcb 100644
--- a/src/LICENSE
+++ b/src/LICENSE
@@ -5,6 +5,9 @@ license. This license is reproduced at the bottom of this file.
Contributors to BoringSSL are required to follow the CLA rules for Chromium:
https://cla.developers.google.com/clas
+Some files from Intel are under yet another license, which is also included
+underneath.
+
The OpenSSL toolkit stays under a dual license, i.e. both the conditions of the
OpenSSL License and the original SSLeay license apply to the toolkit. See below
for the actual license texts. Actually both licenses are BSD-style Open Source
@@ -144,3 +147,39 @@ ISC license used for completely new code in BoringSSL:
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
+
+
+Some files from Intel carry the following license:
+
+# Copyright (c) 2012, Intel Corporation
+#
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+# * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#
+# * Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the
+# distribution.
+#
+# * Neither the name of the Intel Corporation nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+#
+# THIS SOFTWARE IS PROVIDED BY INTEL CORPORATION ""AS IS"" AND ANY
+# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL CORPORATION OR
+# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/src/PORTING.md b/src/PORTING.md
new file mode 100644
index 0000000..70b67cc
--- /dev/null
+++ b/src/PORTING.md
@@ -0,0 +1,157 @@
+# Porting from OpenSSL to BoringSSL
+
+BoringSSL is an OpenSSL derivative and is mostly source-compatible, for the
+subset of OpenSSL retained. Libraries ideally need little to no changes for
+BoringSSL support, provided they do not use removed APIs. In general, see if the
+library compiles and, on failure, consult the documentation in the header files
+and see if problematic features can be removed.
+
+In some cases, BoringSSL-specific code may be necessary. In that case, the
+`OPENSSL_IS_BORINGSSL` preprocessor macro may be used in `#ifdef`s. This macro
+should also be used in lieu of the presence of any particular function to detect
+OpenSSL vs BoringSSL in configure scripts, etc., where those are necessary.
+
+For convenience, BoringSSL defines upstream's `OPENSSL_NO_*` feature macros
+corresponding to removed features. These may also be used to disable code which
+uses a removed feature.
+
+Note: BoringSSL does *not* have a stable API or ABI. It must be updated with its
+consumers. It is not suitable for, say, a system library in a traditional Linux
+distribution. For instance, Chromium statically links the specific revision of
+BoringSSL it was built against. Likewise, Android's system-internal copy of
+BoringSSL is not exposed by the NDK and must not be used by third-party
+applications.
+
+
+## Major API changes
+
+### Integer types
+
+Some APIs have been converted to use `size_t` for consistency and to avoid
+integer overflows at the API boundary. (Existing logic uses a mismash of `int`,
+`long`, and `unsigned`.) For the most part, implicit casts mean that existing
+code continues to compile. In some cases, this may require BoringSSL-specific
+code, particularly to avoid compiler warnings.
+
+Most notably, the `STACK_OF(T)` types have all been converted to use `size_t`
+instead of `int` for indices and lengths.
+
+### Reference counts
+
+Some external consumers increment reference counts directly by calling
+`CRYPTO_add` with the corresponding `CRYPTO_LOCK_*` value.
+
+These APIs no longer exist in BoringSSL. Instead, code which increments
+reference counts should call the corresponding `FOO_up_ref` function, such as
+`EVP_PKEY_up_ref`. Note that not all of these APIs are present in OpenSSL and
+may require `#ifdef`s.
+
+### Error codes
+
+OpenSSL's errors are extremely specific, leaking internals of the library,
+including even a function code for the function which emitted the error! As some
+logic in BoringSSL has been rewritten, code which conditions on the error may
+break (grep for `ERR_GET_REASON` and `ERR_GET_FUNC`). This danger also exists
+when upgrading OpenSSL versions.
+
+Where possible, avoid conditioning on the exact error reason. Otherwise, a
+BoringSSL `#ifdef` may be necessary. Exactly how best to resolve this issue is
+still being determined. It's possible some new APIs will be added in the future.
+
+Function codes have been completely removed. Remove code which conditions on
+these as it will break with the slightest change in the library, OpenSSL or
+BoringSSL.
+
+### `*_ctrl` functions
+
+Some OpenSSL APIs are implemented with `ioctl`-style functions such as
+`SSL_ctrl` and `EVP_PKEY_CTX_ctrl`, combined with convenience macros, such as
+
+ # define SSL_CTX_set_mode(ctx,op) \
+ SSL_CTX_ctrl((ctx),SSL_CTRL_MODE,(op),NULL)
+
+In BoringSSL, these macros have been replaced with proper functions. The
+underlying `_ctrl` functions have been removed.
+
+For convenience, `SSL_CTRL_*` values are retained as macros to `doesnt_exist` so
+existing code which uses them (or the wrapper macros) in `#ifdef` expressions
+will continue to function. However, the macros themselves will not work.
+
+Switch any `*_ctrl` callers to the macro/function versions. This works in both
+OpenSSL and BoringSSL. Note that BoringSSL's function versions will be
+type-checked and may require more care with types.
+
+### HMAC `EVP_PKEY`s
+
+`EVP_PKEY_HMAC` is removed. Use the `HMAC_*` functions in `hmac.h` instead. This
+is compatible with OpenSSL.
+
+### DSA `EVP_PKEY`s
+
+`EVP_PKEY_DSA` is deprecated. It is currently still possible to parse DER into a
+DSA `EVP_PKEY`, but signing or verifying with those objects will not work.
+
+### DES
+
+The `DES_cblock` type has been switched from an array to a struct to avoid the
+pitfalls around array types in C. Where features which require DES cannot be
+disabled, BoringSSL-specific codepaths may be necessary.
+
+### TLS renegotiation
+
+OpenSSL enables TLS renegotiation by default and accepts renegotiation requests
+from the peer transparently. Renegotiation is an extremely problematic protocol
+feature, so BoringSSL rejects peer renegotiations by default.
+
+To enable renegotiation, call `SSL_set_reject_peer_renegotiations` and set it to
+off. Renegotiation is only supported as a client in SSL3/TLS and the
+HelloRequest must be received at a quiet point in the application protocol. This
+is sufficient to support the common use of requesting a new client certificate
+between an HTTP request and response in (unpipelined) HTTP/1.1.
+
+Things which do not work:
+
+* There is no support for renegotiation as a server.
+
+* There is no support for renegotiation in DTLS.
+
+* There is no support for initiating renegotiation; `SSL_renegotiate` always
+ fails and `SSL_set_state` does nothing.
+
+* Interleaving application data with the new handshake is forbidden.
+
+* If a HelloRequest is received while `SSL_write` has unsent application data,
+ the renegotiation is rejected.
+
+
+## Optional BoringSSL-specific simplifications
+
+BoringSSL makes some changes to OpenSSL which simplify the API but remain
+compatible with OpenSSL consumers. In general, consult the BoringSSL
+documentation for any functions in new BoringSSL-only code.
+
+### Return values
+
+Most OpenSSL APIs return 1 on success and either 0 or -1 on failure. BoringSSL
+has narrowed most of these to 1 on success and 0 on failure. BoringSSL-specific
+code may take advantage of the less error-prone APIs and use `!` to check for
+errors.
+
+### Initialization
+
+OpenSSL has a number of different initialization functions for setting up error
+strings and loading algorithms, etc. All of these functions still exist in
+BoringSSL for convenience, but they do nothing and are not necessary.
+
+The one exception is `CRYPTO_library_init` (and `SSL_library_init` which merely
+calls it). In `BORINGSSL_NO_STATIC_INITIALIZER` builds, it must be called to
+query CPU capabitilies before the rest of the library. In the default
+configuration, this is done with a static initializer and is also unnecessary.
+
+### Threading
+
+OpenSSL provides a number of APIs to configure threading callbacks and set up
+locks. Without initializing these, the library is not thread-safe. Configuring
+these does nothing in BoringSSL. Instead, BoringSSL calls pthreads and the
+corresponding Windows APIs internally and is always thread-safe where the API
+guarantees it.
diff --git a/src/STYLE b/src/STYLE
deleted file mode 100644
index 578da68..0000000
--- a/src/STYLE
+++ /dev/null
@@ -1,198 +0,0 @@
-BoringSSL Style Guide.
-
-BoringSSL usually follows the Google C++ style guide, found below. The
-rest of this document describes differences and clarifications on top
-of the base guide.
-
-https://google-styleguide.googlecode.com/svn/trunk/cppguide.html
-
-
-Legacy code.
-
-As a derivative of OpenSSL, BoringSSL contains a lot of legacy code
-that does not follow this style guide. Particularly where public API
-is concerned, balance consistency within a module with the benefits of
-a given rule. Module-wide deviations on naming should be respected
-while integer and return value conventions take precedence over
-consistency.
-
-Some modules have seen few changes, so they still retain the original
-indentation style for now. When editing these, try to retain the
-original style. For Emacs, doc/c-indentation.el from OpenSSL may be
-helpful in this.
-
-
-Language.
-
-The majority of the project is in C, so C++-specific rules in the
-Google style guide do not apply. Support for C99 features depends on
-our target platforms. Typically, Chromium's target MSVC is the most
-restrictive.
-
-Variable declarations in the middle of a function are allowed.
-
-Comments should be /* C-style */ for consistency.
-
-When declaration pointer types, * should be placed next to the variable
-name, not the type. So
-
- uint8_t *ptr;
-
-not
-
- uint8_t* ptr;
-
-Rather than malloc() and free(), use the wrappers OPENSSL_malloc() and
-OPENSSL_free(). Use the standard C assert() function freely.
-
-For new constants, prefer enums when the values are sequential and typed
-constants for flags. If adding values to an existing set of #defines, continue
-with #define.
-
-
-Formatting.
-
-Single-statement blocks are not allowed. All conditions and loops must
-use braces:
-
- if (foo) {
- do_something();
- }
-
-not
-
- if (foo)
- do_something();
-
-
-Integers.
-
-Prefer using explicitly-sized integers where appropriate rather than
-generic C ones. For instance, to represent a byte, use uint8_t, not
-unsigned char. Likewise, represent a two-byte field as uint16_t, not
-unsigned short.
-
-Sizes are represented as size_t.
-
-Within a struct that is retained across the lifetime of an SSL
-connection, if bounds of a size are known and it's easy, use a smaller
-integer type like uint8_t. This is a "free" connection footprint
-optimization for servers. Don't make code significantly more complex
-for it, and do still check the bounds when passing in and out of the
-struct. This narrowing should not propagate to local variables and
-function parameters.
-
-When doing arithmetic, account for overflow conditions.
-
-Except with platform APIs, do not use ssize_t. MSVC lacks it, and
-prefer out-of-band error signaling for size_t (see Return values).
-
-
-Naming.
-
-Follow Google naming conventions in C++ files. In C files, use the
-following naming conventions for consistency with existing OpenSSL and C
-styles:
-
-Define structs with typedef named TYPE_NAME. The corresponding struct
-should be named struct type_name_st.
-
-Name public functions as MODULE_function_name, unless the module
-already uses a different naming scheme for legacy reasons. The module
-name should be a type name if the function is a method of a particular
-type.
-
-Some types are allocated within the library while others are
-initialized into a struct allocated by the caller, often on the
-stack. Name these functions TYPE_NAME_new/TYPE_NAME_free and
-TYPE_NAME_init/TYPE_NAME_cleanup, respectively. All TYPE_NAME_free
-functions must do nothing on NULL input.
-
-If a variable is the length of a pointer value, it has the suffix
-_len. An output parameter is named out or has an out_ prefix. For
-instance, For instance:
-
- uint8_t *out,
- size_t *out_len,
- const uint8_t *in,
- size_t in_len,
-
-Name public headers like include/openssl/evp.h with header guards like
-OPENSSL_HEADER_EVP_H. Name internal headers like crypto/ec/internal.h
-with header guards like OPENSSL_HEADER_EC_INTERNAL_H.
-
-Name enums like unix_hacker_t. For instance:
-
-enum should_free_handshake_buffer_t {
- free_handshake_buffer,
- dont_free_handshake_buffer,
-};
-
-
-Return values.
-
-As even malloc may fail in BoringSSL, the vast majority of functions
-will have a failure case. Functions should return int with one on
-success and zero on error. Do not overload the return value to both
-signal success/failure and output an integer. For example:
-
- OPENSSL_EXPORT int CBS_get_u16(CBS *cbs, uint16_t *out);
-
-If a function needs more than a true/false result code, define an enum
-rather than arbitrarily assigning meaning to int values.
-
-If a function outputs a pointer to an object on success and there are no
-other outputs, return the pointer directly and NULL on error.
-
-
-Parameters.
-
-Where not constrained by legacy code, parameter order should be:
-
-1. context parameters
-2. output parameters
-3. input parameters
-
-For example,
-
-/* CBB_add_asn sets |*out_contents| to a |CBB| into which the contents of an
- * ASN.1 object can be written. The |tag| argument will be used as the tag for
- * the object. It returns one on success or zero on error. */
-OPENSSL_EXPORT int CBB_add_asn1(CBB *cbb, CBB *out_contents, uint8_t tag);
-
-
-Documentation.
-
-All public symbols must have a documentation comment in their header
-file. The style is based on that of Go. The first sentence begins with
-the symbol name, optionally prefixed with "A" or "An". Apart from the
-initial mention of symbol, references to other symbols or parameter
-names should be surrounded by |pipes|.
-
-Documentation should be concise but completely describe the exposed
-behavior of the function. Pay special note to success/failure behaviors
-and caller obligations on object lifetimes. If this sacrifices
-conciseness, consider simplifying the function's behavior.
-
-/* EVP_DigestVerifyUpdate appends |len| bytes from |data| to the data which
- * will be verified by |EVP_DigestVerifyFinal|. It returns one on success and
- * zero otherwise. */
-OPENSSL_EXPORT int EVP_DigestVerifyUpdate(EVP_MD_CTX *ctx, const void *data,
- size_t len);
-
-Explicitly mention any surprising edge cases or deviations from common
-return value patterns in legacy functions.
-
-/* RSA_private_encrypt encrypts |flen| bytes from |from| with the private key in
- * |rsa| and writes the encrypted data to |to|. The |to| buffer must have at
- * least |RSA_size| bytes of space. It returns the number of bytes written, or
- * -1 on error. The |padding| argument must be one of the |RSA_*_PADDING|
- * values. If in doubt, |RSA_PKCS1_PADDING| is the most common.
- *
- * WARNING: this function is dangerous because it breaks the usual return value
- * convention. Use |RSA_sign_raw| instead. */
-OPENSSL_EXPORT int RSA_private_encrypt(int flen, const uint8_t *from,
- uint8_t *to, RSA *rsa, int padding);
-
-Document private functions in their internal.h header or, if static,
-where defined.
diff --git a/src/STYLE.md b/src/STYLE.md
new file mode 100644
index 0000000..d51de78
--- /dev/null
+++ b/src/STYLE.md
@@ -0,0 +1,197 @@
+# BoringSSL Style Guide
+
+BoringSSL usually follows the
+[Google C++ style guide](https://google-styleguide.googlecode.com/svn/trunk/cppguide.html).
+The rest of this document describes differences and clarifications on
+top of the base guide.
+
+
+## Legacy code
+
+As a derivative of OpenSSL, BoringSSL contains a lot of legacy code that
+does not follow this style guide. Particularly where public API is
+concerned, balance consistency within a module with the benefits of a
+given rule. Module-wide deviations on naming should be respected while
+integer and return value conventions take precedence over consistency.
+
+Some modules have seen few changes, so they still retain the original
+indentation style for now. When editing these, try to retain the
+original style. For Emacs, `doc/c-indentation.el` from OpenSSL may be
+helpful in this.
+
+
+## Language
+
+The majority of the project is in C, so C++-specific rules in the
+Google style guide do not apply. Support for C99 features depends on
+our target platforms. Typically, Chromium's target MSVC is the most
+restrictive.
+
+Variable declarations in the middle of a function are allowed.
+
+Comments should be `/* C-style */` for consistency.
+
+When declaration pointer types, `*` should be placed next to the variable
+name, not the type. So
+
+ uint8_t *ptr;
+
+not
+
+ uint8_t* ptr;
+
+Rather than `malloc()` and `free()`, use the wrappers `OPENSSL_malloc()`
+and `OPENSSL_free()`. Use the standard C `assert()` function freely.
+
+For new constants, prefer enums when the values are sequential and typed
+constants for flags. If adding values to an existing set of `#define`s,
+continue with `#define`.
+
+
+## Formatting
+
+Single-statement blocks are not allowed. All conditions and loops must
+use braces:
+
+ if (foo) {
+ do_something();
+ }
+
+not
+
+ if (foo)
+ do_something();
+
+
+## Integers
+
+Prefer using explicitly-sized integers where appropriate rather than
+generic C ones. For instance, to represent a byte, use `uint8_t`, not
+`unsigned char`. Likewise, represent a two-byte field as `uint16_t`, not
+`unsigned short`.
+
+Sizes are represented as `size_t`.
+
+Within a struct that is retained across the lifetime of an SSL
+connection, if bounds of a size are known and it's easy, use a smaller
+integer type like `uint8_t`. This is a "free" connection footprint
+optimization for servers. Don't make code significantly more complex for
+it, and do still check the bounds when passing in and out of the
+struct. This narrowing should not propagate to local variables and
+function parameters.
+
+When doing arithmetic, account for overflow conditions.
+
+Except with platform APIs, do not use `ssize_t`. MSVC lacks it, and
+prefer out-of-band error signaling for `size_t` (see Return values).
+
+
+## Naming
+
+Follow Google naming conventions in C++ files. In C files, use the
+following naming conventions for consistency with existing OpenSSL and C
+styles:
+
+Define structs with typedef named `TYPE_NAME`. The corresponding struct
+should be named `struct type_name_st`.
+
+Name public functions as `MODULE_function_name`, unless the module
+already uses a different naming scheme for legacy reasons. The module
+name should be a type name if the function is a method of a particular
+type.
+
+Some types are allocated within the library while others are initialized
+into a struct allocated by the caller, often on the stack. Name these
+functions `TYPE_NAME_new`/`TYPE_NAME_free` and
+`TYPE_NAME_init`/`TYPE_NAME_cleanup`, respectively. All `TYPE_NAME_free`
+functions must do nothing on `NULL` input.
+
+If a variable is the length of a pointer value, it has the suffix
+`_len`. An output parameter is named `out` or has an `out_` prefix. For
+instance, For instance:
+
+ uint8_t *out,
+ size_t *out_len,
+ const uint8_t *in,
+ size_t in_len,
+
+Name public headers like `include/openssl/evp.h` with header guards like
+`OPENSSL_HEADER_EVP_H`. Name internal headers like
+`crypto/ec/internal.h` with header guards like
+`OPENSSL_HEADER_EC_INTERNAL_H`.
+
+Name enums like `enum unix_hacker_t`. For instance:
+
+ enum should_free_handshake_buffer_t {
+ free_handshake_buffer,
+ dont_free_handshake_buffer,
+ };
+
+
+## Return values
+
+As even `malloc` may fail in BoringSSL, the vast majority of functions
+will have a failure case. Functions should return `int` with one on
+success and zero on error. Do not overload the return value to both
+signal success/failure and output an integer. For example:
+
+ OPENSSL_EXPORT int CBS_get_u16(CBS *cbs, uint16_t *out);
+
+If a function needs more than a true/false result code, define an enum
+rather than arbitrarily assigning meaning to int values.
+
+If a function outputs a pointer to an object on success and there are no
+other outputs, return the pointer directly and `NULL` on error.
+
+
+## Parameters
+
+Where not constrained by legacy code, parameter order should be:
+
+1. context parameters
+2. output parameters
+3. input parameters
+
+For example,
+
+ /* CBB_add_asn sets |*out_contents| to a |CBB| into which the contents of an
+ * ASN.1 object can be written. The |tag| argument will be used as the tag for
+ * the object. It returns one on success or zero on error. */
+ OPENSSL_EXPORT int CBB_add_asn1(CBB *cbb, CBB *out_contents, uint8_t tag);
+
+
+## Documentation
+
+All public symbols must have a documentation comment in their header
+file. The style is based on that of Go. The first sentence begins with
+the symbol name, optionally prefixed with "A" or "An". Apart from the
+initial mention of symbol, references to other symbols or parameter
+names should be surrounded by |pipes|.
+
+Documentation should be concise but completely describe the exposed
+behavior of the function. Pay special note to success/failure behaviors
+and caller obligations on object lifetimes. If this sacrifices
+conciseness, consider simplifying the function's behavior.
+
+ /* EVP_DigestVerifyUpdate appends |len| bytes from |data| to the data which
+ * will be verified by |EVP_DigestVerifyFinal|. It returns one on success and
+ * zero otherwise. */
+ OPENSSL_EXPORT int EVP_DigestVerifyUpdate(EVP_MD_CTX *ctx, const void *data,
+ size_t len);
+
+Explicitly mention any surprising edge cases or deviations from common
+return value patterns in legacy functions.
+
+ /* RSA_private_encrypt encrypts |flen| bytes from |from| with the private key in
+ * |rsa| and writes the encrypted data to |to|. The |to| buffer must have at
+ * least |RSA_size| bytes of space. It returns the number of bytes written, or
+ * -1 on error. The |padding| argument must be one of the |RSA_*_PADDING|
+ * values. If in doubt, |RSA_PKCS1_PADDING| is the most common.
+ *
+ * WARNING: this function is dangerous because it breaks the usual return value
+ * convention. Use |RSA_sign_raw| instead. */
+ OPENSSL_EXPORT int RSA_private_encrypt(int flen, const uint8_t *from,
+ uint8_t *to, RSA *rsa, int padding);
+
+Document private functions in their `internal.h` header or, if static,
+where defined.
diff --git a/src/crypto/CMakeLists.txt b/src/crypto/CMakeLists.txt
index 6858cbb..3115279 100644
--- a/src/crypto/CMakeLists.txt
+++ b/src/crypto/CMakeLists.txt
@@ -1,4 +1,4 @@
-include_directories(. ../include)
+include_directories(../include)
if(APPLE)
if (${ARCH} STREQUAL "x86")
@@ -57,7 +57,6 @@ if (${ARCH} STREQUAL "x86_64")
set(
CRYPTO_ARCH_SOURCES
- cpu-x86_64-asm.${ASM_EXT}
cpu-intel.c
)
endif()
@@ -66,7 +65,6 @@ if (${ARCH} STREQUAL "x86")
set(
CRYPTO_ARCH_SOURCES
- cpu-x86-asm.${ASM_EXT}
cpu-intel.c
)
endif()
@@ -230,6 +228,3 @@ add_executable(
)
target_link_libraries(refcount_test crypto)
-
-perlasm(cpu-x86_64-asm.${ASM_EXT} cpu-x86_64-asm.pl)
-perlasm(cpu-x86-asm.${ASM_EXT} cpu-x86-asm.pl)
diff --git a/src/crypto/aes/CMakeLists.txt b/src/crypto/aes/CMakeLists.txt
index 490f40a..c82d99a 100644
--- a/src/crypto/aes/CMakeLists.txt
+++ b/src/crypto/aes/CMakeLists.txt
@@ -1,4 +1,4 @@
-include_directories(. .. ../../include)
+include_directories(../../include)
if (${ARCH} STREQUAL "x86_64")
set(
@@ -60,3 +60,12 @@ perlasm(aesni-x86.${ASM_EXT} asm/aesni-x86.pl)
perlasm(aes-armv4.${ASM_EXT} asm/aes-armv4.pl)
perlasm(bsaes-armv7.${ASM_EXT} asm/bsaes-armv7.pl)
perlasm(aesv8-armx.${ASM_EXT} asm/aesv8-armx.pl)
+
+add_executable(
+ aes_test
+
+ aes_test.cc
+ $<TARGET_OBJECTS:test_support>
+)
+
+target_link_libraries(aes_test crypto)
diff --git a/src/crypto/aes/aes_test.cc b/src/crypto/aes/aes_test.cc
new file mode 100644
index 0000000..e488d81
--- /dev/null
+++ b/src/crypto/aes/aes_test.cc
@@ -0,0 +1,102 @@
+/* Copyright (c) 2015, Google Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
+
+#include <stdio.h>
+#include <string.h>
+
+#include <openssl/aes.h>
+#include <openssl/crypto.h>
+
+
+static bool TestAES(const uint8_t *key, size_t key_len,
+ const uint8_t plaintext[AES_BLOCK_SIZE],
+ const uint8_t ciphertext[AES_BLOCK_SIZE]) {
+ AES_KEY aes_key;
+ if (AES_set_encrypt_key(key, key_len * 8, &aes_key) != 0) {
+ fprintf(stderr, "AES_set_encrypt_key failed\n");
+ return false;
+ }
+
+ // Test encryption.
+ uint8_t block[AES_BLOCK_SIZE];
+ AES_encrypt(plaintext, block, &aes_key);
+ if (memcmp(block, ciphertext, AES_BLOCK_SIZE) != 0) {
+ fprintf(stderr, "AES_encrypt gave the wrong output\n");
+ return false;
+ }
+
+ // Test in-place encryption.
+ memcpy(block, plaintext, AES_BLOCK_SIZE);
+ AES_encrypt(block, block, &aes_key);
+ if (memcmp(block, ciphertext, AES_BLOCK_SIZE) != 0) {
+ fprintf(stderr, "AES_encrypt gave the wrong output\n");
+ return false;
+ }
+
+ if (AES_set_decrypt_key(key, key_len * 8, &aes_key) != 0) {
+ fprintf(stderr, "AES_set_decrypt_key failed\n");
+ return false;
+ }
+
+ // Test decryption.
+ AES_decrypt(ciphertext, block, &aes_key);
+ if (memcmp(block, plaintext, AES_BLOCK_SIZE) != 0) {
+ fprintf(stderr, "AES_decrypt gave the wrong output\n");
+ return false;
+ }
+
+ // Test in-place decryption.
+ memcpy(block, ciphertext, AES_BLOCK_SIZE);
+ AES_decrypt(block, block, &aes_key);
+ if (memcmp(block, plaintext, AES_BLOCK_SIZE) != 0) {
+ fprintf(stderr, "AES_decrypt gave the wrong output\n");
+ return false;
+ }
+ return true;
+}
+
+int main() {
+ CRYPTO_library_init();
+
+ // Test vectors from FIPS-197, Appendix C.
+ if (!TestAES((const uint8_t *)"\x00\x01\x02\x03\x04\x05\x06\x07"
+ "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f",
+ 128 / 8,
+ (const uint8_t *)"\x00\x11\x22\x33\x44\x55\x66\x77"
+ "\x88\x99\xaa\xbb\xcc\xdd\xee\xff",
+ (const uint8_t *)"\x69\xc4\xe0\xd8\x6a\x7b\x04\x30"
+ "\xd8\xcd\xb7\x80\x70\xb4\xc5\x5a") ||
+ !TestAES((const uint8_t *)"\x00\x01\x02\x03\x04\x05\x06\x07"
+ "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
+ "\x10\x11\x12\x13\x14\x15\x16\x17",
+ 192 / 8,
+ (const uint8_t *)"\x00\x11\x22\x33\x44\x55\x66\x77"
+ "\x88\x99\xaa\xbb\xcc\xdd\xee\xff",
+ (const uint8_t *)"\xdd\xa9\x7c\xa4\x86\x4c\xdf\xe0"
+ "\x6e\xaf\x70\xa0\xec\x0d\x71\x91") ||
+ !TestAES((const uint8_t *)"\x00\x01\x02\x03\x04\x05\x06\x07"
+ "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
+ "\x10\x11\x12\x13\x14\x15\x16\x17"
+ "\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f",
+ 256 / 8,
+ (const uint8_t *)"\x00\x11\x22\x33\x44\x55\x66\x77"
+ "\x88\x99\xaa\xbb\xcc\xdd\xee\xff",
+ (const uint8_t *)"\x8e\xa2\xb7\xca\x51\x67\x45\xbf"
+ "\xea\xfc\x49\x90\x4b\x49\x60\x89")) {
+ return false;
+ }
+
+ printf("PASS\n");
+ return 0;
+}
diff --git a/src/crypto/aes/asm/aes-586.pl b/src/crypto/aes/asm/aes-586.pl
index 07fb94c..6e8a6a8 100755
--- a/src/crypto/aes/asm/aes-586.pl
+++ b/src/crypto/aes/asm/aes-586.pl
@@ -45,7 +45,7 @@
# the undertaken effort was that it appeared that in tight IA-32
# register window little-endian flavor could achieve slightly higher
# Instruction Level Parallelism, and it indeed resulted in up to 15%
-# better performance on most recent µ-archs...
+# better performance on most recent µ-archs...
#
# Third version adds AES_cbc_encrypt implementation, which resulted in
# up to 40% performance imrovement of CBC benchmark results. 40% was
@@ -224,7 +224,7 @@ sub _data_word() { my $i; while(defined($i=shift)) { &data_word($i,$i); } }
$speed_limit=512; # chunks smaller than $speed_limit are
# processed with compact routine in CBC mode
$small_footprint=1; # $small_footprint=1 code is ~5% slower [on
- # recent µ-archs], but ~5 times smaller!
+ # recent µ-archs], but ~5 times smaller!
# I favor compact code to minimize cache
# contention and in hope to "collect" 5% back
# in real-life applications...
@@ -565,7 +565,7 @@ sub enctransform()
# Performance is not actually extraordinary in comparison to pure
# x86 code. In particular encrypt performance is virtually the same.
# Decrypt performance on the other hand is 15-20% better on newer
-# µ-archs [but we're thankful for *any* improvement here], and ~50%
+# µ-archs [but we're thankful for *any* improvement here], and ~50%
# better on PIII:-) And additionally on the pros side this code
# eliminates redundant references to stack and thus relieves/
# minimizes the pressure on the memory bus.
diff --git a/src/crypto/aes/asm/aes-armv4.pl b/src/crypto/aes/asm/aes-armv4.pl
index 36cd3b6..882017a 100644
--- a/src/crypto/aes/asm/aes-armv4.pl
+++ b/src/crypto/aes/asm/aes-armv4.pl
@@ -65,7 +65,7 @@ $rounds="r12";
$code=<<___;
#if defined(__arm__)
#ifndef __KERNEL__
-# include "arm_arch.h"
+# include <openssl/arm_arch.h>
#else
# define __ARM_ARCH__ __LINUX_ARM_ARCH__
#endif
diff --git a/src/crypto/aes/asm/aesv8-armx.pl b/src/crypto/aes/asm/aesv8-armx.pl
index b0916f6..121154a 100644
--- a/src/crypto/aes/asm/aesv8-armx.pl
+++ b/src/crypto/aes/asm/aesv8-armx.pl
@@ -45,7 +45,7 @@ open OUT,"| \"$^X\" $xlate $flavour $output";
$prefix="aes_v8";
$code=<<___;
-#include "arm_arch.h"
+#include <openssl/arm_arch.h>
#if __ARM_MAX_ARCH__>=7
.text
diff --git a/src/crypto/aes/asm/bsaes-armv7.pl b/src/crypto/aes/asm/bsaes-armv7.pl
index 273f0b9..7fe349a 100644
--- a/src/crypto/aes/asm/bsaes-armv7.pl
+++ b/src/crypto/aes/asm/bsaes-armv7.pl
@@ -703,7 +703,7 @@ ___
$code.=<<___;
#if defined(__arm__)
#ifndef __KERNEL__
-# include "arm_arch.h"
+# include <openssl/arm_arch.h>
# define VFP_ABI_PUSH vstmdb sp!,{d8-d15}
# define VFP_ABI_POP vldmia sp!,{d8-d15}
diff --git a/src/crypto/asn1/CMakeLists.txt b/src/crypto/asn1/CMakeLists.txt
index 283636e..41e3122 100644
--- a/src/crypto/asn1/CMakeLists.txt
+++ b/src/crypto/asn1/CMakeLists.txt
@@ -1,4 +1,4 @@
-include_directories(. .. ../../include)
+include_directories(../../include)
add_library(
asn1
diff --git a/src/crypto/asn1/a_bitstr.c b/src/crypto/asn1/a_bitstr.c
index 8055f0c..8bad339 100644
--- a/src/crypto/asn1/a_bitstr.c
+++ b/src/crypto/asn1/a_bitstr.c
@@ -125,8 +125,7 @@ ASN1_BIT_STRING *c2i_ASN1_BIT_STRING(ASN1_BIT_STRING **a,
if (len < 1)
{
- OPENSSL_PUT_ERROR(ASN1, c2i_ASN1_BIT_STRING,
- ASN1_R_STRING_TOO_SHORT);
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_STRING_TOO_SHORT);
goto err;
}
@@ -141,8 +140,7 @@ ASN1_BIT_STRING *c2i_ASN1_BIT_STRING(ASN1_BIT_STRING **a,
padding = *(p++);
if (padding > 7)
{
- OPENSSL_PUT_ERROR(ASN1, c2i_ASN1_BIT_STRING,
- ASN1_R_INVALID_BIT_STRING_BITS_LEFT);
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_INVALID_BIT_STRING_BITS_LEFT);
goto err;
}
@@ -157,8 +155,7 @@ ASN1_BIT_STRING *c2i_ASN1_BIT_STRING(ASN1_BIT_STRING **a,
s=(unsigned char *)OPENSSL_malloc((int)len);
if (s == NULL)
{
- OPENSSL_PUT_ERROR(ASN1, c2i_ASN1_BIT_STRING,
- ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
goto err;
}
memcpy(s,p,(int)len);
@@ -209,7 +206,7 @@ int ASN1_BIT_STRING_set_bit(ASN1_BIT_STRING *a, int n, int value)
w+1);
if (c == NULL)
{
- OPENSSL_PUT_ERROR(ASN1, ASN1_BIT_STRING_set_bit, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
return 0;
}
if (w+1-a->length > 0) memset(c+a->length, 0, w+1-a->length);
diff --git a/src/crypto/asn1/a_bool.c b/src/crypto/asn1/a_bool.c
index c30ee48..826bcf4 100644
--- a/src/crypto/asn1/a_bool.c
+++ b/src/crypto/asn1/a_bool.c
@@ -107,6 +107,6 @@ int d2i_ASN1_BOOLEAN(int *a, const unsigned char **pp, long length)
*pp=p;
return(ret);
err:
- OPENSSL_PUT_ERROR(ASN1, d2i_ASN1_BOOLEAN, i);
+ OPENSSL_PUT_ERROR(ASN1, i);
return(ret);
}
diff --git a/src/crypto/asn1/a_bytes.c b/src/crypto/asn1/a_bytes.c
index 8874f48..1904375 100644
--- a/src/crypto/asn1/a_bytes.c
+++ b/src/crypto/asn1/a_bytes.c
@@ -125,7 +125,7 @@ ASN1_STRING *d2i_ASN1_type_bytes(ASN1_STRING **a, const unsigned char **pp,
*pp=p;
return(ret);
err:
- OPENSSL_PUT_ERROR(ASN1, d2i_ASN1_type_bytes, i);
+ OPENSSL_PUT_ERROR(ASN1, i);
if ((ret != NULL) && ((a == NULL) || (*a != ret)))
ASN1_STRING_free(ret);
return(NULL);
@@ -243,7 +243,7 @@ ASN1_STRING *d2i_ASN1_bytes(ASN1_STRING **a, const unsigned char **pp,
err:
if ((ret != NULL) && ((a == NULL) || (*a != ret)))
ASN1_STRING_free(ret);
- OPENSSL_PUT_ERROR(ASN1, d2i_ASN1_bytes, i);
+ OPENSSL_PUT_ERROR(ASN1, i);
return(NULL);
}
@@ -309,7 +309,7 @@ static int asn1_collate_primitive(ASN1_STRING *a, ASN1_const_CTX *c)
if (os != NULL) ASN1_STRING_free(os);
return(1);
err:
- OPENSSL_PUT_ERROR(ASN1, asn1_collate_primitive, c->error);
+ OPENSSL_PUT_ERROR(ASN1, c->error);
if (os != NULL) ASN1_STRING_free(os);
if (b.data != NULL) OPENSSL_free(b.data);
return(0);
diff --git a/src/crypto/asn1/a_d2i_fp.c b/src/crypto/asn1/a_d2i_fp.c
index 6022c74..97ec75b 100644
--- a/src/crypto/asn1/a_d2i_fp.c
+++ b/src/crypto/asn1/a_d2i_fp.c
@@ -75,7 +75,7 @@ void *ASN1_d2i_fp(void *(*xnew)(void), d2i_of_void *d2i, FILE *in, void **x)
if ((b=BIO_new(BIO_s_file())) == NULL)
{
- OPENSSL_PUT_ERROR(ASN1, ASN1_d2i_fp, ERR_R_BUF_LIB);
+ OPENSSL_PUT_ERROR(ASN1, ERR_R_BUF_LIB);
return(NULL);
}
BIO_set_fp(b,in,BIO_NOCLOSE);
@@ -129,7 +129,7 @@ void *ASN1_item_d2i_fp(const ASN1_ITEM *it, FILE *in, void *x)
if ((b=BIO_new(BIO_s_file())) == NULL)
{
- OPENSSL_PUT_ERROR(ASN1, ASN1_item_d2i_fp, ERR_R_BUF_LIB);
+ OPENSSL_PUT_ERROR(ASN1, ERR_R_BUF_LIB);
return(NULL);
}
BIO_set_fp(b,in,BIO_NOCLOSE);
@@ -154,7 +154,7 @@ static int asn1_d2i_read_bio(BIO *in, BUF_MEM **pb)
b=BUF_MEM_new();
if (b == NULL)
{
- OPENSSL_PUT_ERROR(ASN1, asn1_d2i_read_bio, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
return -1;
}
@@ -167,20 +167,20 @@ static int asn1_d2i_read_bio(BIO *in, BUF_MEM **pb)
if (len + want < len || !BUF_MEM_grow_clean(b,len+want))
{
- OPENSSL_PUT_ERROR(ASN1, asn1_d2i_read_bio, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
goto err;
}
i=BIO_read(in,&(b->data[len]),want);
if ((i < 0) && ((len-off) == 0))
{
- OPENSSL_PUT_ERROR(ASN1, asn1_d2i_read_bio, ASN1_R_NOT_ENOUGH_DATA);
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_NOT_ENOUGH_DATA);
goto err;
}
if (i > 0)
{
if (len+i < len)
{
- OPENSSL_PUT_ERROR(ASN1, asn1_d2i_read_bio, ASN1_R_TOO_LONG);
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_TOO_LONG);
goto err;
}
len+=i;
@@ -211,7 +211,7 @@ static int asn1_d2i_read_bio(BIO *in, BUF_MEM **pb)
eos++;
if (eos < 0)
{
- OPENSSL_PUT_ERROR(ASN1, asn1_d2i_read_bio, ASN1_R_HEADER_TOO_LONG);
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_HEADER_TOO_LONG);
goto err;
}
want=HEADER_SIZE;
@@ -235,12 +235,12 @@ static int asn1_d2i_read_bio(BIO *in, BUF_MEM **pb)
if (want > INT_MAX /* BIO_read takes an int length */ ||
len+want < len)
{
- OPENSSL_PUT_ERROR(ASN1, asn1_d2i_read_bio, ASN1_R_TOO_LONG);
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_TOO_LONG);
goto err;
}
if (!BUF_MEM_grow_clean(b,len+want))
{
- OPENSSL_PUT_ERROR(ASN1, asn1_d2i_read_bio, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
goto err;
}
while (want > 0)
@@ -248,7 +248,7 @@ static int asn1_d2i_read_bio(BIO *in, BUF_MEM **pb)
i=BIO_read(in,&(b->data[len]),want);
if (i <= 0)
{
- OPENSSL_PUT_ERROR(ASN1, asn1_d2i_read_bio, ASN1_R_NOT_ENOUGH_DATA);
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_NOT_ENOUGH_DATA);
goto err;
}
/* This can't overflow because
@@ -259,7 +259,7 @@ static int asn1_d2i_read_bio(BIO *in, BUF_MEM **pb)
}
if (off + c.slen < off)
{
- OPENSSL_PUT_ERROR(ASN1, asn1_d2i_read_bio, ASN1_R_TOO_LONG);
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_TOO_LONG);
goto err;
}
off+=c.slen;
@@ -274,7 +274,7 @@ static int asn1_d2i_read_bio(BIO *in, BUF_MEM **pb)
if (off > INT_MAX)
{
- OPENSSL_PUT_ERROR(ASN1, asn1_d2i_read_bio, ASN1_R_TOO_LONG);
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_TOO_LONG);
goto err;
}
diff --git a/src/crypto/asn1/a_dup.c b/src/crypto/asn1/a_dup.c
index 8ec1c5f..5e87457 100644
--- a/src/crypto/asn1/a_dup.c
+++ b/src/crypto/asn1/a_dup.c
@@ -72,7 +72,7 @@ void *ASN1_dup(i2d_of_void *i2d, d2i_of_void *d2i, void *x)
i=i2d(x,NULL);
b=OPENSSL_malloc(i+10);
if (b == NULL)
- { OPENSSL_PUT_ERROR(ASN1, ASN1_dup, ERR_R_MALLOC_FAILURE); return(NULL); }
+ { OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE); return(NULL); }
p= b;
i=i2d(x,&p);
p2= b;
@@ -95,7 +95,7 @@ void *ASN1_item_dup(const ASN1_ITEM *it, void *x)
i=ASN1_item_i2d(x,&b,it);
if (b == NULL)
- { OPENSSL_PUT_ERROR(ASN1, ASN1_item_dup, ERR_R_MALLOC_FAILURE); return(NULL); }
+ { OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE); return(NULL); }
p= b;
ret=ASN1_item_d2i(NULL,&p,i, it);
OPENSSL_free(b);
diff --git a/src/crypto/asn1/a_enum.c b/src/crypto/asn1/a_enum.c
index a581a34..579dafd 100644
--- a/src/crypto/asn1/a_enum.c
+++ b/src/crypto/asn1/a_enum.c
@@ -84,7 +84,7 @@ int ASN1_ENUMERATED_set(ASN1_ENUMERATED *a, long v)
}
if (a->data == NULL)
{
- OPENSSL_PUT_ERROR(ASN1, ASN1_ENUMERATED_set, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
return(0);
}
d=v;
@@ -147,7 +147,7 @@ ASN1_ENUMERATED *BN_to_ASN1_ENUMERATED(BIGNUM *bn, ASN1_ENUMERATED *ai)
ret=ai;
if (ret == NULL)
{
- OPENSSL_PUT_ERROR(ASN1, BN_to_ASN1_ENUMERATED, ASN1_R_NESTED_ASN1_ERROR);
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR);
goto err;
}
if(BN_is_negative(bn)) ret->type = V_ASN1_NEG_ENUMERATED;
@@ -159,7 +159,7 @@ ASN1_ENUMERATED *BN_to_ASN1_ENUMERATED(BIGNUM *bn, ASN1_ENUMERATED *ai)
unsigned char *new_data=OPENSSL_realloc(ret->data, len+4);
if (!new_data)
{
- OPENSSL_PUT_ERROR(ASN1, BN_to_ASN1_ENUMERATED, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
goto err;
}
ret->data=new_data;
@@ -177,7 +177,7 @@ BIGNUM *ASN1_ENUMERATED_to_BN(ASN1_ENUMERATED *ai, BIGNUM *bn)
BIGNUM *ret;
if ((ret=BN_bin2bn(ai->data,ai->length,bn)) == NULL)
- OPENSSL_PUT_ERROR(ASN1, ASN1_ENUMERATED_to_BN, ASN1_R_BN_LIB);
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_BN_LIB);
else if(ai->type == V_ASN1_NEG_ENUMERATED) BN_set_negative(ret,1);
return(ret);
}
diff --git a/src/crypto/asn1/a_gentm.c b/src/crypto/asn1/a_gentm.c
index be093a4..7cb18a9 100644
--- a/src/crypto/asn1/a_gentm.c
+++ b/src/crypto/asn1/a_gentm.c
@@ -239,7 +239,7 @@ ASN1_GENERALIZEDTIME *ASN1_GENERALIZEDTIME_adj(ASN1_GENERALIZEDTIME *s,
p=OPENSSL_malloc(len);
if (p == NULL)
{
- OPENSSL_PUT_ERROR(ASN1, ASN1_GENERALIZEDTIME_adj, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
return(NULL);
}
if (s->data != NULL)
diff --git a/src/crypto/asn1/a_i2d_fp.c b/src/crypto/asn1/a_i2d_fp.c
index 11e40d3..74ded78 100644
--- a/src/crypto/asn1/a_i2d_fp.c
+++ b/src/crypto/asn1/a_i2d_fp.c
@@ -67,7 +67,7 @@ int ASN1_i2d_fp(i2d_of_void *i2d, FILE *out, void *x)
if ((b=BIO_new(BIO_s_file())) == NULL)
{
- OPENSSL_PUT_ERROR(ASN1, ASN1_i2d_fp, ERR_R_BUF_LIB);
+ OPENSSL_PUT_ERROR(ASN1, ERR_R_BUF_LIB);
return(0);
}
BIO_set_fp(b,out,BIO_NOCLOSE);
@@ -76,7 +76,7 @@ int ASN1_i2d_fp(i2d_of_void *i2d, FILE *out, void *x)
return(ret);
}
-int ASN1_i2d_bio(i2d_of_void *i2d, BIO *out, unsigned char *x)
+int ASN1_i2d_bio(i2d_of_void *i2d, BIO *out, void *x)
{
char *b;
unsigned char *p;
@@ -86,7 +86,7 @@ int ASN1_i2d_bio(i2d_of_void *i2d, BIO *out, unsigned char *x)
b=(char *)OPENSSL_malloc(n);
if (b == NULL)
{
- OPENSSL_PUT_ERROR(ASN1, ASN1_i2d_bio, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
return(0);
}
@@ -116,7 +116,7 @@ int ASN1_item_i2d_fp(const ASN1_ITEM *it, FILE *out, void *x)
if ((b=BIO_new(BIO_s_file())) == NULL)
{
- OPENSSL_PUT_ERROR(ASN1, ASN1_item_i2d_fp, ERR_R_BUF_LIB);
+ OPENSSL_PUT_ERROR(ASN1, ERR_R_BUF_LIB);
return(0);
}
BIO_set_fp(b,out,BIO_NOCLOSE);
@@ -133,7 +133,7 @@ int ASN1_item_i2d_bio(const ASN1_ITEM *it, BIO *out, void *x)
n = ASN1_item_i2d(x, &b, it);
if (b == NULL)
{
- OPENSSL_PUT_ERROR(ASN1, ASN1_item_i2d_bio, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
return(0);
}
diff --git a/src/crypto/asn1/a_int.c b/src/crypto/asn1/a_int.c
index 2ecccc5..9a56534 100644
--- a/src/crypto/asn1/a_int.c
+++ b/src/crypto/asn1/a_int.c
@@ -257,7 +257,7 @@ ASN1_INTEGER *c2i_ASN1_INTEGER(ASN1_INTEGER **a, const unsigned char **pp,
*pp=pend;
return(ret);
err:
- OPENSSL_PUT_ERROR(ASN1, c2i_ASN1_INTEGER, i);
+ OPENSSL_PUT_ERROR(ASN1, i);
if ((ret != NULL) && ((a == NULL) || (*a != ret)))
M_ASN1_INTEGER_free(ret);
return(NULL);
@@ -327,7 +327,7 @@ ASN1_INTEGER *d2i_ASN1_UINTEGER(ASN1_INTEGER **a, const unsigned char **pp,
*pp=p;
return(ret);
err:
- OPENSSL_PUT_ERROR(ASN1, d2i_ASN1_UINTEGER, i);
+ OPENSSL_PUT_ERROR(ASN1, i);
if ((ret != NULL) && ((a == NULL) || (*a != ret)))
M_ASN1_INTEGER_free(ret);
return(NULL);
@@ -350,7 +350,7 @@ int ASN1_INTEGER_set(ASN1_INTEGER *a, long v)
}
if (a->data == NULL)
{
- OPENSSL_PUT_ERROR(ASN1, ASN1_INTEGER_set, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
return(0);
}
d=v;
@@ -413,7 +413,7 @@ ASN1_INTEGER *BN_to_ASN1_INTEGER(const BIGNUM *bn, ASN1_INTEGER *ai)
ret=ai;
if (ret == NULL)
{
- OPENSSL_PUT_ERROR(ASN1, BN_to_ASN1_INTEGER, ASN1_R_NESTED_ASN1_ERROR);
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR);
goto err;
}
if (BN_is_negative(bn) && !BN_is_zero(bn))
@@ -426,7 +426,7 @@ ASN1_INTEGER *BN_to_ASN1_INTEGER(const BIGNUM *bn, ASN1_INTEGER *ai)
unsigned char *new_data=OPENSSL_realloc(ret->data, len+4);
if (!new_data)
{
- OPENSSL_PUT_ERROR(ASN1, BN_to_ASN1_INTEGER, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
goto err;
}
ret->data=new_data;
@@ -449,7 +449,7 @@ BIGNUM *ASN1_INTEGER_to_BN(const ASN1_INTEGER *ai, BIGNUM *bn)
BIGNUM *ret;
if ((ret=BN_bin2bn(ai->data,ai->length,bn)) == NULL)
- OPENSSL_PUT_ERROR(ASN1, ASN1_INTEGER_to_BN, ASN1_R_BN_LIB);
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_BN_LIB);
else if(ai->type == V_ASN1_NEG_INTEGER)
BN_set_negative(ret, 1);
return(ret);
diff --git a/src/crypto/asn1/a_mbstr.c b/src/crypto/asn1/a_mbstr.c
index 9abe659..42806d1 100644
--- a/src/crypto/asn1/a_mbstr.c
+++ b/src/crypto/asn1/a_mbstr.c
@@ -108,7 +108,7 @@ int ASN1_mbstring_ncopy(ASN1_STRING **out, const unsigned char *in, int len,
case MBSTRING_BMP:
if(len & 1) {
- OPENSSL_PUT_ERROR(ASN1, ASN1_mbstring_ncopy, ASN1_R_INVALID_BMPSTRING_LENGTH);
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_INVALID_BMPSTRING_LENGTH);
return -1;
}
nchar = len >> 1;
@@ -116,7 +116,7 @@ int ASN1_mbstring_ncopy(ASN1_STRING **out, const unsigned char *in, int len,
case MBSTRING_UNIV:
if(len & 3) {
- OPENSSL_PUT_ERROR(ASN1, ASN1_mbstring_ncopy, ASN1_R_INVALID_UNIVERSALSTRING_LENGTH);
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_INVALID_UNIVERSALSTRING_LENGTH);
return -1;
}
nchar = len >> 2;
@@ -127,7 +127,7 @@ int ASN1_mbstring_ncopy(ASN1_STRING **out, const unsigned char *in, int len,
/* This counts the characters and does utf8 syntax checking */
ret = traverse_string(in, len, MBSTRING_UTF8, in_utf8, &nchar);
if(ret < 0) {
- OPENSSL_PUT_ERROR(ASN1, ASN1_mbstring_ncopy, ASN1_R_INVALID_UTF8STRING);
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_INVALID_UTF8STRING);
return -1;
}
break;
@@ -137,19 +137,19 @@ int ASN1_mbstring_ncopy(ASN1_STRING **out, const unsigned char *in, int len,
break;
default:
- OPENSSL_PUT_ERROR(ASN1, ASN1_mbstring_ncopy, ASN1_R_UNKNOWN_FORMAT);
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_UNKNOWN_FORMAT);
return -1;
}
if((minsize > 0) && (nchar < minsize)) {
- OPENSSL_PUT_ERROR(ASN1, ASN1_mbstring_ncopy, ASN1_R_STRING_TOO_SHORT);
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_STRING_TOO_SHORT);
BIO_snprintf(strbuf, sizeof strbuf, "%ld", minsize);
ERR_add_error_data(2, "minsize=", strbuf);
return -1;
}
if((maxsize > 0) && (nchar > maxsize)) {
- OPENSSL_PUT_ERROR(ASN1, ASN1_mbstring_ncopy, ASN1_R_STRING_TOO_LONG);
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_STRING_TOO_LONG);
BIO_snprintf(strbuf, sizeof strbuf, "%ld", maxsize);
ERR_add_error_data(2, "maxsize=", strbuf);
return -1;
@@ -157,7 +157,7 @@ int ASN1_mbstring_ncopy(ASN1_STRING **out, const unsigned char *in, int len,
/* Now work out minimal type (if any) */
if(traverse_string(in, len, inform, type_str, &mask) < 0) {
- OPENSSL_PUT_ERROR(ASN1, ASN1_mbstring_ncopy, ASN1_R_ILLEGAL_CHARACTERS);
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_ILLEGAL_CHARACTERS);
return -1;
}
@@ -191,7 +191,7 @@ int ASN1_mbstring_ncopy(ASN1_STRING **out, const unsigned char *in, int len,
free_out = 1;
dest = ASN1_STRING_type_new(str_type);
if(!dest) {
- OPENSSL_PUT_ERROR(ASN1, ASN1_mbstring_ncopy, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
return -1;
}
*out = dest;
@@ -199,7 +199,7 @@ int ASN1_mbstring_ncopy(ASN1_STRING **out, const unsigned char *in, int len,
/* If both the same type just copy across */
if(inform == outform) {
if(!ASN1_STRING_set(dest, in, len)) {
- OPENSSL_PUT_ERROR(ASN1, ASN1_mbstring_ncopy, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
return -1;
}
return str_type;
@@ -230,7 +230,7 @@ int ASN1_mbstring_ncopy(ASN1_STRING **out, const unsigned char *in, int len,
}
if(!(p = OPENSSL_malloc(outlen + 1))) {
if(free_out) ASN1_STRING_free(dest);
- OPENSSL_PUT_ERROR(ASN1, ASN1_mbstring_ncopy, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
return -1;
}
dest->length = outlen;
diff --git a/src/crypto/asn1/a_object.c b/src/crypto/asn1/a_object.c
index 189886c..6ddfca9 100644
--- a/src/crypto/asn1/a_object.c
+++ b/src/crypto/asn1/a_object.c
@@ -106,13 +106,13 @@ int a2d_ASN1_OBJECT(unsigned char *out, int olen, const char *buf, int num)
}
else
{
- OPENSSL_PUT_ERROR(ASN1, a2d_ASN1_OBJECT, ASN1_R_FIRST_NUM_TOO_LARGE);
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_FIRST_NUM_TOO_LARGE);
goto err;
}
if (num <= 0)
{
- OPENSSL_PUT_ERROR(ASN1, a2d_ASN1_OBJECT, ASN1_R_MISSING_SECOND_NUMBER);
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_MISSING_SECOND_NUMBER);
goto err;
}
c= *(p++);
@@ -122,7 +122,7 @@ int a2d_ASN1_OBJECT(unsigned char *out, int olen, const char *buf, int num)
if (num <= 0) break;
if ((c != '.') && (c != ' '))
{
- OPENSSL_PUT_ERROR(ASN1, a2d_ASN1_OBJECT, ASN1_R_INVALID_SEPARATOR);
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_INVALID_SEPARATOR);
goto err;
}
l=0;
@@ -136,7 +136,7 @@ int a2d_ASN1_OBJECT(unsigned char *out, int olen, const char *buf, int num)
break;
if ((c < '0') || (c > '9'))
{
- OPENSSL_PUT_ERROR(ASN1, a2d_ASN1_OBJECT, ASN1_R_INVALID_DIGIT);
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_INVALID_DIGIT);
goto err;
}
if (!use_bn && l >= ((ULONG_MAX - 80) / 10L))
@@ -160,7 +160,7 @@ int a2d_ASN1_OBJECT(unsigned char *out, int olen, const char *buf, int num)
{
if ((first < 2) && (l >= 40))
{
- OPENSSL_PUT_ERROR(ASN1, a2d_ASN1_OBJECT, ASN1_R_SECOND_NUMBER_TOO_LARGE);
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_SECOND_NUMBER_TOO_LARGE);
goto err;
}
if (use_bn)
@@ -204,7 +204,7 @@ int a2d_ASN1_OBJECT(unsigned char *out, int olen, const char *buf, int num)
{
if (len+i > olen)
{
- OPENSSL_PUT_ERROR(ASN1, a2d_ASN1_OBJECT, ASN1_R_BUFFER_TOO_SMALL);
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_BUFFER_TOO_SMALL);
goto err;
}
while (--i > 0)
@@ -280,7 +280,7 @@ ASN1_OBJECT *d2i_ASN1_OBJECT(ASN1_OBJECT **a, const unsigned char **pp,
if(ret) *pp = p;
return ret;
err:
- OPENSSL_PUT_ERROR(ASN1, d2i_ASN1_OBJECT, i);
+ OPENSSL_PUT_ERROR(ASN1, i);
return(NULL);
}
@@ -300,7 +300,7 @@ ASN1_OBJECT *c2i_ASN1_OBJECT(ASN1_OBJECT **a, const unsigned char **pp,
if (len <= 0 || len > INT_MAX || pp == NULL || (p = *pp) == NULL ||
p[len - 1] & 0x80)
{
- OPENSSL_PUT_ERROR(ASN1, c2i_ASN1_OBJECT, ASN1_R_INVALID_OBJECT_ENCODING);
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_INVALID_OBJECT_ENCODING);
return NULL;
}
/* Now 0 < len <= INT_MAX, so the cast is safe. */
@@ -309,7 +309,7 @@ ASN1_OBJECT *c2i_ASN1_OBJECT(ASN1_OBJECT **a, const unsigned char **pp,
{
if (*p == 0x80 && (!i || !(p[-1] & 0x80)))
{
- OPENSSL_PUT_ERROR(ASN1, c2i_ASN1_OBJECT, ASN1_R_INVALID_OBJECT_ENCODING);
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_INVALID_OBJECT_ENCODING);
return NULL;
}
}
@@ -350,7 +350,7 @@ ASN1_OBJECT *c2i_ASN1_OBJECT(ASN1_OBJECT **a, const unsigned char **pp,
*pp=p;
return(ret);
err:
- OPENSSL_PUT_ERROR(ASN1, c2i_ASN1_OBJECT, i);
+ OPENSSL_PUT_ERROR(ASN1, i);
if ((ret != NULL) && ((a == NULL) || (*a != ret)))
ASN1_OBJECT_free(ret);
return(NULL);
@@ -363,7 +363,7 @@ ASN1_OBJECT *ASN1_OBJECT_new(void)
ret=(ASN1_OBJECT *)OPENSSL_malloc(sizeof(ASN1_OBJECT));
if (ret == NULL)
{
- OPENSSL_PUT_ERROR(ASN1, ASN1_OBJECT_new, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
return(NULL);
}
ret->length=0;
diff --git a/src/crypto/asn1/a_strnid.c b/src/crypto/asn1/a_strnid.c
index df849e1..d4316f7 100644
--- a/src/crypto/asn1/a_strnid.c
+++ b/src/crypto/asn1/a_strnid.c
@@ -215,13 +215,13 @@ int ASN1_STRING_TABLE_add(int nid,
flags &= ~STABLE_FLAGS_MALLOC;
if(!stable) stable = sk_ASN1_STRING_TABLE_new(sk_table_cmp);
if(!stable) {
- OPENSSL_PUT_ERROR(ASN1, ASN1_STRING_TABLE_add, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
return 0;
}
if(!(tmp = ASN1_STRING_TABLE_get(nid))) {
tmp = OPENSSL_malloc(sizeof(ASN1_STRING_TABLE));
if(!tmp) {
- OPENSSL_PUT_ERROR(ASN1, ASN1_STRING_TABLE_add, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
return 0;
}
tmp->flags = flags | STABLE_FLAGS_MALLOC;
diff --git a/src/crypto/asn1/a_time.c b/src/crypto/asn1/a_time.c
index e02e858..ac2cb48 100644
--- a/src/crypto/asn1/a_time.c
+++ b/src/crypto/asn1/a_time.c
@@ -85,7 +85,7 @@ int i2d_ASN1_TIME(ASN1_TIME *a, unsigned char **pp)
if(a->type == V_ASN1_UTCTIME || a->type == V_ASN1_GENERALIZEDTIME)
return(i2d_ASN1_bytes((ASN1_STRING *)a,pp,
a->type ,V_ASN1_UNIVERSAL));
- OPENSSL_PUT_ERROR(ASN1, XXX, ASN1_R_EXPECTING_A_TIME);
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_EXPECTING_A_TIME);
return -1;
}
#endif
@@ -105,7 +105,7 @@ ASN1_TIME *ASN1_TIME_adj(ASN1_TIME *s, time_t t,
ts=OPENSSL_gmtime(&t,&data);
if (ts == NULL)
{
- OPENSSL_PUT_ERROR(ASN1, ASN1_TIME_adj, ASN1_R_ERROR_GETTING_TIME);
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_ERROR_GETTING_TIME);
return NULL;
}
if (offset_day || offset_sec)
diff --git a/src/crypto/asn1/a_utctm.c b/src/crypto/asn1/a_utctm.c
index 52b010f..dbbbecb 100644
--- a/src/crypto/asn1/a_utctm.c
+++ b/src/crypto/asn1/a_utctm.c
@@ -81,12 +81,12 @@ ASN1_UTCTIME *d2i_ASN1_UTCTIME(ASN1_UTCTIME **a, unsigned char **pp,
V_ASN1_UTCTIME,V_ASN1_UNIVERSAL);
if (ret == NULL)
{
- OPENSSL_PUT_ERROR(ASN1, XXX, ERR_R_NESTED_ASN1_ERROR);
+ OPENSSL_PUT_ERROR(ASN1, ERR_R_NESTED_ASN1_ERROR);
return(NULL);
}
if (!ASN1_UTCTIME_check(ret))
{
- OPENSSL_PUT_ERROR(ASN1, XXX, ASN1_R_INVALID_TIME_FORMAT);
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_INVALID_TIME_FORMAT);
goto err;
}
@@ -257,7 +257,7 @@ ASN1_UTCTIME *ASN1_UTCTIME_adj(ASN1_UTCTIME *s, time_t t,
p=OPENSSL_malloc(len);
if (p == NULL)
{
- OPENSSL_PUT_ERROR(ASN1, ASN1_UTCTIME_adj, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
goto err;
}
if (s->data != NULL)
diff --git a/src/crypto/asn1/asn1_lib.c b/src/crypto/asn1/asn1_lib.c
index 9aa2678..a109749 100644
--- a/src/crypto/asn1/asn1_lib.c
+++ b/src/crypto/asn1/asn1_lib.c
@@ -69,17 +69,10 @@
OPENSSL_DECLARE_ERROR_REASON(ASN1, MALLOC_FAILURE);
/* Cross-module errors from crypto/x509/i2d_pr.c */
-OPENSSL_DECLARE_ERROR_FUNCTION(ASN1, i2d_PrivateKey);
OPENSSL_DECLARE_ERROR_REASON(ASN1, UNSUPPORTED_PUBLIC_KEY_TYPE);
/* Cross-module errors from crypto/x509/asn1_gen.c.
* TODO(davidben): Remove these once asn1_gen.c is gone. */
-OPENSSL_DECLARE_ERROR_FUNCTION(ASN1, ASN1_generate_v3);
-OPENSSL_DECLARE_ERROR_FUNCTION(ASN1, asn1_cb);
-OPENSSL_DECLARE_ERROR_FUNCTION(ASN1, parse_tagging);
-OPENSSL_DECLARE_ERROR_FUNCTION(ASN1, append_exp);
-OPENSSL_DECLARE_ERROR_FUNCTION(ASN1, asn1_str2type);
-OPENSSL_DECLARE_ERROR_FUNCTION(ASN1, bitstr_cb);
OPENSSL_DECLARE_ERROR_REASON(ASN1, DEPTH_EXCEEDED);
OPENSSL_DECLARE_ERROR_REASON(ASN1, ILLEGAL_BITSTRING_FORMAT);
OPENSSL_DECLARE_ERROR_REASON(ASN1, ILLEGAL_BOOLEAN);
@@ -183,7 +176,7 @@ int ASN1_get_object(const unsigned char **pp, long *plength, int *ptag,
#endif
if (*plength > (omax - (p - *pp)))
{
- OPENSSL_PUT_ERROR(ASN1, ASN1_get_object, ASN1_R_TOO_LONG);
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_TOO_LONG);
/* Set this so that even if things are not long enough
* the values are set correctly */
ret|=0x80;
@@ -191,7 +184,7 @@ int ASN1_get_object(const unsigned char **pp, long *plength, int *ptag,
*pp=p;
return(ret|inf);
err:
- OPENSSL_PUT_ERROR(ASN1, ASN1_get_object, ASN1_R_HEADER_TOO_LONG);
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_HEADER_TOO_LONG);
return(0x80);
}
@@ -433,7 +426,7 @@ int ASN1_STRING_set(ASN1_STRING *str, const void *_data, int len)
if (str->data == NULL)
{
- OPENSSL_PUT_ERROR(ASN1, ASN1_STRING_set, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
str->data=c;
return(0);
}
@@ -469,7 +462,7 @@ ASN1_STRING *ASN1_STRING_type_new(int type)
ret=(ASN1_STRING *)OPENSSL_malloc(sizeof(ASN1_STRING));
if (ret == NULL)
{
- OPENSSL_PUT_ERROR(ASN1, ASN1_STRING_type_new, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
return(NULL);
}
ret->length=0;
diff --git a/src/crypto/asn1/asn_pack.c b/src/crypto/asn1/asn_pack.c
index ee58fa5..e842a10 100644
--- a/src/crypto/asn1/asn_pack.c
+++ b/src/crypto/asn1/asn_pack.c
@@ -68,7 +68,7 @@ ASN1_STRING *ASN1_item_pack(void *obj, const ASN1_ITEM *it, ASN1_STRING **oct)
if (!oct || !*oct) {
if (!(octmp = ASN1_STRING_new ())) {
- OPENSSL_PUT_ERROR(ASN1, ASN1_item_pack, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
return NULL;
}
if (oct) *oct = octmp;
@@ -80,11 +80,11 @@ ASN1_STRING *ASN1_item_pack(void *obj, const ASN1_ITEM *it, ASN1_STRING **oct)
}
if (!(octmp->length = ASN1_item_i2d(obj, &octmp->data, it))) {
- OPENSSL_PUT_ERROR(ASN1, ASN1_item_pack, ASN1_R_ENCODE_ERROR);
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_ENCODE_ERROR);
return NULL;
}
if (!octmp->data) {
- OPENSSL_PUT_ERROR(ASN1, ASN1_item_pack, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
return NULL;
}
return octmp;
@@ -99,6 +99,6 @@ void *ASN1_item_unpack(ASN1_STRING *oct, const ASN1_ITEM *it)
p = oct->data;
if(!(ret = ASN1_item_d2i(NULL, &p, oct->length, it)))
- OPENSSL_PUT_ERROR(ASN1, ASN1_item_unpack, ASN1_R_DECODE_ERROR);
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_DECODE_ERROR);
return ret;
}
diff --git a/src/crypto/asn1/bio_ndef.c b/src/crypto/asn1/bio_ndef.c
index 2f7105d..f07d3de 100644
--- a/src/crypto/asn1/bio_ndef.c
+++ b/src/crypto/asn1/bio_ndef.c
@@ -112,7 +112,7 @@ BIO *BIO_new_NDEF(BIO *out, ASN1_VALUE *val, const ASN1_ITEM *it)
if (!aux || !aux->asn1_cb)
{
- OPENSSL_PUT_ERROR(ASN1, BIO_new_NDEF, ASN1_R_STREAMING_NOT_SUPPORTED);
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_STREAMING_NOT_SUPPORTED);
return NULL;
}
ndef_aux = OPENSSL_malloc(sizeof(NDEF_SUPPORT));
diff --git a/src/crypto/asn1/f_enum.c b/src/crypto/asn1/f_enum.c
index 530afe5..bcdb773 100644
--- a/src/crypto/asn1/f_enum.c
+++ b/src/crypto/asn1/f_enum.c
@@ -144,7 +144,7 @@ int a2i_ASN1_ENUMERATED(BIO *bp, ASN1_ENUMERATED *bs, char *buf, int size)
i-=again;
if (i%2 != 0)
{
- OPENSSL_PUT_ERROR(ASN1, a2i_ASN1_ENUMERATED, ASN1_R_ODD_NUMBER_OF_CHARS);
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_ODD_NUMBER_OF_CHARS);
goto err;
}
i/=2;
@@ -158,7 +158,7 @@ int a2i_ASN1_ENUMERATED(BIO *bp, ASN1_ENUMERATED *bs, char *buf, int size)
(unsigned int)num+i*2);
if (sp == NULL)
{
- OPENSSL_PUT_ERROR(ASN1, a2i_ASN1_ENUMERATED, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
goto err;
}
s=sp;
@@ -177,7 +177,7 @@ int a2i_ASN1_ENUMERATED(BIO *bp, ASN1_ENUMERATED *bs, char *buf, int size)
m=m-'A'+10;
else
{
- OPENSSL_PUT_ERROR(ASN1, a2i_ASN1_ENUMERATED, ASN1_R_NON_HEX_CHARACTERS);
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_NON_HEX_CHARACTERS);
goto err;
}
s[num+j]<<=4;
@@ -197,7 +197,7 @@ err:
if (0)
{
err_sl:
- OPENSSL_PUT_ERROR(ASN1, a2i_ASN1_ENUMERATED, ASN1_R_SHORT_LINE);
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_SHORT_LINE);
}
if (s != NULL)
OPENSSL_free(s);
diff --git a/src/crypto/asn1/f_int.c b/src/crypto/asn1/f_int.c
index 2c4fe6f..5186304 100644
--- a/src/crypto/asn1/f_int.c
+++ b/src/crypto/asn1/f_int.c
@@ -149,7 +149,7 @@ int a2i_ASN1_INTEGER(BIO *bp, ASN1_INTEGER *bs, char *buf, int size)
i-=again;
if (i%2 != 0)
{
- OPENSSL_PUT_ERROR(ASN1, a2i_ASN1_INTEGER, ASN1_R_ODD_NUMBER_OF_CHARS);
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_ODD_NUMBER_OF_CHARS);
goto err;
}
i/=2;
@@ -162,7 +162,7 @@ int a2i_ASN1_INTEGER(BIO *bp, ASN1_INTEGER *bs, char *buf, int size)
sp=OPENSSL_realloc_clean(s,slen,num+i*2);
if (sp == NULL)
{
- OPENSSL_PUT_ERROR(ASN1, a2i_ASN1_INTEGER, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
goto err;
}
s=sp;
@@ -181,7 +181,7 @@ int a2i_ASN1_INTEGER(BIO *bp, ASN1_INTEGER *bs, char *buf, int size)
m=m-'A'+10;
else
{
- OPENSSL_PUT_ERROR(ASN1, a2i_ASN1_INTEGER, ASN1_R_NON_HEX_CHARACTERS);
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_NON_HEX_CHARACTERS);
goto err;
}
s[num+j]<<=4;
@@ -201,7 +201,7 @@ err:
if (0)
{
err_sl:
- OPENSSL_PUT_ERROR(ASN1, a2i_ASN1_INTEGER, ASN1_R_SHORT_LINE);
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_SHORT_LINE);
}
if (s != NULL)
OPENSSL_free(s);
diff --git a/src/crypto/asn1/f_string.c b/src/crypto/asn1/f_string.c
index 2f53670..5a7fe36 100644
--- a/src/crypto/asn1/f_string.c
+++ b/src/crypto/asn1/f_string.c
@@ -142,7 +142,7 @@ int a2i_ASN1_STRING(BIO *bp, ASN1_STRING *bs, char *buf, int size)
i-=again;
if (i%2 != 0)
{
- OPENSSL_PUT_ERROR(ASN1, a2i_ASN1_STRING, ASN1_R_ODD_NUMBER_OF_CHARS);
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_ODD_NUMBER_OF_CHARS);
goto err;
}
i/=2;
@@ -156,7 +156,7 @@ int a2i_ASN1_STRING(BIO *bp, ASN1_STRING *bs, char *buf, int size)
(unsigned int)num+i*2);
if (sp == NULL)
{
- OPENSSL_PUT_ERROR(ASN1, a2i_ASN1_STRING, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
goto err;
}
s=sp;
@@ -175,7 +175,7 @@ int a2i_ASN1_STRING(BIO *bp, ASN1_STRING *bs, char *buf, int size)
m=m-'A'+10;
else
{
- OPENSSL_PUT_ERROR(ASN1, a2i_ASN1_STRING, ASN1_R_NON_HEX_CHARACTERS);
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_NON_HEX_CHARACTERS);
goto err;
}
s[num+j]<<=4;
@@ -195,7 +195,7 @@ err:
if (0)
{
err_sl:
- OPENSSL_PUT_ERROR(ASN1, a2i_ASN1_STRING, ASN1_R_SHORT_LINE);
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_SHORT_LINE);
}
if (s != NULL)
OPENSSL_free(s);
diff --git a/src/crypto/asn1/tasn_dec.c b/src/crypto/asn1/tasn_dec.c
index 73d3bb3..507a842 100644
--- a/src/crypto/asn1/tasn_dec.c
+++ b/src/crypto/asn1/tasn_dec.c
@@ -189,7 +189,7 @@ int ASN1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len,
*/
if ((tag != -1) || opt)
{
- OPENSSL_PUT_ERROR(ASN1, ASN1_item_ex_d2i, ASN1_R_ILLEGAL_OPTIONS_ON_ITEM_TEMPLATE);
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_ILLEGAL_OPTIONS_ON_ITEM_TEMPLATE);
goto err;
}
return asn1_template_ex_d2i(pval, in, len,
@@ -206,7 +206,7 @@ int ASN1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len,
&p, len, -1, 0, 1, ctx);
if (!ret)
{
- OPENSSL_PUT_ERROR(ASN1, ASN1_item_ex_d2i, ASN1_R_NESTED_ASN1_ERROR);
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR);
goto err;
}
@@ -215,7 +215,7 @@ int ASN1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len,
{
/* If OPTIONAL, assume this is OK */
if (opt) return -1;
- OPENSSL_PUT_ERROR(ASN1, ASN1_item_ex_d2i, ASN1_R_MSTRING_NOT_UNIVERSAL);
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_MSTRING_NOT_UNIVERSAL);
goto err;
}
/* Check tag matches bit map */
@@ -224,7 +224,7 @@ int ASN1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len,
/* If OPTIONAL, assume this is OK */
if (opt)
return -1;
- OPENSSL_PUT_ERROR(ASN1, ASN1_item_ex_d2i, ASN1_R_MSTRING_WRONG_TAG);
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_MSTRING_WRONG_TAG);
goto err;
}
return asn1_d2i_ex_primitive(pval, in, len,
@@ -255,7 +255,7 @@ int ASN1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len,
&p, len, exptag, aclass, 1, ctx);
if (!ret)
{
- OPENSSL_PUT_ERROR(ASN1, ASN1_item_ex_d2i, ASN1_R_NESTED_ASN1_ERROR);
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR);
goto err;
}
if (ret == -1)
@@ -283,7 +283,7 @@ int ASN1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len,
imphack = *wp;
if (p == NULL)
{
- OPENSSL_PUT_ERROR(ASN1, ASN1_item_ex_d2i, ASN1_R_NESTED_ASN1_ERROR);
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR);
goto err;
}
*wp = (unsigned char)((*p & V_ASN1_CONSTRUCTED)
@@ -298,7 +298,7 @@ int ASN1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len,
if (ptmpval)
return 1;
- OPENSSL_PUT_ERROR(ASN1, ASN1_item_ex_d2i, ASN1_R_NESTED_ASN1_ERROR);
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR);
goto err;
@@ -320,7 +320,7 @@ int ASN1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len,
}
else if (!ASN1_item_ex_new(pval, it))
{
- OPENSSL_PUT_ERROR(ASN1, ASN1_item_ex_d2i, ASN1_R_NESTED_ASN1_ERROR);
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR);
goto err;
}
/* CHOICE type, try each possibility in turn */
@@ -340,7 +340,7 @@ int ASN1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len,
break;
/* Otherwise must be an ASN1 parsing error */
errtt = tt;
- OPENSSL_PUT_ERROR(ASN1, ASN1_item_ex_d2i, ASN1_R_NESTED_ASN1_ERROR);
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR);
goto err;
}
@@ -354,7 +354,7 @@ int ASN1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len,
ASN1_item_ex_free(pval, it);
return -1;
}
- OPENSSL_PUT_ERROR(ASN1, ASN1_item_ex_d2i, ASN1_R_NO_MATCHING_CHOICE_TYPE);
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_NO_MATCHING_CHOICE_TYPE);
goto err;
}
@@ -380,7 +380,7 @@ int ASN1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len,
&p, len, tag, aclass, opt, ctx);
if (!ret)
{
- OPENSSL_PUT_ERROR(ASN1, ASN1_item_ex_d2i, ASN1_R_NESTED_ASN1_ERROR);
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR);
goto err;
}
else if (ret == -1)
@@ -394,13 +394,13 @@ int ASN1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len,
else seq_nolen = seq_eoc;
if (!cst)
{
- OPENSSL_PUT_ERROR(ASN1, ASN1_item_ex_d2i, ASN1_R_SEQUENCE_NOT_CONSTRUCTED);
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_SEQUENCE_NOT_CONSTRUCTED);
goto err;
}
if (!*pval && !ASN1_item_ex_new(pval, it))
{
- OPENSSL_PUT_ERROR(ASN1, ASN1_item_ex_d2i, ASN1_R_NESTED_ASN1_ERROR);
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR);
goto err;
}
@@ -437,7 +437,7 @@ int ASN1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len,
{
if (!seq_eoc)
{
- OPENSSL_PUT_ERROR(ASN1, ASN1_item_ex_d2i, ASN1_R_UNEXPECTED_EOC);
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_UNEXPECTED_EOC);
goto err;
}
len -= p - q;
@@ -479,13 +479,13 @@ int ASN1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len,
/* Check for EOC if expecting one */
if (seq_eoc && !asn1_check_eoc(&p, len))
{
- OPENSSL_PUT_ERROR(ASN1, ASN1_item_ex_d2i, ASN1_R_MISSING_EOC);
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_MISSING_EOC);
goto err;
}
/* Check all data read */
if (!seq_nolen && len)
{
- OPENSSL_PUT_ERROR(ASN1, ASN1_item_ex_d2i, ASN1_R_SEQUENCE_LENGTH_MISMATCH);
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_SEQUENCE_LENGTH_MISMATCH);
goto err;
}
@@ -508,7 +508,7 @@ int ASN1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len,
else
{
errtt = seqtt;
- OPENSSL_PUT_ERROR(ASN1, ASN1_item_ex_d2i, ASN1_R_FIELD_MISSING);
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_FIELD_MISSING);
goto err;
}
}
@@ -524,7 +524,7 @@ int ASN1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len,
return 0;
}
auxerr:
- OPENSSL_PUT_ERROR(ASN1, ASN1_item_ex_d2i, ASN1_R_AUX_ERROR);
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_AUX_ERROR);
err:
ASN1_item_ex_free(pval, it);
if (errtt)
@@ -569,21 +569,21 @@ static int asn1_template_ex_d2i(ASN1_VALUE **val,
q = p;
if (!ret)
{
- OPENSSL_PUT_ERROR(ASN1, asn1_template_ex_d2i, ASN1_R_NESTED_ASN1_ERROR);
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR);
return 0;
}
else if (ret == -1)
return -1;
if (!cst)
{
- OPENSSL_PUT_ERROR(ASN1, asn1_template_ex_d2i, ASN1_R_EXPLICIT_TAG_NOT_CONSTRUCTED);
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_EXPLICIT_TAG_NOT_CONSTRUCTED);
return 0;
}
/* We've found the field so it can't be OPTIONAL now */
ret = asn1_template_noexp_d2i(val, &p, len, tt, 0, ctx);
if (!ret)
{
- OPENSSL_PUT_ERROR(ASN1, asn1_template_ex_d2i, ASN1_R_NESTED_ASN1_ERROR);
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR);
return 0;
}
/* We read the field in OK so update length */
@@ -593,7 +593,7 @@ static int asn1_template_ex_d2i(ASN1_VALUE **val,
/* If NDEF we must have an EOC here */
if (!asn1_check_eoc(&p, len))
{
- OPENSSL_PUT_ERROR(ASN1, asn1_template_ex_d2i, ASN1_R_MISSING_EOC);
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_MISSING_EOC);
goto err;
}
}
@@ -603,7 +603,7 @@ static int asn1_template_ex_d2i(ASN1_VALUE **val,
* an error */
if (len)
{
- OPENSSL_PUT_ERROR(ASN1, asn1_template_ex_d2i, ASN1_R_EXPLICIT_LENGTH_MISMATCH);
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_EXPLICIT_LENGTH_MISMATCH);
goto err;
}
}
@@ -659,7 +659,7 @@ static int asn1_template_noexp_d2i(ASN1_VALUE **val,
&p, len, sktag, skaclass, opt, ctx);
if (!ret)
{
- OPENSSL_PUT_ERROR(ASN1, asn1_template_noexp_d2i, ASN1_R_NESTED_ASN1_ERROR);
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR);
return 0;
}
else if (ret == -1)
@@ -682,7 +682,7 @@ static int asn1_template_noexp_d2i(ASN1_VALUE **val,
if (!*val)
{
- OPENSSL_PUT_ERROR(ASN1, asn1_template_noexp_d2i, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
goto err;
}
@@ -696,7 +696,7 @@ static int asn1_template_noexp_d2i(ASN1_VALUE **val,
{
if (!sk_eoc)
{
- OPENSSL_PUT_ERROR(ASN1, asn1_template_noexp_d2i, ASN1_R_UNEXPECTED_EOC);
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_UNEXPECTED_EOC);
goto err;
}
len -= p - q;
@@ -708,20 +708,20 @@ static int asn1_template_noexp_d2i(ASN1_VALUE **val,
ASN1_ITEM_ptr(tt->item),
-1, 0, 0, ctx))
{
- OPENSSL_PUT_ERROR(ASN1, asn1_template_noexp_d2i, ASN1_R_NESTED_ASN1_ERROR);
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR);
goto err;
}
len -= p - q;
if (!sk_ASN1_VALUE_push((STACK_OF(ASN1_VALUE) *)*val,
skfield))
{
- OPENSSL_PUT_ERROR(ASN1, asn1_template_noexp_d2i, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
goto err;
}
}
if (sk_eoc)
{
- OPENSSL_PUT_ERROR(ASN1, asn1_template_noexp_d2i, ASN1_R_MISSING_EOC);
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_MISSING_EOC);
goto err;
}
}
@@ -732,7 +732,7 @@ static int asn1_template_noexp_d2i(ASN1_VALUE **val,
ASN1_ITEM_ptr(tt->item), tt->tag, aclass, opt, ctx);
if (!ret)
{
- OPENSSL_PUT_ERROR(ASN1, asn1_template_noexp_d2i, ASN1_R_NESTED_ASN1_ERROR);
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR);
goto err;
}
else if (ret == -1)
@@ -745,7 +745,7 @@ static int asn1_template_noexp_d2i(ASN1_VALUE **val,
-1, 0, opt, ctx);
if (!ret)
{
- OPENSSL_PUT_ERROR(ASN1, asn1_template_noexp_d2i, ASN1_R_NESTED_ASN1_ERROR);
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR);
goto err;
}
else if (ret == -1)
@@ -775,7 +775,7 @@ static int asn1_d2i_ex_primitive(ASN1_VALUE **pval,
long len;
if (!pval)
{
- OPENSSL_PUT_ERROR(ASN1, asn1_d2i_ex_primitive, ASN1_R_ILLEGAL_NULL);
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_ILLEGAL_NULL);
return 0; /* Should never happen */
}
@@ -793,12 +793,12 @@ static int asn1_d2i_ex_primitive(ASN1_VALUE **pval,
unsigned char oclass;
if (tag >= 0)
{
- OPENSSL_PUT_ERROR(ASN1, asn1_d2i_ex_primitive, ASN1_R_ILLEGAL_TAGGED_ANY);
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_ILLEGAL_TAGGED_ANY);
return 0;
}
if (opt)
{
- OPENSSL_PUT_ERROR(ASN1, asn1_d2i_ex_primitive, ASN1_R_ILLEGAL_OPTIONAL_ANY);
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_ILLEGAL_OPTIONAL_ANY);
return 0;
}
p = *in;
@@ -806,7 +806,7 @@ static int asn1_d2i_ex_primitive(ASN1_VALUE **pval,
&p, inlen, -1, 0, 0, ctx);
if (!ret)
{
- OPENSSL_PUT_ERROR(ASN1, asn1_d2i_ex_primitive, ASN1_R_NESTED_ASN1_ERROR);
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR);
return 0;
}
if (oclass != V_ASN1_UNIVERSAL)
@@ -823,7 +823,7 @@ static int asn1_d2i_ex_primitive(ASN1_VALUE **pval,
&p, inlen, tag, aclass, opt, ctx);
if (!ret)
{
- OPENSSL_PUT_ERROR(ASN1, asn1_d2i_ex_primitive, ASN1_R_NESTED_ASN1_ERROR);
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR);
return 0;
}
else if (ret == -1)
@@ -843,7 +843,7 @@ static int asn1_d2i_ex_primitive(ASN1_VALUE **pval,
/* SEQUENCE and SET must be constructed */
else if (!cst)
{
- OPENSSL_PUT_ERROR(ASN1, asn1_d2i_ex_primitive, ASN1_R_TYPE_NOT_CONSTRUCTED);
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_TYPE_NOT_CONSTRUCTED);
return 0;
}
@@ -869,8 +869,7 @@ static int asn1_d2i_ex_primitive(ASN1_VALUE **pval,
|| utype == V_ASN1_ENUMERATED)
{
/* These types only have primitive encodings. */
- OPENSSL_PUT_ERROR(ASN1, asn1_d2i_ex_primitive,
- ASN1_R_TYPE_NOT_PRIMITIVE);
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_TYPE_NOT_PRIMITIVE);
return 0;
}
@@ -892,7 +891,7 @@ static int asn1_d2i_ex_primitive(ASN1_VALUE **pval,
/* Append a final null to string */
if (!BUF_MEM_grow_clean(&buf, len + 1))
{
- OPENSSL_PUT_ERROR(ASN1, asn1_d2i_ex_primitive, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
return 0;
}
buf.data[len] = 0;
@@ -960,7 +959,7 @@ int asn1_ex_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len,
case V_ASN1_NULL:
if (len)
{
- OPENSSL_PUT_ERROR(ASN1, asn1_ex_c2i, ASN1_R_NULL_IS_WRONG_LENGTH);
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_NULL_IS_WRONG_LENGTH);
goto err;
}
*pval = (ASN1_VALUE *)1;
@@ -969,7 +968,7 @@ int asn1_ex_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len,
case V_ASN1_BOOLEAN:
if (len != 1)
{
- OPENSSL_PUT_ERROR(ASN1, asn1_ex_c2i, ASN1_R_BOOLEAN_IS_WRONG_LENGTH);
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_BOOLEAN_IS_WRONG_LENGTH);
goto err;
}
else
@@ -1016,12 +1015,12 @@ int asn1_ex_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len,
default:
if (utype == V_ASN1_BMPSTRING && (len & 1))
{
- OPENSSL_PUT_ERROR(ASN1, asn1_ex_c2i, ASN1_R_BMPSTRING_IS_WRONG_LENGTH);
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_BMPSTRING_IS_WRONG_LENGTH);
goto err;
}
if (utype == V_ASN1_UNIVERSALSTRING && (len & 3))
{
- OPENSSL_PUT_ERROR(ASN1, asn1_ex_c2i, ASN1_R_UNIVERSALSTRING_IS_WRONG_LENGTH);
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_UNIVERSALSTRING_IS_WRONG_LENGTH);
goto err;
}
/* All based on ASN1_STRING and handled the same */
@@ -1030,7 +1029,7 @@ int asn1_ex_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len,
stmp = ASN1_STRING_type_new(utype);
if (!stmp)
{
- OPENSSL_PUT_ERROR(ASN1, asn1_ex_c2i, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
goto err;
}
*pval = (ASN1_VALUE *)stmp;
@@ -1053,7 +1052,7 @@ int asn1_ex_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len,
{
if (!ASN1_STRING_set(stmp, cont, len))
{
- OPENSSL_PUT_ERROR(ASN1, asn1_ex_c2i, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
ASN1_STRING_free(stmp);
*pval = NULL;
goto err;
@@ -1115,7 +1114,7 @@ static int asn1_find_end(const unsigned char **in, long len, char inf)
if(!asn1_check_tlen(&plen, NULL, NULL, &inf, NULL, &p, len,
-1, 0, 0, NULL))
{
- OPENSSL_PUT_ERROR(ASN1, asn1_find_end, ASN1_R_NESTED_ASN1_ERROR);
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR);
return 0;
}
if (inf)
@@ -1126,7 +1125,7 @@ static int asn1_find_end(const unsigned char **in, long len, char inf)
}
if (expected_eoc)
{
- OPENSSL_PUT_ERROR(ASN1, asn1_find_end, ASN1_R_MISSING_EOC);
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_MISSING_EOC);
return 0;
}
*in = p;
@@ -1173,7 +1172,7 @@ static int asn1_collect(BUF_MEM *buf, const unsigned char **in, long len,
* constructed form */
if (!inf)
{
- OPENSSL_PUT_ERROR(ASN1, asn1_collect, ASN1_R_UNEXPECTED_EOC);
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_UNEXPECTED_EOC);
return 0;
}
inf = 0;
@@ -1183,7 +1182,7 @@ static int asn1_collect(BUF_MEM *buf, const unsigned char **in, long len,
if (!asn1_check_tlen(&plen, NULL, NULL, &ininf, &cst, &p,
len, tag, aclass, 0, NULL))
{
- OPENSSL_PUT_ERROR(ASN1, asn1_collect, ASN1_R_NESTED_ASN1_ERROR);
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR);
return 0;
}
@@ -1192,7 +1191,7 @@ static int asn1_collect(BUF_MEM *buf, const unsigned char **in, long len,
{
if (depth >= ASN1_MAX_STRING_NEST)
{
- OPENSSL_PUT_ERROR(ASN1, asn1_collect, ASN1_R_NESTED_ASN1_STRING);
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_STRING);
return 0;
}
if (!asn1_collect(buf, &p, plen, ininf, tag, aclass,
@@ -1205,7 +1204,7 @@ static int asn1_collect(BUF_MEM *buf, const unsigned char **in, long len,
}
if (inf)
{
- OPENSSL_PUT_ERROR(ASN1, asn1_collect, ASN1_R_MISSING_EOC);
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_MISSING_EOC);
return 0;
}
*in = p;
@@ -1220,7 +1219,7 @@ static int collect_data(BUF_MEM *buf, const unsigned char **p, long plen)
len = buf->length;
if (!BUF_MEM_grow_clean(buf, len + plen))
{
- OPENSSL_PUT_ERROR(ASN1, collect_data, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
return 0;
}
memcpy(buf->data + len, *p, plen);
@@ -1288,7 +1287,7 @@ static int asn1_check_tlen(long *olen, int *otag, unsigned char *oclass,
*/
if (!(i & 0x81) && ((plen + ctx->hdrlen) > len))
{
- OPENSSL_PUT_ERROR(ASN1, asn1_check_tlen, ASN1_R_TOO_LONG);
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_TOO_LONG);
asn1_tlc_clear(ctx);
return 0;
}
@@ -1297,7 +1296,7 @@ static int asn1_check_tlen(long *olen, int *otag, unsigned char *oclass,
if (i & 0x80)
{
- OPENSSL_PUT_ERROR(ASN1, asn1_check_tlen, ASN1_R_BAD_OBJECT_HEADER);
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_BAD_OBJECT_HEADER);
asn1_tlc_clear(ctx);
return 0;
}
@@ -1310,7 +1309,7 @@ static int asn1_check_tlen(long *olen, int *otag, unsigned char *oclass,
*/
if (opt) return -1;
asn1_tlc_clear(ctx);
- OPENSSL_PUT_ERROR(ASN1, asn1_check_tlen, ASN1_R_WRONG_TAG);
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_WRONG_TAG);
return 0;
}
/* We have a tag and class match:
diff --git a/src/crypto/asn1/tasn_new.c b/src/crypto/asn1/tasn_new.c
index 6d69dcb..c68fe06 100644
--- a/src/crypto/asn1/tasn_new.c
+++ b/src/crypto/asn1/tasn_new.c
@@ -209,7 +209,7 @@ static int asn1_item_ex_combine_new(ASN1_VALUE **pval, const ASN1_ITEM *it,
return 1;
memerr:
- OPENSSL_PUT_ERROR(ASN1, asn1_item_ex_combine_new, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
ASN1_item_ex_free(pval, it);
#ifdef CRYPTO_MDEBUG
if (it->sname) CRYPTO_pop_info();
@@ -217,7 +217,7 @@ static int asn1_item_ex_combine_new(ASN1_VALUE **pval, const ASN1_ITEM *it,
return 0;
auxerr:
- OPENSSL_PUT_ERROR(ASN1, asn1_item_ex_combine_new, ASN1_R_AUX_ERROR);
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_AUX_ERROR);
ASN1_item_ex_free(pval, it);
#ifdef CRYPTO_MDEBUG
if (it->sname) CRYPTO_pop_info();
@@ -289,7 +289,7 @@ int ASN1_template_new(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt)
skval = sk_ASN1_VALUE_new_null();
if (!skval)
{
- OPENSSL_PUT_ERROR(ASN1, ASN1_template_new, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
ret = 0;
goto done;
}
diff --git a/src/crypto/asn1/tasn_prn.c b/src/crypto/asn1/tasn_prn.c
index df19ff0..6a097a1 100644
--- a/src/crypto/asn1/tasn_prn.c
+++ b/src/crypto/asn1/tasn_prn.c
@@ -88,7 +88,7 @@ ASN1_PCTX *ASN1_PCTX_new(void)
ret = OPENSSL_malloc(sizeof(ASN1_PCTX));
if (ret == NULL)
{
- OPENSSL_PUT_ERROR(ASN1, ASN1_PCTX_new, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
return NULL;
}
ret->flags = 0;
diff --git a/src/crypto/asn1/tasn_utl.c b/src/crypto/asn1/tasn_utl.c
index ff3764e..960cdbb 100644
--- a/src/crypto/asn1/tasn_utl.c
+++ b/src/crypto/asn1/tasn_utl.c
@@ -260,8 +260,7 @@ const ASN1_TEMPLATE *asn1_do_adb(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt,
err:
/* FIXME: should log the value or OID of unsupported type */
if (nullerr) {
- OPENSSL_PUT_ERROR(ASN1, asn1_do_adb,
- ASN1_R_UNSUPPORTED_ANY_DEFINED_BY_TYPE);
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_UNSUPPORTED_ANY_DEFINED_BY_TYPE);
}
return NULL;
}
diff --git a/src/crypto/asn1/x_long.c b/src/crypto/asn1/x_long.c
index 5c2f96e..7b1a6fe 100644
--- a/src/crypto/asn1/x_long.c
+++ b/src/crypto/asn1/x_long.c
@@ -150,7 +150,7 @@ static int long_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len,
unsigned long utmp = 0;
char *cp = (char *)pval;
if(len > (int)sizeof(long)) {
- OPENSSL_PUT_ERROR(ASN1, long_c2i, ASN1_R_INTEGER_TOO_LARGE_FOR_LONG);
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_INTEGER_TOO_LARGE_FOR_LONG);
return 0;
}
/* Is it negative? */
@@ -168,7 +168,7 @@ static int long_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len,
ltmp = -ltmp;
}
if(ltmp == it->size) {
- OPENSSL_PUT_ERROR(ASN1, long_c2i, ASN1_R_INTEGER_TOO_LARGE_FOR_LONG);
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_INTEGER_TOO_LARGE_FOR_LONG);
return 0;
}
memcpy(cp, &ltmp, sizeof(long));
diff --git a/src/crypto/base64/CMakeLists.txt b/src/crypto/base64/CMakeLists.txt
index 42037a5..f1dba6c 100644
--- a/src/crypto/base64/CMakeLists.txt
+++ b/src/crypto/base64/CMakeLists.txt
@@ -1,4 +1,4 @@
-include_directories(. .. ../../include)
+include_directories(../../include)
add_library(
base64
diff --git a/src/crypto/bio/CMakeLists.txt b/src/crypto/bio/CMakeLists.txt
index dbf5951..8de090a 100644
--- a/src/crypto/bio/CMakeLists.txt
+++ b/src/crypto/bio/CMakeLists.txt
@@ -1,4 +1,4 @@
-include_directories(. .. ../../include)
+include_directories(../../include)
add_library(
bio
diff --git a/src/crypto/bio/bio.c b/src/crypto/bio/bio.c
index 5ac5911..4bc98ba 100644
--- a/src/crypto/bio/bio.c
+++ b/src/crypto/bio/bio.c
@@ -90,7 +90,7 @@ static int bio_set(BIO *bio, const BIO_METHOD *method) {
BIO *BIO_new(const BIO_METHOD *method) {
BIO *ret = OPENSSL_malloc(sizeof(BIO));
if (ret == NULL) {
- OPENSSL_PUT_ERROR(BIO, BIO_new, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(BIO, ERR_R_MALLOC_FAILURE);
return NULL;
}
@@ -153,7 +153,7 @@ static int bio_io(BIO *bio, void *buf, int len, size_t method_offset,
}
if (io_func == NULL) {
- OPENSSL_PUT_ERROR(BIO, bio_io, BIO_R_UNSUPPORTED_METHOD);
+ OPENSSL_PUT_ERROR(BIO, BIO_R_UNSUPPORTED_METHOD);
return -2;
}
@@ -165,7 +165,7 @@ static int bio_io(BIO *bio, void *buf, int len, size_t method_offset,
}
if (!bio->init) {
- OPENSSL_PUT_ERROR(BIO, bio_io, BIO_R_UNINITIALIZED);
+ OPENSSL_PUT_ERROR(BIO, BIO_R_UNINITIALIZED);
return -2;
}
@@ -217,7 +217,7 @@ long BIO_ctrl(BIO *bio, int cmd, long larg, void *parg) {
}
if (bio->method == NULL || bio->method->ctrl == NULL) {
- OPENSSL_PUT_ERROR(BIO, BIO_ctrl, BIO_R_UNSUPPORTED_METHOD);
+ OPENSSL_PUT_ERROR(BIO, BIO_R_UNSUPPORTED_METHOD);
return -2;
}
@@ -323,7 +323,7 @@ long BIO_callback_ctrl(BIO *bio, int cmd, bio_info_cb fp) {
}
if (bio->method == NULL || bio->method->callback_ctrl == NULL) {
- OPENSSL_PUT_ERROR(BIO, BIO_callback_ctrl, BIO_R_UNSUPPORTED_METHOD);
+ OPENSSL_PUT_ERROR(BIO, BIO_R_UNSUPPORTED_METHOD);
return 0;
}
@@ -462,6 +462,10 @@ void BIO_print_errors(BIO *bio) {
ERR_print_errors_cb(print_bio, bio);
}
+void ERR_print_errors(BIO *bio) {
+ BIO_print_errors(bio);
+}
+
/* bio_read_all reads everything from |bio| and prepends |prefix| to it. On
* success, |*out| is set to an allocated buffer (which should be freed with
* |OPENSSL_free|), |*out_len| is set to its length and one is returned. The
diff --git a/src/crypto/bio/bio_mem.c b/src/crypto/bio/bio_mem.c
index f3aad6f..ef56111 100644
--- a/src/crypto/bio/bio_mem.c
+++ b/src/crypto/bio/bio_mem.c
@@ -70,7 +70,7 @@ BIO *BIO_new_mem_buf(void *buf, int len) {
const size_t size = len < 0 ? strlen((char *)buf) : (size_t)len;
if (!buf && len != 0) {
- OPENSSL_PUT_ERROR(BIO, BIO_new_mem_buf, BIO_R_NULL_PARAMETER);
+ OPENSSL_PUT_ERROR(BIO, BIO_R_NULL_PARAMETER);
return NULL;
}
@@ -167,7 +167,7 @@ static int mem_write(BIO *bio, const char *in, int inl) {
b = (BUF_MEM *)bio->ptr;
if (bio->flags & BIO_FLAGS_MEM_RDONLY) {
- OPENSSL_PUT_ERROR(BIO, mem_write, BIO_R_WRITE_TO_READ_ONLY_BIO);
+ OPENSSL_PUT_ERROR(BIO, BIO_R_WRITE_TO_READ_ONLY_BIO);
goto err;
}
diff --git a/src/crypto/bio/buffer.c b/src/crypto/bio/buffer.c
index 3fc0685..9d0cb3c 100644
--- a/src/crypto/bio/buffer.c
+++ b/src/crypto/bio/buffer.c
@@ -406,7 +406,7 @@ static long buffer_ctrl(BIO *b, int cmd, long num, void *ptr) {
return ret;
malloc_error:
- OPENSSL_PUT_ERROR(BIO, buffer_ctrl, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(BIO, ERR_R_MALLOC_FAILURE);
return 0;
}
diff --git a/src/crypto/bio/connect.c b/src/crypto/bio/connect.c
index 32361bf..2ed2def 100644
--- a/src/crypto/bio/connect.c
+++ b/src/crypto/bio/connect.c
@@ -142,7 +142,7 @@ static int conn_state(BIO *bio, BIO_CONNECT *c) {
case BIO_CONN_S_BEFORE:
p = c->param_hostname;
if (p == NULL) {
- OPENSSL_PUT_ERROR(BIO, conn_state, BIO_R_NO_HOSTNAME_SPECIFIED);
+ OPENSSL_PUT_ERROR(BIO, BIO_R_NO_HOSTNAME_SPECIFIED);
goto exit_loop;
}
for (; *p != 0; p++) {
@@ -167,7 +167,7 @@ static int conn_state(BIO *bio, BIO_CONNECT *c) {
}
if (c->param_port == NULL) {
- OPENSSL_PUT_ERROR(BIO, conn_state, BIO_R_NO_PORT_SPECIFIED);
+ OPENSSL_PUT_ERROR(BIO, BIO_R_NO_PORT_SPECIFIED);
ERR_add_error_data(2, "host=", c->param_hostname);
goto exit_loop;
}
@@ -175,7 +175,7 @@ static int conn_state(BIO *bio, BIO_CONNECT *c) {
if (!bio_ip_and_port_to_socket_and_addr(
&bio->num, &c->them, &c->them_length, c->param_hostname,
c->param_port)) {
- OPENSSL_PUT_ERROR(BIO, conn_state, BIO_R_UNABLE_TO_CREATE_SOCKET);
+ OPENSSL_PUT_ERROR(BIO, BIO_R_UNABLE_TO_CREATE_SOCKET);
ERR_add_error_data(4, "host=", c->param_hostname, ":", c->param_port);
goto exit_loop;
}
@@ -185,7 +185,7 @@ static int conn_state(BIO *bio, BIO_CONNECT *c) {
if (c->nbio) {
if (!bio_socket_nbio(bio->num, 1)) {
- OPENSSL_PUT_ERROR(BIO, conn_state, BIO_R_ERROR_SETTING_NBIO);
+ OPENSSL_PUT_ERROR(BIO, BIO_R_ERROR_SETTING_NBIO);
ERR_add_error_data(4, "host=", c->param_hostname, ":",
c->param_port);
goto exit_loop;
@@ -197,7 +197,7 @@ static int conn_state(BIO *bio, BIO_CONNECT *c) {
sizeof(i));
if (ret < 0) {
OPENSSL_PUT_SYSTEM_ERROR(setsockopt);
- OPENSSL_PUT_ERROR(BIO, conn_state, BIO_R_KEEPALIVE);
+ OPENSSL_PUT_ERROR(BIO, BIO_R_KEEPALIVE);
ERR_add_error_data(4, "host=", c->param_hostname, ":", c->param_port);
goto exit_loop;
}
@@ -211,7 +211,7 @@ static int conn_state(BIO *bio, BIO_CONNECT *c) {
bio->retry_reason = BIO_RR_CONNECT;
} else {
OPENSSL_PUT_SYSTEM_ERROR(connect);
- OPENSSL_PUT_ERROR(BIO, conn_state, BIO_R_CONNECT_ERROR);
+ OPENSSL_PUT_ERROR(BIO, BIO_R_CONNECT_ERROR);
ERR_add_error_data(4, "host=", c->param_hostname, ":",
c->param_port);
}
@@ -232,7 +232,7 @@ static int conn_state(BIO *bio, BIO_CONNECT *c) {
} else {
BIO_clear_retry_flags(bio);
OPENSSL_PUT_SYSTEM_ERROR(connect);
- OPENSSL_PUT_ERROR(BIO, conn_state, BIO_R_NBIO_CONNECT_ERROR);
+ OPENSSL_PUT_ERROR(BIO, BIO_R_NBIO_CONNECT_ERROR);
ERR_add_error_data(4, "host=", c->param_hostname, ":", c->param_port);
ret = 0;
}
@@ -464,7 +464,7 @@ static long conn_ctrl(BIO *bio, int cmd, long num, void *ptr) {
break;
case BIO_CTRL_SET_CALLBACK: {
#if 0 /* FIXME: Should this be used? -- Richard Levitte */
- OPENSSL_PUT_ERROR(BIO, XXX, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+ OPENSSL_PUT_ERROR(BIO, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
ret = -1;
#else
ret = 0;
diff --git a/src/crypto/bio/file.c b/src/crypto/bio/file.c
index 7f57aad..2d3ccfe 100644
--- a/src/crypto/bio/file.c
+++ b/src/crypto/bio/file.c
@@ -88,7 +88,7 @@
#define BIO_FP_APPEND 0x08
static FILE *open_file(const char *filename, const char *mode) {
-#if defined(_WIN32) && defined(CP_UTF8)
+#if defined(OPENSSL_WINDOWS) && defined(CP_UTF8)
int sz, len_0 = (int)strlen(filename) + 1;
DWORD flags;
@@ -133,9 +133,9 @@ BIO *BIO_new_file(const char *filename, const char *mode) {
ERR_add_error_data(5, "fopen('", filename, "','", mode, "')");
if (errno == ENOENT) {
- OPENSSL_PUT_ERROR(BIO, BIO_new_file, BIO_R_NO_SUCH_FILE);
+ OPENSSL_PUT_ERROR(BIO, BIO_R_NO_SUCH_FILE);
} else {
- OPENSSL_PUT_ERROR(BIO, BIO_new_file, BIO_R_SYS_LIB);
+ OPENSSL_PUT_ERROR(BIO, BIO_R_SYS_LIB);
}
return NULL;
}
@@ -182,20 +182,19 @@ static int file_free(BIO *bio) {
}
static int file_read(BIO *b, char *out, int outl) {
- int ret = 0;
-
if (!b->init) {
return 0;
}
- ret = fread(out, 1, outl, (FILE *)b->ptr);
+ size_t ret = fread(out, 1, outl, (FILE *)b->ptr);
if (ret == 0 && ferror((FILE *)b->ptr)) {
OPENSSL_PUT_SYSTEM_ERROR(fread);
- OPENSSL_PUT_ERROR(BIO, file_read, ERR_R_SYS_LIB);
- ret = -1;
+ OPENSSL_PUT_ERROR(BIO, ERR_R_SYS_LIB);
+ return -1;
}
- return ret;
+ /* fread reads at most |outl| bytes, so |ret| fits in an int. */
+ return (int)ret;
}
static int file_write(BIO *b, const char *in, int inl) {
@@ -253,7 +252,7 @@ static long file_ctrl(BIO *b, int cmd, long num, void *ptr) {
} else if (num & BIO_FP_READ) {
BUF_strlcpy(p, "r", sizeof(p));
} else {
- OPENSSL_PUT_ERROR(BIO, file_ctrl, BIO_R_BAD_FOPEN_MODE);
+ OPENSSL_PUT_ERROR(BIO, BIO_R_BAD_FOPEN_MODE);
ret = 0;
break;
}
@@ -261,7 +260,7 @@ static long file_ctrl(BIO *b, int cmd, long num, void *ptr) {
if (fp == NULL) {
OPENSSL_PUT_SYSTEM_ERROR(fopen);
ERR_add_error_data(5, "fopen('", ptr, "','", p, "')");
- OPENSSL_PUT_ERROR(BIO, file_ctrl, ERR_R_SYS_LIB);
+ OPENSSL_PUT_ERROR(BIO, ERR_R_SYS_LIB);
ret = 0;
break;
}
diff --git a/src/crypto/bio/pair.c b/src/crypto/bio/pair.c
index cc55950..6f78890 100644
--- a/src/crypto/bio/pair.c
+++ b/src/crypto/bio/pair.c
@@ -181,27 +181,25 @@ int BIO_zero_copy_get_read_buf(BIO* bio, uint8_t** out_read_buf,
BIO_clear_retry_flags(bio);
if (!bio->init) {
- OPENSSL_PUT_ERROR(BIO, BIO_zero_copy_get_read_buf, BIO_R_UNINITIALIZED);
+ OPENSSL_PUT_ERROR(BIO, BIO_R_UNINITIALIZED);
return 0;
}
b = bio->ptr;
if (!b || !b->peer) {
- OPENSSL_PUT_ERROR(BIO, BIO_zero_copy_get_read_buf,
- BIO_R_UNSUPPORTED_METHOD);
+ OPENSSL_PUT_ERROR(BIO, BIO_R_UNSUPPORTED_METHOD);
return 0;
}
peer_b = b->peer->ptr;
if (!peer_b || !peer_b->peer || peer_b->peer->ptr != b) {
- OPENSSL_PUT_ERROR(BIO, BIO_zero_copy_get_read_buf,
- BIO_R_UNSUPPORTED_METHOD);
+ OPENSSL_PUT_ERROR(BIO, BIO_R_UNSUPPORTED_METHOD);
return 0;
}
if (peer_b->zero_copy_read_lock) {
- OPENSSL_PUT_ERROR(BIO, BIO_zero_copy_get_read_buf, BIO_R_INVALID_ARGUMENT);
+ OPENSSL_PUT_ERROR(BIO, BIO_R_INVALID_ARGUMENT);
return 0;
}
@@ -229,37 +227,32 @@ int BIO_zero_copy_get_read_buf_done(BIO* bio, size_t bytes_read) {
assert(BIO_get_retry_flags(bio) == 0);
if (!bio->init) {
- OPENSSL_PUT_ERROR(BIO, BIO_zero_copy_get_read_buf_done,
- BIO_R_UNINITIALIZED);
+ OPENSSL_PUT_ERROR(BIO, BIO_R_UNINITIALIZED);
return 0;
}
b = bio->ptr;
if (!b || !b->peer) {
- OPENSSL_PUT_ERROR(BIO, BIO_zero_copy_get_read_buf_done,
- BIO_R_UNSUPPORTED_METHOD);
+ OPENSSL_PUT_ERROR(BIO, BIO_R_UNSUPPORTED_METHOD);
return 0;
}
peer_b = b->peer->ptr;
if (!peer_b || !peer_b->peer || peer_b->peer->ptr != b) {
- OPENSSL_PUT_ERROR(BIO, BIO_zero_copy_get_read_buf_done,
- BIO_R_UNSUPPORTED_METHOD);
+ OPENSSL_PUT_ERROR(BIO, BIO_R_UNSUPPORTED_METHOD);
return 0;
}
if (!peer_b->zero_copy_read_lock) {
- OPENSSL_PUT_ERROR(BIO, BIO_zero_copy_get_read_buf_done,
- BIO_R_INVALID_ARGUMENT);
+ OPENSSL_PUT_ERROR(BIO, BIO_R_INVALID_ARGUMENT);
return 0;
}
max_available =
bio_zero_copy_get_read_buf(peer_b, &dummy_read_buf, &dummy_read_offset);
if (bytes_read > max_available) {
- OPENSSL_PUT_ERROR(BIO, BIO_zero_copy_get_read_buf_done,
- BIO_R_INVALID_ARGUMENT);
+ OPENSSL_PUT_ERROR(BIO, BIO_R_INVALID_ARGUMENT);
return 0;
}
@@ -318,35 +311,33 @@ int BIO_zero_copy_get_write_buf(BIO* bio, uint8_t** out_write_buf,
BIO_clear_retry_flags(bio);
if (!bio->init) {
- OPENSSL_PUT_ERROR(BIO, BIO_zero_copy_get_write_buf, BIO_R_UNINITIALIZED);
+ OPENSSL_PUT_ERROR(BIO, BIO_R_UNINITIALIZED);
return 0;
}
b = bio->ptr;
if (!b || !b->buf || !b->peer) {
- OPENSSL_PUT_ERROR(BIO, BIO_zero_copy_get_write_buf,
- BIO_R_UNSUPPORTED_METHOD);
+ OPENSSL_PUT_ERROR(BIO, BIO_R_UNSUPPORTED_METHOD);
return 0;
}
peer_b = b->peer->ptr;
if (!peer_b || !peer_b->peer || peer_b->peer->ptr != b) {
- OPENSSL_PUT_ERROR(BIO, BIO_zero_copy_get_write_buf,
- BIO_R_UNSUPPORTED_METHOD);
+ OPENSSL_PUT_ERROR(BIO, BIO_R_UNSUPPORTED_METHOD);
return 0;
}
assert(b->buf != NULL);
if (b->zero_copy_write_lock) {
- OPENSSL_PUT_ERROR(BIO, BIO_zero_copy_get_write_buf, BIO_R_INVALID_ARGUMENT);
+ OPENSSL_PUT_ERROR(BIO, BIO_R_INVALID_ARGUMENT);
return 0;
}
b->request = 0;
if (b->closed) {
/* Bio is already closed. */
- OPENSSL_PUT_ERROR(BIO, BIO_zero_copy_get_write_buf, BIO_R_BROKEN_PIPE);
+ OPENSSL_PUT_ERROR(BIO, BIO_R_BROKEN_PIPE);
return 0;
}
@@ -369,43 +360,38 @@ int BIO_zero_copy_get_write_buf_done(BIO* bio, size_t bytes_written) {
uint8_t* dummy_write_buf;
if (!bio->init) {
- OPENSSL_PUT_ERROR(BIO, BIO_zero_copy_get_write_buf_done,
- BIO_R_UNINITIALIZED);
+ OPENSSL_PUT_ERROR(BIO, BIO_R_UNINITIALIZED);
return 0;
}
b = bio->ptr;
if (!b || !b->buf || !b->peer) {
- OPENSSL_PUT_ERROR(BIO, BIO_zero_copy_get_write_buf_done,
- BIO_R_UNSUPPORTED_METHOD);
+ OPENSSL_PUT_ERROR(BIO, BIO_R_UNSUPPORTED_METHOD);
return 0;
}
peer_b = b->peer->ptr;
if (!peer_b || !peer_b->peer || peer_b->peer->ptr != b) {
- OPENSSL_PUT_ERROR(BIO, BIO_zero_copy_get_write_buf_done,
- BIO_R_UNSUPPORTED_METHOD);
+ OPENSSL_PUT_ERROR(BIO, BIO_R_UNSUPPORTED_METHOD);
return 0;
}
b->request = 0;
if (b->closed) {
/* BIO is already closed. */
- OPENSSL_PUT_ERROR(BIO, BIO_zero_copy_get_write_buf_done, BIO_R_BROKEN_PIPE);
+ OPENSSL_PUT_ERROR(BIO, BIO_R_BROKEN_PIPE);
return 0;
}
if (!b->zero_copy_write_lock) {
- OPENSSL_PUT_ERROR(BIO, BIO_zero_copy_get_write_buf_done,
- BIO_R_INVALID_ARGUMENT);
+ OPENSSL_PUT_ERROR(BIO, BIO_R_INVALID_ARGUMENT);
return 0;
}
rest = bio_zero_copy_get_write_buf(b, &dummy_write_buf, &dummy_write_offset);
if (bytes_written > rest) {
- OPENSSL_PUT_ERROR(BIO, BIO_zero_copy_get_write_buf_done,
- BIO_R_INVALID_ARGUMENT);
+ OPENSSL_PUT_ERROR(BIO, BIO_R_INVALID_ARGUMENT);
return 0;
}
@@ -525,7 +511,7 @@ static int bio_write(BIO *bio, const char *buf, int num_) {
b->request = 0;
if (b->closed) {
/* we already closed */
- OPENSSL_PUT_ERROR(BIO, bio_write, BIO_R_BROKEN_PIPE);
+ OPENSSL_PUT_ERROR(BIO, BIO_R_BROKEN_PIPE);
return -1;
}
@@ -590,7 +576,7 @@ static int bio_make_pair(BIO* bio1, BIO* bio2,
b2 = bio2->ptr;
if (b1->peer != NULL || b2->peer != NULL) {
- OPENSSL_PUT_ERROR(BIO, bio_make_pair, BIO_R_IN_USE);
+ OPENSSL_PUT_ERROR(BIO, BIO_R_IN_USE);
return 0;
}
@@ -605,7 +591,7 @@ static int bio_make_pair(BIO* bio1, BIO* bio2,
b1->buf_externally_allocated = 0;
b1->buf = OPENSSL_malloc(b1->size);
if (b1->buf == NULL) {
- OPENSSL_PUT_ERROR(BIO, bio_make_pair, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(BIO, ERR_R_MALLOC_FAILURE);
return 0;
}
} else {
@@ -624,7 +610,7 @@ static int bio_make_pair(BIO* bio1, BIO* bio2,
b2->buf_externally_allocated = 0;
b2->buf = OPENSSL_malloc(b2->size);
if (b2->buf == NULL) {
- OPENSSL_PUT_ERROR(BIO, bio_make_pair, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(BIO, ERR_R_MALLOC_FAILURE);
return 0;
}
} else {
diff --git a/src/crypto/bio/printf.c b/src/crypto/bio/printf.c
index f51b396..2f5ae4a 100644
--- a/src/crypto/bio/printf.c
+++ b/src/crypto/bio/printf.c
@@ -95,7 +95,7 @@ int BIO_printf(BIO *bio, const char *format, ...) {
out = OPENSSL_malloc(requested_len + 1);
out_malloced = 1;
if (out == NULL) {
- OPENSSL_PUT_ERROR(BIO, BIO_printf, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(BIO, ERR_R_MALLOC_FAILURE);
return -1;
}
va_start(args, format);
diff --git a/src/crypto/bio/socket_helper.c b/src/crypto/bio/socket_helper.c
index b1cdd1a..01f635e 100644
--- a/src/crypto/bio/socket_helper.c
+++ b/src/crypto/bio/socket_helper.c
@@ -12,7 +12,8 @@
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
-#define _POSIX_SOURCE
+#undef _POSIX_C_SOURCE
+#define _POSIX_C_SOURCE 200112L
#include <openssl/bio.h>
#include <openssl/err.h>
@@ -50,7 +51,7 @@ int bio_ip_and_port_to_socket_and_addr(int *out_sock,
ret = getaddrinfo(hostname, port_str, &hint, &result);
if (ret != 0) {
- OPENSSL_PUT_ERROR(SYS, getaddrinfo, 0);
+ OPENSSL_PUT_ERROR(SYS, 0);
ERR_add_error_data(1, gai_strerror(ret));
return 0;
}
diff --git a/src/crypto/bn/CMakeLists.txt b/src/crypto/bn/CMakeLists.txt
index 2e0cb45..232e40a 100644
--- a/src/crypto/bn/CMakeLists.txt
+++ b/src/crypto/bn/CMakeLists.txt
@@ -1,4 +1,4 @@
-include_directories(. .. ../../include)
+include_directories(../../include)
if (${ARCH} STREQUAL "x86_64")
set(
@@ -39,6 +39,7 @@ add_library(
add.c
asm/x86_64-gcc.c
bn.c
+ bn_asn1.c
cmp.c
convert.c
ctx.c
diff --git a/src/crypto/bn/add.c b/src/crypto/bn/add.c
index 1c6b2d7..a043d83 100644
--- a/src/crypto/bn/add.c
+++ b/src/crypto/bn/add.c
@@ -267,7 +267,7 @@ int BN_usub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b) {
if (dif < 0) /* hmm... should not be happening */
{
- OPENSSL_PUT_ERROR(BN, BN_usub, BN_R_ARG2_LT_ARG3);
+ OPENSSL_PUT_ERROR(BN, BN_R_ARG2_LT_ARG3);
return 0;
}
diff --git a/src/crypto/bn/asm/armv4-mont.pl b/src/crypto/bn/asm/armv4-mont.pl
index 0f1b6a9..4206fd8 100644
--- a/src/crypto/bn/asm/armv4-mont.pl
+++ b/src/crypto/bn/asm/armv4-mont.pl
@@ -79,7 +79,7 @@ $_n0="$num,#14*4";
$_num="$num,#15*4"; $_bpend=$_num;
$code=<<___;
-#include "arm_arch.h"
+#include <openssl/arm_arch.h>
.text
.code 32
diff --git a/src/crypto/bn/bn.c b/src/crypto/bn/bn.c
index f32d6b0..b342749 100644
--- a/src/crypto/bn/bn.c
+++ b/src/crypto/bn/bn.c
@@ -69,7 +69,7 @@ BIGNUM *BN_new(void) {
BIGNUM *bn = OPENSSL_malloc(sizeof(BIGNUM));
if (bn == NULL) {
- OPENSSL_PUT_ERROR(BN, BN_new, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(BN, ERR_R_MALLOC_FAILURE);
return NULL;
}
@@ -279,26 +279,26 @@ void BN_set_negative(BIGNUM *bn, int sign) {
}
}
-BIGNUM *bn_wexpand(BIGNUM *bn, unsigned words) {
+BIGNUM *bn_wexpand(BIGNUM *bn, size_t words) {
BN_ULONG *a;
- if (words <= (unsigned) bn->dmax) {
+ if (words <= (size_t)bn->dmax) {
return bn;
}
if (words > (INT_MAX / (4 * BN_BITS2))) {
- OPENSSL_PUT_ERROR(BN, bn_wexpand, BN_R_BIGNUM_TOO_LONG);
+ OPENSSL_PUT_ERROR(BN, BN_R_BIGNUM_TOO_LONG);
return NULL;
}
if (bn->flags & BN_FLG_STATIC_DATA) {
- OPENSSL_PUT_ERROR(BN, bn_wexpand, BN_R_EXPAND_ON_STATIC_BIGNUM_DATA);
+ OPENSSL_PUT_ERROR(BN, BN_R_EXPAND_ON_STATIC_BIGNUM_DATA);
return NULL;
}
a = (BN_ULONG *)OPENSSL_malloc(sizeof(BN_ULONG) * words);
if (a == NULL) {
- OPENSSL_PUT_ERROR(BN, bn_wexpand, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(BN, ERR_R_MALLOC_FAILURE);
return NULL;
}
@@ -306,12 +306,16 @@ BIGNUM *bn_wexpand(BIGNUM *bn, unsigned words) {
OPENSSL_free(bn->d);
bn->d = a;
- bn->dmax = words;
+ bn->dmax = (int)words;
return bn;
}
-BIGNUM *bn_expand(BIGNUM *bn, unsigned bits) {
+BIGNUM *bn_expand(BIGNUM *bn, size_t bits) {
+ if (bits + BN_BITS2 - 1 < bits) {
+ OPENSSL_PUT_ERROR(BN, BN_R_BIGNUM_TOO_LONG);
+ return NULL;
+ }
return bn_wexpand(bn, (bits+BN_BITS2-1)/BN_BITS2);
}
diff --git a/src/crypto/bn/bn_asn1.c b/src/crypto/bn/bn_asn1.c
new file mode 100644
index 0000000..9d70ba8
--- /dev/null
+++ b/src/crypto/bn/bn_asn1.c
@@ -0,0 +1,93 @@
+/* Copyright (c) 2015, Google Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
+
+#include <openssl/bn.h>
+
+#include <openssl/bytestring.h>
+#include <openssl/err.h>
+
+
+int BN_cbs2unsigned(CBS *cbs, BIGNUM *ret) {
+ CBS child;
+ if (!CBS_get_asn1(cbs, &child, CBS_ASN1_INTEGER) ||
+ CBS_len(&child) == 0) {
+ OPENSSL_PUT_ERROR(BN, BN_R_BAD_ENCODING);
+ return 0;
+ }
+
+ if (CBS_data(&child)[0] & 0x80) {
+ OPENSSL_PUT_ERROR(BN, BN_R_NEGATIVE_NUMBER);
+ return 0;
+ }
+
+ /* INTEGERs must be minimal. */
+ if (CBS_data(&child)[0] == 0x00 &&
+ CBS_len(&child) > 1 &&
+ !(CBS_data(&child)[1] & 0x80)) {
+ OPENSSL_PUT_ERROR(BN, BN_R_BAD_ENCODING);
+ return 0;
+ }
+
+ return BN_bin2bn(CBS_data(&child), CBS_len(&child), ret) != NULL;
+}
+
+int BN_cbs2unsigned_buggy(CBS *cbs, BIGNUM *ret) {
+ CBS child;
+ if (!CBS_get_asn1(cbs, &child, CBS_ASN1_INTEGER) ||
+ CBS_len(&child) == 0) {
+ OPENSSL_PUT_ERROR(BN, BN_R_BAD_ENCODING);
+ return 0;
+ }
+
+ /* This function intentionally does not reject negative numbers or non-minimal
+ * encodings. Estonian IDs issued between September 2014 to September 2015 are
+ * broken. See https://crbug.com/532048 and https://crbug.com/534766.
+ *
+ * TODO(davidben): Remove this code and callers in March 2016. */
+ return BN_bin2bn(CBS_data(&child), CBS_len(&child), ret) != NULL;
+}
+
+int BN_bn2cbb(CBB *cbb, const BIGNUM *bn) {
+ /* Negative numbers are unsupported. */
+ if (BN_is_negative(bn)) {
+ OPENSSL_PUT_ERROR(BN, BN_R_NEGATIVE_NUMBER);
+ return 0;
+ }
+
+ CBB child;
+ if (!CBB_add_asn1(cbb, &child, CBS_ASN1_INTEGER)) {
+ OPENSSL_PUT_ERROR(BN, BN_R_ENCODE_ERROR);
+ return 0;
+ }
+
+ /* The number must be padded with a leading zero if the high bit would
+ * otherwise be set (or |bn| is zero). */
+ if (BN_num_bits(bn) % 8 == 0 &&
+ !CBB_add_u8(&child, 0x00)) {
+ OPENSSL_PUT_ERROR(BN, BN_R_ENCODE_ERROR);
+ return 0;
+ }
+
+ uint8_t *out;
+ if (!CBB_add_space(&child, &out, BN_num_bytes(bn))) {
+ OPENSSL_PUT_ERROR(BN, BN_R_ENCODE_ERROR);
+ return 0;
+ }
+ BN_bn2bin(bn, out);
+ if (!CBB_flush(cbb)) {
+ OPENSSL_PUT_ERROR(BN, BN_R_ENCODE_ERROR);
+ return 0;
+ }
+ return 1;
+}
diff --git a/src/crypto/bn/bn_test.cc b/src/crypto/bn/bn_test.cc
index 6a7d48c..47093a7 100644
--- a/src/crypto/bn/bn_test.cc
+++ b/src/crypto/bn/bn_test.cc
@@ -82,6 +82,7 @@
#include <openssl/mem.h>
#include "../crypto/test/scoped_types.h"
+#include "../crypto/test/test_util.h"
// This program tests the BIGNUM implementation. It takes an optional -bc
@@ -117,11 +118,13 @@ static bool test_exp_mod_zero(void);
static bool test_small_prime(FILE *fp, BN_CTX *ctx);
static bool test_mod_exp_mont5(FILE *fp, BN_CTX *ctx);
static bool test_sqrt(FILE *fp, BN_CTX *ctx);
-static bool test_bn2bin_padded(FILE *fp, BN_CTX *ctx);
-static bool test_dec2bn(FILE *fp, BN_CTX *ctx);
-static bool test_hex2bn(FILE *fp, BN_CTX *ctx);
-static bool test_asc2bn(FILE *fp, BN_CTX *ctx);
+static bool test_bn2bin_padded(BN_CTX *ctx);
+static bool test_dec2bn(BN_CTX *ctx);
+static bool test_hex2bn(BN_CTX *ctx);
+static bool test_asc2bn(BN_CTX *ctx);
+static bool test_mpi();
static bool test_rand();
+static bool test_asn1();
static const uint8_t kSample[] =
"\xC6\x4F\x43\x04\x2A\xEA\xCA\x6E\x58\x36\x80\x5B\xE8\xC9"
@@ -311,35 +314,15 @@ int main(int argc, char *argv[]) {
}
flush_fp(bc_file.get());
- message(bc_file.get(), "BN_bn2bin_padded");
- if (!test_bn2bin_padded(bc_file.get(), ctx.get())) {
+ if (!test_bn2bin_padded(ctx.get()) ||
+ !test_dec2bn(ctx.get()) ||
+ !test_hex2bn(ctx.get()) ||
+ !test_asc2bn(ctx.get()) ||
+ !test_mpi() ||
+ !test_rand() ||
+ !test_asn1()) {
return 1;
}
- flush_fp(bc_file.get());
-
- message(bc_file.get(), "BN_dec2bn");
- if (!test_dec2bn(bc_file.get(), ctx.get())) {
- return 1;
- }
- flush_fp(bc_file.get());
-
- message(bc_file.get(), "BN_hex2bn");
- if (!test_hex2bn(bc_file.get(), ctx.get())) {
- return 1;
- }
- flush_fp(bc_file.get());
-
- message(bc_file.get(), "BN_asc2bn");
- if (!test_asc2bn(bc_file.get(), ctx.get())) {
- return 1;
- }
- flush_fp(bc_file.get());
-
- message(bc_file.get(), "BN_rand");
- if (!test_rand()) {
- return 1;
- }
- flush_fp(bc_file.get());
printf("PASS\n");
return 0;
@@ -440,6 +423,16 @@ static bool test_div(FILE *fp, BN_CTX *ctx) {
return false;
}
+ if (!BN_one(a.get())) {
+ return false;
+ }
+ BN_zero(b.get());
+ if (BN_div(d.get(), c.get(), a.get(), b.get(), ctx)) {
+ fprintf(stderr, "Division by zero succeeded!\n");
+ return false;
+ }
+ ERR_clear_error();
+
for (int i = 0; i < num0 + num1; i++) {
if (i < num1) {
if (!BN_rand(a.get(), 400, 0, 0) ||
@@ -837,18 +830,17 @@ static bool test_div_word(FILE *fp) {
}
for (int i = 0; i < num0; i++) {
- BN_ULONG s;
do {
if (!BN_rand(a.get(), 512, -1, 0) ||
!BN_rand(b.get(), BN_BITS2, -1, 0)) {
return false;
}
- s = b->d[0];
- } while (!s);
+ } while (BN_is_zero(b.get()));
if (!BN_copy(b.get(), a.get())) {
return false;
}
+ BN_ULONG s = b->d[0];
BN_ULONG r = BN_div_word(b.get(), s);
if (r == (BN_ULONG)-1) {
return false;
@@ -891,8 +883,27 @@ static bool test_mont(FILE *fp, BN_CTX *ctx) {
ScopedBIGNUM B(BN_new());
ScopedBIGNUM n(BN_new());
ScopedBN_MONT_CTX mont(BN_MONT_CTX_new());
- if (!a || !b || !c || !d || !A || !B || !n || !mont ||
- !BN_rand(a.get(), 100, 0, 0) ||
+ if (!a || !b || !c || !d || !A || !B || !n || !mont) {
+ return false;
+ }
+
+ BN_zero(n.get());
+ if (BN_MONT_CTX_set(mont.get(), n.get(), ctx)) {
+ fprintf(stderr, "BN_MONT_CTX_set succeeded for zero modulus!\n");
+ return false;
+ }
+ ERR_clear_error();
+
+ if (!BN_set_word(n.get(), 16)) {
+ return false;
+ }
+ if (BN_MONT_CTX_set(mont.get(), n.get(), ctx)) {
+ fprintf(stderr, "BN_MONT_CTX_set succeeded for even modulus!\n");
+ return false;
+ }
+ ERR_clear_error();
+
+ if (!BN_rand(a.get(), 100, 0, 0) ||
!BN_rand(b.get(), 100, 0, 0)) {
return false;
}
@@ -932,6 +943,7 @@ static bool test_mont(FILE *fp, BN_CTX *ctx) {
return false;
}
}
+
return true;
}
@@ -985,6 +997,16 @@ static bool test_mod_mul(FILE *fp, BN_CTX *ctx) {
return false;
}
+ if (!BN_one(a.get()) || !BN_one(b.get())) {
+ return false;
+ }
+ BN_zero(c.get());
+ if (BN_mod_mul(e.get(), a.get(), b.get(), c.get(), ctx)) {
+ fprintf(stderr, "BN_mod_mul with zero modulus succeeded!\n");
+ return false;
+ }
+ ERR_clear_error();
+
for (int j = 0; j < 3; j++) {
if (!BN_rand(c.get(), 1024, 0, 0)) {
return false;
@@ -1039,8 +1061,21 @@ static bool test_mod_exp(FILE *fp, BN_CTX *ctx) {
ScopedBIGNUM c(BN_new());
ScopedBIGNUM d(BN_new());
ScopedBIGNUM e(BN_new());
- if (!a || !b || !c || !d || !e ||
- !BN_rand(c.get(), 30, 0, 1)) { // must be odd for montgomery
+ if (!a || !b || !c || !d || !e) {
+ return false;
+ }
+
+ if (!BN_one(a.get()) || !BN_one(b.get())) {
+ return false;
+ }
+ BN_zero(c.get());
+ if (BN_mod_exp(d.get(), a.get(), b.get(), c.get(), ctx)) {
+ fprintf(stderr, "BN_mod_exp with zero modulus succeeded!\n");
+ return 0;
+ }
+ ERR_clear_error();
+
+ if (!BN_rand(c.get(), 30, 0, 1)) { // must be odd for montgomery
return false;
}
for (int i = 0; i < num2; i++) {
@@ -1079,8 +1114,32 @@ static bool test_mod_exp_mont_consttime(FILE *fp, BN_CTX *ctx) {
ScopedBIGNUM c(BN_new());
ScopedBIGNUM d(BN_new());
ScopedBIGNUM e(BN_new());
- if (!a || !b || !c || !d || !e ||
- !BN_rand(c.get(), 30, 0, 1)) { // must be odd for montgomery
+ if (!a || !b || !c || !d || !e) {
+ return false;
+ }
+
+ if (!BN_one(a.get()) || !BN_one(b.get())) {
+ return false;
+ }
+ BN_zero(c.get());
+ if (BN_mod_exp_mont_consttime(d.get(), a.get(), b.get(), c.get(), ctx,
+ nullptr)) {
+ fprintf(stderr, "BN_mod_exp_mont_consttime with zero modulus succeeded!\n");
+ return 0;
+ }
+ ERR_clear_error();
+
+ if (!BN_set_word(c.get(), 16)) {
+ return false;
+ }
+ if (BN_mod_exp_mont_consttime(d.get(), a.get(), b.get(), c.get(), ctx,
+ nullptr)) {
+ fprintf(stderr, "BN_mod_exp_mont_consttime with even modulus succeeded!\n");
+ return 0;
+ }
+ ERR_clear_error();
+
+ if (!BN_rand(c.get(), 30, 0, 1)) { // must be odd for montgomery
return false;
}
for (int i = 0; i < num2; i++) {
@@ -1208,8 +1267,9 @@ static bool test_exp(FILE *fp, BN_CTX *ctx) {
if (!BN_one(e.get())) {
return false;
}
- for (; !BN_is_zero(b.get()); BN_sub(b.get(), b.get(), BN_value_one())) {
- if (!BN_mul(e.get(), e.get(), a.get(), ctx)) {
+ while (!BN_is_zero(b.get())) {
+ if (!BN_mul(e.get(), e.get(), a.get(), ctx) ||
+ !BN_sub(b.get(), b.get(), BN_value_one())) {
return false;
}
}
@@ -1371,7 +1431,7 @@ static bool test_sqrt(FILE *fp, BN_CTX *ctx) {
return true;
}
-static bool test_bn2bin_padded(FILE *fp, BN_CTX *ctx) {
+static bool test_bn2bin_padded(BN_CTX *ctx) {
uint8_t zeros[256], out[256], reference[128];
memset(zeros, 0, sizeof(zeros));
@@ -1448,7 +1508,7 @@ static int DecimalToBIGNUM(ScopedBIGNUM *out, const char *in) {
return ret;
}
-static bool test_dec2bn(FILE *fp, BN_CTX *ctx) {
+static bool test_dec2bn(BN_CTX *ctx) {
ScopedBIGNUM bn;
int ret = DecimalToBIGNUM(&bn, "0");
if (ret != 1 || !BN_is_zero(bn.get()) || BN_is_negative(bn.get())) {
@@ -1490,7 +1550,7 @@ static int HexToBIGNUM(ScopedBIGNUM *out, const char *in) {
return ret;
}
-static bool test_hex2bn(FILE *fp, BN_CTX *ctx) {
+static bool test_hex2bn(BN_CTX *ctx) {
ScopedBIGNUM bn;
int ret = HexToBIGNUM(&bn, "0");
if (ret != 1 || !BN_is_zero(bn.get()) || BN_is_negative(bn.get())) {
@@ -1533,7 +1593,7 @@ static ScopedBIGNUM ASCIIToBIGNUM(const char *in) {
return ScopedBIGNUM(raw);
}
-static bool test_asc2bn(FILE *fp, BN_CTX *ctx) {
+static bool test_asc2bn(BN_CTX *ctx) {
ScopedBIGNUM bn = ASCIIToBIGNUM("0");
if (!bn || !BN_is_zero(bn.get()) || BN_is_negative(bn.get())) {
fprintf(stderr, "BN_asc2bn gave a bad result.\n");
@@ -1585,6 +1645,63 @@ static bool test_asc2bn(FILE *fp, BN_CTX *ctx) {
return true;
}
+struct MPITest {
+ const char *base10;
+ const char *mpi;
+ size_t mpi_len;
+};
+
+static const MPITest kMPITests[] = {
+ { "0", "\x00\x00\x00\x00", 4 },
+ { "1", "\x00\x00\x00\x01\x01", 5 },
+ { "-1", "\x00\x00\x00\x01\x81", 5 },
+ { "128", "\x00\x00\x00\x02\x00\x80", 6 },
+ { "256", "\x00\x00\x00\x02\x01\x00", 6 },
+ { "-256", "\x00\x00\x00\x02\x81\x00", 6 },
+};
+
+static bool test_mpi() {
+ uint8_t scratch[8];
+
+ for (size_t i = 0; i < sizeof(kMPITests) / sizeof(kMPITests[0]); i++) {
+ const MPITest &test = kMPITests[i];
+ ScopedBIGNUM bn(ASCIIToBIGNUM(test.base10));
+ const size_t mpi_len = BN_bn2mpi(bn.get(), NULL);
+ if (mpi_len > sizeof(scratch)) {
+ fprintf(stderr, "MPI test #%u: MPI size is too large to test.\n",
+ (unsigned)i);
+ return false;
+ }
+
+ const size_t mpi_len2 = BN_bn2mpi(bn.get(), scratch);
+ if (mpi_len != mpi_len2) {
+ fprintf(stderr, "MPI test #%u: length changes.\n", (unsigned)i);
+ return false;
+ }
+
+ if (mpi_len != test.mpi_len ||
+ memcmp(test.mpi, scratch, mpi_len) != 0) {
+ fprintf(stderr, "MPI test #%u failed:\n", (unsigned)i);
+ hexdump(stderr, "Expected: ", test.mpi, test.mpi_len);
+ hexdump(stderr, "Got: ", scratch, mpi_len);
+ return false;
+ }
+
+ ScopedBIGNUM bn2(BN_mpi2bn(scratch, mpi_len, NULL));
+ if (bn2.get() == nullptr) {
+ fprintf(stderr, "MPI test #%u: failed to parse\n", (unsigned)i);
+ return false;
+ }
+
+ if (BN_cmp(bn.get(), bn2.get()) != 0) {
+ fprintf(stderr, "MPI test #%u: wrong result\n", (unsigned)i);
+ return false;
+ }
+ }
+
+ return true;
+}
+
static bool test_rand() {
ScopedBIGNUM bn(BN_new());
if (!bn) {
@@ -1628,3 +1745,170 @@ static bool test_rand() {
return true;
}
+
+struct ASN1Test {
+ const char *value_ascii;
+ const char *der;
+ size_t der_len;
+};
+
+static const ASN1Test kASN1Tests[] = {
+ {"0", "\x02\x01\x00", 3},
+ {"1", "\x02\x01\x01", 3},
+ {"127", "\x02\x01\x7f", 3},
+ {"128", "\x02\x02\x00\x80", 4},
+ {"0xdeadbeef", "\x02\x05\x00\xde\xad\xbe\xef", 7},
+ {"0x0102030405060708",
+ "\x02\x08\x01\x02\x03\x04\x05\x06\x07\x08", 10},
+ {"0xffffffffffffffff",
+ "\x02\x09\x00\xff\xff\xff\xff\xff\xff\xff\xff", 11},
+};
+
+struct ASN1InvalidTest {
+ const char *der;
+ size_t der_len;
+};
+
+static const ASN1InvalidTest kASN1InvalidTests[] = {
+ // Bad tag.
+ {"\x03\x01\x00", 3},
+ // Empty contents.
+ {"\x02\x00", 2},
+};
+
+// kASN1BuggyTests are incorrect encodings and how |BN_cbs2unsigned_buggy|
+// should interpret them.
+static const ASN1Test kASN1BuggyTests[] = {
+ // Negative numbers.
+ {"128", "\x02\x01\x80", 3},
+ {"255", "\x02\x01\xff", 3},
+ // Unnecessary leading zeros.
+ {"1", "\x02\x02\x00\x01", 4},
+};
+
+static bool test_asn1() {
+ for (const ASN1Test &test : kASN1Tests) {
+ ScopedBIGNUM bn = ASCIIToBIGNUM(test.value_ascii);
+ if (!bn) {
+ return false;
+ }
+
+ // Test that the input is correctly parsed.
+ ScopedBIGNUM bn2(BN_new());
+ if (!bn2) {
+ return false;
+ }
+ CBS cbs;
+ CBS_init(&cbs, reinterpret_cast<const uint8_t*>(test.der), test.der_len);
+ if (!BN_cbs2unsigned(&cbs, bn2.get()) || CBS_len(&cbs) != 0) {
+ fprintf(stderr, "Parsing ASN.1 INTEGER failed.\n");
+ return false;
+ }
+ if (BN_cmp(bn.get(), bn2.get()) != 0) {
+ fprintf(stderr, "Bad parse.\n");
+ return false;
+ }
+
+ // Test the value serializes correctly.
+ CBB cbb;
+ uint8_t *der;
+ size_t der_len;
+ CBB_zero(&cbb);
+ if (!CBB_init(&cbb, 0) ||
+ !BN_bn2cbb(&cbb, bn.get()) ||
+ !CBB_finish(&cbb, &der, &der_len)) {
+ CBB_cleanup(&cbb);
+ return false;
+ }
+ ScopedOpenSSLBytes delete_der(der);
+ if (der_len != test.der_len ||
+ memcmp(der, reinterpret_cast<const uint8_t*>(test.der), der_len) != 0) {
+ fprintf(stderr, "Bad serialization.\n");
+ return false;
+ }
+
+ // |BN_cbs2unsigned_buggy| parses all valid input.
+ CBS_init(&cbs, reinterpret_cast<const uint8_t*>(test.der), test.der_len);
+ if (!BN_cbs2unsigned_buggy(&cbs, bn2.get()) || CBS_len(&cbs) != 0) {
+ fprintf(stderr, "Parsing ASN.1 INTEGER failed.\n");
+ return false;
+ }
+ if (BN_cmp(bn.get(), bn2.get()) != 0) {
+ fprintf(stderr, "Bad parse.\n");
+ return false;
+ }
+ }
+
+ for (const ASN1InvalidTest &test : kASN1InvalidTests) {
+ ScopedBIGNUM bn(BN_new());
+ if (!bn) {
+ return false;
+ }
+ CBS cbs;
+ CBS_init(&cbs, reinterpret_cast<const uint8_t*>(test.der), test.der_len);
+ if (BN_cbs2unsigned(&cbs, bn.get())) {
+ fprintf(stderr, "Parsed invalid input.\n");
+ return false;
+ }
+ ERR_clear_error();
+
+ // All tests in kASN1InvalidTests are also rejected by
+ // |BN_cbs2unsigned_buggy|.
+ CBS_init(&cbs, reinterpret_cast<const uint8_t*>(test.der), test.der_len);
+ if (BN_cbs2unsigned_buggy(&cbs, bn.get())) {
+ fprintf(stderr, "Parsed invalid input.\n");
+ return false;
+ }
+ ERR_clear_error();
+ }
+
+ for (const ASN1Test &test : kASN1BuggyTests) {
+ // These broken encodings are rejected by |BN_cbs2unsigned|.
+ ScopedBIGNUM bn(BN_new());
+ if (!bn) {
+ return false;
+ }
+
+ CBS cbs;
+ CBS_init(&cbs, reinterpret_cast<const uint8_t*>(test.der), test.der_len);
+ if (BN_cbs2unsigned(&cbs, bn.get())) {
+ fprintf(stderr, "Parsed invalid input.\n");
+ return false;
+ }
+ ERR_clear_error();
+
+ // However |BN_cbs2unsigned_buggy| accepts them.
+ ScopedBIGNUM bn2 = ASCIIToBIGNUM(test.value_ascii);
+ if (!bn2) {
+ return false;
+ }
+
+ CBS_init(&cbs, reinterpret_cast<const uint8_t*>(test.der), test.der_len);
+ if (!BN_cbs2unsigned_buggy(&cbs, bn.get()) || CBS_len(&cbs) != 0) {
+ fprintf(stderr, "Parsing (invalid) ASN.1 INTEGER failed.\n");
+ return false;
+ }
+
+ if (BN_cmp(bn.get(), bn2.get()) != 0) {
+ fprintf(stderr, "\"Bad\" parse.\n");
+ return false;
+ }
+ }
+
+ // Serializing negative numbers is not supported.
+ ScopedBIGNUM bn = ASCIIToBIGNUM("-1");
+ if (!bn) {
+ return false;
+ }
+ CBB cbb;
+ CBB_zero(&cbb);
+ if (!CBB_init(&cbb, 0) ||
+ BN_bn2cbb(&cbb, bn.get())) {
+ fprintf(stderr, "Serialized negative number.\n");
+ CBB_cleanup(&cbb);
+ return false;
+ }
+ CBB_cleanup(&cbb);
+
+ return true;
+}
diff --git a/src/crypto/bn/convert.c b/src/crypto/bn/convert.c
index 531b661..0122709 100644
--- a/src/crypto/bn/convert.c
+++ b/src/crypto/bn/convert.c
@@ -56,7 +56,9 @@
#include <openssl/bn.h>
+#include <assert.h>
#include <ctype.h>
+#include <limits.h>
#include <stdio.h>
#include <string.h>
@@ -67,7 +69,8 @@
#include "internal.h"
BIGNUM *BN_bin2bn(const uint8_t *in, size_t len, BIGNUM *ret) {
- unsigned num_words, m;
+ size_t num_words;
+ unsigned m;
BN_ULONG word = 0;
BIGNUM *bn = NULL;
@@ -93,7 +96,10 @@ BIGNUM *BN_bin2bn(const uint8_t *in, size_t len, BIGNUM *ret) {
return NULL;
}
- ret->top = num_words;
+ /* |bn_wexpand| must check bounds on |num_words| to write it into
+ * |ret->dmax|. */
+ assert(num_words <= INT_MAX);
+ ret->top = (int)num_words;
ret->neg = 0;
while (len--) {
@@ -198,7 +204,7 @@ char *BN_bn2hex(const BIGNUM *bn) {
buf = (char *)OPENSSL_malloc(bn->top * BN_BYTES * 2 + 2);
if (buf == NULL) {
- OPENSSL_PUT_ERROR(BN, BN_bn2hex, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(BN, ERR_R_MALLOC_FAILURE);
return NULL;
}
@@ -227,47 +233,59 @@ char *BN_bn2hex(const BIGNUM *bn) {
return buf;
}
-/* decode_hex decodes |i| bytes of hex data from |in| and updates |bn|. */
-static void decode_hex(BIGNUM *bn, const char *in, int i) {
- int h, m, j, k, c;
- BN_ULONG l=0;
-
- j = i; /* least significant 'hex' */
- h = 0;
- while (j > 0) {
- m = ((BN_BYTES * 2) <= j) ? (BN_BYTES * 2) : j;
- l = 0;
- for (;;) {
- c = in[j - m];
- if ((c >= '0') && (c <= '9')) {
- k = c - '0';
- } else if ((c >= 'a') && (c <= 'f')) {
- k = c - 'a' + 10;
- } else if ((c >= 'A') && (c <= 'F')) {
- k = c - 'A' + 10;
- } else {
- k = 0; /* paranoia */
- }
+/* decode_hex decodes |in_len| bytes of hex data from |in| and updates |bn|. */
+static int decode_hex(BIGNUM *bn, const char *in, int in_len) {
+ if (in_len > INT_MAX/4) {
+ OPENSSL_PUT_ERROR(BN, BN_R_BIGNUM_TOO_LONG);
+ return 0;
+ }
+ /* |in_len| is the number of hex digits. */
+ if (bn_expand(bn, in_len * 4) == NULL) {
+ return 0;
+ }
- l = (l << 4) | k;
+ int i = 0;
+ while (in_len > 0) {
+ /* Decode one |BN_ULONG| at a time. */
+ int todo = BN_BYTES * 2;
+ if (todo > in_len) {
+ todo = in_len;
+ }
- if (--m <= 0) {
- bn->d[h++] = l;
- break;
+ BN_ULONG word = 0;
+ int j;
+ for (j = todo; j > 0; j--) {
+ char c = in[in_len - j];
+
+ BN_ULONG hex;
+ if (c >= '0' && c <= '9') {
+ hex = c - '0';
+ } else if (c >= 'a' && c <= 'f') {
+ hex = c - 'a' + 10;
+ } else if (c >= 'A' && c <= 'F') {
+ hex = c - 'A' + 10;
+ } else {
+ hex = 0;
+ /* This shouldn't happen. The caller checks |isxdigit|. */
+ assert(0);
}
+ word = (word << 4) | hex;
}
- j -= (BN_BYTES * 2);
+ bn->d[i++] = word;
+ in_len -= todo;
}
-
- bn->top = h;
+ assert(i <= bn->dmax);
+ bn->top = i;
+ return 1;
}
/* decode_dec decodes |in_len| bytes of decimal data from |in| and updates |bn|. */
-static void decode_dec(BIGNUM *bn, const char *in, int in_len) {
+static int decode_dec(BIGNUM *bn, const char *in, int in_len) {
int i, j;
BN_ULONG l = 0;
+ /* Decode |BN_DEC_NUM| digits at a time. */
j = BN_DEC_NUM - (in_len % BN_DEC_NUM);
if (j == BN_DEC_NUM) {
j = 0;
@@ -277,15 +295,18 @@ static void decode_dec(BIGNUM *bn, const char *in, int in_len) {
l *= 10;
l += in[i] - '0';
if (++j == BN_DEC_NUM) {
- BN_mul_word(bn, BN_DEC_CONV);
- BN_add_word(bn, l);
+ if (!BN_mul_word(bn, BN_DEC_CONV) ||
+ !BN_add_word(bn, l)) {
+ return 0;
+ }
l = 0;
j = 0;
}
}
+ return 1;
}
-typedef void (*decode_func) (BIGNUM *bn, const char *in, int i);
+typedef int (*decode_func) (BIGNUM *bn, const char *in, int in_len);
typedef int (*char_test_func) (int c);
static int bn_x2bn(BIGNUM **outp, const char *in, decode_func decode, char_test_func want_char) {
@@ -302,7 +323,7 @@ static int bn_x2bn(BIGNUM **outp, const char *in, decode_func decode, char_test_
in++;
}
- for (i = 0; want_char((unsigned char)in[i]); i++) {}
+ for (i = 0; want_char((unsigned char)in[i]) && i + neg < INT_MAX; i++) {}
num = i + neg;
if (outp == NULL) {
@@ -320,13 +341,10 @@ static int bn_x2bn(BIGNUM **outp, const char *in, decode_func decode, char_test_
BN_zero(ret);
}
- /* i is the number of hex digests; */
- if (bn_expand(ret, i * 4) == NULL) {
+ if (!decode(ret, in, i)) {
goto err;
}
- decode(ret, in, i);
-
bn_correct_top(ret);
if (!BN_is_zero(ret)) {
ret->neg = neg;
@@ -365,7 +383,7 @@ char *BN_bn2dec(const BIGNUM *a) {
(BN_ULONG *)OPENSSL_malloc((num / BN_DEC_NUM + 1) * sizeof(BN_ULONG));
buf = (char *)OPENSSL_malloc(num + 3);
if ((buf == NULL) || (bn_data == NULL)) {
- OPENSSL_PUT_ERROR(BN, BN_bn2dec, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(BN, ERR_R_MALLOC_FAILURE);
goto err;
}
t = BN_dup(a);
@@ -499,3 +517,81 @@ BN_ULONG BN_get_word(const BIGNUM *bn) {
return BN_MASK2;
}
}
+
+size_t BN_bn2mpi(const BIGNUM *in, uint8_t *out) {
+ const size_t bits = BN_num_bits(in);
+ const size_t bytes = (bits + 7) / 8;
+ /* If the number of bits is a multiple of 8, i.e. if the MSB is set,
+ * prefix with a zero byte. */
+ int extend = 0;
+ if (bytes != 0 && (bits & 0x07) == 0) {
+ extend = 1;
+ }
+
+ const size_t len = bytes + extend;
+ if (len < bytes ||
+ 4 + len < len ||
+ (len & 0xffffffff) != len) {
+ /* If we cannot represent the number then we emit zero as the interface
+ * doesn't allow an error to be signalled. */
+ if (out) {
+ memset(out, 0, 4);
+ }
+ return 4;
+ }
+
+ if (out == NULL) {
+ return 4 + len;
+ }
+
+ out[0] = len >> 24;
+ out[1] = len >> 16;
+ out[2] = len >> 8;
+ out[3] = len;
+ if (extend) {
+ out[4] = 0;
+ }
+ BN_bn2bin(in, out + 4 + extend);
+ if (in->neg && len > 0) {
+ out[4] |= 0x80;
+ }
+ return len + 4;
+}
+
+BIGNUM *BN_mpi2bn(const uint8_t *in, size_t len, BIGNUM *out) {
+ if (len < 4) {
+ OPENSSL_PUT_ERROR(BN, BN_R_BAD_ENCODING);
+ return NULL;
+ }
+ const size_t in_len = ((size_t)in[0] << 24) |
+ ((size_t)in[1] << 16) |
+ ((size_t)in[2] << 8) |
+ ((size_t)in[3]);
+ if (in_len != len - 4) {
+ OPENSSL_PUT_ERROR(BN, BN_R_BAD_ENCODING);
+ return NULL;
+ }
+
+ if (out == NULL) {
+ out = BN_new();
+ }
+ if (out == NULL) {
+ OPENSSL_PUT_ERROR(BN, ERR_R_MALLOC_FAILURE);
+ return NULL;
+ }
+
+ if (in_len == 0) {
+ BN_zero(out);
+ return out;
+ }
+
+ in += 4;
+ if (BN_bin2bn(in, in_len, out) == NULL) {
+ return NULL;
+ }
+ out->neg = ((*in) & 0x80) != 0;
+ if (out->neg) {
+ BN_clear_bit(out, BN_num_bits(out) - 1);
+ }
+ return out;
+}
diff --git a/src/crypto/bn/ctx.c b/src/crypto/bn/ctx.c
index 0578376..48d9adf 100644
--- a/src/crypto/bn/ctx.c
+++ b/src/crypto/bn/ctx.c
@@ -124,7 +124,7 @@ struct bignum_ctx {
BN_CTX *BN_CTX_new(void) {
BN_CTX *ret = OPENSSL_malloc(sizeof(BN_CTX));
if (!ret) {
- OPENSSL_PUT_ERROR(BN, BN_CTX_new, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(BN, ERR_R_MALLOC_FAILURE);
return NULL;
}
@@ -153,7 +153,7 @@ void BN_CTX_start(BN_CTX *ctx) {
ctx->err_stack++;
} else if (!BN_STACK_push(&ctx->stack, ctx->used)) {
/* (Try to) get a new frame pointer */
- OPENSSL_PUT_ERROR(BN, BN_CTX_start, BN_R_TOO_MANY_TEMPORARY_VARIABLES);
+ OPENSSL_PUT_ERROR(BN, BN_R_TOO_MANY_TEMPORARY_VARIABLES);
ctx->err_stack++;
}
}
@@ -169,7 +169,7 @@ BIGNUM *BN_CTX_get(BN_CTX *ctx) {
/* Setting too_many prevents repeated "get" attempts from
* cluttering the error stack. */
ctx->too_many = 1;
- OPENSSL_PUT_ERROR(BN, BN_CTX_get, BN_R_TOO_MANY_TEMPORARY_VARIABLES);
+ OPENSSL_PUT_ERROR(BN, BN_R_TOO_MANY_TEMPORARY_VARIABLES);
return NULL;
}
diff --git a/src/crypto/bn/div.c b/src/crypto/bn/div.c
index 3588ea1..779dda2 100644
--- a/src/crypto/bn/div.c
+++ b/src/crypto/bn/div.c
@@ -125,7 +125,7 @@ int BN_div(BIGNUM *dv, BIGNUM *rm, const BIGNUM *num, const BIGNUM *divisor,
* so don't just rely on bn_check_top() here */
if ((num->top > 0 && num->d[num->top - 1] == 0) ||
(divisor->top > 0 && divisor->d[divisor->top - 1] == 0)) {
- OPENSSL_PUT_ERROR(BN, BN_div, BN_R_NOT_INITIALIZED);
+ OPENSSL_PUT_ERROR(BN, BN_R_NOT_INITIALIZED);
return 0;
}
@@ -135,7 +135,7 @@ int BN_div(BIGNUM *dv, BIGNUM *rm, const BIGNUM *num, const BIGNUM *divisor,
}
if (BN_is_zero(divisor)) {
- OPENSSL_PUT_ERROR(BN, BN_div, BN_R_DIV_BY_ZERO);
+ OPENSSL_PUT_ERROR(BN, BN_R_DIV_BY_ZERO);
return 0;
}
@@ -511,7 +511,7 @@ int BN_mod_lshift_quick(BIGNUM *r, const BIGNUM *a, int n, const BIGNUM *m) {
/* max_shift >= 0 */
if (max_shift < 0) {
- OPENSSL_PUT_ERROR(BN, BN_mod_lshift_quick, BN_R_INPUT_NOT_REDUCED);
+ OPENSSL_PUT_ERROR(BN, BN_R_INPUT_NOT_REDUCED);
return 0;
}
diff --git a/src/crypto/bn/exponentiation.c b/src/crypto/bn/exponentiation.c
index d3063c9..6c5e11b 100644
--- a/src/crypto/bn/exponentiation.c
+++ b/src/crypto/bn/exponentiation.c
@@ -131,7 +131,7 @@ int BN_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx) {
if ((p->flags & BN_FLG_CONSTTIME) != 0) {
/* BN_FLG_CONSTTIME only supported by BN_mod_exp_mont() */
- OPENSSL_PUT_ERROR(BN, BN_exp, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+ OPENSSL_PUT_ERROR(BN, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
return 0;
}
@@ -173,8 +173,8 @@ int BN_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx) {
}
}
- if (r != rr) {
- BN_copy(r, rr);
+ if (r != rr && !BN_copy(r, rr)) {
+ goto err;
}
ret = 1;
@@ -333,7 +333,7 @@ static int BN_div_recp(BIGNUM *dv, BIGNUM *rem, const BIGNUM *m,
j = 0;
while (BN_ucmp(r, &(recp->N)) >= 0) {
if (j++ > 2) {
- OPENSSL_PUT_ERROR(BN, BN_div_recp, BN_R_BAD_RECIPROCAL);
+ OPENSSL_PUT_ERROR(BN, BN_R_BAD_RECIPROCAL);
goto err;
}
if (!BN_usub(r, r, &(recp->N))) {
@@ -427,7 +427,7 @@ static int mod_exp_recp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
if (BN_get_flags(p, BN_FLG_CONSTTIME) != 0) {
/* BN_FLG_CONSTTIME only supported by BN_mod_exp_mont() */
- OPENSSL_PUT_ERROR(BN, mod_exp_recp, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+ OPENSSL_PUT_ERROR(BN, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
return 0;
}
@@ -616,7 +616,7 @@ int BN_mod_exp_mont(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p,
}
if (!BN_is_odd(m)) {
- OPENSSL_PUT_ERROR(BN, BN_mod_exp_mont, BN_R_CALLED_WITH_EVEN_MODULUS);
+ OPENSSL_PUT_ERROR(BN, BN_R_CALLED_WITH_EVEN_MODULUS);
return 0;
}
bits = BN_num_bits(p);
@@ -862,13 +862,13 @@ int BN_mod_exp_mont_consttime(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p,
unsigned char *powerbuf = NULL;
BIGNUM tmp, am;
- top = m->top;
-
- if (!(m->d[0] & 1)) {
- OPENSSL_PUT_ERROR(BN, BN_mod_exp_mont_consttime,
- BN_R_CALLED_WITH_EVEN_MODULUS);
+ if (!BN_is_odd(m)) {
+ OPENSSL_PUT_ERROR(BN, BN_R_CALLED_WITH_EVEN_MODULUS);
return 0;
}
+
+ top = m->top;
+
bits = BN_num_bits(p);
if (bits == 0) {
ret = BN_one(rr);
@@ -926,7 +926,6 @@ int BN_mod_exp_mont_consttime(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p,
}
}
#endif
- (void)0;
/* Allocate a buffer large enough to hold all of the pre-computed
* powers of am, am itself and tmp.
@@ -1223,13 +1222,12 @@ int BN_mod_exp_mont_word(BIGNUM *rr, BN_ULONG a, const BIGNUM *p,
if (BN_get_flags(p, BN_FLG_CONSTTIME) != 0) {
/* BN_FLG_CONSTTIME only supported by BN_mod_exp_mont() */
- OPENSSL_PUT_ERROR(BN, BN_mod_exp_mont_word,
- ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+ OPENSSL_PUT_ERROR(BN, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
return 0;
}
if (!BN_is_odd(m)) {
- OPENSSL_PUT_ERROR(BN, BN_mod_exp_mont_word, BN_R_CALLED_WITH_EVEN_MODULUS);
+ OPENSSL_PUT_ERROR(BN, BN_R_CALLED_WITH_EVEN_MODULUS);
return 0;
}
@@ -1372,7 +1370,7 @@ int BN_mod_exp2_mont(BIGNUM *rr, const BIGNUM *a1, const BIGNUM *p1,
BN_MONT_CTX *mont = NULL;
if (!(m->d[0] & 1)) {
- OPENSSL_PUT_ERROR(BN, BN_mod_exp2_mont, BN_R_CALLED_WITH_EVEN_MODULUS);
+ OPENSSL_PUT_ERROR(BN, BN_R_CALLED_WITH_EVEN_MODULUS);
return 0;
}
bits1 = BN_num_bits(p1);
diff --git a/src/crypto/bn/gcd.c b/src/crypto/bn/gcd.c
index 3132c29..e106149 100644
--- a/src/crypto/bn/gcd.c
+++ b/src/crypto/bn/gcd.c
@@ -223,20 +223,23 @@ err:
}
/* solves ax == 1 (mod n) */
-static BIGNUM *BN_mod_inverse_no_branch(BIGNUM *out, const BIGNUM *a,
- const BIGNUM *n, BN_CTX *ctx);
+static BIGNUM *BN_mod_inverse_no_branch(BIGNUM *out, int *out_no_inverse,
+ const BIGNUM *a, const BIGNUM *n,
+ BN_CTX *ctx);
-BIGNUM *BN_mod_inverse(BIGNUM *out, const BIGNUM *a, const BIGNUM *n,
- BN_CTX *ctx) {
+BIGNUM *BN_mod_inverse_ex(BIGNUM *out, int *out_no_inverse, const BIGNUM *a,
+ const BIGNUM *n, BN_CTX *ctx) {
BIGNUM *A, *B, *X, *Y, *M, *D, *T, *R = NULL;
BIGNUM *ret = NULL;
int sign;
if ((a->flags & BN_FLG_CONSTTIME) != 0 ||
(n->flags & BN_FLG_CONSTTIME) != 0) {
- return BN_mod_inverse_no_branch(out, a, n, ctx);
+ return BN_mod_inverse_no_branch(out, out_no_inverse, a, n, ctx);
}
+ *out_no_inverse = 0;
+
BN_CTX_start(ctx);
A = BN_CTX_get(ctx);
B = BN_CTX_get(ctx);
@@ -522,7 +525,8 @@ BIGNUM *BN_mod_inverse(BIGNUM *out, const BIGNUM *a, const BIGNUM *n,
}
}
} else {
- OPENSSL_PUT_ERROR(BN, BN_mod_inverse, BN_R_NO_INVERSE);
+ *out_no_inverse = 1;
+ OPENSSL_PUT_ERROR(BN, BN_R_NO_INVERSE);
goto err;
}
ret = R;
@@ -535,16 +539,25 @@ err:
return ret;
}
+BIGNUM *BN_mod_inverse(BIGNUM *out, const BIGNUM *a, const BIGNUM *n,
+ BN_CTX *ctx) {
+ int no_inverse;
+ return BN_mod_inverse_ex(out, &no_inverse, a, n, ctx);
+}
+
/* BN_mod_inverse_no_branch is a special version of BN_mod_inverse.
* It does not contain branches that may leak sensitive information. */
-static BIGNUM *BN_mod_inverse_no_branch(BIGNUM *out, const BIGNUM *a,
- const BIGNUM *n, BN_CTX *ctx) {
+static BIGNUM *BN_mod_inverse_no_branch(BIGNUM *out, int *out_no_inverse,
+ const BIGNUM *a, const BIGNUM *n,
+ BN_CTX *ctx) {
BIGNUM *A, *B, *X, *Y, *M, *D, *T, *R = NULL;
BIGNUM local_A, local_B;
BIGNUM *pA, *pB;
BIGNUM *ret = NULL;
int sign;
+ *out_no_inverse = 0;
+
BN_CTX_start(ctx);
A = BN_CTX_get(ctx);
B = BN_CTX_get(ctx);
@@ -682,7 +695,8 @@ static BIGNUM *BN_mod_inverse_no_branch(BIGNUM *out, const BIGNUM *a,
}
}
} else {
- OPENSSL_PUT_ERROR(BN, BN_mod_inverse_no_branch, BN_R_NO_INVERSE);
+ *out_no_inverse = 1;
+ OPENSSL_PUT_ERROR(BN, BN_R_NO_INVERSE);
goto err;
}
ret = R;
diff --git a/src/crypto/bn/internal.h b/src/crypto/bn/internal.h
index 2674b3c..0d0eb44 100644
--- a/src/crypto/bn/internal.h
+++ b/src/crypto/bn/internal.h
@@ -136,9 +136,9 @@
extern "C" {
#endif
-/* bn_expand acts the same as |BN_wexpand|, but takes a number of bits rather
+/* bn_expand acts the same as |bn_wexpand|, but takes a number of bits rather
* than a number of words. */
-BIGNUM *bn_expand(BIGNUM *bn, unsigned bits);
+BIGNUM *bn_expand(BIGNUM *bn, size_t bits);
#if defined(OPENSSL_64_BIT)
diff --git a/src/crypto/bn/montgomery.c b/src/crypto/bn/montgomery.c
index 152cf2d..c6c9c88 100644
--- a/src/crypto/bn/montgomery.c
+++ b/src/crypto/bn/montgomery.c
@@ -110,6 +110,7 @@
#include <string.h>
+#include <openssl/err.h>
#include <openssl/mem.h>
#include <openssl/thread.h>
@@ -176,6 +177,11 @@ int BN_MONT_CTX_set(BN_MONT_CTX *mont, const BIGNUM *mod, BN_CTX *ctx) {
BIGNUM tmod;
BN_ULONG buf[2];
+ if (BN_is_zero(mod)) {
+ OPENSSL_PUT_ERROR(BN, BN_R_DIV_BY_ZERO);
+ return 0;
+ }
+
BN_CTX_start(ctx);
Ri = BN_CTX_get(ctx);
if (Ri == NULL) {
diff --git a/src/crypto/bn/mul.c b/src/crypto/bn/mul.c
index a17d766..029a59e 100644
--- a/src/crypto/bn/mul.c
+++ b/src/crypto/bn/mul.c
@@ -666,8 +666,8 @@ int BN_mul(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx) {
end:
bn_correct_top(rr);
- if (r != rr) {
- BN_copy(r, rr);
+ if (r != rr && !BN_copy(r, rr)) {
+ goto err;
}
ret = 1;
@@ -877,8 +877,8 @@ int BN_sqr(BIGNUM *r, const BIGNUM *a, BN_CTX *ctx) {
rr->top = max;
}
- if (rr != r) {
- BN_copy(r, rr);
+ if (rr != r && !BN_copy(r, rr)) {
+ goto err;
}
ret = 1;
diff --git a/src/crypto/bn/prime.c b/src/crypto/bn/prime.c
index cf3afcf..bbb8fe0 100644
--- a/src/crypto/bn/prime.c
+++ b/src/crypto/bn/prime.c
@@ -362,11 +362,11 @@ int BN_generate_prime_ex(BIGNUM *ret, int bits, int safe, const BIGNUM *add,
if (bits < 2) {
/* There are no prime numbers this small. */
- OPENSSL_PUT_ERROR(BN, BN_generate_prime_ex, BN_R_BITS_TOO_SMALL);
+ OPENSSL_PUT_ERROR(BN, BN_R_BITS_TOO_SMALL);
return 0;
} else if (bits == 2 && safe) {
/* The smallest safe prime (7) is three bits. */
- OPENSSL_PUT_ERROR(BN, BN_generate_prime_ex, BN_R_BITS_TOO_SMALL);
+ OPENSSL_PUT_ERROR(BN, BN_R_BITS_TOO_SMALL);
return 0;
}
@@ -515,11 +515,10 @@ int BN_is_prime_fasttest_ex(const BIGNUM *a, int checks, BN_CTX *ctx_passed,
/* A := abs(a) */
if (a->neg) {
- BIGNUM *t;
- if ((t = BN_CTX_get(ctx)) == NULL) {
+ BIGNUM *t = BN_CTX_get(ctx);
+ if (t == NULL || !BN_copy(t, a)) {
goto err;
}
- BN_copy(t, a);
t->neg = 0;
A = t;
} else {
diff --git a/src/crypto/bn/random.c b/src/crypto/bn/random.c
index 549ac48..3116e54 100644
--- a/src/crypto/bn/random.c
+++ b/src/crypto/bn/random.c
@@ -134,7 +134,7 @@ int BN_rand(BIGNUM *rnd, int bits, int top, int bottom) {
buf = OPENSSL_malloc(bytes);
if (buf == NULL) {
- OPENSSL_PUT_ERROR(BN, BN_rand, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(BN, ERR_R_MALLOC_FAILURE);
goto err;
}
@@ -186,7 +186,7 @@ int BN_rand_range(BIGNUM *r, const BIGNUM *range) {
unsigned count = 100;
if (range->neg || BN_is_zero(range)) {
- OPENSSL_PUT_ERROR(BN, BN_rand_range, BN_R_INVALID_RANGE);
+ OPENSSL_PUT_ERROR(BN, BN_R_INVALID_RANGE);
return 0;
}
@@ -219,7 +219,7 @@ int BN_rand_range(BIGNUM *r, const BIGNUM *range) {
}
if (!--count) {
- OPENSSL_PUT_ERROR(BN, BN_rand_range, BN_R_TOO_MANY_ITERATIONS);
+ OPENSSL_PUT_ERROR(BN, BN_R_TOO_MANY_ITERATIONS);
return 0;
}
} while (BN_cmp(r, range) >= 0);
@@ -231,7 +231,7 @@ int BN_rand_range(BIGNUM *r, const BIGNUM *range) {
}
if (!--count) {
- OPENSSL_PUT_ERROR(BN, BN_rand_range, BN_R_TOO_MANY_ITERATIONS);
+ OPENSSL_PUT_ERROR(BN, BN_R_TOO_MANY_ITERATIONS);
return 0;
}
} while (BN_cmp(r, range) >= 0);
@@ -264,13 +264,13 @@ int BN_generate_dsa_nonce(BIGNUM *out, const BIGNUM *range, const BIGNUM *priv,
}
if (BN_is_zero(range)) {
- OPENSSL_PUT_ERROR(BN, BN_generate_dsa_nonce, BN_R_DIV_BY_ZERO);
+ OPENSSL_PUT_ERROR(BN, BN_R_DIV_BY_ZERO);
goto err;
}
k_bytes = OPENSSL_malloc(num_k_bytes);
if (!k_bytes) {
- OPENSSL_PUT_ERROR(BN, BN_generate_dsa_nonce, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(BN, ERR_R_MALLOC_FAILURE);
goto err;
}
@@ -281,7 +281,7 @@ int BN_generate_dsa_nonce(BIGNUM *out, const BIGNUM *range, const BIGNUM *priv,
/* No reasonable DSA or ECDSA key should have a private key
* this large and we don't handle this case in order to avoid
* leaking the length of the private key. */
- OPENSSL_PUT_ERROR(BN, BN_generate_dsa_nonce, BN_R_PRIVATE_KEY_TOO_LARGE);
+ OPENSSL_PUT_ERROR(BN, BN_R_PRIVATE_KEY_TOO_LARGE);
goto err;
}
memcpy(private_bytes, priv->d, todo);
diff --git a/src/crypto/bn/rsaz_exp.h b/src/crypto/bn/rsaz_exp.h
index 0bb6b0c..c752b45 100644
--- a/src/crypto/bn/rsaz_exp.h
+++ b/src/crypto/bn/rsaz_exp.h
@@ -1,32 +1,44 @@
-/******************************************************************************
-* Copyright(c) 2012, Intel Corp.
-* Developers and authors:
-* Shay Gueron (1, 2), and Vlad Krasnov (1)
-* (1) Intel Corporation, Israel Development Center, Haifa, Israel
-* (2) University of Haifa, Israel
+/*****************************************************************************
+* *
+* Copyright (c) 2012, Intel Corporation *
+* *
+* All rights reserved. *
+* *
+* Redistribution and use in source and binary forms, with or without *
+* modification, are permitted provided that the following conditions are *
+* met: *
+* *
+* * Redistributions of source code must retain the above copyright *
+* notice, this list of conditions and the following disclaimer. *
+* *
+* * Redistributions in binary form must reproduce the above copyright *
+* notice, this list of conditions and the following disclaimer in the *
+* documentation and/or other materials provided with the *
+* distribution. *
+* *
+* * Neither the name of the Intel Corporation nor the names of its *
+* contributors may be used to endorse or promote products derived from *
+* this software without specific prior written permission. *
+* *
+* *
+* THIS SOFTWARE IS PROVIDED BY INTEL CORPORATION ""AS IS"" AND ANY *
+* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE *
+* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR *
+* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTEL CORPORATION OR *
+* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, *
+* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, *
+* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR *
+* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF *
+* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING *
+* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS *
+* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *
+* *
******************************************************************************
-* LICENSE:
-* This submission to OpenSSL is to be made available under the OpenSSL
-* license, and only to the OpenSSL project, in order to allow integration
-* into the publicly distributed code.
-* The use of this code, or portions of this code, or concepts embedded in
-* this code, or modification of this code and/or algorithm(s) in it, or the
-* use of this code for any other purpose than stated above, requires special
-* licensing.
-******************************************************************************
-* DISCLAIMER:
-* THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS AND THE COPYRIGHT OWNERS
-* ``AS IS''. ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
-* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS OR THE COPYRIGHT
-* OWNERS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
-* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-* POSSIBILITY OF SUCH DAMAGE.
-******************************************************************************/
+* Developers and authors: *
+* Shay Gueron (1, 2), and Vlad Krasnov (1) *
+* (1) Intel Corporation, Israel Development Center, Haifa, Israel *
+* (2) University of Haifa, Israel *
+*****************************************************************************/
#ifndef RSAZ_EXP_H
#define RSAZ_EXP_H
diff --git a/src/crypto/bn/shift.c b/src/crypto/bn/shift.c
index f143996..defec92 100644
--- a/src/crypto/bn/shift.c
+++ b/src/crypto/bn/shift.c
@@ -69,7 +69,7 @@ int BN_lshift(BIGNUM *r, const BIGNUM *a, int n) {
BN_ULONG l;
if (n < 0) {
- OPENSSL_PUT_ERROR(BN, BN_lshift, BN_R_NEGATIVE_NUMBER);
+ OPENSSL_PUT_ERROR(BN, BN_R_NEGATIVE_NUMBER);
return 0;
}
@@ -138,7 +138,7 @@ int BN_rshift(BIGNUM *r, const BIGNUM *a, int n) {
BN_ULONG l, tmp;
if (n < 0) {
- OPENSSL_PUT_ERROR(BN, BN_rshift, BN_R_NEGATIVE_NUMBER);
+ OPENSSL_PUT_ERROR(BN, BN_R_NEGATIVE_NUMBER);
return 0;
}
diff --git a/src/crypto/bn/sqrt.c b/src/crypto/bn/sqrt.c
index e71a818..2ed66c2 100644
--- a/src/crypto/bn/sqrt.c
+++ b/src/crypto/bn/sqrt.c
@@ -86,7 +86,7 @@ BIGNUM *BN_mod_sqrt(BIGNUM *in, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx) {
return ret;
}
- OPENSSL_PUT_ERROR(BN, BN_mod_sqrt, BN_R_P_IS_NOT_PRIME);
+ OPENSSL_PUT_ERROR(BN, BN_R_P_IS_NOT_PRIME);
return (NULL);
}
@@ -260,7 +260,7 @@ BIGNUM *BN_mod_sqrt(BIGNUM *in, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx) {
}
if (r == 0) {
/* m divides p */
- OPENSSL_PUT_ERROR(BN, BN_mod_sqrt, BN_R_P_IS_NOT_PRIME);
+ OPENSSL_PUT_ERROR(BN, BN_R_P_IS_NOT_PRIME);
goto end;
}
} while (r == 1 && ++i < 82);
@@ -271,7 +271,7 @@ BIGNUM *BN_mod_sqrt(BIGNUM *in, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx) {
* Even if p is not prime, we should have found some y
* such that r == -1.
*/
- OPENSSL_PUT_ERROR(BN, BN_mod_sqrt, BN_R_TOO_MANY_ITERATIONS);
+ OPENSSL_PUT_ERROR(BN, BN_R_TOO_MANY_ITERATIONS);
goto end;
}
@@ -286,7 +286,7 @@ BIGNUM *BN_mod_sqrt(BIGNUM *in, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx) {
goto end;
}
if (BN_is_one(y)) {
- OPENSSL_PUT_ERROR(BN, BN_mod_sqrt, BN_R_P_IS_NOT_PRIME);
+ OPENSSL_PUT_ERROR(BN, BN_R_P_IS_NOT_PRIME);
goto end;
}
@@ -377,7 +377,7 @@ BIGNUM *BN_mod_sqrt(BIGNUM *in, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx) {
while (!BN_is_one(t)) {
i++;
if (i == e) {
- OPENSSL_PUT_ERROR(BN, BN_mod_sqrt, BN_R_NOT_A_SQUARE);
+ OPENSSL_PUT_ERROR(BN, BN_R_NOT_A_SQUARE);
goto end;
}
if (!BN_mod_mul(t, t, t, p, ctx)) {
@@ -413,7 +413,7 @@ vrfy:
}
if (!err && 0 != BN_cmp(x, A)) {
- OPENSSL_PUT_ERROR(BN, BN_mod_sqrt, BN_R_NOT_A_SQUARE);
+ OPENSSL_PUT_ERROR(BN, BN_R_NOT_A_SQUARE);
err = 1;
}
}
@@ -434,7 +434,7 @@ int BN_sqrt(BIGNUM *out_sqrt, const BIGNUM *in, BN_CTX *ctx) {
int ok = 0, last_delta_valid = 0;
if (in->neg) {
- OPENSSL_PUT_ERROR(BN, BN_sqrt, BN_R_NEGATIVE_NUMBER);
+ OPENSSL_PUT_ERROR(BN, BN_R_NEGATIVE_NUMBER);
return 0;
}
if (BN_is_zero(in)) {
@@ -452,7 +452,7 @@ int BN_sqrt(BIGNUM *out_sqrt, const BIGNUM *in, BN_CTX *ctx) {
last_delta = BN_CTX_get(ctx);
delta = BN_CTX_get(ctx);
if (estimate == NULL || tmp == NULL || last_delta == NULL || delta == NULL) {
- OPENSSL_PUT_ERROR(BN, BN_sqrt, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(BN, ERR_R_MALLOC_FAILURE);
goto err;
}
@@ -470,7 +470,7 @@ int BN_sqrt(BIGNUM *out_sqrt, const BIGNUM *in, BN_CTX *ctx) {
!BN_sqr(tmp, estimate, ctx) ||
/* |delta| = |in| - |tmp| */
!BN_sub(delta, in, tmp)) {
- OPENSSL_PUT_ERROR(BN, BN_sqrt, ERR_R_BN_LIB);
+ OPENSSL_PUT_ERROR(BN, ERR_R_BN_LIB);
goto err;
}
@@ -490,15 +490,15 @@ int BN_sqrt(BIGNUM *out_sqrt, const BIGNUM *in, BN_CTX *ctx) {
}
if (BN_cmp(tmp, in) != 0) {
- OPENSSL_PUT_ERROR(BN, BN_sqrt, BN_R_NOT_A_SQUARE);
+ OPENSSL_PUT_ERROR(BN, BN_R_NOT_A_SQUARE);
goto err;
}
ok = 1;
err:
- if (ok && out_sqrt == in) {
- BN_copy(out_sqrt, estimate);
+ if (ok && out_sqrt == in && !BN_copy(out_sqrt, estimate)) {
+ ok = 0;
}
BN_CTX_end(ctx);
return ok;
diff --git a/src/crypto/buf/CMakeLists.txt b/src/crypto/buf/CMakeLists.txt
index 19edf7d..63f1025 100644
--- a/src/crypto/buf/CMakeLists.txt
+++ b/src/crypto/buf/CMakeLists.txt
@@ -1,4 +1,4 @@
-include_directories(. .. ../../include)
+include_directories(../../include)
add_library(
buf
diff --git a/src/crypto/buf/buf.c b/src/crypto/buf/buf.c
index 5769e77..13b5ceb 100644
--- a/src/crypto/buf/buf.c
+++ b/src/crypto/buf/buf.c
@@ -67,7 +67,7 @@ BUF_MEM *BUF_MEM_new(void) {
ret = OPENSSL_malloc(sizeof(BUF_MEM));
if (ret == NULL) {
- OPENSSL_PUT_ERROR(BUF, BUF_MEM_new, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(BUF, ERR_R_MALLOC_FAILURE);
return NULL;
}
@@ -105,14 +105,14 @@ static size_t buf_mem_grow(BUF_MEM *buf, size_t len, char clean) {
n = len + 3;
if (n < len) {
/* overflow */
- OPENSSL_PUT_ERROR(BUF, buf_mem_grow, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(BUF, ERR_R_MALLOC_FAILURE);
return 0;
}
n = n / 3;
alloc_size = n * 4;
if (alloc_size / 4 != n) {
/* overflow */
- OPENSSL_PUT_ERROR(BUF, buf_mem_grow, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(BUF, ERR_R_MALLOC_FAILURE);
return 0;
}
@@ -127,7 +127,7 @@ static size_t buf_mem_grow(BUF_MEM *buf, size_t len, char clean) {
}
if (new_buf == NULL) {
- OPENSSL_PUT_ERROR(BUF, buf_mem_grow, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(BUF, ERR_R_MALLOC_FAILURE);
len = 0;
} else {
buf->data = new_buf;
@@ -180,12 +180,12 @@ char *BUF_strndup(const char *buf, size_t size) {
alloc_size = size + 1;
if (alloc_size < size) {
/* overflow */
- OPENSSL_PUT_ERROR(BUF, BUF_strndup, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(BUF, ERR_R_MALLOC_FAILURE);
return NULL;
}
ret = OPENSSL_malloc(alloc_size);
if (ret == NULL) {
- OPENSSL_PUT_ERROR(BUF, BUF_strndup, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(BUF, ERR_R_MALLOC_FAILURE);
return NULL;
}
@@ -226,7 +226,7 @@ void *BUF_memdup(const void *data, size_t dst_size) {
ret = OPENSSL_malloc(dst_size);
if (ret == NULL) {
- OPENSSL_PUT_ERROR(BUF, BUF_memdup, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(BUF, ERR_R_MALLOC_FAILURE);
return NULL;
}
diff --git a/src/crypto/bytestring/CMakeLists.txt b/src/crypto/bytestring/CMakeLists.txt
index cbbacf2..3462aee 100644
--- a/src/crypto/bytestring/CMakeLists.txt
+++ b/src/crypto/bytestring/CMakeLists.txt
@@ -1,4 +1,4 @@
-include_directories(. .. ../../include)
+include_directories(../../include)
add_library(
bytestring
diff --git a/src/crypto/bytestring/bytestring_test.cc b/src/crypto/bytestring/bytestring_test.cc
index 66e9c1e..e987e1b 100644
--- a/src/crypto/bytestring/bytestring_test.cc
+++ b/src/crypto/bytestring/bytestring_test.cc
@@ -109,7 +109,7 @@ static bool TestGetASN1() {
static const uint8_t kData2[] = {0x30, 3, 1, 2};
static const uint8_t kData3[] = {0x30, 0x80};
static const uint8_t kData4[] = {0x30, 0x81, 1, 1};
- static const uint8_t kData5[] = {0x30, 0x82, 0, 1, 1};
+ static const uint8_t kData5[4 + 0x80] = {0x30, 0x82, 0, 0x80};
static const uint8_t kData6[] = {0xa1, 3, 0x4, 1, 1};
static const uint8_t kData7[] = {0xa1, 3, 0x4, 2, 1};
static const uint8_t kData8[] = {0xa1, 3, 0x2, 1, 1};
@@ -649,6 +649,14 @@ static bool TestASN1Uint64() {
return true;
}
+static int TestZero() {
+ CBB cbb;
+ CBB_zero(&cbb);
+ // Calling |CBB_cleanup| on a zero-state |CBB| must not crash.
+ CBB_cleanup(&cbb);
+ return 1;
+}
+
int main(void) {
CRYPTO_library_init();
@@ -665,7 +673,8 @@ int main(void) {
!TestCBBASN1() ||
!TestBerConvert() ||
!TestASN1Uint64() ||
- !TestGetOptionalASN1Bool()) {
+ !TestGetOptionalASN1Bool() ||
+ !TestZero()) {
return 1;
}
diff --git a/src/crypto/bytestring/cbb.c b/src/crypto/bytestring/cbb.c
index f1e09a2..1da6a21 100644
--- a/src/crypto/bytestring/cbb.c
+++ b/src/crypto/bytestring/cbb.c
@@ -20,6 +20,10 @@
#include <openssl/mem.h>
+void CBB_zero(CBB *cbb) {
+ memset(cbb, 0, sizeof(CBB));
+}
+
static int cbb_init(CBB *cbb, uint8_t *buf, size_t cap) {
struct cbb_buffer_st *base;
@@ -243,6 +247,11 @@ int CBB_flush(CBB *cbb) {
return 1;
}
+size_t CBB_len(const CBB *cbb) {
+ assert(cbb->child == NULL);
+
+ return cbb->base->len;
+}
static int cbb_add_length_prefixed(CBB *cbb, CBB *out_contents,
size_t len_len) {
diff --git a/src/crypto/bytestring/cbs.c b/src/crypto/bytestring/cbs.c
index b8caedd..5e0c538 100644
--- a/src/crypto/bytestring/cbs.c
+++ b/src/crypto/bytestring/cbs.c
@@ -137,6 +137,15 @@ int CBS_get_bytes(CBS *cbs, CBS *out, size_t len) {
return 1;
}
+int CBS_copy_bytes(CBS *cbs, uint8_t *out, size_t len) {
+ const uint8_t *v;
+ if (!cbs_get(cbs, &v, len)) {
+ return 0;
+ }
+ memcpy(out, v, len);
+ return 1;
+}
+
static int cbs_get_length_prefixed(CBS *cbs, CBS *out, size_t len_len) {
uint32_t len;
if (!cbs_get_u(cbs, &len, len_len)) {
@@ -320,14 +329,19 @@ int CBS_get_asn1_uint64(CBS *cbs, uint64_t *out) {
}
int CBS_get_optional_asn1(CBS *cbs, CBS *out, int *out_present, unsigned tag) {
+ int present = 0;
+
if (CBS_peek_asn1_tag(cbs, tag)) {
if (!CBS_get_asn1(cbs, out, tag)) {
return 0;
}
- *out_present = 1;
- } else {
- *out_present = 0;
+ present = 1;
+ }
+
+ if (out_present != NULL) {
+ *out_present = present;
}
+
return 1;
}
diff --git a/src/crypto/bytestring/internal.h b/src/crypto/bytestring/internal.h
index 391ad19..b4ea7e5 100644
--- a/src/crypto/bytestring/internal.h
+++ b/src/crypto/bytestring/internal.h
@@ -38,14 +38,6 @@ extern "C" {
* It returns one on success and zero otherwise. */
OPENSSL_EXPORT int CBS_asn1_ber_to_der(CBS *in, uint8_t **out, size_t *out_len);
-/* CBS_get_any_ber_asn1_element acts the same as |CBS_get_any_asn1_element| but
- * also allows indefinite-length elements to be returned. In that case,
- * |*out_header_len| and |CBS_len(out)| will both be two as only the header is
- * returned. */
-OPENSSL_EXPORT int CBS_get_any_ber_asn1_element(CBS *cbs, CBS *out,
- unsigned *out_tag,
- size_t *out_header_len);
-
#if defined(__cplusplus)
} /* extern C */
diff --git a/src/crypto/chacha/CMakeLists.txt b/src/crypto/chacha/CMakeLists.txt
index 6c3f87e..266e869 100644
--- a/src/crypto/chacha/CMakeLists.txt
+++ b/src/crypto/chacha/CMakeLists.txt
@@ -1,4 +1,4 @@
-include_directories(. .. ../../include)
+include_directories(../../include)
if (${ARCH} STREQUAL "arm")
set(
diff --git a/src/crypto/chacha/chacha_vec_arm.S b/src/crypto/chacha/chacha_vec_arm.S
index ddc374e..0f82627 100644
--- a/src/crypto/chacha/chacha_vec_arm.S
+++ b/src/crypto/chacha/chacha_vec_arm.S
@@ -23,6 +23,7 @@
# /opt/gcc-linaro-4.9-2014.11-x86_64_arm-linux-gnueabihf/bin/arm-linux-gnueabihf-gcc -O3 -mcpu=cortex-a8 -mfpu=neon -fpic -DASM_GEN -I ../../include -S chacha_vec.c -o -
#if !defined(OPENSSL_NO_ASM)
+#if defined(__arm__) || defined(__aarch64__)
.syntax unified
.cpu cortex-a8
@@ -1423,4 +1424,5 @@ CRYPTO_chacha_20_neon:
.ident "GCC: (Linaro GCC 2014.11) 4.9.3 20141031 (prerelease)"
.section .note.GNU-stack,"",%progbits
+#endif /* __arm__ || __aarch64__ */
#endif /* !OPENSSL_NO_ASM */
diff --git a/src/crypto/chacha/chacha_vec_arm_generate.go b/src/crypto/chacha/chacha_vec_arm_generate.go
index d681e8a..6d167b9 100644
--- a/src/crypto/chacha/chacha_vec_arm_generate.go
+++ b/src/crypto/chacha/chacha_vec_arm_generate.go
@@ -52,7 +52,8 @@ func main() {
output.WriteString(compiler)
output.WriteString(" ")
output.WriteString(strings.Join(args, " "))
- output.WriteString("\n\n#if !defined(OPENSSL_NO_ASM)\n\n")
+ output.WriteString("\n\n#if !defined(OPENSSL_NO_ASM)\n")
+ output.WriteString("#if defined(__arm__) || defined(__aarch64__)\n\n")
cmd := exec.Command(compiler, args...)
cmd.Stderr = os.Stderr
@@ -144,5 +145,6 @@ const attr28Block = `
`
const trailer = `
+#endif /* __arm__ || __aarch64__ */
#endif /* !OPENSSL_NO_ASM */
`
diff --git a/src/crypto/cipher/CMakeLists.txt b/src/crypto/cipher/CMakeLists.txt
index 2775698..6b4c729 100644
--- a/src/crypto/cipher/CMakeLists.txt
+++ b/src/crypto/cipher/CMakeLists.txt
@@ -1,4 +1,4 @@
-include_directories(. .. ../../include)
+include_directories(../../include)
add_library(
cipher
diff --git a/src/crypto/cipher/aead.c b/src/crypto/cipher/aead.c
index 20d699d..7e747f8 100644
--- a/src/crypto/cipher/aead.c
+++ b/src/crypto/cipher/aead.c
@@ -30,11 +30,15 @@ size_t EVP_AEAD_max_overhead(const EVP_AEAD *aead) { return aead->overhead; }
size_t EVP_AEAD_max_tag_len(const EVP_AEAD *aead) { return aead->max_tag_len; }
+void EVP_AEAD_CTX_zero(EVP_AEAD_CTX *ctx) {
+ memset(ctx, 0, sizeof(EVP_AEAD_CTX));
+}
+
int EVP_AEAD_CTX_init(EVP_AEAD_CTX *ctx, const EVP_AEAD *aead,
const uint8_t *key, size_t key_len, size_t tag_len,
ENGINE *impl) {
if (!aead->init) {
- OPENSSL_PUT_ERROR(CIPHER, EVP_AEAD_CTX_init, CIPHER_R_NO_DIRECTION_SET);
+ OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_NO_DIRECTION_SET);
ctx->aead = NULL;
return 0;
}
@@ -47,8 +51,7 @@ int EVP_AEAD_CTX_init_with_direction(EVP_AEAD_CTX *ctx, const EVP_AEAD *aead,
size_t tag_len,
enum evp_aead_direction_t dir) {
if (key_len != aead->key_len) {
- OPENSSL_PUT_ERROR(CIPHER, EVP_AEAD_CTX_init_with_direction,
- CIPHER_R_UNSUPPORTED_KEY_SIZE);
+ OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_UNSUPPORTED_KEY_SIZE);
ctx->aead = NULL;
return 0;
}
@@ -101,12 +104,12 @@ int EVP_AEAD_CTX_seal(const EVP_AEAD_CTX *ctx, uint8_t *out, size_t *out_len,
size_t possible_out_len = in_len + ctx->aead->overhead;
if (possible_out_len < in_len /* overflow */) {
- OPENSSL_PUT_ERROR(CIPHER, EVP_AEAD_CTX_seal, CIPHER_R_TOO_LARGE);
+ OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_TOO_LARGE);
goto error;
}
if (!check_alias(in, in_len, out)) {
- OPENSSL_PUT_ERROR(CIPHER, EVP_AEAD_CTX_seal, CIPHER_R_OUTPUT_ALIASES_INPUT);
+ OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_OUTPUT_ALIASES_INPUT);
goto error;
}
@@ -128,7 +131,7 @@ int EVP_AEAD_CTX_open(const EVP_AEAD_CTX *ctx, uint8_t *out, size_t *out_len,
size_t nonce_len, const uint8_t *in, size_t in_len,
const uint8_t *ad, size_t ad_len) {
if (!check_alias(in, in_len, out)) {
- OPENSSL_PUT_ERROR(CIPHER, EVP_AEAD_CTX_open, CIPHER_R_OUTPUT_ALIASES_INPUT);
+ OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_OUTPUT_ALIASES_INPUT);
goto error;
}
diff --git a/src/crypto/cipher/aead_test.cc b/src/crypto/cipher/aead_test.cc
index e4b75d6..baaee9e 100644
--- a/src/crypto/cipher/aead_test.cc
+++ b/src/crypto/cipher/aead_test.cc
@@ -22,6 +22,7 @@
#include <openssl/err.h>
#include "../test/file_test.h"
+#include "../test/scoped_types.h"
#include "../test/stl_compat.h"
@@ -35,18 +36,6 @@
// CT: 5294265a60
// TAG: 1d45758621762e061368e68868e2f929
-// EVP_AEAD_CTX lacks a zero state, so it doesn't fit easily into
-// ScopedOpenSSLContext.
-class EVP_AEAD_CTXScoper {
- public:
- EVP_AEAD_CTXScoper(EVP_AEAD_CTX *ctx) : ctx_(ctx) {}
- ~EVP_AEAD_CTXScoper() {
- EVP_AEAD_CTX_cleanup(ctx_);
- }
- private:
- EVP_AEAD_CTX *ctx_;
-};
-
static bool TestAEAD(FileTest *t, void *arg) {
const EVP_AEAD *aead = reinterpret_cast<const EVP_AEAD*>(arg);
@@ -60,20 +49,19 @@ static bool TestAEAD(FileTest *t, void *arg) {
return false;
}
- EVP_AEAD_CTX ctx;
- if (!EVP_AEAD_CTX_init_with_direction(&ctx, aead, bssl::vector_data(&key),
- key.size(), tag.size(),
- evp_aead_seal)) {
+ ScopedEVP_AEAD_CTX ctx;
+ if (!EVP_AEAD_CTX_init_with_direction(ctx.get(), aead,
+ bssl::vector_data(&key), key.size(),
+ tag.size(), evp_aead_seal)) {
t->PrintLine("Failed to init AEAD.");
return false;
}
- EVP_AEAD_CTXScoper cleanup(&ctx);
std::vector<uint8_t> out(in.size() + EVP_AEAD_max_overhead(aead));
if (!t->HasAttribute("NO_SEAL")) {
size_t out_len;
- if (!EVP_AEAD_CTX_seal(&ctx, bssl::vector_data(&out), &out_len, out.size(),
- bssl::vector_data(&nonce), nonce.size(),
+ if (!EVP_AEAD_CTX_seal(ctx.get(), bssl::vector_data(&out), &out_len,
+ out.size(), bssl::vector_data(&nonce), nonce.size(),
bssl::vector_data(&in), in.size(),
bssl::vector_data(&ad), ad.size())) {
t->PrintLine("Failed to run AEAD.");
@@ -101,17 +89,17 @@ static bool TestAEAD(FileTest *t, void *arg) {
// The "stateful" AEADs for implementing pre-AEAD cipher suites need to be
// reset after each operation.
- EVP_AEAD_CTX_cleanup(&ctx);
- if (!EVP_AEAD_CTX_init_with_direction(&ctx, aead, bssl::vector_data(&key),
- key.size(), tag.size(),
- evp_aead_open)) {
+ ctx.Reset();
+ if (!EVP_AEAD_CTX_init_with_direction(ctx.get(), aead,
+ bssl::vector_data(&key), key.size(),
+ tag.size(), evp_aead_open)) {
t->PrintLine("Failed to init AEAD.");
return false;
}
std::vector<uint8_t> out2(out.size());
size_t out2_len;
- int ret = EVP_AEAD_CTX_open(&ctx,
+ int ret = EVP_AEAD_CTX_open(ctx.get(),
bssl::vector_data(&out2), &out2_len, out2.size(),
bssl::vector_data(&nonce), nonce.size(),
bssl::vector_data(&out), out.size(),
@@ -137,10 +125,10 @@ static bool TestAEAD(FileTest *t, void *arg) {
// The "stateful" AEADs for implementing pre-AEAD cipher suites need to be
// reset after each operation.
- EVP_AEAD_CTX_cleanup(&ctx);
- if (!EVP_AEAD_CTX_init_with_direction(&ctx, aead, bssl::vector_data(&key),
- key.size(), tag.size(),
- evp_aead_open)) {
+ ctx.Reset();
+ if (!EVP_AEAD_CTX_init_with_direction(ctx.get(), aead,
+ bssl::vector_data(&key), key.size(),
+ tag.size(), evp_aead_open)) {
t->PrintLine("Failed to init AEAD.");
return false;
}
@@ -148,8 +136,8 @@ static bool TestAEAD(FileTest *t, void *arg) {
// Garbage at the end isn't ignored.
out.push_back(0);
out2.resize(out.size());
- if (EVP_AEAD_CTX_open(&ctx, bssl::vector_data(&out2), &out2_len, out2.size(),
- bssl::vector_data(&nonce), nonce.size(),
+ if (EVP_AEAD_CTX_open(ctx.get(), bssl::vector_data(&out2), &out2_len,
+ out2.size(), bssl::vector_data(&nonce), nonce.size(),
bssl::vector_data(&out), out.size(),
bssl::vector_data(&ad), ad.size())) {
t->PrintLine("Decrypted bad data with trailing garbage.");
@@ -159,10 +147,10 @@ static bool TestAEAD(FileTest *t, void *arg) {
// The "stateful" AEADs for implementing pre-AEAD cipher suites need to be
// reset after each operation.
- EVP_AEAD_CTX_cleanup(&ctx);
- if (!EVP_AEAD_CTX_init_with_direction(&ctx, aead, bssl::vector_data(&key),
- key.size(), tag.size(),
- evp_aead_open)) {
+ ctx.Reset();
+ if (!EVP_AEAD_CTX_init_with_direction(ctx.get(), aead,
+ bssl::vector_data(&key), key.size(),
+ tag.size(), evp_aead_open)) {
t->PrintLine("Failed to init AEAD.");
return false;
}
@@ -171,8 +159,8 @@ static bool TestAEAD(FileTest *t, void *arg) {
out[0] ^= 0x80;
out.resize(out.size() - 1);
out2.resize(out.size());
- if (EVP_AEAD_CTX_open(&ctx, bssl::vector_data(&out2), &out2_len, out2.size(),
- bssl::vector_data(&nonce), nonce.size(),
+ if (EVP_AEAD_CTX_open(ctx.get(), bssl::vector_data(&out2), &out2_len,
+ out2.size(), bssl::vector_data(&nonce), nonce.size(),
bssl::vector_data(&out), out.size(),
bssl::vector_data(&ad), ad.size())) {
t->PrintLine("Decrypted bad data with corrupted byte.");
@@ -200,6 +188,7 @@ static int TestCleanupAfterInitFailure(const EVP_AEAD *aead) {
fprintf(stderr, "A silly tag length didn't trigger an error!\n");
return 0;
}
+ ERR_clear_error();
/* Running a second, failed _init should not cause a memory leak. */
if (EVP_AEAD_CTX_init(&ctx, aead, key, key_len,
@@ -208,6 +197,7 @@ static int TestCleanupAfterInitFailure(const EVP_AEAD *aead) {
fprintf(stderr, "A silly tag length didn't trigger an error!\n");
return 0;
}
+ ERR_clear_error();
/* Calling _cleanup on an |EVP_AEAD_CTX| after a failed _init should be a
* no-op. */
diff --git a/src/crypto/cipher/cipher.c b/src/crypto/cipher/cipher.c
index 400c3f5..4401867 100644
--- a/src/crypto/cipher/cipher.c
+++ b/src/crypto/cipher/cipher.c
@@ -68,12 +68,18 @@
const EVP_CIPHER *EVP_get_cipherbynid(int nid) {
switch (nid) {
+ case NID_rc2_cbc:
+ return EVP_rc2_cbc();
+ case NID_rc2_40_cbc:
+ return EVP_rc2_40_cbc();
case NID_des_ede3_cbc:
return EVP_des_ede3_cbc();
case NID_des_ede_cbc:
return EVP_des_cbc();
case NID_aes_128_cbc:
return EVP_aes_128_cbc();
+ case NID_aes_192_cbc:
+ return EVP_aes_192_cbc();
case NID_aes_256_cbc:
return EVP_aes_256_cbc();
default:
@@ -115,7 +121,7 @@ void EVP_CIPHER_CTX_free(EVP_CIPHER_CTX *ctx) {
int EVP_CIPHER_CTX_copy(EVP_CIPHER_CTX *out, const EVP_CIPHER_CTX *in) {
if (in == NULL || in->cipher == NULL) {
- OPENSSL_PUT_ERROR(CIPHER, EVP_CIPHER_CTX_copy, CIPHER_R_INPUT_NOT_INITIALIZED);
+ OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_INPUT_NOT_INITIALIZED);
return 0;
}
@@ -125,7 +131,7 @@ int EVP_CIPHER_CTX_copy(EVP_CIPHER_CTX *out, const EVP_CIPHER_CTX *in) {
if (in->cipher_data && in->cipher->ctx_size) {
out->cipher_data = OPENSSL_malloc(in->cipher->ctx_size);
if (!out->cipher_data) {
- OPENSSL_PUT_ERROR(CIPHER, EVP_CIPHER_CTX_copy, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(CIPHER, ERR_R_MALLOC_FAILURE);
return 0;
}
memcpy(out->cipher_data, in->cipher_data, in->cipher->ctx_size);
@@ -165,7 +171,7 @@ int EVP_CipherInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher,
ctx->cipher_data = OPENSSL_malloc(ctx->cipher->ctx_size);
if (!ctx->cipher_data) {
ctx->cipher = NULL;
- OPENSSL_PUT_ERROR(CIPHER, EVP_CipherInit_ex, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(CIPHER, ERR_R_MALLOC_FAILURE);
return 0;
}
} else {
@@ -178,12 +184,12 @@ int EVP_CipherInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher,
if (ctx->cipher->flags & EVP_CIPH_CTRL_INIT) {
if (!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_INIT, 0, NULL)) {
ctx->cipher = NULL;
- OPENSSL_PUT_ERROR(CIPHER, EVP_CipherInit_ex, CIPHER_R_INITIALIZATION_ERROR);
+ OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_INITIALIZATION_ERROR);
return 0;
}
}
} else if (!ctx->cipher) {
- OPENSSL_PUT_ERROR(CIPHER, EVP_CipherInit_ex, CIPHER_R_NO_CIPHER_SET);
+ OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_NO_CIPHER_SET);
return 0;
}
@@ -338,8 +344,7 @@ int EVP_EncryptFinal_ex(EVP_CIPHER_CTX *ctx, uint8_t *out, int *out_len) {
bl = ctx->buf_len;
if (ctx->flags & EVP_CIPH_NO_PADDING) {
if (bl) {
- OPENSSL_PUT_ERROR(CIPHER, EVP_EncryptFinal_ex,
- CIPHER_R_DATA_NOT_MULTIPLE_OF_BLOCK_LENGTH);
+ OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_DATA_NOT_MULTIPLE_OF_BLOCK_LENGTH);
return 0;
}
*out_len = 0;
@@ -434,8 +439,7 @@ int EVP_DecryptFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *out, int *out_len) {
b = ctx->cipher->block_size;
if (ctx->flags & EVP_CIPH_NO_PADDING) {
if (ctx->buf_len) {
- OPENSSL_PUT_ERROR(CIPHER, EVP_DecryptFinal_ex,
- CIPHER_R_DATA_NOT_MULTIPLE_OF_BLOCK_LENGTH);
+ OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_DATA_NOT_MULTIPLE_OF_BLOCK_LENGTH);
return 0;
}
*out_len = 0;
@@ -444,8 +448,7 @@ int EVP_DecryptFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *out, int *out_len) {
if (b > 1) {
if (ctx->buf_len || !ctx->final_used) {
- OPENSSL_PUT_ERROR(CIPHER, EVP_DecryptFinal_ex,
- CIPHER_R_WRONG_FINAL_BLOCK_LENGTH);
+ OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_WRONG_FINAL_BLOCK_LENGTH);
return 0;
}
assert(b <= sizeof(ctx->final));
@@ -454,13 +457,13 @@ int EVP_DecryptFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *out, int *out_len) {
* Otherwise it provides a padding oracle. */
n = ctx->final[b - 1];
if (n == 0 || n > (int)b) {
- OPENSSL_PUT_ERROR(CIPHER, EVP_DecryptFinal_ex, CIPHER_R_BAD_DECRYPT);
+ OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_DECRYPT);
return 0;
}
for (i = 0; i < n; i++) {
if (ctx->final[--b] != n) {
- OPENSSL_PUT_ERROR(CIPHER, EVP_DecryptFinal_ex, CIPHER_R_BAD_DECRYPT);
+ OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_DECRYPT);
return 0;
}
}
@@ -538,19 +541,18 @@ uint32_t EVP_CIPHER_CTX_mode(const EVP_CIPHER_CTX *ctx) {
int EVP_CIPHER_CTX_ctrl(EVP_CIPHER_CTX *ctx, int command, int arg, void *ptr) {
int ret;
if (!ctx->cipher) {
- OPENSSL_PUT_ERROR(CIPHER, EVP_CIPHER_CTX_ctrl, CIPHER_R_NO_CIPHER_SET);
+ OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_NO_CIPHER_SET);
return 0;
}
if (!ctx->cipher->ctrl) {
- OPENSSL_PUT_ERROR(CIPHER, EVP_CIPHER_CTX_ctrl, CIPHER_R_CTRL_NOT_IMPLEMENTED);
+ OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_CTRL_NOT_IMPLEMENTED);
return 0;
}
ret = ctx->cipher->ctrl(ctx, command, arg, ptr);
if (ret == -1) {
- OPENSSL_PUT_ERROR(CIPHER, EVP_CIPHER_CTX_ctrl,
- CIPHER_R_CTRL_OPERATION_NOT_IMPLEMENTED);
+ OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_CTRL_OPERATION_NOT_IMPLEMENTED);
return 0;
}
@@ -572,8 +574,7 @@ int EVP_CIPHER_CTX_set_key_length(EVP_CIPHER_CTX *c, unsigned key_len) {
}
if (key_len == 0 || !(c->cipher->flags & EVP_CIPH_VARIABLE_LENGTH)) {
- OPENSSL_PUT_ERROR(CIPHER, EVP_CIPHER_CTX_set_key_length,
- CIPHER_R_INVALID_KEY_LENGTH);
+ OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_INVALID_KEY_LENGTH);
return 0;
}
@@ -630,7 +631,7 @@ const EVP_CIPHER *EVP_get_cipherbyname(const char *name) {
return EVP_rc4();
} else if (OPENSSL_strcasecmp(name, "des-cbc") == 0) {
return EVP_des_cbc();
- } else if (OPENSSL_strcasecmp(name, "3des-cbc") == 0 ||
+ } else if (OPENSSL_strcasecmp(name, "des-ede3-cbc") == 0 ||
OPENSSL_strcasecmp(name, "3des") == 0) {
return EVP_des_ede3_cbc();
} else if (OPENSSL_strcasecmp(name, "aes-128-cbc") == 0) {
diff --git a/src/crypto/cipher/cipher_test.cc b/src/crypto/cipher/cipher_test.cc
index 97a84e0..5f04178 100644
--- a/src/crypto/cipher/cipher_test.cc
+++ b/src/crypto/cipher/cipher_test.cc
@@ -69,6 +69,12 @@
static const EVP_CIPHER *GetCipher(const std::string &name) {
if (name == "DES-CBC") {
return EVP_des_cbc();
+ } else if (name == "DES-ECB") {
+ return EVP_des_ecb();
+ } else if (name == "DES-EDE") {
+ return EVP_des_ede();
+ } else if (name == "DES-EDE-CBC") {
+ return EVP_des_ede_cbc();
} else if (name == "DES-EDE3-CBC") {
return EVP_des_ede3_cbc();
} else if (name == "RC4") {
@@ -104,6 +110,7 @@ static const EVP_CIPHER *GetCipher(const std::string &name) {
static bool TestOperation(FileTest *t,
const EVP_CIPHER *cipher,
bool encrypt,
+ bool streaming,
const std::vector<uint8_t> &key,
const std::vector<uint8_t> &iv,
const std::vector<uint8_t> &plaintext,
@@ -160,11 +167,29 @@ static bool TestOperation(FileTest *t,
(!aad.empty() &&
!EVP_CipherUpdate(ctx.get(), nullptr, &unused, bssl::vector_data(&aad),
aad.size())) ||
- !EVP_CIPHER_CTX_set_padding(ctx.get(), 0) ||
- (!in->empty() &&
- !EVP_CipherUpdate(ctx.get(), bssl::vector_data(&result), &result_len1,
- bssl::vector_data(in), in->size())) ||
- !EVP_CipherFinal_ex(ctx.get(), bssl::vector_data(&result) + result_len1,
+ !EVP_CIPHER_CTX_set_padding(ctx.get(), 0)) {
+ t->PrintLine("Operation failed.");
+ return false;
+ }
+ if (streaming) {
+ for (size_t i = 0; i < in->size(); i++) {
+ uint8_t c = (*in)[i];
+ int len;
+ if (!EVP_CipherUpdate(ctx.get(), bssl::vector_data(&result) + result_len1,
+ &len, &c, 1)) {
+ t->PrintLine("Operation failed.");
+ return false;
+ }
+ result_len1 += len;
+ }
+ } else if (!in->empty() &&
+ !EVP_CipherUpdate(ctx.get(), bssl::vector_data(&result),
+ &result_len1, bssl::vector_data(in),
+ in->size())) {
+ t->PrintLine("Operation failed.");
+ return false;
+ }
+ if (!EVP_CipherFinal_ex(ctx.get(), bssl::vector_data(&result) + result_len1,
&result_len2)) {
t->PrintLine("Operation failed.");
return false;
@@ -236,15 +261,21 @@ static bool TestCipher(FileTest *t, void *arg) {
}
// By default, both directions are run, unless overridden by the operation.
- if (operation != kDecrypt &&
- !TestOperation(t, cipher, true /* encrypt */, key, iv, plaintext,
- ciphertext, aad, tag)) {
- return false;
+ if (operation != kDecrypt) {
+ if (!TestOperation(t, cipher, true /* encrypt */, false /* single-shot */,
+ key, iv, plaintext, ciphertext, aad, tag) ||
+ !TestOperation(t, cipher, true /* encrypt */, true /* streaming */, key,
+ iv, plaintext, ciphertext, aad, tag)) {
+ return false;
+ }
}
- if (operation != kEncrypt &&
- !TestOperation(t, cipher, false /* decrypt */, key, iv, plaintext,
- ciphertext, aad, tag)) {
- return false;
+ if (operation != kEncrypt) {
+ if (!TestOperation(t, cipher, false /* decrypt */, false /* single-shot */,
+ key, iv, plaintext, ciphertext, aad, tag) ||
+ !TestOperation(t, cipher, false /* decrypt */, true /* streaming */,
+ key, iv, plaintext, ciphertext, aad, tag)) {
+ return false;
+ }
}
return true;
diff --git a/src/crypto/cipher/e_aes.c b/src/crypto/cipher/e_aes.c
index 41d0aec..e8905f6 100644
--- a/src/crypto/cipher/e_aes.c
+++ b/src/crypto/cipher/e_aes.c
@@ -64,7 +64,7 @@
#include "../modes/internal.h"
#if defined(OPENSSL_ARM) || defined(OPENSSL_AARCH64)
-#include "../arm_arch.h"
+#include <openssl/arm_arch.h>
#endif
@@ -98,8 +98,6 @@ typedef struct {
#if !defined(OPENSSL_NO_ASM) && \
(defined(OPENSSL_X86_64) || defined(OPENSSL_X86))
#define VPAES
-extern unsigned int OPENSSL_ia32cap_P[];
-
static char vpaes_capable(void) {
return (OPENSSL_ia32cap_P[1] & (1 << (41 - 32))) != 0;
}
@@ -113,7 +111,6 @@ static char bsaes_capable(void) {
#elif !defined(OPENSSL_NO_ASM) && \
(defined(OPENSSL_ARM) || defined(OPENSSL_AARCH64))
-#include "../arm_arch.h"
#if defined(OPENSSL_ARM) && __ARM_MAX_ARCH__ >= 7
#define BSAES
@@ -338,7 +335,7 @@ static int aes_init_key(EVP_CIPHER_CTX *ctx, const uint8_t *key,
}
if (ret < 0) {
- OPENSSL_PUT_ERROR(CIPHER, aes_init_key, CIPHER_R_AES_KEY_SETUP_FAILED);
+ OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_AES_KEY_SETUP_FAILED);
return 0;
}
@@ -711,7 +708,7 @@ static int aes_gcm_cipher(EVP_CIPHER_CTX *ctx, uint8_t *out, const uint8_t *in,
} else {
if (!ctx->encrypt) {
if (gctx->taglen < 0 ||
- !CRYPTO_gcm128_finish(&gctx->gcm, ctx->buf, gctx->taglen) != 0) {
+ !CRYPTO_gcm128_finish(&gctx->gcm, ctx->buf, gctx->taglen)) {
return -1;
}
gctx->iv_set = 0;
@@ -853,7 +850,7 @@ static int aesni_init_key(EVP_CIPHER_CTX *ctx, const uint8_t *key,
}
if (ret < 0) {
- OPENSSL_PUT_ERROR(CIPHER, aesni_init_key, CIPHER_R_AES_KEY_SETUP_FAILED);
+ OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_AES_KEY_SETUP_FAILED);
return 0;
}
@@ -1066,7 +1063,7 @@ static int aead_aes_gcm_init(EVP_AEAD_CTX *ctx, const uint8_t *key,
const size_t key_bits = key_len * 8;
if (key_bits != 128 && key_bits != 256) {
- OPENSSL_PUT_ERROR(CIPHER, aead_aes_gcm_init, CIPHER_R_BAD_KEY_LENGTH);
+ OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_KEY_LENGTH);
return 0; /* EVP_AEAD_CTX_init should catch this. */
}
@@ -1075,7 +1072,7 @@ static int aead_aes_gcm_init(EVP_AEAD_CTX *ctx, const uint8_t *key,
}
if (tag_len > EVP_AEAD_AES_GCM_TAG_LEN) {
- OPENSSL_PUT_ERROR(CIPHER, aead_aes_gcm_init, CIPHER_R_TAG_TOO_LARGE);
+ OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_TAG_TOO_LARGE);
return 0;
}
@@ -1108,12 +1105,12 @@ static int aead_aes_gcm_seal(const EVP_AEAD_CTX *ctx, uint8_t *out,
GCM128_CONTEXT gcm;
if (in_len + gcm_ctx->tag_len < in_len) {
- OPENSSL_PUT_ERROR(CIPHER, aead_aes_gcm_seal, CIPHER_R_TOO_LARGE);
+ OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_TOO_LARGE);
return 0;
}
if (max_out_len < in_len + gcm_ctx->tag_len) {
- OPENSSL_PUT_ERROR(CIPHER, aead_aes_gcm_seal, CIPHER_R_BUFFER_TOO_SMALL);
+ OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BUFFER_TOO_SMALL);
return 0;
}
@@ -1152,14 +1149,14 @@ static int aead_aes_gcm_open(const EVP_AEAD_CTX *ctx, uint8_t *out,
GCM128_CONTEXT gcm;
if (in_len < gcm_ctx->tag_len) {
- OPENSSL_PUT_ERROR(CIPHER, aead_aes_gcm_open, CIPHER_R_BAD_DECRYPT);
+ OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_DECRYPT);
return 0;
}
plaintext_len = in_len - gcm_ctx->tag_len;
if (max_out_len < plaintext_len) {
- OPENSSL_PUT_ERROR(CIPHER, aead_aes_gcm_open, CIPHER_R_BUFFER_TOO_SMALL);
+ OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BUFFER_TOO_SMALL);
return 0;
}
@@ -1185,7 +1182,7 @@ static int aead_aes_gcm_open(const EVP_AEAD_CTX *ctx, uint8_t *out,
CRYPTO_gcm128_tag(&gcm, tag, gcm_ctx->tag_len);
if (CRYPTO_memcmp(tag, in + plaintext_len, gcm_ctx->tag_len) != 0) {
- OPENSSL_PUT_ERROR(CIPHER, aead_aes_gcm_open, CIPHER_R_BAD_DECRYPT);
+ OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_DECRYPT);
return 0;
}
@@ -1239,7 +1236,7 @@ static int aead_aes_key_wrap_init(EVP_AEAD_CTX *ctx, const uint8_t *key,
const size_t key_bits = key_len * 8;
if (key_bits != 128 && key_bits != 256) {
- OPENSSL_PUT_ERROR(CIPHER, aead_aes_key_wrap_init, CIPHER_R_BAD_KEY_LENGTH);
+ OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_KEY_LENGTH);
return 0; /* EVP_AEAD_CTX_init should catch this. */
}
@@ -1248,14 +1245,13 @@ static int aead_aes_key_wrap_init(EVP_AEAD_CTX *ctx, const uint8_t *key,
}
if (tag_len != 8) {
- OPENSSL_PUT_ERROR(CIPHER, aead_aes_key_wrap_init,
- CIPHER_R_UNSUPPORTED_TAG_SIZE);
+ OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_UNSUPPORTED_TAG_SIZE);
return 0;
}
kw_ctx = OPENSSL_malloc(sizeof(struct aead_aes_key_wrap_ctx));
if (kw_ctx == NULL) {
- OPENSSL_PUT_ERROR(CIPHER, aead_aes_key_wrap_init, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(CIPHER, ERR_R_MALLOC_FAILURE);
return 0;
}
@@ -1293,8 +1289,7 @@ static int aead_aes_key_wrap_seal(const EVP_AEAD_CTX *ctx, uint8_t *out,
uint8_t A[AES_BLOCK_SIZE];
if (ad_len != 0) {
- OPENSSL_PUT_ERROR(CIPHER, aead_aes_key_wrap_seal,
- CIPHER_R_UNSUPPORTED_AD_SIZE);
+ OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_UNSUPPORTED_AD_SIZE);
return 0;
}
@@ -1304,14 +1299,12 @@ static int aead_aes_key_wrap_seal(const EVP_AEAD_CTX *ctx, uint8_t *out,
}
if (nonce_len != 8) {
- OPENSSL_PUT_ERROR(CIPHER, aead_aes_key_wrap_seal,
- CIPHER_R_UNSUPPORTED_NONCE_SIZE);
+ OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_UNSUPPORTED_NONCE_SIZE);
return 0;
}
if (in_len % 8 != 0) {
- OPENSSL_PUT_ERROR(CIPHER, aead_aes_key_wrap_seal,
- CIPHER_R_UNSUPPORTED_INPUT_SIZE);
+ OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_UNSUPPORTED_INPUT_SIZE);
return 0;
}
@@ -1320,32 +1313,29 @@ static int aead_aes_key_wrap_seal(const EVP_AEAD_CTX *ctx, uint8_t *out,
* conservatively cap it to 2^32-16 to stop 32-bit platforms complaining that
* a comparison is always true. */
if (in_len > 0xfffffff0) {
- OPENSSL_PUT_ERROR(CIPHER, aead_aes_key_wrap_seal, CIPHER_R_TOO_LARGE);
+ OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_TOO_LARGE);
return 0;
}
n = in_len / 8;
if (n < 2) {
- OPENSSL_PUT_ERROR(CIPHER, aead_aes_key_wrap_seal,
- CIPHER_R_UNSUPPORTED_INPUT_SIZE);
+ OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_UNSUPPORTED_INPUT_SIZE);
return 0;
}
if (in_len + 8 < in_len) {
- OPENSSL_PUT_ERROR(CIPHER, aead_aes_key_wrap_seal, CIPHER_R_TOO_LARGE);
+ OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_TOO_LARGE);
return 0;
}
if (max_out_len < in_len + 8) {
- OPENSSL_PUT_ERROR(CIPHER, aead_aes_key_wrap_seal,
- CIPHER_R_BUFFER_TOO_SMALL);
+ OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BUFFER_TOO_SMALL);
return 0;
}
if (AES_set_encrypt_key(kw_ctx->key, kw_ctx->key_bits, &ks.ks) < 0) {
- OPENSSL_PUT_ERROR(CIPHER, aead_aes_key_wrap_seal,
- CIPHER_R_AES_KEY_SETUP_FAILED);
+ OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_AES_KEY_SETUP_FAILED);
return 0;
}
@@ -1388,8 +1378,7 @@ static int aead_aes_key_wrap_open(const EVP_AEAD_CTX *ctx, uint8_t *out,
uint8_t A[AES_BLOCK_SIZE];
if (ad_len != 0) {
- OPENSSL_PUT_ERROR(CIPHER, aead_aes_key_wrap_open,
- CIPHER_R_UNSUPPORTED_AD_SIZE);
+ OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_UNSUPPORTED_AD_SIZE);
return 0;
}
@@ -1399,14 +1388,12 @@ static int aead_aes_key_wrap_open(const EVP_AEAD_CTX *ctx, uint8_t *out,
}
if (nonce_len != 8) {
- OPENSSL_PUT_ERROR(CIPHER, aead_aes_key_wrap_open,
- CIPHER_R_UNSUPPORTED_NONCE_SIZE);
+ OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_UNSUPPORTED_NONCE_SIZE);
return 0;
}
if (in_len % 8 != 0) {
- OPENSSL_PUT_ERROR(CIPHER, aead_aes_key_wrap_open,
- CIPHER_R_UNSUPPORTED_INPUT_SIZE);
+ OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_UNSUPPORTED_INPUT_SIZE);
return 0;
}
@@ -1415,26 +1402,24 @@ static int aead_aes_key_wrap_open(const EVP_AEAD_CTX *ctx, uint8_t *out,
* conservatively cap it to 2^32-8 to stop 32-bit platforms complaining that
* a comparison is always true. */
if (in_len > 0xfffffff8) {
- OPENSSL_PUT_ERROR(CIPHER, aead_aes_key_wrap_open, CIPHER_R_TOO_LARGE);
+ OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_TOO_LARGE);
return 0;
}
if (in_len < 24) {
- OPENSSL_PUT_ERROR(CIPHER, aead_aes_key_wrap_open, CIPHER_R_BAD_DECRYPT);
+ OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_DECRYPT);
return 0;
}
n = (in_len / 8) - 1;
if (max_out_len < in_len - 8) {
- OPENSSL_PUT_ERROR(CIPHER, aead_aes_key_wrap_open,
- CIPHER_R_BUFFER_TOO_SMALL);
+ OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BUFFER_TOO_SMALL);
return 0;
}
if (AES_set_decrypt_key(kw_ctx->key, kw_ctx->key_bits, &ks.ks) < 0) {
- OPENSSL_PUT_ERROR(CIPHER, aead_aes_key_wrap_open,
- CIPHER_R_AES_KEY_SETUP_FAILED);
+ OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_AES_KEY_SETUP_FAILED);
return 0;
}
@@ -1457,7 +1442,7 @@ static int aead_aes_key_wrap_open(const EVP_AEAD_CTX *ctx, uint8_t *out,
}
if (CRYPTO_memcmp(A, nonce, 8) != 0) {
- OPENSSL_PUT_ERROR(CIPHER, aead_aes_key_wrap_open, CIPHER_R_BAD_DECRYPT);
+ OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_DECRYPT);
return 0;
}
@@ -1541,15 +1526,13 @@ static int aead_aes_ctr_hmac_sha256_init(EVP_AEAD_CTX *ctx, const uint8_t *key,
static const size_t hmac_key_len = 32;
if (key_len < hmac_key_len) {
- OPENSSL_PUT_ERROR(CIPHER, aead_aes_ctr_hmac_sha256_init,
- CIPHER_R_BAD_KEY_LENGTH);
+ OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_KEY_LENGTH);
return 0; /* EVP_AEAD_CTX_init should catch this. */
}
const size_t aes_key_len = key_len - hmac_key_len;
if (aes_key_len != 16 && aes_key_len != 32) {
- OPENSSL_PUT_ERROR(CIPHER, aead_aes_ctr_hmac_sha256_init,
- CIPHER_R_BAD_KEY_LENGTH);
+ OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_KEY_LENGTH);
return 0; /* EVP_AEAD_CTX_init should catch this. */
}
@@ -1558,15 +1541,13 @@ static int aead_aes_ctr_hmac_sha256_init(EVP_AEAD_CTX *ctx, const uint8_t *key,
}
if (tag_len > EVP_AEAD_AES_CTR_HMAC_SHA256_TAG_LEN) {
- OPENSSL_PUT_ERROR(CIPHER, aead_aes_ctr_hmac_sha256_init,
- CIPHER_R_TAG_TOO_LARGE);
+ OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_TAG_TOO_LARGE);
return 0;
}
aes_ctx = OPENSSL_malloc(sizeof(struct aead_aes_ctr_hmac_sha256_ctx));
if (aes_ctx == NULL) {
- OPENSSL_PUT_ERROR(CIPHER, aead_aes_ctr_hmac_sha256_init,
- ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(CIPHER, ERR_R_MALLOC_FAILURE);
return 0;
}
@@ -1666,20 +1647,17 @@ static int aead_aes_ctr_hmac_sha256_seal(const EVP_AEAD_CTX *ctx, uint8_t *out,
if (in_len + aes_ctx->tag_len < in_len ||
/* This input is so large it would overflow the 32-bit block counter. */
in_len_64 >= (OPENSSL_U64(1) << 32) * AES_BLOCK_SIZE) {
- OPENSSL_PUT_ERROR(CIPHER, aead_aes_ctr_hmac_sha256_seal,
- CIPHER_R_TOO_LARGE);
+ OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_TOO_LARGE);
return 0;
}
if (max_out_len < in_len + aes_ctx->tag_len) {
- OPENSSL_PUT_ERROR(CIPHER, aead_aes_ctr_hmac_sha256_seal,
- CIPHER_R_BUFFER_TOO_SMALL);
+ OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BUFFER_TOO_SMALL);
return 0;
}
if (nonce_len != EVP_AEAD_AES_CTR_HMAC_SHA256_NONCE_LEN) {
- OPENSSL_PUT_ERROR(CIPHER, aead_aes_ctr_hmac_sha256_seal,
- CIPHER_R_UNSUPPORTED_NONCE_SIZE);
+ OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_UNSUPPORTED_NONCE_SIZE);
return 0;
}
@@ -1703,22 +1681,19 @@ static int aead_aes_ctr_hmac_sha256_open(const EVP_AEAD_CTX *ctx, uint8_t *out,
size_t plaintext_len;
if (in_len < aes_ctx->tag_len) {
- OPENSSL_PUT_ERROR(CIPHER, aead_aes_ctr_hmac_sha256_open,
- CIPHER_R_BAD_DECRYPT);
+ OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_DECRYPT);
return 0;
}
plaintext_len = in_len - aes_ctx->tag_len;
if (max_out_len < plaintext_len) {
- OPENSSL_PUT_ERROR(CIPHER, aead_aes_ctr_hmac_sha256_open,
- CIPHER_R_BUFFER_TOO_SMALL);
+ OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BUFFER_TOO_SMALL);
return 0;
}
if (nonce_len != EVP_AEAD_AES_CTR_HMAC_SHA256_NONCE_LEN) {
- OPENSSL_PUT_ERROR(CIPHER, aead_aes_ctr_hmac_sha256_open,
- CIPHER_R_UNSUPPORTED_NONCE_SIZE);
+ OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_UNSUPPORTED_NONCE_SIZE);
return 0;
}
@@ -1727,8 +1702,7 @@ static int aead_aes_ctr_hmac_sha256_open(const EVP_AEAD_CTX *ctx, uint8_t *out,
&aes_ctx->outer_init_state, ad, ad_len, nonce, in,
plaintext_len);
if (CRYPTO_memcmp(hmac_result, in + plaintext_len, aes_ctx->tag_len) != 0) {
- OPENSSL_PUT_ERROR(CIPHER, aead_aes_ctr_hmac_sha256_open,
- CIPHER_R_BAD_DECRYPT);
+ OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_DECRYPT);
return 0;
}
diff --git a/src/crypto/cipher/e_chacha20poly1305.c b/src/crypto/cipher/e_chacha20poly1305.c
index ebf0088..9dda1b0 100644
--- a/src/crypto/cipher/e_chacha20poly1305.c
+++ b/src/crypto/cipher/e_chacha20poly1305.c
@@ -42,7 +42,7 @@ static int aead_chacha20_poly1305_init(EVP_AEAD_CTX *ctx, const uint8_t *key,
}
if (tag_len > POLY1305_TAG_LEN) {
- OPENSSL_PUT_ERROR(CIPHER, aead_chacha20_poly1305_init, CIPHER_R_TOO_LARGE);
+ OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_TOO_LARGE);
return 0;
}
@@ -107,23 +107,22 @@ static int aead_chacha20_poly1305_seal(const EVP_AEAD_CTX *ctx, uint8_t *out,
* Casting to uint64_t inside the conditional is not sufficient to stop
* the warning. */
if (in_len_64 >= (1ull << 32) * 64 - 64) {
- OPENSSL_PUT_ERROR(CIPHER, aead_chacha20_poly1305_seal, CIPHER_R_TOO_LARGE);
+ OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_TOO_LARGE);
return 0;
}
if (in_len + c20_ctx->tag_len < in_len) {
- OPENSSL_PUT_ERROR(CIPHER, aead_chacha20_poly1305_seal, CIPHER_R_TOO_LARGE);
+ OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_TOO_LARGE);
return 0;
}
if (max_out_len < in_len + c20_ctx->tag_len) {
- OPENSSL_PUT_ERROR(CIPHER, aead_chacha20_poly1305_seal,
- CIPHER_R_BUFFER_TOO_SMALL);
+ OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BUFFER_TOO_SMALL);
return 0;
}
if (nonce_len != CHACHA20_NONCE_LEN) {
- OPENSSL_PUT_ERROR(CIPHER, aead_chacha20_poly1305_seal, CIPHER_R_IV_TOO_LARGE);
+ OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_IV_TOO_LARGE);
return 0;
}
@@ -156,7 +155,7 @@ static int aead_chacha20_poly1305_open(const EVP_AEAD_CTX *ctx, uint8_t *out,
const uint64_t in_len_64 = in_len;
if (in_len < c20_ctx->tag_len) {
- OPENSSL_PUT_ERROR(CIPHER, aead_chacha20_poly1305_open, CIPHER_R_BAD_DECRYPT);
+ OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_DECRYPT);
return 0;
}
@@ -168,20 +167,19 @@ static int aead_chacha20_poly1305_open(const EVP_AEAD_CTX *ctx, uint8_t *out,
* Casting to uint64_t inside the conditional is not sufficient to stop
* the warning. */
if (in_len_64 >= (1ull << 32) * 64 - 64) {
- OPENSSL_PUT_ERROR(CIPHER, aead_chacha20_poly1305_open, CIPHER_R_TOO_LARGE);
+ OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_TOO_LARGE);
return 0;
}
if (nonce_len != CHACHA20_NONCE_LEN) {
- OPENSSL_PUT_ERROR(CIPHER, aead_chacha20_poly1305_open, CIPHER_R_IV_TOO_LARGE);
+ OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_IV_TOO_LARGE);
return 0;
}
plaintext_len = in_len - c20_ctx->tag_len;
if (max_out_len < plaintext_len) {
- OPENSSL_PUT_ERROR(CIPHER, aead_chacha20_poly1305_open,
- CIPHER_R_BUFFER_TOO_SMALL);
+ OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BUFFER_TOO_SMALL);
return 0;
}
@@ -195,7 +193,7 @@ static int aead_chacha20_poly1305_open(const EVP_AEAD_CTX *ctx, uint8_t *out,
CRYPTO_poly1305_finish(&poly1305, mac);
if (CRYPTO_memcmp(mac, in + plaintext_len, c20_ctx->tag_len) != 0) {
- OPENSSL_PUT_ERROR(CIPHER, aead_chacha20_poly1305_open, CIPHER_R_BAD_DECRYPT);
+ OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_DECRYPT);
return 0;
}
diff --git a/src/crypto/cipher/e_des.c b/src/crypto/cipher/e_des.c
index 74e1fce..b1d312c 100644
--- a/src/crypto/cipher/e_des.c
+++ b/src/crypto/cipher/e_des.c
@@ -96,6 +96,31 @@ static const EVP_CIPHER des_cbc = {
const EVP_CIPHER *EVP_des_cbc(void) { return &des_cbc; }
+static int des_ecb_cipher(EVP_CIPHER_CTX *ctx, uint8_t *out, const uint8_t *in,
+ size_t in_len) {
+ if (in_len < ctx->cipher->block_size) {
+ return 1;
+ }
+ in_len -= ctx->cipher->block_size;
+
+ EVP_DES_KEY *dat = (EVP_DES_KEY *) ctx->cipher_data;
+ size_t i;
+ for (i = 0; i <= in_len; i += ctx->cipher->block_size) {
+ DES_ecb_encrypt((DES_cblock *) (in + i), (DES_cblock *) (out + i),
+ &dat->ks.ks, ctx->encrypt);
+ }
+ return 1;
+}
+
+static const EVP_CIPHER des_ecb = {
+ NID_des_ecb, 8 /* block_size */, 8 /* key_size */,
+ 0 /* iv_len */, sizeof(EVP_DES_KEY), EVP_CIPH_ECB_MODE,
+ NULL /* app_data */, des_init_key, des_ecb_cipher,
+ NULL /* cleanup */, NULL /* ctrl */, };
+
+const EVP_CIPHER *EVP_des_ecb(void) { return &des_ecb; }
+
+
typedef struct {
union {
double align;
@@ -126,10 +151,57 @@ static int des_ede3_cbc_cipher(EVP_CIPHER_CTX *ctx, uint8_t *out,
return 1;
}
-static const EVP_CIPHER des3_cbc = {
- NID_des_cbc, 8 /* block_size */, 24 /* key_size */,
+static const EVP_CIPHER des_ede3_cbc = {
+ NID_des_ede3_cbc, 8 /* block_size */, 24 /* key_size */,
8 /* iv_len */, sizeof(DES_EDE_KEY), EVP_CIPH_CBC_MODE,
NULL /* app_data */, des_ede3_init_key, des_ede3_cbc_cipher,
NULL /* cleanup */, NULL /* ctrl */, };
-const EVP_CIPHER *EVP_des_ede3_cbc(void) { return &des3_cbc; }
+const EVP_CIPHER *EVP_des_ede3_cbc(void) { return &des_ede3_cbc; }
+
+
+static int des_ede_init_key(EVP_CIPHER_CTX *ctx, const uint8_t *key,
+ const uint8_t *iv, int enc) {
+ DES_cblock *deskey = (DES_cblock *) key;
+ DES_EDE_KEY *dat = (DES_EDE_KEY *) ctx->cipher_data;
+
+ DES_set_key(&deskey[0], &dat->ks.ks[0]);
+ DES_set_key(&deskey[1], &dat->ks.ks[1]);
+ DES_set_key(&deskey[0], &dat->ks.ks[2]);
+
+ return 1;
+}
+
+static const EVP_CIPHER des_ede_cbc = {
+ NID_des_ede_cbc, 8 /* block_size */, 16 /* key_size */,
+ 8 /* iv_len */, sizeof(DES_EDE_KEY), EVP_CIPH_CBC_MODE,
+ NULL /* app_data */, des_ede_init_key , des_ede3_cbc_cipher,
+ NULL /* cleanup */, NULL /* ctrl */, };
+
+const EVP_CIPHER *EVP_des_ede_cbc(void) { return &des_ede_cbc; }
+
+
+static int des_ede_ecb_cipher(EVP_CIPHER_CTX *ctx, uint8_t *out,
+ const uint8_t *in, size_t in_len) {
+ if (in_len < ctx->cipher->block_size) {
+ return 1;
+ }
+ in_len -= ctx->cipher->block_size;
+
+ DES_EDE_KEY *dat = (DES_EDE_KEY *) ctx->cipher_data;
+ size_t i;
+ for (i = 0; i <= in_len; i += ctx->cipher->block_size) {
+ DES_ecb3_encrypt((DES_cblock *) (in + i), (DES_cblock *) (out + i),
+ &dat->ks.ks[0], &dat->ks.ks[1], &dat->ks.ks[2],
+ ctx->encrypt);
+ }
+ return 1;
+}
+
+static const EVP_CIPHER des_ede_ecb = {
+ NID_des_ede_cbc, 8 /* block_size */, 16 /* key_size */,
+ 0 /* iv_len */, sizeof(DES_EDE_KEY), EVP_CIPH_ECB_MODE,
+ NULL /* app_data */, des_ede_init_key , des_ede_ecb_cipher,
+ NULL /* cleanup */, NULL /* ctrl */, };
+
+const EVP_CIPHER *EVP_des_ede(void) { return &des_ede_ecb; }
diff --git a/src/crypto/cipher/e_rc2.c b/src/crypto/cipher/e_rc2.c
index c90ab93..8ca7bba 100644
--- a/src/crypto/cipher/e_rc2.c
+++ b/src/crypto/cipher/e_rc2.c
@@ -395,13 +395,18 @@ static int rc2_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg, void *ptr) {
case EVP_CTRL_INIT:
key->key_bits = EVP_CIPHER_CTX_key_length(ctx) * 8;
return 1;
+ case EVP_CTRL_SET_RC2_KEY_BITS:
+ /* Should be overridden by later call to |EVP_CTRL_INIT|, but
+ * people call it, so it may as well work. */
+ key->key_bits = arg;
+ return 1;
default:
return -1;
}
}
-static const EVP_CIPHER rc2_40_cbc_cipher = {
+static const EVP_CIPHER rc2_40_cbc = {
NID_rc2_40_cbc,
8 /* block size */,
5 /* 40 bit */,
@@ -416,5 +421,23 @@ static const EVP_CIPHER rc2_40_cbc_cipher = {
};
const EVP_CIPHER *EVP_rc2_40_cbc(void) {
- return &rc2_40_cbc_cipher;
+ return &rc2_40_cbc;
+}
+
+static const EVP_CIPHER rc2_cbc = {
+ NID_rc2_cbc,
+ 8 /* block size */,
+ 16 /* 128 bit */,
+ 8 /* iv len */,
+ sizeof(EVP_RC2_KEY),
+ EVP_CIPH_CBC_MODE | EVP_CIPH_VARIABLE_LENGTH | EVP_CIPH_CTRL_INIT,
+ NULL /* app_data */,
+ rc2_init_key,
+ rc2_cbc_cipher,
+ NULL,
+ rc2_ctrl,
+};
+
+const EVP_CIPHER *EVP_rc2_cbc(void) {
+ return &rc2_cbc;
}
diff --git a/src/crypto/cipher/e_rc4.c b/src/crypto/cipher/e_rc4.c
index 80dea36..e05b9fd 100644
--- a/src/crypto/cipher/e_rc4.c
+++ b/src/crypto/cipher/e_rc4.c
@@ -115,20 +115,20 @@ aead_rc4_md5_tls_init(EVP_AEAD_CTX *ctx, const uint8_t *key, size_t key_len,
}
if (tag_len > MD5_DIGEST_LENGTH) {
- OPENSSL_PUT_ERROR(CIPHER, aead_rc4_md5_tls_init, CIPHER_R_TOO_LARGE);
+ OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_TOO_LARGE);
return 0;
}
/* The keys consists of |MD5_DIGEST_LENGTH| bytes of HMAC(MD5) key followed
* by some number of bytes of RC4 key. */
if (key_len <= MD5_DIGEST_LENGTH) {
- OPENSSL_PUT_ERROR(CIPHER, aead_rc4_md5_tls_init, CIPHER_R_BAD_KEY_LENGTH);
+ OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_KEY_LENGTH);
return 0;
}
rc4_ctx = OPENSSL_malloc(sizeof(struct aead_rc4_md5_tls_ctx));
if (rc4_ctx == NULL) {
- OPENSSL_PUT_ERROR(CIPHER, aead_rc4_md5_tls_init, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(CIPHER, ERR_R_MALLOC_FAILURE);
return 0;
}
memset(rc4_ctx, 0, sizeof(struct aead_rc4_md5_tls_ctx));
@@ -185,22 +185,22 @@ static int aead_rc4_md5_tls_seal(const EVP_AEAD_CTX *ctx, uint8_t *out,
uint8_t digest[MD5_DIGEST_LENGTH];
if (in_len + rc4_ctx->tag_len < in_len) {
- OPENSSL_PUT_ERROR(CIPHER, aead_rc4_md5_tls_seal, CIPHER_R_TOO_LARGE);
+ OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_TOO_LARGE);
return 0;
}
if (nonce_len != 0) {
- OPENSSL_PUT_ERROR(CIPHER, aead_rc4_md5_tls_seal, CIPHER_R_IV_TOO_LARGE);
+ OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_IV_TOO_LARGE);
return 0;
}
if (max_out_len < in_len + rc4_ctx->tag_len) {
- OPENSSL_PUT_ERROR(CIPHER, aead_rc4_md5_tls_seal, CIPHER_R_BUFFER_TOO_SMALL);
+ OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BUFFER_TOO_SMALL);
return 0;
}
if (nonce_len != 0) {
- OPENSSL_PUT_ERROR(CIPHER, aead_rc4_md5_tls_seal, CIPHER_R_TOO_LARGE);
+ OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_TOO_LARGE);
return 0;
}
@@ -288,21 +288,21 @@ static int aead_rc4_md5_tls_open(const EVP_AEAD_CTX *ctx, uint8_t *out,
uint8_t digest[MD5_DIGEST_LENGTH];
if (in_len < rc4_ctx->tag_len) {
- OPENSSL_PUT_ERROR(CIPHER, aead_rc4_md5_tls_open, CIPHER_R_BAD_DECRYPT);
+ OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_DECRYPT);
return 0;
}
plaintext_len = in_len - rc4_ctx->tag_len;
if (nonce_len != 0) {
- OPENSSL_PUT_ERROR(CIPHER, aead_rc4_md5_tls_open, CIPHER_R_TOO_LARGE);
+ OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_TOO_LARGE);
return 0;
}
if (max_out_len < in_len) {
/* This requires that the caller provide space for the MAC, even though it
* will always be removed on return. */
- OPENSSL_PUT_ERROR(CIPHER, aead_rc4_md5_tls_open, CIPHER_R_BUFFER_TOO_SMALL);
+ OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BUFFER_TOO_SMALL);
return 0;
}
@@ -366,7 +366,7 @@ static int aead_rc4_md5_tls_open(const EVP_AEAD_CTX *ctx, uint8_t *out,
MD5_Final(digest, &md);
if (CRYPTO_memcmp(out + plaintext_len, digest, rc4_ctx->tag_len)) {
- OPENSSL_PUT_ERROR(CIPHER, aead_rc4_md5_tls_open, CIPHER_R_BAD_DECRYPT);
+ OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_DECRYPT);
return 0;
}
diff --git a/src/crypto/cipher/e_ssl3.c b/src/crypto/cipher/e_ssl3.c
index 1031d9b..389c52f 100644
--- a/src/crypto/cipher/e_ssl3.c
+++ b/src/crypto/cipher/e_ssl3.c
@@ -85,12 +85,12 @@ static int aead_ssl3_init(EVP_AEAD_CTX *ctx, const uint8_t *key, size_t key_len,
const EVP_CIPHER *cipher, const EVP_MD *md) {
if (tag_len != EVP_AEAD_DEFAULT_TAG_LENGTH &&
tag_len != EVP_MD_size(md)) {
- OPENSSL_PUT_ERROR(CIPHER, aead_ssl3_init, CIPHER_R_UNSUPPORTED_TAG_SIZE);
+ OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_UNSUPPORTED_TAG_SIZE);
return 0;
}
if (key_len != EVP_AEAD_key_length(ctx->aead)) {
- OPENSSL_PUT_ERROR(CIPHER, aead_ssl3_init, CIPHER_R_BAD_KEY_LENGTH);
+ OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_KEY_LENGTH);
return 0;
}
@@ -102,7 +102,7 @@ static int aead_ssl3_init(EVP_AEAD_CTX *ctx, const uint8_t *key, size_t key_len,
AEAD_SSL3_CTX *ssl3_ctx = OPENSSL_malloc(sizeof(AEAD_SSL3_CTX));
if (ssl3_ctx == NULL) {
- OPENSSL_PUT_ERROR(CIPHER, aead_ssl3_init, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(CIPHER, ERR_R_MALLOC_FAILURE);
return 0;
}
EVP_CIPHER_CTX_init(&ssl3_ctx->cipher_ctx);
@@ -133,29 +133,29 @@ static int aead_ssl3_seal(const EVP_AEAD_CTX *ctx, uint8_t *out,
if (!ssl3_ctx->cipher_ctx.encrypt) {
/* Unlike a normal AEAD, an SSL3 AEAD may only be used in one direction. */
- OPENSSL_PUT_ERROR(CIPHER, aead_ssl3_seal, CIPHER_R_INVALID_OPERATION);
+ OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_INVALID_OPERATION);
return 0;
}
if (in_len + EVP_AEAD_max_overhead(ctx->aead) < in_len ||
in_len > INT_MAX) {
/* EVP_CIPHER takes int as input. */
- OPENSSL_PUT_ERROR(CIPHER, aead_ssl3_seal, CIPHER_R_TOO_LARGE);
+ OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_TOO_LARGE);
return 0;
}
if (max_out_len < in_len + EVP_AEAD_max_overhead(ctx->aead)) {
- OPENSSL_PUT_ERROR(CIPHER, aead_ssl3_seal, CIPHER_R_BUFFER_TOO_SMALL);
+ OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BUFFER_TOO_SMALL);
return 0;
}
if (nonce_len != 0) {
- OPENSSL_PUT_ERROR(CIPHER, aead_ssl3_seal, CIPHER_R_IV_TOO_LARGE);
+ OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_IV_TOO_LARGE);
return 0;
}
if (ad_len != 11 - 2 /* length bytes */) {
- OPENSSL_PUT_ERROR(CIPHER, aead_ssl3_seal, CIPHER_R_INVALID_AD_SIZE);
+ OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_INVALID_AD_SIZE);
return 0;
}
@@ -217,36 +217,36 @@ static int aead_ssl3_open(const EVP_AEAD_CTX *ctx, uint8_t *out,
if (ssl3_ctx->cipher_ctx.encrypt) {
/* Unlike a normal AEAD, an SSL3 AEAD may only be used in one direction. */
- OPENSSL_PUT_ERROR(CIPHER, aead_ssl3_open, CIPHER_R_INVALID_OPERATION);
+ OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_INVALID_OPERATION);
return 0;
}
size_t mac_len = EVP_MD_CTX_size(&ssl3_ctx->md_ctx);
if (in_len < mac_len) {
- OPENSSL_PUT_ERROR(CIPHER, aead_ssl3_open, CIPHER_R_BAD_DECRYPT);
+ OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_DECRYPT);
return 0;
}
if (max_out_len < in_len) {
/* This requires that the caller provide space for the MAC, even though it
* will always be removed on return. */
- OPENSSL_PUT_ERROR(CIPHER, aead_ssl3_open, CIPHER_R_BUFFER_TOO_SMALL);
+ OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BUFFER_TOO_SMALL);
return 0;
}
if (nonce_len != 0) {
- OPENSSL_PUT_ERROR(CIPHER, aead_ssl3_open, CIPHER_R_TOO_LARGE);
+ OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_TOO_LARGE);
return 0;
}
if (ad_len != 11 - 2 /* length bytes */) {
- OPENSSL_PUT_ERROR(CIPHER, aead_ssl3_open, CIPHER_R_INVALID_AD_SIZE);
+ OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_INVALID_AD_SIZE);
return 0;
}
if (in_len > INT_MAX) {
/* EVP_CIPHER takes int as input. */
- OPENSSL_PUT_ERROR(CIPHER, aead_ssl3_open, CIPHER_R_TOO_LARGE);
+ OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_TOO_LARGE);
return 0;
}
@@ -270,12 +270,12 @@ static int aead_ssl3_open(const EVP_AEAD_CTX *ctx, uint8_t *out,
if (EVP_CIPHER_CTX_mode(&ssl3_ctx->cipher_ctx) == EVP_CIPH_CBC_MODE) {
unsigned padding_length = out[total - 1];
if (total < padding_length + 1 + mac_len) {
- OPENSSL_PUT_ERROR(CIPHER, aead_ssl3_open, CIPHER_R_BAD_DECRYPT);
+ OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_DECRYPT);
return 0;
}
/* The padding must be minimal. */
if (padding_length + 1 > EVP_CIPHER_CTX_block_size(&ssl3_ctx->cipher_ctx)) {
- OPENSSL_PUT_ERROR(CIPHER, aead_ssl3_open, CIPHER_R_BAD_DECRYPT);
+ OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_DECRYPT);
return 0;
}
data_len = total - padding_length - 1 - mac_len;
@@ -289,7 +289,7 @@ static int aead_ssl3_open(const EVP_AEAD_CTX *ctx, uint8_t *out,
return 0;
}
if (CRYPTO_memcmp(&out[data_len], mac, mac_len) != 0) {
- OPENSSL_PUT_ERROR(CIPHER, aead_ssl3_open, CIPHER_R_BAD_DECRYPT);
+ OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_DECRYPT);
return 0;
}
@@ -340,6 +340,13 @@ static int aead_des_ede3_cbc_sha1_ssl3_init(EVP_AEAD_CTX *ctx,
EVP_sha1());
}
+static int aead_null_sha1_ssl3_init(EVP_AEAD_CTX *ctx, const uint8_t *key,
+ size_t key_len, size_t tag_len,
+ enum evp_aead_direction_t dir) {
+ return aead_ssl3_init(ctx, key, key_len, tag_len, dir, EVP_enc_null(),
+ EVP_sha1());
+}
+
static const EVP_AEAD aead_rc4_md5_ssl3 = {
MD5_DIGEST_LENGTH + 16, /* key len (MD5 + RC4) */
0, /* nonce len */
@@ -405,6 +412,19 @@ static const EVP_AEAD aead_des_ede3_cbc_sha1_ssl3 = {
NULL, /* get_rc4_state */
};
+static const EVP_AEAD aead_null_sha1_ssl3 = {
+ SHA_DIGEST_LENGTH, /* key len */
+ 0, /* nonce len */
+ SHA_DIGEST_LENGTH, /* overhead (SHA1) */
+ SHA_DIGEST_LENGTH, /* max tag length */
+ NULL, /* init */
+ aead_null_sha1_ssl3_init,
+ aead_ssl3_cleanup,
+ aead_ssl3_seal,
+ aead_ssl3_open,
+ NULL, /* get_rc4_state */
+};
+
const EVP_AEAD *EVP_aead_rc4_md5_ssl3(void) { return &aead_rc4_md5_ssl3; }
const EVP_AEAD *EVP_aead_rc4_sha1_ssl3(void) { return &aead_rc4_sha1_ssl3; }
@@ -420,3 +440,5 @@ const EVP_AEAD *EVP_aead_aes_256_cbc_sha1_ssl3(void) {
const EVP_AEAD *EVP_aead_des_ede3_cbc_sha1_ssl3(void) {
return &aead_des_ede3_cbc_sha1_ssl3;
}
+
+const EVP_AEAD *EVP_aead_null_sha1_ssl3(void) { return &aead_null_sha1_ssl3; }
diff --git a/src/crypto/cipher/e_tls.c b/src/crypto/cipher/e_tls.c
index bed02cb..2778881 100644
--- a/src/crypto/cipher/e_tls.c
+++ b/src/crypto/cipher/e_tls.c
@@ -57,12 +57,12 @@ static int aead_tls_init(EVP_AEAD_CTX *ctx, const uint8_t *key, size_t key_len,
char implicit_iv) {
if (tag_len != EVP_AEAD_DEFAULT_TAG_LENGTH &&
tag_len != EVP_MD_size(md)) {
- OPENSSL_PUT_ERROR(CIPHER, aead_tls_init, CIPHER_R_UNSUPPORTED_TAG_SIZE);
+ OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_UNSUPPORTED_TAG_SIZE);
return 0;
}
if (key_len != EVP_AEAD_key_length(ctx->aead)) {
- OPENSSL_PUT_ERROR(CIPHER, aead_tls_init, CIPHER_R_BAD_KEY_LENGTH);
+ OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_KEY_LENGTH);
return 0;
}
@@ -75,7 +75,7 @@ static int aead_tls_init(EVP_AEAD_CTX *ctx, const uint8_t *key, size_t key_len,
AEAD_TLS_CTX *tls_ctx = OPENSSL_malloc(sizeof(AEAD_TLS_CTX));
if (tls_ctx == NULL) {
- OPENSSL_PUT_ERROR(CIPHER, aead_tls_init, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(CIPHER, ERR_R_MALLOC_FAILURE);
return 0;
}
EVP_CIPHER_CTX_init(&tls_ctx->cipher_ctx);
@@ -109,7 +109,7 @@ static int aead_tls_seal(const EVP_AEAD_CTX *ctx, uint8_t *out,
if (!tls_ctx->cipher_ctx.encrypt) {
/* Unlike a normal AEAD, a TLS AEAD may only be used in one direction. */
- OPENSSL_PUT_ERROR(CIPHER, aead_tls_seal, CIPHER_R_INVALID_OPERATION);
+ OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_INVALID_OPERATION);
return 0;
}
@@ -117,22 +117,22 @@ static int aead_tls_seal(const EVP_AEAD_CTX *ctx, uint8_t *out,
if (in_len + EVP_AEAD_max_overhead(ctx->aead) < in_len ||
in_len > INT_MAX) {
/* EVP_CIPHER takes int as input. */
- OPENSSL_PUT_ERROR(CIPHER, aead_tls_seal, CIPHER_R_TOO_LARGE);
+ OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_TOO_LARGE);
return 0;
}
if (max_out_len < in_len + EVP_AEAD_max_overhead(ctx->aead)) {
- OPENSSL_PUT_ERROR(CIPHER, aead_tls_seal, CIPHER_R_BUFFER_TOO_SMALL);
+ OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BUFFER_TOO_SMALL);
return 0;
}
if (nonce_len != EVP_AEAD_nonce_length(ctx->aead)) {
- OPENSSL_PUT_ERROR(CIPHER, aead_tls_seal, CIPHER_R_INVALID_NONCE_SIZE);
+ OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_INVALID_NONCE_SIZE);
return 0;
}
if (ad_len != 13 - 2 /* length bytes */) {
- OPENSSL_PUT_ERROR(CIPHER, aead_tls_seal, CIPHER_R_INVALID_AD_SIZE);
+ OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_INVALID_AD_SIZE);
return 0;
}
@@ -214,36 +214,36 @@ static int aead_tls_open(const EVP_AEAD_CTX *ctx, uint8_t *out,
if (tls_ctx->cipher_ctx.encrypt) {
/* Unlike a normal AEAD, a TLS AEAD may only be used in one direction. */
- OPENSSL_PUT_ERROR(CIPHER, aead_tls_open, CIPHER_R_INVALID_OPERATION);
+ OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_INVALID_OPERATION);
return 0;
}
if (in_len < HMAC_size(&tls_ctx->hmac_ctx)) {
- OPENSSL_PUT_ERROR(CIPHER, aead_tls_open, CIPHER_R_BAD_DECRYPT);
+ OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_DECRYPT);
return 0;
}
if (max_out_len < in_len) {
/* This requires that the caller provide space for the MAC, even though it
* will always be removed on return. */
- OPENSSL_PUT_ERROR(CIPHER, aead_tls_open, CIPHER_R_BUFFER_TOO_SMALL);
+ OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BUFFER_TOO_SMALL);
return 0;
}
if (nonce_len != EVP_AEAD_nonce_length(ctx->aead)) {
- OPENSSL_PUT_ERROR(CIPHER, aead_tls_open, CIPHER_R_INVALID_NONCE_SIZE);
+ OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_INVALID_NONCE_SIZE);
return 0;
}
if (ad_len != 13 - 2 /* length bytes */) {
- OPENSSL_PUT_ERROR(CIPHER, aead_tls_open, CIPHER_R_INVALID_AD_SIZE);
+ OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_INVALID_AD_SIZE);
return 0;
}
if (in_len > INT_MAX) {
/* EVP_CIPHER takes int as input. */
- OPENSSL_PUT_ERROR(CIPHER, aead_tls_open, CIPHER_R_TOO_LARGE);
+ OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_TOO_LARGE);
return 0;
}
@@ -278,7 +278,7 @@ static int aead_tls_open(const EVP_AEAD_CTX *ctx, uint8_t *out,
(unsigned)HMAC_size(&tls_ctx->hmac_ctx));
/* Publicly invalid. This can be rejected in non-constant time. */
if (padding_ok == 0) {
- OPENSSL_PUT_ERROR(CIPHER, aead_tls_open, CIPHER_R_BAD_DECRYPT);
+ OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_DECRYPT);
return 0;
}
} else {
@@ -312,7 +312,7 @@ static int aead_tls_open(const EVP_AEAD_CTX *ctx, uint8_t *out,
if (!EVP_tls_cbc_digest_record(tls_ctx->hmac_ctx.md, mac, &mac_len,
ad_fixed, out, data_plus_mac_len, total,
tls_ctx->mac_key, tls_ctx->mac_key_len)) {
- OPENSSL_PUT_ERROR(CIPHER, aead_tls_open, CIPHER_R_BAD_DECRYPT);
+ OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_DECRYPT);
return 0;
}
assert(mac_len == HMAC_size(&tls_ctx->hmac_ctx));
@@ -349,7 +349,7 @@ static int aead_tls_open(const EVP_AEAD_CTX *ctx, uint8_t *out,
0);
good &= constant_time_eq_int(padding_ok, 1);
if (!good) {
- OPENSSL_PUT_ERROR(CIPHER, aead_tls_open, CIPHER_R_BAD_DECRYPT);
+ OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_DECRYPT);
return 0;
}
@@ -444,6 +444,13 @@ static int aead_rc4_sha1_tls_get_rc4_state(const EVP_AEAD_CTX *ctx,
return 1;
}
+static int aead_null_sha1_tls_init(EVP_AEAD_CTX *ctx, const uint8_t *key,
+ size_t key_len, size_t tag_len,
+ enum evp_aead_direction_t dir) {
+ return aead_tls_init(ctx, key, key_len, tag_len, dir, EVP_enc_null(),
+ EVP_sha1(), 1 /* implicit iv */);
+}
+
static const EVP_AEAD aead_rc4_sha1_tls = {
SHA_DIGEST_LENGTH + 16, /* key len (SHA1 + RC4) */
0, /* nonce len */
@@ -574,6 +581,19 @@ static const EVP_AEAD aead_des_ede3_cbc_sha1_tls_implicit_iv = {
NULL, /* get_rc4_state */
};
+static const EVP_AEAD aead_null_sha1_tls = {
+ SHA_DIGEST_LENGTH, /* key len */
+ 0, /* nonce len */
+ SHA_DIGEST_LENGTH, /* overhead (SHA1) */
+ SHA_DIGEST_LENGTH, /* max tag length */
+ NULL, /* init */
+ aead_null_sha1_tls_init,
+ aead_tls_cleanup,
+ aead_tls_seal,
+ aead_tls_open,
+ NULL, /* get_rc4_state */
+};
+
const EVP_AEAD *EVP_aead_rc4_sha1_tls(void) { return &aead_rc4_sha1_tls; }
const EVP_AEAD *EVP_aead_aes_128_cbc_sha1_tls(void) {
@@ -611,3 +631,5 @@ const EVP_AEAD *EVP_aead_des_ede3_cbc_sha1_tls(void) {
const EVP_AEAD *EVP_aead_des_ede3_cbc_sha1_tls_implicit_iv(void) {
return &aead_des_ede3_cbc_sha1_tls_implicit_iv;
}
+
+const EVP_AEAD *EVP_aead_null_sha1_tls(void) { return &aead_null_sha1_tls; }
diff --git a/src/crypto/cipher/test/aes_128_gcm_tests.txt b/src/crypto/cipher/test/aes_128_gcm_tests.txt
index 5f7ad35..75466fe 100644
--- a/src/crypto/cipher/test/aes_128_gcm_tests.txt
+++ b/src/crypto/cipher/test/aes_128_gcm_tests.txt
@@ -418,3 +418,9 @@ AD: 18e2ed6d500b176e49f7e1b5074c0b7dbfdefdf00a63d9fa2fea8c5e78a1c4ae00f17b234429
CT: 5f3627bd53f8da0bbe6f3c9246d6f96fe9abb91cdecf66ddd42f833d98f4d4634c2e1e1ad4088c84c22191bdb9d99ef227320e455dd112c4a9e9cca95724fcc9ae024ed12bf60a802d0b87b99d9bf22590786567c2962171d2b05bec9754c627608e9eba7bccc70540aa4da72e1e04b26d8f968b10230f707501c0091a8ac118f86e87aae1ac00257aee29c3345bd3839154977acd378fc1b2197f5c1fd8e12262f9c2974fb92dc481eeb51aadd44a8851f61b93a84ba57f2870df0423d289bfdcfe634f9ecb7d7c6110a95b49418a2dd6663377690275c205b3efa79a0a77c92567fb429d8ee437312a39df7516dc238f7b9414938223d7ec24d256d3fb3a5954a7c75dbd79486d49ba6bb38a7ccce0f58700260b71319adf98ab8684e34913abe2d9d97193e2
TAG: e690e89af39ff367f5d40a1b7c7ccd4f
+KEY: 31323334353637383930313233343536
+NONCE: 31323334353637383930313233343536
+IN: 48656c6c6f2c20576f726c64
+AD:
+CT: cec189d0e8419b90fb16d555
+TAG: 32893832a8d609224d77c2e56a922282
diff --git a/src/crypto/cipher/test/cipher_test.txt b/src/crypto/cipher/test/cipher_test.txt
index 93cb8f3..21fffdb 100644
--- a/src/crypto/cipher/test/cipher_test.txt
+++ b/src/crypto/cipher/test/cipher_test.txt
@@ -38,6 +38,22 @@ Plaintext = 37363534333231204E6F77206973207468652074696D6520666F722000000000
Ciphertext = 3FE301C962AC01D02213763C1CBD4CDC799657C064ECF5D41C673812CFDE9675
+# DES EDE CBC tests
+Cipher = DES-EDE-CBC
+Key = 0123456789abcdeff1e0d3c2b5a49786
+IV = fedcba9876543210
+Plaintext = 37363534333231204E6F77206973207468652074696D6520666F722000000000
+Ciphertext = 7948C0DA4FE91CD815DCA96DBC9B60A857EB954F4DEB08EB98722642AE69257B
+
+
+# DES EDE tests
+Cipher = DES-EDE
+Key = 0123456789abcdeff1e0d3c2b5a49786
+IV = fedcba9876543210
+Plaintext = 37363534333231204E6F77206973207468652074696D6520666F722000000000
+Ciphertext = 22E889402E28422F8167AD279D90A566DA75B734E12C671FC2669AECB3E4FE8F
+
+
# AES 128 ECB tests (from FIPS-197 test vectors, encrypt)
Cipher = AES-128-ECB
Key = 000102030405060708090A0B0C0D0E0F
@@ -360,6 +376,13 @@ Ciphertext = 6268c6fa2a80b2d137467f092f657ac04d89be2beaa623d61b5a868c8f03ff95d3d
AAD = 00000000000000000000000000000000101112131415161718191a1b1c1d1e1f
Tag = 3b629ccfbc1119b7319e1dce2cd6fd6d
+Cipher = AES-128-GCM
+Key = 31323334353637383930313233343536
+IV = 31323334353637383930313233343536
+Plaintext = 48656c6c6f2c20576f726c64
+Ciphertext = cec189d0e8419b90fb16d555
+Tag = 32893832a8d609224d77c2e56a922282
+AAD =
# OFB tests from OpenSSL upstream.
@@ -535,3 +558,40 @@ Cipher = AES-192-ECB
Key = 8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B
Plaintext = F69F2445DF4F9B17AD2B417BE66C3710
Ciphertext = 9A4B41BA738D6C72FB16691603C18E0E
+
+# DES ECB tests
+
+Cipher = DES-ECB
+Key = 0000000000000000
+Plaintext = 0000000000000000
+Ciphertext = 8CA64DE9C1B123A7
+
+Cipher = DES-ECB
+Key = FFFFFFFFFFFFFFFF
+Plaintext = FFFFFFFFFFFFFFFF
+Ciphertext = 7359B2163E4EDC58
+
+Cipher = DES-ECB
+Key = 3000000000000000
+Plaintext = 1000000000000001
+Ciphertext = 958E6E627A05557B
+
+Cipher = DES-ECB
+Key = 1111111111111111
+Plaintext = 1111111111111111
+Ciphertext = F40379AB9E0EC533
+
+Cipher = DES-ECB
+Key = 0123456789ABCDEF
+Plaintext = 1111111111111111
+Ciphertext = 17668DFC7292532D
+
+Cipher = DES-ECB
+Key = 1111111111111111
+Plaintext = 0123456789ABCDEF
+Ciphertext = 8A5AE1F81AB8F2DD
+
+Cipher = DES-ECB
+Key = FEDCBA9876543210
+Plaintext = 0123456789ABCDEF
+Ciphertext = ED39D950FA74BCC4
diff --git a/src/crypto/cmac/CMakeLists.txt b/src/crypto/cmac/CMakeLists.txt
index 8ebd80c..bb3abc3 100644
--- a/src/crypto/cmac/CMakeLists.txt
+++ b/src/crypto/cmac/CMakeLists.txt
@@ -1,4 +1,4 @@
-include_directories(. .. ../../include)
+include_directories(../../include)
add_library(
cmac
@@ -12,6 +12,8 @@ add_executable(
cmac_test
cmac_test.cc
+
+ $<TARGET_OBJECTS:test_support>
)
target_link_libraries(cmac_test crypto)
diff --git a/src/crypto/cmac/cmac_test.cc b/src/crypto/cmac/cmac_test.cc
index 0f06860..53f45d1 100644
--- a/src/crypto/cmac/cmac_test.cc
+++ b/src/crypto/cmac/cmac_test.cc
@@ -19,16 +19,13 @@
#include <openssl/cmac.h>
#include "../test/scoped_types.h"
+#include "../test/test_util.h"
-static void dump(const uint8_t *got, const uint8_t *expected, size_t len) {
- ScopedBIO bio(BIO_new_fp(stderr, 0 /* don't close */));
-
- BIO_puts(bio.get(), "\nGot:\n");
- BIO_hexdump(bio.get(), got, len, 2 /* indent */);
- BIO_puts(bio.get(), "Expected:\n");
- BIO_hexdump(bio.get(), expected, len, 2 /* indent */);
- BIO_flush(bio.get());
+static void dump(const uint8_t *got, const uint8_t *want, size_t len) {
+ hexdump(stderr, "got :", got, len);
+ hexdump(stderr, "want:", want, len);
+ fflush(stderr);
}
static int test(const char *name, const uint8_t *key, size_t key_len,
diff --git a/src/crypto/conf/CMakeLists.txt b/src/crypto/conf/CMakeLists.txt
index 8046bb8..0a3c795 100644
--- a/src/crypto/conf/CMakeLists.txt
+++ b/src/crypto/conf/CMakeLists.txt
@@ -1,4 +1,4 @@
-include_directories(. .. ../../include)
+include_directories(../../include)
add_library(
conf
diff --git a/src/crypto/conf/conf.c b/src/crypto/conf/conf.c
index 213efc5..e098a2c 100644
--- a/src/crypto/conf/conf.c
+++ b/src/crypto/conf/conf.c
@@ -111,6 +111,16 @@ CONF *NCONF_new(void *method) {
return conf;
}
+CONF_VALUE *CONF_VALUE_new(void) {
+ CONF_VALUE *v = OPENSSL_malloc(sizeof(CONF_VALUE));
+ if (!v) {
+ OPENSSL_PUT_ERROR(CONF, ERR_R_MALLOC_FAILURE);
+ return NULL;
+ }
+ memset(v, 0, sizeof(CONF_VALUE));
+ return v;
+}
+
static void value_free_contents(CONF_VALUE *value) {
if (value->section) {
OPENSSL_free(value->section);
@@ -137,29 +147,26 @@ void NCONF_free(CONF *conf) {
return;
}
- lh_CONF_VALUE_doall(conf->data, value_free_contents);
+ lh_CONF_VALUE_doall(conf->data, value_free);
lh_CONF_VALUE_free(conf->data);
OPENSSL_free(conf);
}
CONF_VALUE *NCONF_new_section(const CONF *conf, const char *section) {
STACK_OF(CONF_VALUE) *sk = NULL;
- int ok = 0, i;
+ int ok = 0;
CONF_VALUE *v = NULL, *old_value;
sk = sk_CONF_VALUE_new_null();
- v = OPENSSL_malloc(sizeof(CONF_VALUE));
+ v = CONF_VALUE_new();
if (sk == NULL || v == NULL) {
goto err;
}
- i = strlen(section) + 1;
- v->section = OPENSSL_malloc(i);
+ v->section = OPENSSL_strdup(section);
if (v->section == NULL) {
goto err;
}
- memcpy(v->section, section, i);
- v->section[i-1] = 0;
v->name = NULL;
v->value = (char *)sk;
@@ -285,7 +292,7 @@ static int str_copy(CONF *conf, char *section, char **pto, char *from) {
rp = e;
if (q) {
if (r != q) {
- OPENSSL_PUT_ERROR(CONF, str_copy, CONF_R_NO_CLOSE_BRACE);
+ OPENSSL_PUT_ERROR(CONF, CONF_R_NO_CLOSE_BRACE);
goto err;
}
e++;
@@ -304,7 +311,7 @@ static int str_copy(CONF *conf, char *section, char **pto, char *from) {
}
*rp = r;
if (p == NULL) {
- OPENSSL_PUT_ERROR(CONF, str_copy, CONF_R_VARIABLE_HAS_NO_VALUE);
+ OPENSSL_PUT_ERROR(CONF, CONF_R_VARIABLE_HAS_NO_VALUE);
goto err;
}
BUF_MEM_grow_clean(buf, (strlen(p) + buf->length - (e - from)));
@@ -372,11 +379,12 @@ const char *NCONF_get_string(const CONF *conf, const char *section,
return value->value;
}
-int add_string(const CONF *conf, CONF_VALUE *section, CONF_VALUE *value) {
+static int add_string(const CONF *conf, CONF_VALUE *section,
+ CONF_VALUE *value) {
STACK_OF(CONF_VALUE) *section_stack = (STACK_OF(CONF_VALUE)*) section->value;
CONF_VALUE *old_value;
- value->section = section->section;
+ value->section = OPENSSL_strdup(section->section);
if (!sk_CONF_VALUE_push(section_stack, value)) {
return 0;
}
@@ -505,20 +513,19 @@ static int def_load_bio(CONF *conf, BIO *in, long *out_error_line) {
char *start, *psection, *pname;
if ((buff = BUF_MEM_new()) == NULL) {
- OPENSSL_PUT_ERROR(CONF, def_load_bio, ERR_R_BUF_LIB);
+ OPENSSL_PUT_ERROR(CONF, ERR_R_BUF_LIB);
goto err;
}
- section = (char *)OPENSSL_malloc(10);
+ section = OPENSSL_strdup("default");
if (section == NULL) {
- OPENSSL_PUT_ERROR(CONF, def_load_bio, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(CONF, ERR_R_MALLOC_FAILURE);
goto err;
}
- BUF_strlcpy(section, "default", 10);
sv = NCONF_new_section(conf, section);
if (sv == NULL) {
- OPENSSL_PUT_ERROR(CONF, def_load_bio, CONF_R_UNABLE_TO_CREATE_NEW_SECTION);
+ OPENSSL_PUT_ERROR(CONF, CONF_R_UNABLE_TO_CREATE_NEW_SECTION);
goto err;
}
@@ -526,7 +533,7 @@ static int def_load_bio(CONF *conf, BIO *in, long *out_error_line) {
again = 0;
for (;;) {
if (!BUF_MEM_grow(buff, bufnum + CONFBUFSIZE)) {
- OPENSSL_PUT_ERROR(CONF, def_load_bio, ERR_R_BUF_LIB);
+ OPENSSL_PUT_ERROR(CONF, ERR_R_BUF_LIB);
goto err;
}
p = &(buff->data[bufnum]);
@@ -595,7 +602,7 @@ static int def_load_bio(CONF *conf, BIO *in, long *out_error_line) {
ss = p;
goto again;
}
- OPENSSL_PUT_ERROR(CONF, def_load_bio, CONF_R_MISSING_CLOSE_SQUARE_BRACKET);
+ OPENSSL_PUT_ERROR(CONF, CONF_R_MISSING_CLOSE_SQUARE_BRACKET);
goto err;
}
*end = '\0';
@@ -606,7 +613,7 @@ static int def_load_bio(CONF *conf, BIO *in, long *out_error_line) {
sv = NCONF_new_section(conf, section);
}
if (sv == NULL) {
- OPENSSL_PUT_ERROR(CONF, def_load_bio, CONF_R_UNABLE_TO_CREATE_NEW_SECTION);
+ OPENSSL_PUT_ERROR(CONF, CONF_R_UNABLE_TO_CREATE_NEW_SECTION);
goto err;
}
continue;
@@ -623,7 +630,7 @@ static int def_load_bio(CONF *conf, BIO *in, long *out_error_line) {
}
p = eat_ws(conf, end);
if (*p != '=') {
- OPENSSL_PUT_ERROR(CONF, def_load_bio, CONF_R_MISSING_EQUAL_SIGN);
+ OPENSSL_PUT_ERROR(CONF, CONF_R_MISSING_EQUAL_SIGN);
goto err;
}
*end = '\0';
@@ -639,20 +646,17 @@ static int def_load_bio(CONF *conf, BIO *in, long *out_error_line) {
p++;
*p = '\0';
- if (!(v = (CONF_VALUE *)OPENSSL_malloc(sizeof(CONF_VALUE)))) {
- OPENSSL_PUT_ERROR(CONF, def_load_bio, ERR_R_MALLOC_FAILURE);
+ if (!(v = CONF_VALUE_new())) {
goto err;
}
if (psection == NULL) {
psection = section;
}
- v->name = (char *)OPENSSL_malloc(strlen(pname) + 1);
- v->value = NULL;
+ v->name = OPENSSL_strdup(pname);
if (v->name == NULL) {
- OPENSSL_PUT_ERROR(CONF, def_load_bio, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(CONF, ERR_R_MALLOC_FAILURE);
goto err;
}
- BUF_strlcpy(v->name, pname, strlen(pname) + 1);
if (!str_copy(conf, psection, &(v->value), start)) {
goto err;
}
@@ -662,14 +666,14 @@ static int def_load_bio(CONF *conf, BIO *in, long *out_error_line) {
tv = NCONF_new_section(conf, psection);
}
if (tv == NULL) {
- OPENSSL_PUT_ERROR(CONF, def_load_bio, CONF_R_UNABLE_TO_CREATE_NEW_SECTION);
+ OPENSSL_PUT_ERROR(CONF, CONF_R_UNABLE_TO_CREATE_NEW_SECTION);
goto err;
}
} else {
tv = sv;
}
if (add_string(conf, tv, v) == 0) {
- OPENSSL_PUT_ERROR(CONF, def_load_bio, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(CONF, ERR_R_MALLOC_FAILURE);
goto err;
}
v = NULL;
@@ -715,7 +719,7 @@ int NCONF_load(CONF *conf, const char *filename, long *out_error_line) {
int ret;
if (in == NULL) {
- OPENSSL_PUT_ERROR(CONF, NCONF_load, ERR_R_SYS_LIB);
+ OPENSSL_PUT_ERROR(CONF, ERR_R_SYS_LIB);
return 0;
}
@@ -736,7 +740,7 @@ int CONF_parse_list(const char *list, char sep, int remove_whitespace,
const char *lstart, *tmpend, *p;
if (list == NULL) {
- OPENSSL_PUT_ERROR(CONF, CONF_parse_list, CONF_R_LIST_CANNOT_BE_NULL);
+ OPENSSL_PUT_ERROR(CONF, CONF_R_LIST_CANNOT_BE_NULL);
return 0;
}
diff --git a/src/crypto/conf/internal.h b/src/crypto/conf/internal.h
new file mode 100644
index 0000000..03d1a8f
--- /dev/null
+++ b/src/crypto/conf/internal.h
@@ -0,0 +1,31 @@
+/* Copyright (c) 2015, Google Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
+
+#ifndef OPENSSL_HEADER_CRYPTO_CONF_INTERNAL_H
+#define OPENSSL_HEADER_CRYPTO_CONF_INTERNAL_H
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+
+/* CONF_VALUE_new returns a freshly allocated and zeroed |CONF_VALUE|. */
+CONF_VALUE *CONF_VALUE_new(void);
+
+
+#if defined(__cplusplus)
+} /* extern C */
+#endif
+
+#endif /* OPENSSL_HEADER_CRYPTO_CONF_INTERNAL_H */
diff --git a/src/crypto/cpu-arm.c b/src/crypto/cpu-arm.c
index 74e937b..6e037ab 100644
--- a/src/crypto/cpu-arm.c
+++ b/src/crypto/cpu-arm.c
@@ -24,7 +24,7 @@
#include <signal.h>
#endif
-#include "arm_arch.h"
+#include <openssl/arm_arch.h>
/* We can't include <sys/auxv.h> because the Android SDK version against which
@@ -70,12 +70,12 @@ static void sigill_handler(int signal) {
siglongjmp(sigill_jmp, signal);
}
-void CRYPTO_arm_neon_probe();
+void CRYPTO_arm_neon_probe(void);
// probe_for_NEON returns 1 if a NEON instruction runs successfully. Because
// getauxval doesn't exist on Android until Jelly Bean, supporting NEON on
// older devices requires this.
-static int probe_for_NEON() {
+static int probe_for_NEON(void) {
int supported = 0;
sigset_t sigmask;
diff --git a/src/crypto/cpu-intel.c b/src/crypto/cpu-intel.c
index df0e127..924bab0 100644
--- a/src/crypto/cpu-intel.c
+++ b/src/crypto/cpu-intel.c
@@ -68,8 +68,58 @@
#include <stdio.h>
#include <string.h>
-/* OPENSSL_ia32_cpuid is defined in cpu-x86_64-asm.pl. */
-extern uint64_t OPENSSL_ia32_cpuid(uint32_t*);
+#if defined(OPENSSL_WINDOWS)
+#pragma warning(push, 3)
+#include <immintrin.h>
+#include <intrin.h>
+#pragma warning(pop)
+#endif
+
+
+/* OPENSSL_cpuid runs the cpuid instruction. |leaf| is passed in as EAX and ECX
+ * is set to zero. It writes EAX, EBX, ECX, and EDX to |*out_eax| through
+ * |*out_edx|. */
+static void OPENSSL_cpuid(uint32_t *out_eax, uint32_t *out_ebx,
+ uint32_t *out_ecx, uint32_t *out_edx, uint32_t leaf) {
+#if defined(OPENSSL_WINDOWS)
+ int tmp[4];
+ __cpuid(tmp, (int)leaf);
+ *out_eax = (uint32_t)tmp[0];
+ *out_ebx = (uint32_t)tmp[1];
+ *out_ecx = (uint32_t)tmp[2];
+ *out_edx = (uint32_t)tmp[3];
+#elif defined(__pic__) && defined(OPENSSL_32_BIT)
+ /* Inline assembly may not clobber the PIC register. For 32-bit, this is EBX.
+ * See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=47602. */
+ __asm__ volatile (
+ "xor %%ecx, %%ecx\n"
+ "mov %%ebx, %%edi\n"
+ "cpuid\n"
+ "xchg %%edi, %%ebx\n"
+ : "=a"(*out_eax), "=D"(*out_ebx), "=c"(*out_ecx), "=d"(*out_edx)
+ : "a"(leaf)
+ );
+#else
+ __asm__ volatile (
+ "xor %%ecx, %%ecx\n"
+ "cpuid\n"
+ : "=a"(*out_eax), "=b"(*out_ebx), "=c"(*out_ecx), "=d"(*out_edx)
+ : "a"(leaf)
+ );
+#endif
+}
+
+/* OPENSSL_xgetbv returns the value of an Intel Extended Control Register (XCR).
+ * Currently only XCR0 is defined by Intel so |xcr| should always be zero. */
+static uint64_t OPENSSL_xgetbv(uint32_t xcr) {
+#if defined(OPENSSL_WINDOWS)
+ return (uint64_t)_xgetbv(xcr);
+#else
+ uint32_t eax, edx;
+ __asm__ volatile ("xgetbv" : "=a"(eax), "=d"(edx) : "c"(xcr));
+ return (((uint64_t)edx) << 32) | eax;
+#endif
+}
/* handle_cpu_env applies the value from |in| to the CPUID values in |out[0]|
* and |out[1]|. See the comment in |OPENSSL_cpuid_setup| about this. */
@@ -91,18 +141,101 @@ static void handle_cpu_env(uint32_t *out, const char *in) {
}
void OPENSSL_cpuid_setup(void) {
- const char *env1, *env2;
+ /* Determine the vendor and maximum input value. */
+ uint32_t eax, ebx, ecx, edx;
+ OPENSSL_cpuid(&eax, &ebx, &ecx, &edx, 0);
-#if defined(OPENSSL_X86_64)
- OPENSSL_ia32_cpuid(OPENSSL_ia32cap_P);
-#else
- uint64_t vec = OPENSSL_ia32_cpuid(OPENSSL_ia32cap_P);
- /* 1<<10 sets a reserved bit to indicate that the variable
- * was already initialised. */
- OPENSSL_ia32cap_P[0] = ((uint32_t)vec) | (1 << 10);
- OPENSSL_ia32cap_P[1] = vec >> 32;
-#endif
+ uint32_t num_ids = eax;
+
+ int is_intel = ebx == 0x756e6547 /* Genu */ &&
+ edx == 0x49656e69 /* ineI */ &&
+ ecx == 0x6c65746e /* ntel */;
+ int is_amd = ebx == 0x68747541 /* Auth */ &&
+ edx == 0x69746e65 /* enti */ &&
+ ecx == 0x444d4163 /* cAMD */;
+
+ int has_amd_xop = 0;
+ if (is_amd) {
+ /* AMD-specific logic.
+ * See http://developer.amd.com/wordpress/media/2012/10/254811.pdf */
+ OPENSSL_cpuid(&eax, &ebx, &ecx, &edx, 0x80000000);
+ uint32_t num_extended_ids = eax;
+ if (num_extended_ids >= 0x80000001) {
+ OPENSSL_cpuid(&eax, &ebx, &ecx, &edx, 0x80000001);
+ if (ecx & (1 << 11)) {
+ has_amd_xop = 1;
+ }
+ }
+ }
+
+ uint32_t extended_features = 0;
+ if (num_ids >= 7) {
+ OPENSSL_cpuid(&eax, &ebx, &ecx, &edx, 7);
+ extended_features = ebx;
+ }
+ /* Determine the number of cores sharing an L1 data cache to adjust the
+ * hyper-threading bit. */
+ uint32_t cores_per_cache = 0;
+ if (is_amd) {
+ /* AMD CPUs never share an L1 data cache between threads but do set the HTT
+ * bit on multi-core CPUs. */
+ cores_per_cache = 1;
+ } else if (num_ids >= 4) {
+ /* TODO(davidben): The Intel manual says this CPUID leaf enumerates all
+ * caches using ECX and doesn't say which is first. Does this matter? */
+ OPENSSL_cpuid(&eax, &ebx, &ecx, &edx, 4);
+ cores_per_cache = 1 + ((eax >> 14) & 0xfff);
+ }
+
+ OPENSSL_cpuid(&eax, &ebx, &ecx, &edx, 1);
+
+ /* Adjust the hyper-threading bit. */
+ if (edx & (1 << 28)) {
+ uint32_t num_logical_cores = (ebx >> 16) & 0xff;
+ if (cores_per_cache == 1 || num_logical_cores <= 1) {
+ edx &= ~(1 << 28);
+ }
+ }
+
+ /* Reserved bit #20 was historically repurposed to control the in-memory
+ * representation of RC4 state. Always set it to zero. */
+ edx &= ~(1 << 20);
+
+ /* Reserved bit #30 is repurposed to signal an Intel CPU. */
+ if (is_intel) {
+ edx |= (1 << 30);
+ } else {
+ edx &= ~(1 << 30);
+ }
+
+ /* The SDBG bit is repurposed to denote AMD XOP support. */
+ if (has_amd_xop) {
+ ecx |= (1 << 11);
+ } else {
+ ecx &= ~(1 << 11);
+ }
+
+ uint64_t xcr0 = 0;
+ if (ecx & (1 << 27)) {
+ /* XCR0 may only be queried if the OSXSAVE bit is set. */
+ xcr0 = OPENSSL_xgetbv(0);
+ }
+ /* See Intel manual, section 14.3. */
+ if ((xcr0 & 6) != 6) {
+ /* YMM registers cannot be used. */
+ ecx &= ~(1 << 28); /* AVX */
+ ecx &= ~(1 << 12); /* FMA */
+ ecx &= ~(1 << 11); /* AMD XOP */
+ extended_features &= ~(1 << 5); /* AVX2 */
+ }
+
+ OPENSSL_ia32cap_P[0] = edx;
+ OPENSSL_ia32cap_P[1] = ecx;
+ OPENSSL_ia32cap_P[2] = extended_features;
+ OPENSSL_ia32cap_P[3] = 0;
+
+ const char *env1, *env2;
env1 = getenv("OPENSSL_ia32cap");
if (env1 == NULL) {
return;
diff --git a/src/crypto/cpu-x86-asm.pl b/src/crypto/cpu-x86-asm.pl
deleted file mode 100644
index 319c436..0000000
--- a/src/crypto/cpu-x86-asm.pl
+++ /dev/null
@@ -1,334 +0,0 @@
-#!/usr/bin/env perl
-
-$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
-push(@INC, "${dir}perlasm", "perlasm");
-require "x86asm.pl";
-
-&asm_init($ARGV[0],"crypto/cpu-x86-asm");
-
-for (@ARGV) { $sse2=1 if (/-DOPENSSL_IA32_SSE2/); }
-
-&function_begin("OPENSSL_ia32_cpuid");
- &xor ("edx","edx");
- &pushf ();
- &pop ("eax");
- &mov ("ecx","eax");
- &xor ("eax",1<<21);
- &push ("eax");
- &popf ();
- &pushf ();
- &pop ("eax");
- &xor ("ecx","eax");
- &xor ("eax","eax");
- &bt ("ecx",21);
- &jnc (&label("nocpuid"));
- &mov ("esi",&wparam(0));
- &mov (&DWP(8,"esi"),"eax"); # clear 3rd word
- &cpuid ();
- &mov ("edi","eax"); # max value for standard query level
-
- &xor ("eax","eax");
- &cmp ("ebx",0x756e6547); # "Genu"
- &setne (&LB("eax"));
- &mov ("ebp","eax");
- &cmp ("edx",0x49656e69); # "ineI"
- &setne (&LB("eax"));
- &or ("ebp","eax");
- &cmp ("ecx",0x6c65746e); # "ntel"
- &setne (&LB("eax"));
- &or ("ebp","eax"); # 0 indicates Intel CPU
- &jz (&label("intel"));
-
- &cmp ("ebx",0x68747541); # "Auth"
- &setne (&LB("eax"));
- &mov ("esi","eax");
- &cmp ("edx",0x69746E65); # "enti"
- &setne (&LB("eax"));
- &or ("esi","eax");
- &cmp ("ecx",0x444D4163); # "cAMD"
- &setne (&LB("eax"));
- &or ("esi","eax"); # 0 indicates AMD CPU
- &jnz (&label("intel"));
-
- # AMD specific
- &mov ("eax",0x80000000);
- &cpuid ();
- &cmp ("eax",0x80000001);
- &jb (&label("intel"));
- &mov ("esi","eax");
- &mov ("eax",0x80000001);
- &cpuid ();
- &or ("ebp","ecx");
- &and ("ebp",1<<11|1); # isolate XOP bit
- &cmp ("esi",0x80000008);
- &jb (&label("intel"));
-
- &mov ("eax",0x80000008);
- &cpuid ();
- &movz ("esi",&LB("ecx")); # number of cores - 1
- &inc ("esi"); # number of cores
-
- &mov ("eax",1);
- &xor ("ecx","ecx");
- &cpuid ();
- &bt ("edx",28);
- &jnc (&label("generic"));
- &shr ("ebx",16);
- &and ("ebx",0xff);
- &cmp ("ebx","esi");
- &ja (&label("generic"));
- &and ("edx",0xefffffff); # clear hyper-threading bit
- &jmp (&label("generic"));
-
-&set_label("intel");
- &cmp ("edi",7);
- &jb (&label("cacheinfo"));
-
- &mov ("esi",&wparam(0));
- &mov ("eax",7);
- &xor ("ecx","ecx");
- &cpuid ();
- &mov (&DWP(8,"esi"),"ebx");
-
-&set_label("cacheinfo");
- &cmp ("edi",4);
- &mov ("edi",-1);
- &jb (&label("nocacheinfo"));
-
- &mov ("eax",4);
- &mov ("ecx",0); # query L1D
- &cpuid ();
- &mov ("edi","eax");
- &shr ("edi",14);
- &and ("edi",0xfff); # number of cores -1 per L1D
-
-&set_label("nocacheinfo");
- &mov ("eax",1);
- &xor ("ecx","ecx");
- &cpuid ();
- &and ("edx",0xbfefffff); # force reserved bits #20, #30 to 0
- &cmp ("ebp",0);
- &jne (&label("notintel"));
- &or ("edx",1<<30); # set reserved bit#30 on Intel CPUs
-&set_label("notintel");
- &bt ("edx",28); # test hyper-threading bit
- &jnc (&label("generic"));
- &and ("edx",0xefffffff);
- &cmp ("edi",0);
- &je (&label("generic"));
-
- &or ("edx",0x10000000);
- &shr ("ebx",16);
- &cmp (&LB("ebx"),1);
- &ja (&label("generic"));
- &and ("edx",0xefffffff); # clear hyper-threading bit if not
-
-&set_label("generic");
- &and ("ebp",1<<11); # isolate AMD XOP flag
- &and ("ecx",0xfffff7ff); # force 11th bit to 0
- &mov ("esi","edx");
- &or ("ebp","ecx"); # merge AMD XOP flag
-
- &bt ("ecx",27); # check OSXSAVE bit
- &jnc (&label("clear_avx"));
- &xor ("ecx","ecx");
- &data_byte(0x0f,0x01,0xd0); # xgetbv
- &and ("eax",6);
- &cmp ("eax",6);
- &je (&label("done"));
- &cmp ("eax",2);
- &je (&label("clear_avx"));
-&set_label("clear_xmm");
- &and ("ebp",0xfdfffffd); # clear AESNI and PCLMULQDQ bits
- &and ("esi",0xfeffffff); # clear FXSR
-&set_label("clear_avx");
- &and ("ebp",0xefffe7ff); # clear AVX, FMA and AMD XOP bits
- &mov ("edi",&wparam(0));
- &and (&DWP(8,"edi"),0xffffffdf); # clear AVX2
-&set_label("done");
- &mov ("eax","esi");
- &mov ("edx","ebp");
-&set_label("nocpuid");
-&function_end("OPENSSL_ia32_cpuid");
-
-&external_label("OPENSSL_ia32cap_P");
-
-&function_begin_B("OPENSSL_rdtsc","EXTRN\t_OPENSSL_ia32cap_P:DWORD");
- &xor ("eax","eax");
- &xor ("edx","edx");
- &picmeup("ecx","OPENSSL_ia32cap_P");
- &bt (&DWP(0,"ecx"),4);
- &jnc (&label("notsc"));
- &rdtsc ();
-&set_label("notsc");
- &ret ();
-&function_end_B("OPENSSL_rdtsc");
-
-# This works in Ring 0 only [read DJGPP+MS-DOS+privileged DPMI host],
-# but it's safe to call it on any [supported] 32-bit platform...
-# Just check for [non-]zero return value...
-&function_begin_B("OPENSSL_instrument_halt","EXTRN\t_OPENSSL_ia32cap_P:DWORD");
- &picmeup("ecx","OPENSSL_ia32cap_P");
- &bt (&DWP(0,"ecx"),4);
- &jnc (&label("nohalt")); # no TSC
-
- &data_word(0x9058900e); # push %cs; pop %eax
- &and ("eax",3);
- &jnz (&label("nohalt")); # not enough privileges
-
- &pushf ();
- &pop ("eax");
- &bt ("eax",9);
- &jnc (&label("nohalt")); # interrupts are disabled
-
- &rdtsc ();
- &push ("edx");
- &push ("eax");
- &halt ();
- &rdtsc ();
-
- &sub ("eax",&DWP(0,"esp"));
- &sbb ("edx",&DWP(4,"esp"));
- &add ("esp",8);
- &ret ();
-
-&set_label("nohalt");
- &xor ("eax","eax");
- &xor ("edx","edx");
- &ret ();
-&function_end_B("OPENSSL_instrument_halt");
-
-# Essentially there is only one use for this function. Under DJGPP:
-#
-# #include <go32.h>
-# ...
-# i=OPENSSL_far_spin(_dos_ds,0x46c);
-# ...
-# to obtain the number of spins till closest timer interrupt.
-
-&function_begin_B("OPENSSL_far_spin");
- &pushf ();
- &pop ("eax");
- &bt ("eax",9);
- &jnc (&label("nospin")); # interrupts are disabled
-
- &mov ("eax",&DWP(4,"esp"));
- &mov ("ecx",&DWP(8,"esp"));
- &data_word (0x90d88e1e); # push %ds, mov %eax,%ds
- &xor ("eax","eax");
- &mov ("edx",&DWP(0,"ecx"));
- &jmp (&label("spin"));
-
- &align (16);
-&set_label("spin");
- &inc ("eax");
- &cmp ("edx",&DWP(0,"ecx"));
- &je (&label("spin"));
-
- &data_word (0x1f909090); # pop %ds
- &ret ();
-
-&set_label("nospin");
- &xor ("eax","eax");
- &xor ("edx","edx");
- &ret ();
-&function_end_B("OPENSSL_far_spin");
-
-&function_begin_B("OPENSSL_wipe_cpu","EXTRN\t_OPENSSL_ia32cap_P:DWORD");
- &xor ("eax","eax");
- &xor ("edx","edx");
- &picmeup("ecx","OPENSSL_ia32cap_P");
- &mov ("ecx",&DWP(0,"ecx"));
- &bt (&DWP(0,"ecx"),1);
- &jnc (&label("no_x87"));
- if ($sse2) {
- &and ("ecx",1<<26|1<<24); # check SSE2 and FXSR bits
- &cmp ("ecx",1<<26|1<<24);
- &jne (&label("no_sse2"));
- &pxor ("xmm0","xmm0");
- &pxor ("xmm1","xmm1");
- &pxor ("xmm2","xmm2");
- &pxor ("xmm3","xmm3");
- &pxor ("xmm4","xmm4");
- &pxor ("xmm5","xmm5");
- &pxor ("xmm6","xmm6");
- &pxor ("xmm7","xmm7");
- &set_label("no_sse2");
- }
- # just a bunch of fldz to zap the fp/mm bank followed by finit...
- &data_word(0xeed9eed9,0xeed9eed9,0xeed9eed9,0xeed9eed9,0x90e3db9b);
-&set_label("no_x87");
- &lea ("eax",&DWP(4,"esp"));
- &ret ();
-&function_end_B("OPENSSL_wipe_cpu");
-
-&function_begin_B("OPENSSL_atomic_add");
- &mov ("edx",&DWP(4,"esp")); # fetch the pointer, 1st arg
- &mov ("ecx",&DWP(8,"esp")); # fetch the increment, 2nd arg
- &push ("ebx");
- &nop ();
- &mov ("eax",&DWP(0,"edx"));
-&set_label("spin");
- &lea ("ebx",&DWP(0,"eax","ecx"));
- &nop ();
- &data_word(0x1ab10ff0); # lock; cmpxchg %ebx,(%edx) # %eax is envolved and is always reloaded
- &jne (&label("spin"));
- &mov ("eax","ebx"); # OpenSSL expects the new value
- &pop ("ebx");
- &ret ();
-&function_end_B("OPENSSL_atomic_add");
-
-# This function can become handy under Win32 in situations when
-# we don't know which calling convention, __stdcall or __cdecl(*),
-# indirect callee is using. In C it can be deployed as
-#
-#ifdef OPENSSL_CPUID_OBJ
-# type OPENSSL_indirect_call(void *f,...);
-# ...
-# OPENSSL_indirect_call(func,[up to $max arguments]);
-#endif
-#
-# (*) it's designed to work even for __fastcall if number of
-# arguments is 1 or 2!
-&function_begin_B("OPENSSL_indirect_call");
- {
- my ($max,$i)=(7,); # $max has to be chosen as 4*n-1
- # in order to preserve eventual
- # stack alignment
- &push ("ebp");
- &mov ("ebp","esp");
- &sub ("esp",$max*4);
- &mov ("ecx",&DWP(12,"ebp"));
- &mov (&DWP(0,"esp"),"ecx");
- &mov ("edx",&DWP(16,"ebp"));
- &mov (&DWP(4,"esp"),"edx");
- for($i=2;$i<$max;$i++)
- {
- # Some copies will be redundant/bogus...
- &mov ("eax",&DWP(12+$i*4,"ebp"));
- &mov (&DWP(0+$i*4,"esp"),"eax");
- }
- &call_ptr (&DWP(8,"ebp"));# make the call...
- &mov ("esp","ebp"); # ... and just restore the stack pointer
- # without paying attention to what we called,
- # (__cdecl *func) or (__stdcall *one).
- &pop ("ebp");
- &ret ();
- }
-&function_end_B("OPENSSL_indirect_call");
-
-&function_begin_B("OPENSSL_ia32_rdrand");
- &mov ("ecx",8);
-&set_label("loop");
- &rdrand ("eax");
- &jc (&label("break"));
- &loop (&label("loop"));
-&set_label("break");
- &cmp ("eax",0);
- &cmove ("eax","ecx");
- &ret ();
-&function_end_B("OPENSSL_ia32_rdrand");
-
-&hidden("OPENSSL_ia32cap_P");
-
-&asm_finish();
diff --git a/src/crypto/cpu-x86_64-asm.pl b/src/crypto/cpu-x86_64-asm.pl
deleted file mode 100644
index 89d7a6c..0000000
--- a/src/crypto/cpu-x86_64-asm.pl
+++ /dev/null
@@ -1,163 +0,0 @@
-#!/usr/bin/env perl
-
-$flavour = shift;
-$output = shift;
-if ($flavour =~ /\./) { $output = $flavour; undef $flavour; }
-
-$win64=0; $win64=1 if ($flavour =~ /[nm]asm|mingw64/ || $output =~ /\.asm$/);
-
-$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
-( $xlate="${dir}x86_64-xlate.pl" and -f $xlate ) or
-( $xlate="${dir}perlasm/x86_64-xlate.pl" and -f $xlate) or
-die "can't locate x86_64-xlate.pl";
-
-open OUT,"| \"$^X\" $xlate $flavour $output";
-*STDOUT=*OUT;
-
-($arg1,$arg2,$arg3,$arg4)=$win64?("%rcx","%rdx","%r8", "%r9") : # Win64 order
- ("%rdi","%rsi","%rdx","%rcx"); # Unix order
-
-print<<___;
-.text
-
-.globl OPENSSL_ia32_cpuid
-.type OPENSSL_ia32_cpuid,\@function,1
-.align 16
-OPENSSL_ia32_cpuid:
- # On Windows, $arg1 is rcx, but that will be clobbered. So make Windows
- # use the same register as Unix.
- mov $arg1,%rdi
- mov %rbx,%r8 # save %rbx
-
- xor %eax,%eax
- mov %eax,8(%rdi) # clear 3rd word
- cpuid
- mov %eax,%r11d # max value for standard query level
-
- xor %eax,%eax
- cmp \$0x756e6547,%ebx # "Genu"
- setne %al
- mov %eax,%r9d
- cmp \$0x49656e69,%edx # "ineI"
- setne %al
- or %eax,%r9d
- cmp \$0x6c65746e,%ecx # "ntel"
- setne %al
- or %eax,%r9d # 0 indicates Intel CPU
- jz .Lintel
-
- cmp \$0x68747541,%ebx # "Auth"
- setne %al
- mov %eax,%r10d
- cmp \$0x69746E65,%edx # "enti"
- setne %al
- or %eax,%r10d
- cmp \$0x444D4163,%ecx # "cAMD"
- setne %al
- or %eax,%r10d # 0 indicates AMD CPU
- jnz .Lintel
-
- # AMD specific
- # See http://developer.amd.com/wordpress/media/2012/10/254811.pdf (1)
-
- mov \$0x80000000,%eax
- cpuid
- # Returns "The largest CPUID extended function input value supported by
- # the processor implementation." in EAX.
- cmp \$0x80000001,%eax
- jb .Lintel
- mov %eax,%r10d
- mov \$0x80000001,%eax
- cpuid
- # Returns feature bits in ECX. See page 20 of [1].
- # TODO(fork): I think this should be a MOV.
- or %ecx,%r9d
- and \$0x00000801,%r9d # isolate AMD XOP bit, 1<<11
-
- cmp \$0x80000008,%r10d
- jb .Lintel
-
- mov \$0x80000008,%eax
- cpuid
- # Returns APIC ID and number of cores in ECX. See page 27 of [1].
- movzb %cl,%r10 # number of cores - 1
- inc %r10 # number of cores
-
- mov \$1,%eax
- cpuid
- # See page 13 of [1].
- bt \$28,%edx # test hyper-threading bit
- jnc .Lgeneric
- shr \$16,%ebx # number of logical processors
- cmp %r10b,%bl
- ja .Lgeneric
- and \$0xefffffff,%edx # Clear hyper-threading bit.
- jmp .Lgeneric
-
-.Lintel:
- cmp \$4,%r11d
- mov \$-1,%r10d
- jb .Lnocacheinfo
-
- mov \$4,%eax
- mov \$0,%ecx # query L1D
- cpuid
- mov %eax,%r10d
- shr \$14,%r10d
- and \$0xfff,%r10d # number of cores -1 per L1D
-
- cmp \$7,%r11d
- jb .Lnocacheinfo
-
- mov \$7,%eax
- xor %ecx,%ecx
- cpuid
- mov %ebx,8(%rdi)
-
-.Lnocacheinfo:
- mov \$1,%eax
- cpuid
- # Gets feature information. See table 3-21 in the Intel manual.
- and \$0xbfefffff,%edx # force reserved bits to 0
- cmp \$0,%r9d
- jne .Lnotintel
- or \$0x40000000,%edx # set reserved bit#30 on Intel CPUs
-.Lnotintel:
- bt \$28,%edx # test hyper-threading bit
- jnc .Lgeneric
- and \$0xefffffff,%edx # ~(1<<28) - clear hyper-threading.
- cmp \$0,%r10d
- je .Lgeneric
-
- or \$0x10000000,%edx # 1<<28
- shr \$16,%ebx
- cmp \$1,%bl # see if cache is shared
- ja .Lgeneric
- and \$0xefffffff,%edx # ~(1<<28)
-.Lgeneric:
- and \$0x00000800,%r9d # isolate AMD XOP flag
- and \$0xfffff7ff,%ecx
- or %ecx,%r9d # merge AMD XOP flag
-
- mov %edx,%r10d # %r9d:%r10d is copy of %ecx:%edx
- bt \$27,%r9d # check OSXSAVE bit
- jnc .Lclear_avx
- xor %ecx,%ecx # XCR0
- .byte 0x0f,0x01,0xd0 # xgetbv
- and \$6,%eax # isolate XMM and YMM state support
- cmp \$6,%eax
- je .Ldone
-.Lclear_avx:
- mov \$0xefffe7ff,%eax # ~(1<<28|1<<12|1<<11)
- and %eax,%r9d # clear AVX, FMA and AMD XOP bits
- andl \$0xffffffdf,8(%rdi) # cleax AVX2, ~(1<<5)
-.Ldone:
- movl %r9d,4(%rdi)
- movl %r10d,0(%rdi)
- mov %r8,%rbx # restore %rbx
- ret
-.size OPENSSL_ia32_cpuid,.-OPENSSL_ia32_cpuid
-
-___
-
-close STDOUT; # flush
diff --git a/src/crypto/crypto.c b/src/crypto/crypto.c
index d9bb07e..34d04b4 100644
--- a/src/crypto/crypto.c
+++ b/src/crypto/crypto.c
@@ -55,7 +55,7 @@
uint32_t OPENSSL_ia32cap_P[4] = {0};
#elif defined(OPENSSL_ARM) || defined(OPENSSL_AARCH64)
-#include "arm_arch.h"
+#include <openssl/arm_arch.h>
#if defined(__ARM_NEON__)
uint32_t OPENSSL_armcap_P = ARMV7_NEON | ARMV7_NEON_FUNCTIONAL;
diff --git a/src/crypto/des/CMakeLists.txt b/src/crypto/des/CMakeLists.txt
index 7d49ff3..f61fa14 100644
--- a/src/crypto/des/CMakeLists.txt
+++ b/src/crypto/des/CMakeLists.txt
@@ -1,4 +1,4 @@
-include_directories(. .. ../../include)
+include_directories(../../include)
add_library(
des
diff --git a/src/crypto/des/des.c b/src/crypto/des/des.c
index 9cd75f5..a5669a6 100644
--- a/src/crypto/des/des.c
+++ b/src/crypto/des/des.c
@@ -298,10 +298,8 @@ void DES_set_key(const DES_cblock *key, DES_key_schedule *schedule) {
0, 1, 1, 1, 1, 1, 1, 0};
uint32_t c, d, t, s, t2;
const uint8_t *in;
- uint32_t *k;
int i;
- k = &schedule->ks->deslong[0];
in = key->bytes;
c2l(in, c);
@@ -344,10 +342,10 @@ void DES_set_key(const DES_cblock *key, DES_key_schedule *schedule) {
/* table contained 0213 4657 */
t2 = ((t << 16L) | (s & 0x0000ffffL)) & 0xffffffffL;
- *(k++) = ROTATE(t2, 30) & 0xffffffffL;
+ schedule->subkeys[i][0] = ROTATE(t2, 30) & 0xffffffffL;
t2 = ((s >> 16L) | (t & 0xffff0000L));
- *(k++) = ROTATE(t2, 26) & 0xffffffffL;
+ schedule->subkeys[i][1] = ROTATE(t2, 26) & 0xffffffffL;
}
}
@@ -382,7 +380,6 @@ void DES_set_odd_parity(DES_cblock *key) {
static void DES_encrypt1(uint32_t *data, const DES_key_schedule *ks, int enc) {
uint32_t l, r, t, u;
- const uint32_t *s;
r = data[0];
l = data[1];
@@ -398,43 +395,42 @@ static void DES_encrypt1(uint32_t *data, const DES_key_schedule *ks, int enc) {
r = ROTATE(r, 29) & 0xffffffffL;
l = ROTATE(l, 29) & 0xffffffffL;
- s = ks->ks->deslong;
/* I don't know if it is worth the effort of loop unrolling the
* inner loop */
if (enc) {
- D_ENCRYPT(l, r, 0); /* 1 */
- D_ENCRYPT(r, l, 2); /* 2 */
- D_ENCRYPT(l, r, 4); /* 3 */
- D_ENCRYPT(r, l, 6); /* 4 */
- D_ENCRYPT(l, r, 8); /* 5 */
- D_ENCRYPT(r, l, 10); /* 6 */
- D_ENCRYPT(l, r, 12); /* 7 */
- D_ENCRYPT(r, l, 14); /* 8 */
- D_ENCRYPT(l, r, 16); /* 9 */
- D_ENCRYPT(r, l, 18); /* 10 */
- D_ENCRYPT(l, r, 20); /* 11 */
- D_ENCRYPT(r, l, 22); /* 12 */
- D_ENCRYPT(l, r, 24); /* 13 */
- D_ENCRYPT(r, l, 26); /* 14 */
- D_ENCRYPT(l, r, 28); /* 15 */
- D_ENCRYPT(r, l, 30); /* 16 */
+ D_ENCRYPT(ks, l, r, 0);
+ D_ENCRYPT(ks, r, l, 1);
+ D_ENCRYPT(ks, l, r, 2);
+ D_ENCRYPT(ks, r, l, 3);
+ D_ENCRYPT(ks, l, r, 4);
+ D_ENCRYPT(ks, r, l, 5);
+ D_ENCRYPT(ks, l, r, 6);
+ D_ENCRYPT(ks, r, l, 7);
+ D_ENCRYPT(ks, l, r, 8);
+ D_ENCRYPT(ks, r, l, 9);
+ D_ENCRYPT(ks, l, r, 10);
+ D_ENCRYPT(ks, r, l, 11);
+ D_ENCRYPT(ks, l, r, 12);
+ D_ENCRYPT(ks, r, l, 13);
+ D_ENCRYPT(ks, l, r, 14);
+ D_ENCRYPT(ks, r, l, 15);
} else {
- D_ENCRYPT(l, r, 30); /* 16 */
- D_ENCRYPT(r, l, 28); /* 15 */
- D_ENCRYPT(l, r, 26); /* 14 */
- D_ENCRYPT(r, l, 24); /* 13 */
- D_ENCRYPT(l, r, 22); /* 12 */
- D_ENCRYPT(r, l, 20); /* 11 */
- D_ENCRYPT(l, r, 18); /* 10 */
- D_ENCRYPT(r, l, 16); /* 9 */
- D_ENCRYPT(l, r, 14); /* 8 */
- D_ENCRYPT(r, l, 12); /* 7 */
- D_ENCRYPT(l, r, 10); /* 6 */
- D_ENCRYPT(r, l, 8); /* 5 */
- D_ENCRYPT(l, r, 6); /* 4 */
- D_ENCRYPT(r, l, 4); /* 3 */
- D_ENCRYPT(l, r, 2); /* 2 */
- D_ENCRYPT(r, l, 0); /* 1 */
+ D_ENCRYPT(ks, l, r, 15);
+ D_ENCRYPT(ks, r, l, 14);
+ D_ENCRYPT(ks, l, r, 13);
+ D_ENCRYPT(ks, r, l, 12);
+ D_ENCRYPT(ks, l, r, 11);
+ D_ENCRYPT(ks, r, l, 10);
+ D_ENCRYPT(ks, l, r, 9);
+ D_ENCRYPT(ks, r, l, 8);
+ D_ENCRYPT(ks, l, r, 7);
+ D_ENCRYPT(ks, r, l, 6);
+ D_ENCRYPT(ks, l, r, 5);
+ D_ENCRYPT(ks, r, l, 4);
+ D_ENCRYPT(ks, l, r, 3);
+ D_ENCRYPT(ks, r, l, 2);
+ D_ENCRYPT(ks, l, r, 1);
+ D_ENCRYPT(ks, r, l, 0);
}
/* rotate and clear the top bits on machines with 8byte longs */
@@ -448,7 +444,6 @@ static void DES_encrypt1(uint32_t *data, const DES_key_schedule *ks, int enc) {
static void DES_encrypt2(uint32_t *data, const DES_key_schedule *ks, int enc) {
uint32_t l, r, t, u;
- const uint32_t *s;
r = data[0];
l = data[1];
@@ -462,52 +457,51 @@ static void DES_encrypt2(uint32_t *data, const DES_key_schedule *ks, int enc) {
r = ROTATE(r, 29) & 0xffffffffL;
l = ROTATE(l, 29) & 0xffffffffL;
- s = ks->ks->deslong;
/* I don't know if it is worth the effort of loop unrolling the
* inner loop */
if (enc) {
- D_ENCRYPT(l, r, 0); /* 1 */
- D_ENCRYPT(r, l, 2); /* 2 */
- D_ENCRYPT(l, r, 4); /* 3 */
- D_ENCRYPT(r, l, 6); /* 4 */
- D_ENCRYPT(l, r, 8); /* 5 */
- D_ENCRYPT(r, l, 10); /* 6 */
- D_ENCRYPT(l, r, 12); /* 7 */
- D_ENCRYPT(r, l, 14); /* 8 */
- D_ENCRYPT(l, r, 16); /* 9 */
- D_ENCRYPT(r, l, 18); /* 10 */
- D_ENCRYPT(l, r, 20); /* 11 */
- D_ENCRYPT(r, l, 22); /* 12 */
- D_ENCRYPT(l, r, 24); /* 13 */
- D_ENCRYPT(r, l, 26); /* 14 */
- D_ENCRYPT(l, r, 28); /* 15 */
- D_ENCRYPT(r, l, 30); /* 16 */
+ D_ENCRYPT(ks, l, r, 0);
+ D_ENCRYPT(ks, r, l, 1);
+ D_ENCRYPT(ks, l, r, 2);
+ D_ENCRYPT(ks, r, l, 3);
+ D_ENCRYPT(ks, l, r, 4);
+ D_ENCRYPT(ks, r, l, 5);
+ D_ENCRYPT(ks, l, r, 6);
+ D_ENCRYPT(ks, r, l, 7);
+ D_ENCRYPT(ks, l, r, 8);
+ D_ENCRYPT(ks, r, l, 9);
+ D_ENCRYPT(ks, l, r, 10);
+ D_ENCRYPT(ks, r, l, 11);
+ D_ENCRYPT(ks, l, r, 12);
+ D_ENCRYPT(ks, r, l, 13);
+ D_ENCRYPT(ks, l, r, 14);
+ D_ENCRYPT(ks, r, l, 15);
} else {
- D_ENCRYPT(l, r, 30); /* 16 */
- D_ENCRYPT(r, l, 28); /* 15 */
- D_ENCRYPT(l, r, 26); /* 14 */
- D_ENCRYPT(r, l, 24); /* 13 */
- D_ENCRYPT(l, r, 22); /* 12 */
- D_ENCRYPT(r, l, 20); /* 11 */
- D_ENCRYPT(l, r, 18); /* 10 */
- D_ENCRYPT(r, l, 16); /* 9 */
- D_ENCRYPT(l, r, 14); /* 8 */
- D_ENCRYPT(r, l, 12); /* 7 */
- D_ENCRYPT(l, r, 10); /* 6 */
- D_ENCRYPT(r, l, 8); /* 5 */
- D_ENCRYPT(l, r, 6); /* 4 */
- D_ENCRYPT(r, l, 4); /* 3 */
- D_ENCRYPT(l, r, 2); /* 2 */
- D_ENCRYPT(r, l, 0); /* 1 */
+ D_ENCRYPT(ks, l, r, 15);
+ D_ENCRYPT(ks, r, l, 14);
+ D_ENCRYPT(ks, l, r, 13);
+ D_ENCRYPT(ks, r, l, 12);
+ D_ENCRYPT(ks, l, r, 11);
+ D_ENCRYPT(ks, r, l, 10);
+ D_ENCRYPT(ks, l, r, 9);
+ D_ENCRYPT(ks, r, l, 8);
+ D_ENCRYPT(ks, l, r, 7);
+ D_ENCRYPT(ks, r, l, 6);
+ D_ENCRYPT(ks, l, r, 5);
+ D_ENCRYPT(ks, r, l, 4);
+ D_ENCRYPT(ks, l, r, 3);
+ D_ENCRYPT(ks, r, l, 2);
+ D_ENCRYPT(ks, l, r, 1);
+ D_ENCRYPT(ks, r, l, 0);
}
/* rotate and clear the top bits on machines with 8byte longs */
data[0] = ROTATE(l, 3) & 0xffffffffL;
data[1] = ROTATE(r, 3) & 0xffffffffL;
}
-static void DES_encrypt3(uint32_t *data, const DES_key_schedule *ks1,
- const DES_key_schedule *ks2,
- const DES_key_schedule *ks3) {
+/* DES_encrypt3 is not static because it's used in decrepit. */
+void DES_encrypt3(uint32_t *data, const DES_key_schedule *ks1,
+ const DES_key_schedule *ks2, const DES_key_schedule *ks3) {
uint32_t l, r;
l = data[0];
@@ -525,9 +519,9 @@ static void DES_encrypt3(uint32_t *data, const DES_key_schedule *ks1,
data[1] = r;
}
-static void DES_decrypt3(uint32_t *data, const DES_key_schedule *ks1,
- const DES_key_schedule *ks2,
- const DES_key_schedule *ks3) {
+/* DES_decrypt3 is not static because it's used in decrepit. */
+void DES_decrypt3(uint32_t *data, const DES_key_schedule *ks1,
+ const DES_key_schedule *ks2, const DES_key_schedule *ks3) {
uint32_t l, r;
l = data[0];
@@ -770,3 +764,10 @@ void DES_ede2_cbc_encrypt(const uint8_t *in, uint8_t *out, size_t len,
int enc) {
DES_ede3_cbc_encrypt(in, out, len, ks1, ks2, ks1, ivec, enc);
}
+
+
+/* Deprecated functions. */
+
+void DES_set_key_unchecked(const DES_cblock *key, DES_key_schedule *schedule) {
+ DES_set_key(key, schedule);
+}
diff --git a/src/crypto/des/internal.h b/src/crypto/des/internal.h
index d3a5cec..91559ff 100644
--- a/src/crypto/des/internal.h
+++ b/src/crypto/des/internal.h
@@ -183,13 +183,13 @@ how to use xors :-) I got it to its final state.
PERM_OP(l, r, tt, 4, 0x0f0f0f0fL); \
}
-#define LOAD_DATA(R, S, u, t, E0, E1) \
- u = R ^ s[S]; \
- t = R ^ s[S + 1]
+#define LOAD_DATA(ks, R, S, u, t, E0, E1) \
+ u = R ^ ks->subkeys[S][0]; \
+ t = R ^ ks->subkeys[S][1]
-#define D_ENCRYPT(LL, R, S) \
+#define D_ENCRYPT(ks, LL, R, S) \
{ \
- LOAD_DATA(R, S, u, t, E0, E1); \
+ LOAD_DATA(ks, R, S, u, t, E0, E1); \
t = ROTATE(t, 4); \
LL ^= \
DES_SPtrans[0][(u >> 2L) & 0x3f] ^ DES_SPtrans[2][(u >> 10L) & 0x3f] ^ \
diff --git a/src/crypto/dh/CMakeLists.txt b/src/crypto/dh/CMakeLists.txt
index d0c1da7..1a46512 100644
--- a/src/crypto/dh/CMakeLists.txt
+++ b/src/crypto/dh/CMakeLists.txt
@@ -1,4 +1,4 @@
-include_directories(. .. ../../include)
+include_directories(../../include)
add_library(
dh
diff --git a/src/crypto/dh/dh.c b/src/crypto/dh/dh.c
index 96b85f3..d25f358 100644
--- a/src/crypto/dh/dh.c
+++ b/src/crypto/dh/dh.c
@@ -78,7 +78,7 @@ DH *DH_new(void) { return DH_new_method(NULL); }
DH *DH_new_method(const ENGINE *engine) {
DH *dh = (DH *)OPENSSL_malloc(sizeof(DH));
if (dh == NULL) {
- OPENSSL_PUT_ERROR(DH, DH_new_method, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(DH, ERR_R_MALLOC_FAILURE);
return NULL;
}
diff --git a/src/crypto/dh/dh_impl.c b/src/crypto/dh/dh_impl.c
index f269412..6cf0abb 100644
--- a/src/crypto/dh/dh_impl.c
+++ b/src/crypto/dh/dh_impl.c
@@ -117,7 +117,7 @@ static int generate_parameters(DH *ret, int prime_bits, int generator, BN_GENCB
}
if (generator <= 1) {
- OPENSSL_PUT_ERROR(DH, generate_parameters, DH_R_BAD_GENERATOR);
+ OPENSSL_PUT_ERROR(DH, DH_R_BAD_GENERATOR);
goto err;
}
if (generator == DH_GENERATOR_2) {
@@ -165,7 +165,7 @@ static int generate_parameters(DH *ret, int prime_bits, int generator, BN_GENCB
err:
if (!ok) {
- OPENSSL_PUT_ERROR(DH, generate_parameters, ERR_R_BN_LIB);
+ OPENSSL_PUT_ERROR(DH, ERR_R_BN_LIB);
}
if (ctx != NULL) {
@@ -242,7 +242,7 @@ static int generate_key(DH *dh) {
err:
if (ok != 1) {
- OPENSSL_PUT_ERROR(DH, generate_key, ERR_R_BN_LIB);
+ OPENSSL_PUT_ERROR(DH, ERR_R_BN_LIB);
}
if (dh->pub_key == NULL) {
@@ -264,7 +264,7 @@ static int compute_key(DH *dh, unsigned char *out, const BIGNUM *pub_key) {
BIGNUM local_priv;
if (BN_num_bits(dh->p) > OPENSSL_DH_MAX_MODULUS_BITS) {
- OPENSSL_PUT_ERROR(DH, compute_key, DH_R_MODULUS_TOO_LARGE);
+ OPENSSL_PUT_ERROR(DH, DH_R_MODULUS_TOO_LARGE);
goto err;
}
@@ -279,7 +279,7 @@ static int compute_key(DH *dh, unsigned char *out, const BIGNUM *pub_key) {
}
if (dh->priv_key == NULL) {
- OPENSSL_PUT_ERROR(DH, compute_key, DH_R_NO_PRIVATE_VALUE);
+ OPENSSL_PUT_ERROR(DH, DH_R_NO_PRIVATE_VALUE);
goto err;
}
@@ -290,14 +290,14 @@ static int compute_key(DH *dh, unsigned char *out, const BIGNUM *pub_key) {
}
if (!DH_check_pub_key(dh, pub_key, &check_result) || check_result) {
- OPENSSL_PUT_ERROR(DH, compute_key, DH_R_INVALID_PUBKEY);
+ OPENSSL_PUT_ERROR(DH, DH_R_INVALID_PUBKEY);
goto err;
}
BN_with_flags(&local_priv, dh->priv_key, BN_FLG_CONSTTIME);
if (!BN_mod_exp_mont(shared_key, pub_key, &local_priv, dh->p, ctx,
mont)) {
- OPENSSL_PUT_ERROR(DH, compute_key, ERR_R_BN_LIB);
+ OPENSSL_PUT_ERROR(DH, ERR_R_BN_LIB);
goto err;
}
diff --git a/src/crypto/digest/CMakeLists.txt b/src/crypto/digest/CMakeLists.txt
index 816d116..856e45a 100644
--- a/src/crypto/digest/CMakeLists.txt
+++ b/src/crypto/digest/CMakeLists.txt
@@ -1,4 +1,4 @@
-include_directories(. .. ../../include)
+include_directories(../../include)
add_library(
digest
diff --git a/src/crypto/digest/digest.c b/src/crypto/digest/digest.c
index f09948b..eb71b07 100644
--- a/src/crypto/digest/digest.c
+++ b/src/crypto/digest/digest.c
@@ -116,8 +116,7 @@ int EVP_MD_CTX_copy_ex(EVP_MD_CTX *out, const EVP_MD_CTX *in) {
uint8_t *tmp_buf = NULL;
if (in == NULL || in->digest == NULL) {
- OPENSSL_PUT_ERROR(DIGEST, EVP_MD_CTX_copy_ex,
- DIGEST_R_INPUT_NOT_INITIALIZED);
+ OPENSSL_PUT_ERROR(DIGEST, DIGEST_R_INPUT_NOT_INITIALIZED);
return 0;
}
@@ -130,15 +129,15 @@ int EVP_MD_CTX_copy_ex(EVP_MD_CTX *out, const EVP_MD_CTX *in) {
}
EVP_MD_CTX_cleanup(out);
- memcpy(out, in, sizeof(EVP_MD_CTX));
+ out->digest = in->digest;
if (in->md_data && in->digest->ctx_size) {
if (tmp_buf) {
out->md_data = tmp_buf;
} else {
out->md_data = OPENSSL_malloc(in->digest->ctx_size);
if (!out->md_data) {
- OPENSSL_PUT_ERROR(DIGEST, EVP_MD_CTX_copy_ex, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(DIGEST, ERR_R_MALLOC_FAILURE);
return 0;
}
}
@@ -146,6 +145,7 @@ int EVP_MD_CTX_copy_ex(EVP_MD_CTX *out, const EVP_MD_CTX *in) {
}
assert(in->pctx == NULL || in->pctx_ops != NULL);
+ out->pctx_ops = in->pctx_ops;
if (in->pctx && in->pctx_ops) {
out->pctx = in->pctx_ops->dup(in->pctx);
if (!out->pctx) {
@@ -164,30 +164,20 @@ int EVP_MD_CTX_copy(EVP_MD_CTX *out, const EVP_MD_CTX *in) {
int EVP_DigestInit_ex(EVP_MD_CTX *ctx, const EVP_MD *type, ENGINE *engine) {
if (ctx->digest != type) {
- if (ctx->digest && ctx->digest->ctx_size) {
+ if (ctx->digest && ctx->digest->ctx_size > 0) {
OPENSSL_free(ctx->md_data);
}
ctx->digest = type;
- if (!(ctx->flags & EVP_MD_CTX_FLAG_NO_INIT) && type->ctx_size) {
- ctx->update = type->update;
+ if (type->ctx_size > 0) {
ctx->md_data = OPENSSL_malloc(type->ctx_size);
if (ctx->md_data == NULL) {
- OPENSSL_PUT_ERROR(DIGEST, EVP_DigestInit_ex, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(DIGEST, ERR_R_MALLOC_FAILURE);
return 0;
}
}
}
assert(ctx->pctx == NULL || ctx->pctx_ops != NULL);
- if (ctx->pctx_ops) {
- if (!ctx->pctx_ops->begin_digest(ctx)) {
- return 0;
- }
- }
-
- if (ctx->flags & EVP_MD_CTX_FLAG_NO_INIT) {
- return 1;
- }
ctx->digest->init(ctx);
return 1;
@@ -199,7 +189,7 @@ int EVP_DigestInit(EVP_MD_CTX *ctx, const EVP_MD *type) {
}
int EVP_DigestUpdate(EVP_MD_CTX *ctx, const void *data, size_t len) {
- ctx->update(ctx, data, len);
+ ctx->digest->update(ctx, data, len);
return 1;
}
@@ -214,7 +204,7 @@ int EVP_DigestFinal_ex(EVP_MD_CTX *ctx, uint8_t *md_out, unsigned int *size) {
}
int EVP_DigestFinal(EVP_MD_CTX *ctx, uint8_t *md, unsigned int *size) {
- EVP_DigestFinal_ex(ctx, md, size);
+ (void)EVP_DigestFinal_ex(ctx, md, size);
EVP_MD_CTX_cleanup(ctx);
return 1;
}
@@ -253,10 +243,6 @@ int EVP_MD_CTX_type(const EVP_MD_CTX *ctx) {
return EVP_MD_type(EVP_MD_CTX_md(ctx));
}
-void EVP_MD_CTX_set_flags(EVP_MD_CTX *ctx, uint32_t flags) {
- ctx->flags |= flags;
-}
-
int EVP_add_digest(const EVP_MD *digest) {
return 1;
}
diff --git a/src/crypto/digest/digests.c b/src/crypto/digest/digests.c
index f5eda36..3307f26 100644
--- a/src/crypto/digest/digests.c
+++ b/src/crypto/digest/digests.c
@@ -67,7 +67,7 @@
#include "internal.h"
#if defined(NDEBUG)
-#define CHECK(x) x
+#define CHECK(x) (void) (x)
#else
#define CHECK(x) assert(x)
#endif
@@ -262,6 +262,7 @@ struct nid_to_digest {
};
static const struct nid_to_digest nid_to_digest_mapping[] = {
+ { NID_md4, EVP_md4, SN_md4, LN_md4 },
{ NID_md5, EVP_md5, SN_md5, LN_md5 },
{ NID_sha1, EVP_sha1, SN_sha1, LN_sha1 },
{ NID_sha224, EVP_sha224, SN_sha224, LN_sha224 },
diff --git a/src/crypto/digest/internal.h b/src/crypto/digest/internal.h
index 1572fa8..e3d812a 100644
--- a/src/crypto/digest/internal.h
+++ b/src/crypto/digest/internal.h
@@ -92,7 +92,7 @@ struct env_md_st {
};
/* evp_md_pctx_ops contains function pointers to allow the |pctx| member of
- * |EVP_MD_CTX| to be manipulated without breaking laying by calling EVP
+ * |EVP_MD_CTX| to be manipulated without breaking layering by calling EVP
* functions. */
struct evp_md_pctx_ops {
/* free is called when an |EVP_MD_CTX| is being freed and the |pctx| also
@@ -102,23 +102,8 @@ struct evp_md_pctx_ops {
/* dup is called when an |EVP_MD_CTX| is copied and so the |pctx| also needs
* to be copied. */
EVP_PKEY_CTX* (*dup) (EVP_PKEY_CTX *pctx);
-
- /* begin_digest is called when a new digest operation is started. It returns
- * one on success and zero otherwise. */
- int (*begin_digest) (EVP_MD_CTX *ctx);
};
-/* EVP_MD_CTX_set_flags ORs |flags| into the flags member of |ctx|. */
-OPENSSL_EXPORT void EVP_MD_CTX_set_flags(EVP_MD_CTX *ctx, uint32_t flags);
-
-/* EVP_MD_CTX_FLAG_NO_INIT causes the |EVP_MD|'s |init| function not to be
- * called, the |update| member not to be copied from the |EVP_MD| in
- * |EVP_DigestInit_ex| and for |md_data| not to be initialised.
- *
- * TODO(davidben): This is an implementation detail of |EVP_PKEY_HMAC| and can
- * be removed when it is gone. */
-#define EVP_MD_CTX_FLAG_NO_INIT 1
-
#if defined(__cplusplus)
} /* extern C */
diff --git a/src/crypto/dsa/CMakeLists.txt b/src/crypto/dsa/CMakeLists.txt
index 1bb8b63..e8b7793 100644
--- a/src/crypto/dsa/CMakeLists.txt
+++ b/src/crypto/dsa/CMakeLists.txt
@@ -1,4 +1,4 @@
-include_directories(. .. ../../include)
+include_directories(../../include)
add_library(
dsa
diff --git a/src/crypto/dsa/dsa.c b/src/crypto/dsa/dsa.c
index 65444b1..3ff29c4 100644
--- a/src/crypto/dsa/dsa.c
+++ b/src/crypto/dsa/dsa.c
@@ -82,7 +82,7 @@ DSA *DSA_new(void) { return DSA_new_method(NULL); }
DSA *DSA_new_method(const ENGINE *engine) {
DSA *dsa = (DSA *)OPENSSL_malloc(sizeof(DSA));
if (dsa == NULL) {
- OPENSSL_PUT_ERROR(DSA, DSA_new_method, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(DSA, ERR_R_MALLOC_FAILURE);
return NULL;
}
diff --git a/src/crypto/dsa/dsa_asn1.c b/src/crypto/dsa/dsa_asn1.c
index 933fba7..b6b3fa4 100644
--- a/src/crypto/dsa/dsa_asn1.c
+++ b/src/crypto/dsa/dsa_asn1.c
@@ -73,7 +73,7 @@ static int dsa_sig_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
DSA_SIG *sig;
sig = OPENSSL_malloc(sizeof(DSA_SIG));
if (!sig) {
- OPENSSL_PUT_ERROR(DSA, dsa_sig_cb, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(DSA, ERR_R_MALLOC_FAILURE);
return 0;
}
diff --git a/src/crypto/dsa/dsa_impl.c b/src/crypto/dsa/dsa_impl.c
index 2ab8ba8..b10610d 100644
--- a/src/crypto/dsa/dsa_impl.c
+++ b/src/crypto/dsa/dsa_impl.c
@@ -83,7 +83,7 @@ static int sign_setup(const DSA *dsa, BN_CTX *ctx_in, BIGNUM **kinvp,
int ret = 0;
if (!dsa->p || !dsa->q || !dsa->g) {
- OPENSSL_PUT_ERROR(DSA, sign_setup, DSA_R_MISSING_PARAMETERS);
+ OPENSSL_PUT_ERROR(DSA, DSA_R_MISSING_PARAMETERS);
return 0;
}
@@ -171,7 +171,7 @@ static int sign_setup(const DSA *dsa, BN_CTX *ctx_in, BIGNUM **kinvp,
err:
if (!ret) {
- OPENSSL_PUT_ERROR(DSA, sign_setup, ERR_R_BN_LIB);
+ OPENSSL_PUT_ERROR(DSA, ERR_R_BN_LIB);
if (r != NULL) {
BN_clear_free(r);
}
@@ -269,7 +269,7 @@ redo:
err:
if (!ret) {
- OPENSSL_PUT_ERROR(DSA, sign, reason);
+ OPENSSL_PUT_ERROR(DSA, reason);
BN_free(r);
BN_free(s);
}
@@ -292,19 +292,19 @@ static int verify(int *out_valid, const uint8_t *dgst, size_t digest_len,
*out_valid = 0;
if (!dsa->p || !dsa->q || !dsa->g) {
- OPENSSL_PUT_ERROR(DSA, verify, DSA_R_MISSING_PARAMETERS);
+ OPENSSL_PUT_ERROR(DSA, DSA_R_MISSING_PARAMETERS);
return 0;
}
i = BN_num_bits(dsa->q);
/* fips 186-3 allows only different sizes for q */
if (i != 160 && i != 224 && i != 256) {
- OPENSSL_PUT_ERROR(DSA, verify, DSA_R_BAD_Q_VALUE);
+ OPENSSL_PUT_ERROR(DSA, DSA_R_BAD_Q_VALUE);
return 0;
}
if (BN_num_bits(dsa->p) > OPENSSL_DSA_MAX_MODULUS_BITS) {
- OPENSSL_PUT_ERROR(DSA, verify, DSA_R_MODULUS_TOO_LARGE);
+ OPENSSL_PUT_ERROR(DSA, DSA_R_MODULUS_TOO_LARGE);
return 0;
}
@@ -381,7 +381,7 @@ static int verify(int *out_valid, const uint8_t *dgst, size_t digest_len,
err:
if (ret != 1) {
- OPENSSL_PUT_ERROR(DSA, verify, ERR_R_BN_LIB);
+ OPENSSL_PUT_ERROR(DSA, ERR_R_BN_LIB);
}
BN_CTX_free(ctx);
BN_free(&u1);
@@ -487,16 +487,14 @@ static int paramgen(DSA *ret, unsigned bits, const uint8_t *seed_in,
bits = (bits + 63) / 64 * 64;
- /* NB: seed_len == 0 is special case: copy generated seed to
- * seed_in if it is not NULL. */
- if (seed_len && (seed_len < (size_t)qsize)) {
- seed_in = NULL; /* seed buffer too small -- ignore */
- }
- if (seed_len > (size_t)qsize) {
- seed_len = qsize; /* App. 2.2 of FIPS PUB 186 allows larger SEED,
- * but our internal buffers are restricted to 160 bits*/
- }
if (seed_in != NULL) {
+ if (seed_len < (size_t)qsize) {
+ return 0;
+ }
+ if (seed_len > (size_t)qsize) {
+ /* Only consume as much seed as is expected. */
+ seed_len = qsize;
+ }
memcpy(seed, seed_in, seed_len);
}
@@ -527,21 +525,19 @@ static int paramgen(DSA *ret, unsigned bits, const uint8_t *seed_in,
for (;;) {
/* Find q. */
for (;;) {
- int seed_is_random;
-
/* step 1 */
if (!BN_GENCB_call(cb, 0, m++)) {
goto err;
}
- if (!seed_len) {
+ int use_random_seed = (seed_in == NULL);
+ if (use_random_seed) {
if (!RAND_bytes(seed, qsize)) {
goto err;
}
- seed_is_random = 1;
} else {
- seed_is_random = 0;
- seed_len = 0; /* use random seed if 'seed_in' turns out to be bad*/
+ /* If we come back through, use random seed next time. */
+ seed_in = NULL;
}
memcpy(buf, seed, qsize);
memcpy(buf2, seed, qsize);
@@ -570,7 +566,7 @@ static int paramgen(DSA *ret, unsigned bits, const uint8_t *seed_in,
}
/* step 4 */
- r = BN_is_prime_fasttest_ex(q, DSS_prime_checks, ctx, seed_is_random, cb);
+ r = BN_is_prime_fasttest_ex(q, DSS_prime_checks, ctx, use_random_seed, cb);
if (r > 0) {
break;
}
diff --git a/src/crypto/ec/CMakeLists.txt b/src/crypto/ec/CMakeLists.txt
index b5ebefa..38a91f8 100644
--- a/src/crypto/ec/CMakeLists.txt
+++ b/src/crypto/ec/CMakeLists.txt
@@ -1,4 +1,4 @@
-include_directories(. .. ../../include)
+include_directories(../../include)
add_library(
ec
diff --git a/src/crypto/ec/ec.c b/src/crypto/ec/ec.c
index f38eba6..3117f16 100644
--- a/src/crypto/ec/ec.c
+++ b/src/crypto/ec/ec.c
@@ -222,7 +222,11 @@ const struct built_in_curve OPENSSL_built_in_curves[] = {
{NID_secp224r1, &P224, 0},
{
NID_X9_62_prime256v1, &P256,
-#if defined(OPENSSL_64_BIT) && !defined(OPENSSL_WINDOWS)
+ /* MSAN appears to have a bug that causes this P-256 code to be miscompiled
+ * in opt mode. While that is being looked at, don't run the uint128_t
+ * P-256 code under MSAN for now. */
+#if defined(OPENSSL_64_BIT) && !defined(OPENSSL_WINDOWS) && \
+ !defined(MEMORY_SANITIZER)
EC_GFp_nistp256_method,
#else
0,
@@ -237,18 +241,18 @@ EC_GROUP *ec_group_new(const EC_METHOD *meth) {
EC_GROUP *ret;
if (meth == NULL) {
- OPENSSL_PUT_ERROR(EC, ec_group_new, EC_R_SLOT_FULL);
+ OPENSSL_PUT_ERROR(EC, EC_R_SLOT_FULL);
return NULL;
}
if (meth->group_init == 0) {
- OPENSSL_PUT_ERROR(EC, ec_group_new, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+ OPENSSL_PUT_ERROR(EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
return NULL;
}
ret = OPENSSL_malloc(sizeof(EC_GROUP));
if (ret == NULL) {
- OPENSSL_PUT_ERROR(EC, ec_group_new, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE);
return NULL;
}
memset(ret, 0, sizeof(EC_GROUP));
@@ -276,8 +280,7 @@ EC_GROUP *EC_GROUP_new_curve_GFp(const BIGNUM *p, const BIGNUM *a,
}
if (ret->meth->group_set_curve == 0) {
- OPENSSL_PUT_ERROR(EC, EC_GROUP_new_curve_GFp,
- ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+ OPENSSL_PUT_ERROR(EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
return 0;
}
if (!ret->meth->group_set_curve(ret, p, a, b, ctx)) {
@@ -329,7 +332,7 @@ static EC_GROUP *ec_group_new_from_data(const struct built_in_curve *curve) {
EC_GROUP *group = NULL;
EC_POINT *P = NULL;
BN_CTX *ctx = NULL;
- BIGNUM *p = NULL, *a = NULL, *b = NULL, *x = NULL, *y = NULL, *order = NULL;
+ BIGNUM *p = NULL, *a = NULL, *b = NULL, *x = NULL, *y = NULL;
int ok = 0;
unsigned param_len;
const EC_METHOD *meth;
@@ -337,7 +340,7 @@ static EC_GROUP *ec_group_new_from_data(const struct built_in_curve *curve) {
const uint8_t *params;
if ((ctx = BN_CTX_new()) == NULL) {
- OPENSSL_PUT_ERROR(EC, ec_group_new_from_data, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE);
goto err;
}
@@ -348,7 +351,7 @@ static EC_GROUP *ec_group_new_from_data(const struct built_in_curve *curve) {
if (!(p = BN_bin2bn(params + 0 * param_len, param_len, NULL)) ||
!(a = BN_bin2bn(params + 1 * param_len, param_len, NULL)) ||
!(b = BN_bin2bn(params + 2 * param_len, param_len, NULL))) {
- OPENSSL_PUT_ERROR(EC, ec_group_new_from_data, ERR_R_BN_LIB);
+ OPENSSL_PUT_ERROR(EC, ERR_R_BN_LIB);
goto err;
}
@@ -356,45 +359,39 @@ static EC_GROUP *ec_group_new_from_data(const struct built_in_curve *curve) {
meth = curve->method();
if (((group = ec_group_new(meth)) == NULL) ||
(!(group->meth->group_set_curve(group, p, a, b, ctx)))) {
- OPENSSL_PUT_ERROR(EC, ec_group_new_from_data, ERR_R_EC_LIB);
+ OPENSSL_PUT_ERROR(EC, ERR_R_EC_LIB);
goto err;
}
} else {
if ((group = EC_GROUP_new_curve_GFp(p, a, b, ctx)) == NULL) {
- OPENSSL_PUT_ERROR(EC, ec_group_new_from_data, ERR_R_EC_LIB);
+ OPENSSL_PUT_ERROR(EC, ERR_R_EC_LIB);
goto err;
}
}
if ((P = EC_POINT_new(group)) == NULL) {
- OPENSSL_PUT_ERROR(EC, ec_group_new_from_data, ERR_R_EC_LIB);
+ OPENSSL_PUT_ERROR(EC, ERR_R_EC_LIB);
goto err;
}
if (!(x = BN_bin2bn(params + 3 * param_len, param_len, NULL)) ||
!(y = BN_bin2bn(params + 4 * param_len, param_len, NULL))) {
- OPENSSL_PUT_ERROR(EC, ec_group_new_from_data, ERR_R_BN_LIB);
+ OPENSSL_PUT_ERROR(EC, ERR_R_BN_LIB);
goto err;
}
if (!EC_POINT_set_affine_coordinates_GFp(group, P, x, y, ctx)) {
- OPENSSL_PUT_ERROR(EC, ec_group_new_from_data, ERR_R_EC_LIB);
+ OPENSSL_PUT_ERROR(EC, ERR_R_EC_LIB);
goto err;
}
- if (!(order = BN_bin2bn(params + 5 * param_len, param_len, NULL)) ||
- !BN_set_word(x, (BN_ULONG)data->cofactor)) {
- OPENSSL_PUT_ERROR(EC, ec_group_new_from_data, ERR_R_BN_LIB);
+ if (!BN_bin2bn(params + 5 * param_len, param_len, &group->order) ||
+ !BN_set_word(&group->cofactor, (BN_ULONG)data->cofactor)) {
+ OPENSSL_PUT_ERROR(EC, ERR_R_BN_LIB);
goto err;
}
group->generator = P;
P = NULL;
- if (!BN_copy(&group->order, order) ||
- !BN_set_word(&group->cofactor, (BN_ULONG)data->cofactor)) {
- OPENSSL_PUT_ERROR(EC, ec_group_new_from_data, ERR_R_BN_LIB);
- goto err;
- }
-
ok = 1;
err:
@@ -407,7 +404,6 @@ err:
BN_free(p);
BN_free(a);
BN_free(b);
- BN_free(order);
BN_free(x);
BN_free(y);
return group;
@@ -427,7 +423,7 @@ EC_GROUP *EC_GROUP_new_by_curve_name(int nid) {
}
if (ret == NULL) {
- OPENSSL_PUT_ERROR(EC, EC_GROUP_new_by_curve_name, EC_R_UNKNOWN_GROUP);
+ OPENSSL_PUT_ERROR(EC, EC_R_UNKNOWN_GROUP);
return NULL;
}
@@ -455,11 +451,11 @@ void EC_GROUP_free(EC_GROUP *group) {
int ec_group_copy(EC_GROUP *dest, const EC_GROUP *src) {
if (dest->meth->group_copy == 0) {
- OPENSSL_PUT_ERROR(EC, EC_GROUP_copy, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+ OPENSSL_PUT_ERROR(EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
return 0;
}
if (dest->meth != src->meth) {
- OPENSSL_PUT_ERROR(EC, EC_GROUP_copy, EC_R_INCOMPATIBLE_OBJECTS);
+ OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
return 0;
}
if (dest == src) {
@@ -554,8 +550,7 @@ int EC_GROUP_get_cofactor(const EC_GROUP *group, BIGNUM *cofactor,
int EC_GROUP_get_curve_GFp(const EC_GROUP *group, BIGNUM *out_p, BIGNUM *out_a,
BIGNUM *out_b, BN_CTX *ctx) {
if (group->meth->group_get_curve == 0) {
- OPENSSL_PUT_ERROR(EC, EC_GROUP_get_curve_GFp,
- ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+ OPENSSL_PUT_ERROR(EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
return 0;
}
return group->meth->group_get_curve(group, out_p, out_a, out_b, ctx);
@@ -565,8 +560,7 @@ int EC_GROUP_get_curve_name(const EC_GROUP *group) { return group->curve_name; }
int EC_GROUP_get_degree(const EC_GROUP *group) {
if (group->meth->group_get_degree == 0) {
- OPENSSL_PUT_ERROR(EC, EC_GROUP_get_degree,
- ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+ OPENSSL_PUT_ERROR(EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
return 0;
}
return group->meth->group_get_degree(group);
@@ -602,17 +596,17 @@ EC_POINT *EC_POINT_new(const EC_GROUP *group) {
EC_POINT *ret;
if (group == NULL) {
- OPENSSL_PUT_ERROR(EC, EC_POINT_new, ERR_R_PASSED_NULL_PARAMETER);
+ OPENSSL_PUT_ERROR(EC, ERR_R_PASSED_NULL_PARAMETER);
return NULL;
}
if (group->meth->point_init == 0) {
- OPENSSL_PUT_ERROR(EC, EC_POINT_new, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+ OPENSSL_PUT_ERROR(EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
return NULL;
}
ret = OPENSSL_malloc(sizeof *ret);
if (ret == NULL) {
- OPENSSL_PUT_ERROR(EC, EC_POINT_new, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE);
return NULL;
}
@@ -653,11 +647,11 @@ void EC_POINT_clear_free(EC_POINT *point) {
int EC_POINT_copy(EC_POINT *dest, const EC_POINT *src) {
if (dest->meth->point_copy == 0) {
- OPENSSL_PUT_ERROR(EC, EC_POINT_copy, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+ OPENSSL_PUT_ERROR(EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
return 0;
}
if (dest->meth != src->meth) {
- OPENSSL_PUT_ERROR(EC, EC_POINT_copy, EC_R_INCOMPATIBLE_OBJECTS);
+ OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
return 0;
}
if (dest == src) {
@@ -676,7 +670,7 @@ EC_POINT *EC_POINT_dup(const EC_POINT *a, const EC_GROUP *group) {
t = EC_POINT_new(group);
if (t == NULL) {
- OPENSSL_PUT_ERROR(EC, EC_POINT_dup, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE);
return NULL;
}
r = EC_POINT_copy(t, a);
@@ -690,12 +684,11 @@ EC_POINT *EC_POINT_dup(const EC_POINT *a, const EC_GROUP *group) {
int EC_POINT_set_to_infinity(const EC_GROUP *group, EC_POINT *point) {
if (group->meth->point_set_to_infinity == 0) {
- OPENSSL_PUT_ERROR(EC, EC_POINT_set_to_infinity,
- ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+ OPENSSL_PUT_ERROR(EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
return 0;
}
if (group->meth != point->meth) {
- OPENSSL_PUT_ERROR(EC, EC_POINT_set_to_infinity, EC_R_INCOMPATIBLE_OBJECTS);
+ OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
return 0;
}
return group->meth->point_set_to_infinity(group, point);
@@ -703,12 +696,11 @@ int EC_POINT_set_to_infinity(const EC_GROUP *group, EC_POINT *point) {
int EC_POINT_is_at_infinity(const EC_GROUP *group, const EC_POINT *point) {
if (group->meth->is_at_infinity == 0) {
- OPENSSL_PUT_ERROR(EC, EC_POINT_is_at_infinity,
- ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+ OPENSSL_PUT_ERROR(EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
return 0;
}
if (group->meth != point->meth) {
- OPENSSL_PUT_ERROR(EC, EC_POINT_is_at_infinity, EC_R_INCOMPATIBLE_OBJECTS);
+ OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
return 0;
}
return group->meth->is_at_infinity(group, point);
@@ -717,12 +709,11 @@ int EC_POINT_is_at_infinity(const EC_GROUP *group, const EC_POINT *point) {
int EC_POINT_is_on_curve(const EC_GROUP *group, const EC_POINT *point,
BN_CTX *ctx) {
if (group->meth->is_on_curve == 0) {
- OPENSSL_PUT_ERROR(EC, EC_POINT_is_on_curve,
- ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+ OPENSSL_PUT_ERROR(EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
return 0;
}
if (group->meth != point->meth) {
- OPENSSL_PUT_ERROR(EC, EC_POINT_is_on_curve, EC_R_INCOMPATIBLE_OBJECTS);
+ OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
return 0;
}
return group->meth->is_on_curve(group, point, ctx);
@@ -731,11 +722,11 @@ int EC_POINT_is_on_curve(const EC_GROUP *group, const EC_POINT *point,
int EC_POINT_cmp(const EC_GROUP *group, const EC_POINT *a, const EC_POINT *b,
BN_CTX *ctx) {
if (group->meth->point_cmp == 0) {
- OPENSSL_PUT_ERROR(EC, EC_POINT_cmp, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+ OPENSSL_PUT_ERROR(EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
return -1;
}
if ((group->meth != a->meth) || (a->meth != b->meth)) {
- OPENSSL_PUT_ERROR(EC, EC_POINT_cmp, EC_R_INCOMPATIBLE_OBJECTS);
+ OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
return -1;
}
return group->meth->point_cmp(group, a, b, ctx);
@@ -743,12 +734,11 @@ int EC_POINT_cmp(const EC_GROUP *group, const EC_POINT *a, const EC_POINT *b,
int EC_POINT_make_affine(const EC_GROUP *group, EC_POINT *point, BN_CTX *ctx) {
if (group->meth->make_affine == 0) {
- OPENSSL_PUT_ERROR(EC, EC_POINT_make_affine,
- ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+ OPENSSL_PUT_ERROR(EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
return 0;
}
if (group->meth != point->meth) {
- OPENSSL_PUT_ERROR(EC, EC_POINT_make_affine, EC_R_INCOMPATIBLE_OBJECTS);
+ OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
return 0;
}
return group->meth->make_affine(group, point, ctx);
@@ -759,13 +749,12 @@ int EC_POINTs_make_affine(const EC_GROUP *group, size_t num, EC_POINT *points[],
size_t i;
if (group->meth->points_make_affine == 0) {
- OPENSSL_PUT_ERROR(EC, EC_POINTs_make_affine,
- ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+ OPENSSL_PUT_ERROR(EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
return 0;
}
for (i = 0; i < num; i++) {
if (group->meth != points[i]->meth) {
- OPENSSL_PUT_ERROR(EC, EC_POINTs_make_affine, EC_R_INCOMPATIBLE_OBJECTS);
+ OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
return 0;
}
}
@@ -776,13 +765,11 @@ int EC_POINT_get_affine_coordinates_GFp(const EC_GROUP *group,
const EC_POINT *point, BIGNUM *x,
BIGNUM *y, BN_CTX *ctx) {
if (group->meth->point_get_affine_coordinates == 0) {
- OPENSSL_PUT_ERROR(EC, EC_POINT_get_affine_coordinates_GFp,
- ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+ OPENSSL_PUT_ERROR(EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
return 0;
}
if (group->meth != point->meth) {
- OPENSSL_PUT_ERROR(EC, EC_POINT_get_affine_coordinates_GFp,
- EC_R_INCOMPATIBLE_OBJECTS);
+ OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
return 0;
}
return group->meth->point_get_affine_coordinates(group, point, x, y, ctx);
@@ -792,13 +779,11 @@ int EC_POINT_set_affine_coordinates_GFp(const EC_GROUP *group, EC_POINT *point,
const BIGNUM *x, const BIGNUM *y,
BN_CTX *ctx) {
if (group->meth->point_set_affine_coordinates == 0) {
- OPENSSL_PUT_ERROR(EC, EC_POINT_set_affine_coordinates_GFp,
- ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+ OPENSSL_PUT_ERROR(EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
return 0;
}
if (group->meth != point->meth) {
- OPENSSL_PUT_ERROR(EC, EC_POINT_set_affine_coordinates_GFp,
- EC_R_INCOMPATIBLE_OBJECTS);
+ OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
return 0;
}
return group->meth->point_set_affine_coordinates(group, point, x, y, ctx);
@@ -807,12 +792,12 @@ int EC_POINT_set_affine_coordinates_GFp(const EC_GROUP *group, EC_POINT *point,
int EC_POINT_add(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a,
const EC_POINT *b, BN_CTX *ctx) {
if (group->meth->add == 0) {
- OPENSSL_PUT_ERROR(EC, EC_POINT_add, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+ OPENSSL_PUT_ERROR(EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
return 0;
}
if ((group->meth != r->meth) || (r->meth != a->meth) ||
(a->meth != b->meth)) {
- OPENSSL_PUT_ERROR(EC, EC_POINT_add, EC_R_INCOMPATIBLE_OBJECTS);
+ OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
return 0;
}
return group->meth->add(group, r, a, b, ctx);
@@ -822,11 +807,11 @@ int EC_POINT_add(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a,
int EC_POINT_dbl(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a,
BN_CTX *ctx) {
if (group->meth->dbl == 0) {
- OPENSSL_PUT_ERROR(EC, EC_POINT_dbl, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+ OPENSSL_PUT_ERROR(EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
return 0;
}
if ((group->meth != r->meth) || (r->meth != a->meth)) {
- OPENSSL_PUT_ERROR(EC, EC_POINT_dbl, EC_R_INCOMPATIBLE_OBJECTS);
+ OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
return 0;
}
return group->meth->dbl(group, r, a, ctx);
@@ -835,11 +820,11 @@ int EC_POINT_dbl(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a,
int EC_POINT_invert(const EC_GROUP *group, EC_POINT *a, BN_CTX *ctx) {
if (group->meth->invert == 0) {
- OPENSSL_PUT_ERROR(EC, EC_POINT_invert, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+ OPENSSL_PUT_ERROR(EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
return 0;
}
if (group->meth != a->meth) {
- OPENSSL_PUT_ERROR(EC, EC_POINT_invert, EC_R_INCOMPATIBLE_OBJECTS);
+ OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
return 0;
}
return group->meth->invert(group, a, ctx);
@@ -874,13 +859,11 @@ int ec_point_set_Jprojective_coordinates_GFp(const EC_GROUP *group, EC_POINT *po
const BIGNUM *x, const BIGNUM *y,
const BIGNUM *z, BN_CTX *ctx) {
if (group->meth->point_set_Jprojective_coordinates_GFp == 0) {
- OPENSSL_PUT_ERROR(EC, ec_point_set_Jprojective_coordinates_GFp,
- ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+ OPENSSL_PUT_ERROR(EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
return 0;
}
if (group->meth != point->meth) {
- OPENSSL_PUT_ERROR(EC, ec_point_set_Jprojective_coordinates_GFp,
- EC_R_INCOMPATIBLE_OBJECTS);
+ OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
return 0;
}
return group->meth->point_set_Jprojective_coordinates_GFp(group, point, x, y,
diff --git a/src/crypto/ec/ec_asn1.c b/src/crypto/ec/ec_asn1.c
index ff3dca6..31d8944 100644
--- a/src/crypto/ec/ec_asn1.c
+++ b/src/crypto/ec/ec_asn1.c
@@ -168,7 +168,7 @@ ECPKPARAMETERS *ec_asn1_group2pkparameters(const EC_GROUP *group,
if (ret == NULL) {
ret = ECPKPARAMETERS_new();
if (ret == NULL) {
- OPENSSL_PUT_ERROR(EC, ec_asn1_group2pkparameters, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE);
return NULL;
}
} else {
@@ -196,7 +196,7 @@ EC_GROUP *ec_asn1_pkparameters2group(const ECPKPARAMETERS *params) {
int nid = NID_undef;
if (params == NULL) {
- OPENSSL_PUT_ERROR(EC, ec_asn1_pkparameters2group, EC_R_MISSING_PARAMETERS);
+ OPENSSL_PUT_ERROR(EC, EC_R_MISSING_PARAMETERS);
return NULL;
}
@@ -222,14 +222,13 @@ EC_GROUP *ec_asn1_pkparameters2group(const ECPKPARAMETERS *params) {
}
if (nid == NID_undef) {
- OPENSSL_PUT_ERROR(EC, ec_asn1_pkparameters2group, EC_R_NON_NAMED_CURVE);
+ OPENSSL_PUT_ERROR(EC, EC_R_NON_NAMED_CURVE);
return NULL;
}
ret = EC_GROUP_new_by_curve_name(nid);
if (ret == NULL) {
- OPENSSL_PUT_ERROR(EC, ec_asn1_pkparameters2group,
- EC_R_EC_GROUP_NEW_BY_NAME_FAILURE);
+ OPENSSL_PUT_ERROR(EC, EC_R_EC_GROUP_NEW_BY_NAME_FAILURE);
return NULL;
}
@@ -243,14 +242,14 @@ static EC_GROUP *d2i_ECPKParameters(EC_GROUP **groupp, const uint8_t **inp,
params = d2i_ECPKPARAMETERS(NULL, inp, len);
if (params == NULL) {
- OPENSSL_PUT_ERROR(EC, d2i_ECPKParameters, EC_R_D2I_ECPKPARAMETERS_FAILURE);
+ OPENSSL_PUT_ERROR(EC, EC_R_D2I_ECPKPARAMETERS_FAILURE);
ECPKPARAMETERS_free(params);
return NULL;
}
group = ec_asn1_pkparameters2group(params);
if (group == NULL) {
- OPENSSL_PUT_ERROR(EC, d2i_ECPKParameters, EC_R_PKPARAMETERS2GROUP_FAILURE);
+ OPENSSL_PUT_ERROR(EC, EC_R_PKPARAMETERS2GROUP_FAILURE);
ECPKPARAMETERS_free(params);
return NULL;
}
@@ -268,12 +267,12 @@ static int i2d_ECPKParameters(const EC_GROUP *group, uint8_t **outp) {
int ret = 0;
ECPKPARAMETERS *tmp = ec_asn1_group2pkparameters(group, NULL);
if (tmp == NULL) {
- OPENSSL_PUT_ERROR(EC, i2d_ECPKParameters, EC_R_GROUP2PKPARAMETERS_FAILURE);
+ OPENSSL_PUT_ERROR(EC, EC_R_GROUP2PKPARAMETERS_FAILURE);
return 0;
}
ret = i2d_ECPKPARAMETERS(tmp, outp);
if (ret == 0) {
- OPENSSL_PUT_ERROR(EC, i2d_ECPKParameters, EC_R_I2D_ECPKPARAMETERS_FAILURE);
+ OPENSSL_PUT_ERROR(EC, EC_R_I2D_ECPKPARAMETERS_FAILURE);
ECPKPARAMETERS_free(tmp);
return 0;
}
@@ -288,14 +287,14 @@ EC_KEY *d2i_ECPrivateKey(EC_KEY **a, const uint8_t **in, long len) {
priv_key = d2i_EC_PRIVATEKEY(NULL, in, len);
if (priv_key == NULL) {
- OPENSSL_PUT_ERROR(EC, d2i_ECPrivateKey, ERR_R_EC_LIB);
+ OPENSSL_PUT_ERROR(EC, ERR_R_EC_LIB);
return NULL;
}
if (a == NULL || *a == NULL) {
ret = EC_KEY_new();
if (ret == NULL) {
- OPENSSL_PUT_ERROR(EC, d2i_ECPrivateKey, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE);
goto err;
}
} else {
@@ -308,7 +307,7 @@ EC_KEY *d2i_ECPrivateKey(EC_KEY **a, const uint8_t **in, long len) {
}
if (ret->group == NULL) {
- OPENSSL_PUT_ERROR(EC, d2i_ECPrivateKey, ERR_R_EC_LIB);
+ OPENSSL_PUT_ERROR(EC, ERR_R_EC_LIB);
goto err;
}
@@ -319,18 +318,18 @@ EC_KEY *d2i_ECPrivateKey(EC_KEY **a, const uint8_t **in, long len) {
BN_bin2bn(M_ASN1_STRING_data(priv_key->privateKey),
M_ASN1_STRING_length(priv_key->privateKey), ret->priv_key);
if (ret->priv_key == NULL) {
- OPENSSL_PUT_ERROR(EC, d2i_ECPrivateKey, ERR_R_BN_LIB);
+ OPENSSL_PUT_ERROR(EC, ERR_R_BN_LIB);
goto err;
}
} else {
- OPENSSL_PUT_ERROR(EC, d2i_ECPrivateKey, EC_R_MISSING_PRIVATE_KEY);
+ OPENSSL_PUT_ERROR(EC, EC_R_MISSING_PRIVATE_KEY);
goto err;
}
EC_POINT_free(ret->pub_key);
ret->pub_key = EC_POINT_new(ret->group);
if (ret->pub_key == NULL) {
- OPENSSL_PUT_ERROR(EC, d2i_ECPrivateKey, ERR_R_EC_LIB);
+ OPENSSL_PUT_ERROR(EC, ERR_R_EC_LIB);
goto err;
}
@@ -342,20 +341,20 @@ EC_KEY *d2i_ECPrivateKey(EC_KEY **a, const uint8_t **in, long len) {
pub_oct_len = M_ASN1_STRING_length(priv_key->publicKey);
/* The first byte (the point conversion form) must be present. */
if (pub_oct_len <= 0) {
- OPENSSL_PUT_ERROR(EC, d2i_ECPrivateKey, EC_R_BUFFER_TOO_SMALL);
+ OPENSSL_PUT_ERROR(EC, EC_R_BUFFER_TOO_SMALL);
goto err;
}
/* Save the point conversion form. */
ret->conv_form = (point_conversion_form_t)(pub_oct[0] & ~0x01);
if (!EC_POINT_oct2point(ret->group, ret->pub_key, pub_oct, pub_oct_len,
NULL)) {
- OPENSSL_PUT_ERROR(EC, d2i_ECPrivateKey, ERR_R_EC_LIB);
+ OPENSSL_PUT_ERROR(EC, ERR_R_EC_LIB);
goto err;
}
} else {
if (!EC_POINT_mul(ret->group, ret->pub_key, ret->priv_key, NULL, NULL,
NULL)) {
- OPENSSL_PUT_ERROR(EC, d2i_ECPrivateKey, ERR_R_EC_LIB);
+ OPENSSL_PUT_ERROR(EC, ERR_R_EC_LIB);
goto err;
}
/* Remember the original private-key-only encoding. */
@@ -387,13 +386,13 @@ int i2d_ECPrivateKey(const EC_KEY *key, uint8_t **outp) {
EC_PRIVATEKEY *priv_key = NULL;
if (key == NULL || key->group == NULL || key->priv_key == NULL) {
- OPENSSL_PUT_ERROR(EC, i2d_ECPrivateKey, ERR_R_PASSED_NULL_PARAMETER);
+ OPENSSL_PUT_ERROR(EC, ERR_R_PASSED_NULL_PARAMETER);
goto err;
}
priv_key = EC_PRIVATEKEY_new();
if (priv_key == NULL) {
- OPENSSL_PUT_ERROR(EC, i2d_ECPrivateKey, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE);
goto err;
}
@@ -402,17 +401,17 @@ int i2d_ECPrivateKey(const EC_KEY *key, uint8_t **outp) {
buf_len = BN_num_bytes(&key->group->order);
buffer = OPENSSL_malloc(buf_len);
if (buffer == NULL) {
- OPENSSL_PUT_ERROR(EC, i2d_ECPrivateKey, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE);
goto err;
}
if (!BN_bn2bin_padded(buffer, buf_len, key->priv_key)) {
- OPENSSL_PUT_ERROR(EC, i2d_ECPrivateKey, ERR_R_BN_LIB);
+ OPENSSL_PUT_ERROR(EC, ERR_R_BN_LIB);
goto err;
}
if (!M_ASN1_OCTET_STRING_set(priv_key->privateKey, buffer, buf_len)) {
- OPENSSL_PUT_ERROR(EC, i2d_ECPrivateKey, ERR_R_ASN1_LIB);
+ OPENSSL_PUT_ERROR(EC, ERR_R_ASN1_LIB);
goto err;
}
@@ -420,7 +419,7 @@ int i2d_ECPrivateKey(const EC_KEY *key, uint8_t **outp) {
if (!(key->enc_flag & EC_PKEY_NO_PARAMETERS)) {
if ((priv_key->parameters = ec_asn1_group2pkparameters(
key->group, priv_key->parameters)) == NULL) {
- OPENSSL_PUT_ERROR(EC, i2d_ECPrivateKey, ERR_R_EC_LIB);
+ OPENSSL_PUT_ERROR(EC, ERR_R_EC_LIB);
goto err;
}
}
@@ -429,7 +428,7 @@ int i2d_ECPrivateKey(const EC_KEY *key, uint8_t **outp) {
if (!(key->enc_flag & EC_PKEY_NO_PUBKEY) && key->pub_key != NULL) {
priv_key->publicKey = M_ASN1_BIT_STRING_new();
if (priv_key->publicKey == NULL) {
- OPENSSL_PUT_ERROR(EC, i2d_ECPrivateKey, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE);
goto err;
}
@@ -439,7 +438,7 @@ int i2d_ECPrivateKey(const EC_KEY *key, uint8_t **outp) {
if (tmp_len > buf_len) {
uint8_t *tmp_buffer = OPENSSL_realloc(buffer, tmp_len);
if (!tmp_buffer) {
- OPENSSL_PUT_ERROR(EC, i2d_ECPrivateKey, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE);
goto err;
}
buffer = tmp_buffer;
@@ -448,21 +447,21 @@ int i2d_ECPrivateKey(const EC_KEY *key, uint8_t **outp) {
if (!EC_POINT_point2oct(key->group, key->pub_key, key->conv_form, buffer,
buf_len, NULL)) {
- OPENSSL_PUT_ERROR(EC, i2d_ECPrivateKey, ERR_R_EC_LIB);
+ OPENSSL_PUT_ERROR(EC, ERR_R_EC_LIB);
goto err;
}
priv_key->publicKey->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07);
priv_key->publicKey->flags |= ASN1_STRING_FLAG_BITS_LEFT;
if (!M_ASN1_BIT_STRING_set(priv_key->publicKey, buffer, buf_len)) {
- OPENSSL_PUT_ERROR(EC, i2d_ECPrivateKey, ERR_R_ASN1_LIB);
+ OPENSSL_PUT_ERROR(EC, ERR_R_ASN1_LIB);
goto err;
}
}
ret = i2d_EC_PRIVATEKEY(priv_key, outp);
if (ret == 0) {
- OPENSSL_PUT_ERROR(EC, i2d_ECPrivateKey, ERR_R_EC_LIB);
+ OPENSSL_PUT_ERROR(EC, ERR_R_EC_LIB);
goto err;
}
ok = 1;
@@ -475,7 +474,7 @@ err:
int i2d_ECParameters(const EC_KEY *key, uint8_t **outp) {
if (key == NULL) {
- OPENSSL_PUT_ERROR(EC, i2d_ECParameters, ERR_R_PASSED_NULL_PARAMETER);
+ OPENSSL_PUT_ERROR(EC, ERR_R_PASSED_NULL_PARAMETER);
return 0;
}
return i2d_ECPKParameters(key->group, outp);
@@ -485,14 +484,14 @@ EC_KEY *d2i_ECParameters(EC_KEY **key, const uint8_t **inp, long len) {
EC_KEY *ret;
if (inp == NULL || *inp == NULL) {
- OPENSSL_PUT_ERROR(EC, d2i_ECParameters, ERR_R_PASSED_NULL_PARAMETER);
+ OPENSSL_PUT_ERROR(EC, ERR_R_PASSED_NULL_PARAMETER);
return NULL;
}
if (key == NULL || *key == NULL) {
ret = EC_KEY_new();
if (ret == NULL) {
- OPENSSL_PUT_ERROR(EC, d2i_ECParameters, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE);
return NULL;
}
} else {
@@ -500,7 +499,7 @@ EC_KEY *d2i_ECParameters(EC_KEY **key, const uint8_t **inp, long len) {
}
if (!d2i_ECPKParameters(&ret->group, inp, len)) {
- OPENSSL_PUT_ERROR(EC, d2i_ECParameters, ERR_R_EC_LIB);
+ OPENSSL_PUT_ERROR(EC, ERR_R_EC_LIB);
if (key == NULL || *key == NULL) {
EC_KEY_free(ret);
}
@@ -517,17 +516,17 @@ EC_KEY *o2i_ECPublicKey(EC_KEY **keyp, const uint8_t **inp, long len) {
EC_KEY *ret = NULL;
if (keyp == NULL || *keyp == NULL || (*keyp)->group == NULL) {
- OPENSSL_PUT_ERROR(EC, o2i_ECPublicKey, ERR_R_PASSED_NULL_PARAMETER);
+ OPENSSL_PUT_ERROR(EC, ERR_R_PASSED_NULL_PARAMETER);
return 0;
}
ret = *keyp;
if (ret->pub_key == NULL &&
(ret->pub_key = EC_POINT_new(ret->group)) == NULL) {
- OPENSSL_PUT_ERROR(EC, o2i_ECPublicKey, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE);
return 0;
}
if (!EC_POINT_oct2point(ret->group, ret->pub_key, *inp, len, NULL)) {
- OPENSSL_PUT_ERROR(EC, o2i_ECPublicKey, ERR_R_EC_LIB);
+ OPENSSL_PUT_ERROR(EC, ERR_R_EC_LIB);
return 0;
}
/* save the point conversion form */
@@ -541,7 +540,7 @@ int i2o_ECPublicKey(const EC_KEY *key, uint8_t **outp) {
int new_buffer = 0;
if (key == NULL) {
- OPENSSL_PUT_ERROR(EC, i2o_ECPublicKey, ERR_R_PASSED_NULL_PARAMETER);
+ OPENSSL_PUT_ERROR(EC, ERR_R_PASSED_NULL_PARAMETER);
return 0;
}
@@ -556,14 +555,14 @@ int i2o_ECPublicKey(const EC_KEY *key, uint8_t **outp) {
if (*outp == NULL) {
*outp = OPENSSL_malloc(buf_len);
if (*outp == NULL) {
- OPENSSL_PUT_ERROR(EC, i2o_ECPublicKey, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE);
return 0;
}
new_buffer = 1;
}
if (!EC_POINT_point2oct(key->group, key->pub_key, key->conv_form, *outp,
buf_len, NULL)) {
- OPENSSL_PUT_ERROR(EC, i2o_ECPublicKey, ERR_R_EC_LIB);
+ OPENSSL_PUT_ERROR(EC, ERR_R_EC_LIB);
if (new_buffer) {
OPENSSL_free(*outp);
*outp = NULL;
diff --git a/src/crypto/ec/ec_key.c b/src/crypto/ec/ec_key.c
index e5cbfed..0defa98 100644
--- a/src/crypto/ec/ec_key.c
+++ b/src/crypto/ec/ec_key.c
@@ -87,7 +87,7 @@ EC_KEY *EC_KEY_new(void) { return EC_KEY_new_method(NULL); }
EC_KEY *EC_KEY_new_method(const ENGINE *engine) {
EC_KEY *ret = (EC_KEY *)OPENSSL_malloc(sizeof(EC_KEY));
if (ret == NULL) {
- OPENSSL_PUT_ERROR(EC, EC_KEY_new_method, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE);
return NULL;
}
@@ -127,7 +127,7 @@ err1:
EC_KEY *EC_KEY_new_by_curve_name(int nid) {
EC_KEY *ret = EC_KEY_new();
if (ret == NULL) {
- OPENSSL_PUT_ERROR(EC, EC_KEY_new_by_curve_name, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE);
return NULL;
}
ret->group = EC_GROUP_new_by_curve_name(nid);
@@ -166,7 +166,7 @@ void EC_KEY_free(EC_KEY *r) {
EC_KEY *EC_KEY_copy(EC_KEY *dest, const EC_KEY *src) {
if (dest == NULL || src == NULL) {
- OPENSSL_PUT_ERROR(EC, EC_KEY_copy, ERR_R_PASSED_NULL_PARAMETER);
+ OPENSSL_PUT_ERROR(EC, ERR_R_PASSED_NULL_PARAMETER);
return NULL;
}
/* Copy the parameters. */
@@ -300,12 +300,12 @@ int EC_KEY_check_key(const EC_KEY *eckey) {
EC_POINT *point = NULL;
if (!eckey || !eckey->group || !eckey->pub_key) {
- OPENSSL_PUT_ERROR(EC, EC_KEY_check_key, ERR_R_PASSED_NULL_PARAMETER);
+ OPENSSL_PUT_ERROR(EC, ERR_R_PASSED_NULL_PARAMETER);
return 0;
}
if (EC_POINT_is_at_infinity(eckey->group, eckey->pub_key)) {
- OPENSSL_PUT_ERROR(EC, EC_KEY_check_key, EC_R_POINT_AT_INFINITY);
+ OPENSSL_PUT_ERROR(EC, EC_R_POINT_AT_INFINITY);
goto err;
}
@@ -319,7 +319,7 @@ int EC_KEY_check_key(const EC_KEY *eckey) {
/* testing whether the pub_key is on the elliptic curve */
if (!EC_POINT_is_on_curve(eckey->group, eckey->pub_key, ctx)) {
- OPENSSL_PUT_ERROR(EC, EC_KEY_check_key, EC_R_POINT_IS_NOT_ON_CURVE);
+ OPENSSL_PUT_ERROR(EC, EC_R_POINT_IS_NOT_ON_CURVE);
goto err;
}
/* testing whether pub_key * order is the point at infinity */
@@ -327,15 +327,15 @@ int EC_KEY_check_key(const EC_KEY *eckey) {
* to check the private key, below? */
order = &eckey->group->order;
if (BN_is_zero(order)) {
- OPENSSL_PUT_ERROR(EC, EC_KEY_check_key, EC_R_INVALID_GROUP_ORDER);
+ OPENSSL_PUT_ERROR(EC, EC_R_INVALID_GROUP_ORDER);
goto err;
}
if (!EC_POINT_mul(eckey->group, point, NULL, eckey->pub_key, order, ctx)) {
- OPENSSL_PUT_ERROR(EC, EC_KEY_check_key, ERR_R_EC_LIB);
+ OPENSSL_PUT_ERROR(EC, ERR_R_EC_LIB);
goto err;
}
if (!EC_POINT_is_at_infinity(eckey->group, point)) {
- OPENSSL_PUT_ERROR(EC, EC_KEY_check_key, EC_R_WRONG_ORDER);
+ OPENSSL_PUT_ERROR(EC, EC_R_WRONG_ORDER);
goto err;
}
/* in case the priv_key is present :
@@ -343,15 +343,15 @@ int EC_KEY_check_key(const EC_KEY *eckey) {
*/
if (eckey->priv_key) {
if (BN_cmp(eckey->priv_key, order) >= 0) {
- OPENSSL_PUT_ERROR(EC, EC_KEY_check_key, EC_R_WRONG_ORDER);
+ OPENSSL_PUT_ERROR(EC, EC_R_WRONG_ORDER);
goto err;
}
if (!EC_POINT_mul(eckey->group, point, eckey->priv_key, NULL, NULL, ctx)) {
- OPENSSL_PUT_ERROR(EC, EC_KEY_check_key, ERR_R_EC_LIB);
+ OPENSSL_PUT_ERROR(EC, ERR_R_EC_LIB);
goto err;
}
if (EC_POINT_cmp(eckey->group, point, eckey->pub_key, ctx) != 0) {
- OPENSSL_PUT_ERROR(EC, EC_KEY_check_key, EC_R_INVALID_PRIVATE_KEY);
+ OPENSSL_PUT_ERROR(EC, EC_R_INVALID_PRIVATE_KEY);
goto err;
}
}
@@ -371,8 +371,7 @@ int EC_KEY_set_public_key_affine_coordinates(EC_KEY *key, BIGNUM *x,
int ok = 0;
if (!key || !key->group || !x || !y) {
- OPENSSL_PUT_ERROR(EC, EC_KEY_set_public_key_affine_coordinates,
- ERR_R_PASSED_NULL_PARAMETER);
+ OPENSSL_PUT_ERROR(EC, ERR_R_PASSED_NULL_PARAMETER);
return 0;
}
ctx = BN_CTX_new();
@@ -394,8 +393,7 @@ int EC_KEY_set_public_key_affine_coordinates(EC_KEY *key, BIGNUM *x,
/* Check if retrieved coordinates match originals: if not values
* are out of range. */
if (BN_cmp(x, tx) || BN_cmp(y, ty)) {
- OPENSSL_PUT_ERROR(EC, EC_KEY_set_public_key_affine_coordinates,
- EC_R_COORDINATES_OUT_OF_RANGE);
+ OPENSSL_PUT_ERROR(EC, EC_R_COORDINATES_OUT_OF_RANGE);
goto err;
}
@@ -422,7 +420,7 @@ int EC_KEY_generate_key(EC_KEY *eckey) {
EC_POINT *pub_key = NULL;
if (!eckey || !eckey->group) {
- OPENSSL_PUT_ERROR(EC, EC_KEY_generate_key, ERR_R_PASSED_NULL_PARAMETER);
+ OPENSSL_PUT_ERROR(EC, ERR_R_PASSED_NULL_PARAMETER);
return 0;
}
diff --git a/src/crypto/ec/ec_montgomery.c b/src/crypto/ec/ec_montgomery.c
index 74dbc6c..b897000 100644
--- a/src/crypto/ec/ec_montgomery.c
+++ b/src/crypto/ec/ec_montgomery.c
@@ -200,7 +200,7 @@ int ec_GFp_mont_group_set_curve(EC_GROUP *group, const BIGNUM *p,
goto err;
}
if (!BN_MONT_CTX_set(mont, p, ctx)) {
- OPENSSL_PUT_ERROR(EC, ec_GFp_mont_group_set_curve, ERR_R_BN_LIB);
+ OPENSSL_PUT_ERROR(EC, ERR_R_BN_LIB);
goto err;
}
one = BN_new();
@@ -232,7 +232,7 @@ err:
int ec_GFp_mont_field_mul(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a,
const BIGNUM *b, BN_CTX *ctx) {
if (group->mont == NULL) {
- OPENSSL_PUT_ERROR(EC, ec_GFp_mont_field_mul, EC_R_NOT_INITIALIZED);
+ OPENSSL_PUT_ERROR(EC, EC_R_NOT_INITIALIZED);
return 0;
}
@@ -242,7 +242,7 @@ int ec_GFp_mont_field_mul(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a,
int ec_GFp_mont_field_sqr(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a,
BN_CTX *ctx) {
if (group->mont == NULL) {
- OPENSSL_PUT_ERROR(EC, ec_GFp_mont_field_sqr, EC_R_NOT_INITIALIZED);
+ OPENSSL_PUT_ERROR(EC, EC_R_NOT_INITIALIZED);
return 0;
}
@@ -252,7 +252,7 @@ int ec_GFp_mont_field_sqr(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a,
int ec_GFp_mont_field_encode(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a,
BN_CTX *ctx) {
if (group->mont == NULL) {
- OPENSSL_PUT_ERROR(EC, ec_GFp_mont_field_encode, EC_R_NOT_INITIALIZED);
+ OPENSSL_PUT_ERROR(EC, EC_R_NOT_INITIALIZED);
return 0;
}
@@ -262,7 +262,7 @@ int ec_GFp_mont_field_encode(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a,
int ec_GFp_mont_field_decode(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a,
BN_CTX *ctx) {
if (group->mont == NULL) {
- OPENSSL_PUT_ERROR(EC, ec_GFp_mont_field_decode, EC_R_NOT_INITIALIZED);
+ OPENSSL_PUT_ERROR(EC, EC_R_NOT_INITIALIZED);
return 0;
}
@@ -272,7 +272,7 @@ int ec_GFp_mont_field_decode(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a,
int ec_GFp_mont_field_set_to_one(const EC_GROUP *group, BIGNUM *r,
BN_CTX *ctx) {
if (group->one == NULL) {
- OPENSSL_PUT_ERROR(EC, ec_GFp_mont_field_set_to_one, EC_R_NOT_INITIALIZED);
+ OPENSSL_PUT_ERROR(EC, EC_R_NOT_INITIALIZED);
return 0;
}
diff --git a/src/crypto/ec/oct.c b/src/crypto/ec/oct.c
index 816a42f..cb50e17 100644
--- a/src/crypto/ec/oct.c
+++ b/src/crypto/ec/oct.c
@@ -85,7 +85,7 @@ static size_t ec_GFp_simple_point2oct(const EC_GROUP *group,
if ((form != POINT_CONVERSION_COMPRESSED) &&
(form != POINT_CONVERSION_UNCOMPRESSED)) {
- OPENSSL_PUT_ERROR(EC, ec_GFp_simple_point2oct, EC_R_INVALID_FORM);
+ OPENSSL_PUT_ERROR(EC, EC_R_INVALID_FORM);
goto err;
}
@@ -93,7 +93,7 @@ static size_t ec_GFp_simple_point2oct(const EC_GROUP *group,
/* encodes to a single 0 octet */
if (buf != NULL) {
if (len < 1) {
- OPENSSL_PUT_ERROR(EC, ec_GFp_simple_point2oct, EC_R_BUFFER_TOO_SMALL);
+ OPENSSL_PUT_ERROR(EC, EC_R_BUFFER_TOO_SMALL);
return 0;
}
buf[0] = 0;
@@ -110,7 +110,7 @@ static size_t ec_GFp_simple_point2oct(const EC_GROUP *group,
/* if 'buf' is NULL, just return required length */
if (buf != NULL) {
if (len < ret) {
- OPENSSL_PUT_ERROR(EC, ec_GFp_simple_point2oct, EC_R_BUFFER_TOO_SMALL);
+ OPENSSL_PUT_ERROR(EC, EC_R_BUFFER_TOO_SMALL);
goto err;
}
@@ -142,21 +142,21 @@ static size_t ec_GFp_simple_point2oct(const EC_GROUP *group,
i = 1;
if (!BN_bn2bin_padded(buf + i, field_len, x)) {
- OPENSSL_PUT_ERROR(EC, ec_GFp_simple_point2oct, ERR_R_INTERNAL_ERROR);
+ OPENSSL_PUT_ERROR(EC, ERR_R_INTERNAL_ERROR);
goto err;
}
i += field_len;
if (form == POINT_CONVERSION_UNCOMPRESSED) {
if (!BN_bn2bin_padded(buf + i, field_len, y)) {
- OPENSSL_PUT_ERROR(EC, ec_GFp_simple_point2oct, ERR_R_INTERNAL_ERROR);
+ OPENSSL_PUT_ERROR(EC, ERR_R_INTERNAL_ERROR);
goto err;
}
i += field_len;
}
if (i != ret) {
- OPENSSL_PUT_ERROR(EC, ec_GFp_simple_point2oct, ERR_R_INTERNAL_ERROR);
+ OPENSSL_PUT_ERROR(EC, ERR_R_INTERNAL_ERROR);
goto err;
}
}
@@ -187,7 +187,7 @@ static int ec_GFp_simple_oct2point(const EC_GROUP *group, EC_POINT *point,
int ret = 0;
if (len == 0) {
- OPENSSL_PUT_ERROR(EC, ec_GFp_simple_oct2point, EC_R_BUFFER_TOO_SMALL);
+ OPENSSL_PUT_ERROR(EC, EC_R_BUFFER_TOO_SMALL);
return 0;
}
form = buf[0];
@@ -195,17 +195,17 @@ static int ec_GFp_simple_oct2point(const EC_GROUP *group, EC_POINT *point,
form = form & ~1U;
if ((form != 0) && (form != POINT_CONVERSION_COMPRESSED) &&
(form != POINT_CONVERSION_UNCOMPRESSED)) {
- OPENSSL_PUT_ERROR(EC, ec_GFp_simple_oct2point, EC_R_INVALID_ENCODING);
+ OPENSSL_PUT_ERROR(EC, EC_R_INVALID_ENCODING);
return 0;
}
if ((form == 0 || form == POINT_CONVERSION_UNCOMPRESSED) && y_bit) {
- OPENSSL_PUT_ERROR(EC, ec_GFp_simple_oct2point, EC_R_INVALID_ENCODING);
+ OPENSSL_PUT_ERROR(EC, EC_R_INVALID_ENCODING);
return 0;
}
if (form == 0) {
if (len != 1) {
- OPENSSL_PUT_ERROR(EC, ec_GFp_simple_oct2point, EC_R_INVALID_ENCODING);
+ OPENSSL_PUT_ERROR(EC, EC_R_INVALID_ENCODING);
return 0;
}
@@ -217,7 +217,7 @@ static int ec_GFp_simple_oct2point(const EC_GROUP *group, EC_POINT *point,
(form == POINT_CONVERSION_COMPRESSED) ? 1 + field_len : 1 + 2 * field_len;
if (len != enc_len) {
- OPENSSL_PUT_ERROR(EC, ec_GFp_simple_oct2point, EC_R_INVALID_ENCODING);
+ OPENSSL_PUT_ERROR(EC, EC_R_INVALID_ENCODING);
return 0;
}
@@ -231,7 +231,7 @@ static int ec_GFp_simple_oct2point(const EC_GROUP *group, EC_POINT *point,
BN_CTX_start(ctx);
x = BN_CTX_get(ctx);
y = BN_CTX_get(ctx);
- if (y == NULL) {
+ if (x == NULL || y == NULL) {
goto err;
}
@@ -239,7 +239,7 @@ static int ec_GFp_simple_oct2point(const EC_GROUP *group, EC_POINT *point,
goto err;
}
if (BN_ucmp(x, &group->field) >= 0) {
- OPENSSL_PUT_ERROR(EC, ec_GFp_simple_oct2point, EC_R_INVALID_ENCODING);
+ OPENSSL_PUT_ERROR(EC, EC_R_INVALID_ENCODING);
goto err;
}
@@ -252,7 +252,7 @@ static int ec_GFp_simple_oct2point(const EC_GROUP *group, EC_POINT *point,
goto err;
}
if (BN_ucmp(y, &group->field) >= 0) {
- OPENSSL_PUT_ERROR(EC, ec_GFp_simple_oct2point, EC_R_INVALID_ENCODING);
+ OPENSSL_PUT_ERROR(EC, EC_R_INVALID_ENCODING);
goto err;
}
@@ -263,7 +263,7 @@ static int ec_GFp_simple_oct2point(const EC_GROUP *group, EC_POINT *point,
/* test required by X9.62 */
if (!EC_POINT_is_on_curve(group, point, ctx)) {
- OPENSSL_PUT_ERROR(EC, ec_GFp_simple_oct2point, EC_R_POINT_IS_NOT_ON_CURVE);
+ OPENSSL_PUT_ERROR(EC, EC_R_POINT_IS_NOT_ON_CURVE);
goto err;
}
@@ -279,12 +279,11 @@ int EC_POINT_oct2point(const EC_GROUP *group, EC_POINT *point,
const uint8_t *buf, size_t len, BN_CTX *ctx) {
if (group->meth->oct2point == 0 &&
!(group->meth->flags & EC_FLAGS_DEFAULT_OCT)) {
- OPENSSL_PUT_ERROR(EC, EC_POINT_oct2point,
- ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+ OPENSSL_PUT_ERROR(EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
return 0;
}
if (group->meth != point->meth) {
- OPENSSL_PUT_ERROR(EC, EC_POINT_oct2point, EC_R_INCOMPATIBLE_OBJECTS);
+ OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
return 0;
}
if (group->meth->flags & EC_FLAGS_DEFAULT_OCT) {
@@ -299,12 +298,11 @@ size_t EC_POINT_point2oct(const EC_GROUP *group, const EC_POINT *point,
size_t len, BN_CTX *ctx) {
if (group->meth->point2oct == 0 &&
!(group->meth->flags & EC_FLAGS_DEFAULT_OCT)) {
- OPENSSL_PUT_ERROR(EC, EC_POINT_point2oct,
- ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+ OPENSSL_PUT_ERROR(EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
return 0;
}
if (group->meth != point->meth) {
- OPENSSL_PUT_ERROR(EC, EC_POINT_point2oct, EC_R_INCOMPATIBLE_OBJECTS);
+ OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
return 0;
}
if (group->meth->flags & EC_FLAGS_DEFAULT_OCT) {
@@ -406,9 +404,9 @@ int ec_GFp_simple_set_compressed_coordinates(const EC_GROUP *group,
if (ERR_GET_LIB(err) == ERR_LIB_BN &&
ERR_GET_REASON(err) == BN_R_NOT_A_SQUARE) {
ERR_clear_error();
- OPENSSL_PUT_ERROR(EC, ec_GFp_simple_set_compressed_coordinates, EC_R_INVALID_COMPRESSED_POINT);
+ OPENSSL_PUT_ERROR(EC, EC_R_INVALID_COMPRESSED_POINT);
} else {
- OPENSSL_PUT_ERROR(EC, ec_GFp_simple_set_compressed_coordinates, ERR_R_BN_LIB);
+ OPENSSL_PUT_ERROR(EC, ERR_R_BN_LIB);
}
goto err;
}
@@ -423,12 +421,10 @@ int ec_GFp_simple_set_compressed_coordinates(const EC_GROUP *group,
}
if (kron == 1) {
- OPENSSL_PUT_ERROR(EC, ec_GFp_simple_set_compressed_coordinates,
- EC_R_INVALID_COMPRESSION_BIT);
+ OPENSSL_PUT_ERROR(EC, EC_R_INVALID_COMPRESSION_BIT);
} else {
/* BN_mod_sqrt() should have cought this error (not a square) */
- OPENSSL_PUT_ERROR(EC, ec_GFp_simple_set_compressed_coordinates,
- EC_R_INVALID_COMPRESSED_POINT);
+ OPENSSL_PUT_ERROR(EC, EC_R_INVALID_COMPRESSED_POINT);
}
goto err;
}
@@ -437,8 +433,7 @@ int ec_GFp_simple_set_compressed_coordinates(const EC_GROUP *group,
}
}
if (y_bit != BN_is_odd(y)) {
- OPENSSL_PUT_ERROR(EC, ec_GFp_simple_set_compressed_coordinates,
- ERR_R_INTERNAL_ERROR);
+ OPENSSL_PUT_ERROR(EC, ERR_R_INTERNAL_ERROR);
goto err;
}
@@ -459,13 +454,11 @@ int EC_POINT_set_compressed_coordinates_GFp(const EC_GROUP *group,
int y_bit, BN_CTX *ctx) {
if (group->meth->point_set_compressed_coordinates == 0 &&
!(group->meth->flags & EC_FLAGS_DEFAULT_OCT)) {
- OPENSSL_PUT_ERROR(EC, EC_POINT_set_compressed_coordinates_GFp,
- ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+ OPENSSL_PUT_ERROR(EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
return 0;
}
if (group->meth != point->meth) {
- OPENSSL_PUT_ERROR(EC, EC_POINT_set_compressed_coordinates_GFp,
- EC_R_INCOMPATIBLE_OBJECTS);
+ OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
return 0;
}
if (group->meth->flags & EC_FLAGS_DEFAULT_OCT) {
diff --git a/src/crypto/ec/p256-64.c b/src/crypto/ec/p256-64.c
index fdb942c..3946b29 100644
--- a/src/crypto/ec/p256-64.c
+++ b/src/crypto/ec/p256-64.c
@@ -125,7 +125,7 @@ static void flip_endian(u8 *out, const u8 *in, unsigned len) {
/* BN_to_felem converts an OpenSSL BIGNUM into an felem. */
static int BN_to_felem(felem out, const BIGNUM *bn) {
if (BN_is_negative(bn)) {
- OPENSSL_PUT_ERROR(EC, BN_to_felem, EC_R_BIGNUM_OUT_OF_RANGE);
+ OPENSSL_PUT_ERROR(EC, EC_R_BIGNUM_OUT_OF_RANGE);
return 0;
}
@@ -134,7 +134,7 @@ static int BN_to_felem(felem out, const BIGNUM *bn) {
memset(b_out, 0, sizeof(b_out));
unsigned num_bytes = BN_num_bytes(bn);
if (num_bytes > sizeof(b_out)) {
- OPENSSL_PUT_ERROR(EC, BN_to_felem, EC_R_BIGNUM_OUT_OF_RANGE);
+ OPENSSL_PUT_ERROR(EC, EC_R_BIGNUM_OUT_OF_RANGE);
return 0;
}
@@ -1638,8 +1638,7 @@ int ec_GFp_nistp256_group_set_curve(EC_GROUP *group, const BIGNUM *p,
if (BN_cmp(curve_p, p) ||
BN_cmp(curve_a, a) ||
BN_cmp(curve_b, b)) {
- OPENSSL_PUT_ERROR(EC, ec_GFp_nistp256_group_set_curve,
- EC_R_WRONG_CURVE_PARAMETERS);
+ OPENSSL_PUT_ERROR(EC, EC_R_WRONG_CURVE_PARAMETERS);
goto err;
}
ret = ec_GFp_simple_group_set_curve(group, p, a, b, ctx);
@@ -1661,8 +1660,7 @@ int ec_GFp_nistp256_point_get_affine_coordinates(const EC_GROUP *group,
longfelem tmp;
if (EC_POINT_is_at_infinity(group, point)) {
- OPENSSL_PUT_ERROR(EC, ec_GFp_nistp256_point_get_affine_coordinates,
- EC_R_POINT_AT_INFINITY);
+ OPENSSL_PUT_ERROR(EC, EC_R_POINT_AT_INFINITY);
return 0;
}
if (!BN_to_felem(x_in, &point->X) ||
@@ -1677,8 +1675,7 @@ int ec_GFp_nistp256_point_get_affine_coordinates(const EC_GROUP *group,
felem_reduce(x_in, tmp);
felem_contract(x_out, x_in);
if (x != NULL && !smallfelem_to_BN(x, x_out)) {
- OPENSSL_PUT_ERROR(EC, ec_GFp_nistp256_point_get_affine_coordinates,
- ERR_R_BN_LIB);
+ OPENSSL_PUT_ERROR(EC, ERR_R_BN_LIB);
return 0;
}
felem_mul(tmp, z1, z2);
@@ -1687,8 +1684,7 @@ int ec_GFp_nistp256_point_get_affine_coordinates(const EC_GROUP *group,
felem_reduce(y_in, tmp);
felem_contract(y_out, y_in);
if (y != NULL && !smallfelem_to_BN(y, y_out)) {
- OPENSSL_PUT_ERROR(EC, ec_GFp_nistp256_point_get_affine_coordinates,
- ERR_R_BN_LIB);
+ OPENSSL_PUT_ERROR(EC, ERR_R_BN_LIB);
return 0;
}
return 1;
@@ -1763,7 +1759,7 @@ int ec_GFp_nistp256_points_mul(const EC_GROUP *group, EC_POINT *r,
if (!smallfelem_to_BN(x, g_pre_comp[0][1][0]) ||
!smallfelem_to_BN(y, g_pre_comp[0][1][1]) ||
!smallfelem_to_BN(z, g_pre_comp[0][1][2])) {
- OPENSSL_PUT_ERROR(EC, ec_GFp_nistp256_points_mul, ERR_R_BN_LIB);
+ OPENSSL_PUT_ERROR(EC, ERR_R_BN_LIB);
goto err;
}
if (!ec_point_set_Jprojective_coordinates_GFp(group, generator, x, y, z,
@@ -1794,7 +1790,7 @@ int ec_GFp_nistp256_points_mul(const EC_GROUP *group, EC_POINT *r,
}
if (secrets == NULL || pre_comp == NULL ||
(mixed && tmp_smallfelems == NULL)) {
- OPENSSL_PUT_ERROR(EC, ec_GFp_nistp256_points_mul, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE);
goto err;
}
@@ -1818,7 +1814,7 @@ int ec_GFp_nistp256_points_mul(const EC_GROUP *group, EC_POINT *r,
/* this is an unusual input, and we don't guarantee
* constant-timeness. */
if (!BN_nnmod(tmp_scalar, p_scalar, &group->order, ctx)) {
- OPENSSL_PUT_ERROR(EC, ec_GFp_nistp256_points_mul, ERR_R_BN_LIB);
+ OPENSSL_PUT_ERROR(EC, ERR_R_BN_LIB);
goto err;
}
num_bytes = BN_bn2bin(tmp_scalar, tmp);
@@ -1863,7 +1859,7 @@ int ec_GFp_nistp256_points_mul(const EC_GROUP *group, EC_POINT *r,
/* this is an unusual input, and we don't guarantee
* constant-timeness. */
if (!BN_nnmod(tmp_scalar, scalar, &group->order, ctx)) {
- OPENSSL_PUT_ERROR(EC, ec_GFp_nistp256_points_mul, ERR_R_BN_LIB);
+ OPENSSL_PUT_ERROR(EC, ERR_R_BN_LIB);
goto err;
}
num_bytes = BN_bn2bin(tmp_scalar, tmp);
@@ -1889,7 +1885,7 @@ int ec_GFp_nistp256_points_mul(const EC_GROUP *group, EC_POINT *r,
if (!smallfelem_to_BN(x, x_in) ||
!smallfelem_to_BN(y, y_in) ||
!smallfelem_to_BN(z, z_in)) {
- OPENSSL_PUT_ERROR(EC, ec_GFp_nistp256_points_mul, ERR_R_BN_LIB);
+ OPENSSL_PUT_ERROR(EC, ERR_R_BN_LIB);
goto err;
}
ret = ec_point_set_Jprojective_coordinates_GFp(group, r, x, y, z, ctx);
diff --git a/src/crypto/ec/simple.c b/src/crypto/ec/simple.c
index 69fd2e4..c62199c 100644
--- a/src/crypto/ec/simple.c
+++ b/src/crypto/ec/simple.c
@@ -172,7 +172,7 @@ int ec_GFp_simple_group_set_curve(EC_GROUP *group, const BIGNUM *p,
/* p must be a prime > 3 */
if (BN_num_bits(p) <= 2 || !BN_is_odd(p)) {
- OPENSSL_PUT_ERROR(EC, ec_GFp_simple_group_set_curve, EC_R_INVALID_FIELD);
+ OPENSSL_PUT_ERROR(EC, EC_R_INVALID_FIELD);
return 0;
}
@@ -283,8 +283,7 @@ int ec_GFp_simple_group_check_discriminant(const EC_GROUP *group, BN_CTX *ctx) {
if (ctx == NULL) {
ctx = new_ctx = BN_CTX_new();
if (ctx == NULL) {
- OPENSSL_PUT_ERROR(EC, ec_GFp_simple_group_check_discriminant,
- ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE);
goto err;
}
}
@@ -492,8 +491,7 @@ int ec_GFp_simple_point_set_affine_coordinates(const EC_GROUP *group,
const BIGNUM *y, BN_CTX *ctx) {
if (x == NULL || y == NULL) {
/* unlike for projective coordinates, we do not tolerate this */
- OPENSSL_PUT_ERROR(EC, ec_GFp_simple_point_set_affine_coordinates,
- ERR_R_PASSED_NULL_PARAMETER);
+ OPENSSL_PUT_ERROR(EC, ERR_R_PASSED_NULL_PARAMETER);
return 0;
}
@@ -510,8 +508,7 @@ int ec_GFp_simple_point_get_affine_coordinates(const EC_GROUP *group,
int ret = 0;
if (EC_POINT_is_at_infinity(group, point)) {
- OPENSSL_PUT_ERROR(EC, ec_GFp_simple_point_get_affine_coordinates,
- EC_R_POINT_AT_INFINITY);
+ OPENSSL_PUT_ERROR(EC, EC_R_POINT_AT_INFINITY);
return 0;
}
@@ -527,7 +524,7 @@ int ec_GFp_simple_point_get_affine_coordinates(const EC_GROUP *group,
Z_1 = BN_CTX_get(ctx);
Z_2 = BN_CTX_get(ctx);
Z_3 = BN_CTX_get(ctx);
- if (Z_3 == NULL) {
+ if (Z == NULL || Z_1 == NULL || Z_2 == NULL || Z_3 == NULL) {
goto err;
}
@@ -560,8 +557,7 @@ int ec_GFp_simple_point_get_affine_coordinates(const EC_GROUP *group,
}
} else {
if (!BN_mod_inverse(Z_1, Z_, &group->field, ctx)) {
- OPENSSL_PUT_ERROR(EC, ec_GFp_simple_point_get_affine_coordinates,
- ERR_R_BN_LIB);
+ OPENSSL_PUT_ERROR(EC, ERR_R_BN_LIB);
goto err;
}
@@ -1183,7 +1179,7 @@ int ec_GFp_simple_make_affine(const EC_GROUP *group, EC_POINT *point,
goto err;
}
if (!point->Z_is_one) {
- OPENSSL_PUT_ERROR(EC, ec_GFp_simple_make_affine, ERR_R_INTERNAL_ERROR);
+ OPENSSL_PUT_ERROR(EC, ERR_R_INTERNAL_ERROR);
goto err;
}
@@ -1269,7 +1265,7 @@ int ec_GFp_simple_points_make_affine(const EC_GROUP *group, size_t num,
* non-zero points[i]->Z by its inverse. */
if (!BN_mod_inverse(tmp, prod_Z[num - 1], &group->field, ctx)) {
- OPENSSL_PUT_ERROR(EC, ec_GFp_simple_points_make_affine, ERR_R_BN_LIB);
+ OPENSSL_PUT_ERROR(EC, ERR_R_BN_LIB);
goto err;
}
diff --git a/src/crypto/ec/wnaf.c b/src/crypto/ec/wnaf.c
index ae0d73f..7fa0e1b 100644
--- a/src/crypto/ec/wnaf.c
+++ b/src/crypto/ec/wnaf.c
@@ -100,7 +100,7 @@ static EC_PRE_COMP *ec_pre_comp_new(void) {
ret = (EC_PRE_COMP *)OPENSSL_malloc(sizeof(EC_PRE_COMP));
if (!ret) {
- OPENSSL_PUT_ERROR(EC, ec_pre_comp_new, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE);
return ret;
}
ret->blocksize = 8; /* default */
@@ -158,7 +158,7 @@ static signed char *compute_wNAF(const BIGNUM *scalar, int w, size_t *ret_len) {
if (BN_is_zero(scalar)) {
r = OPENSSL_malloc(1);
if (!r) {
- OPENSSL_PUT_ERROR(EC, compute_wNAF, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE);
goto err;
}
r[0] = 0;
@@ -169,7 +169,7 @@ static signed char *compute_wNAF(const BIGNUM *scalar, int w, size_t *ret_len) {
if (w <= 0 || w > 7) /* 'signed char' can represent integers with absolute
values less than 2^7 */
{
- OPENSSL_PUT_ERROR(EC, compute_wNAF, ERR_R_INTERNAL_ERROR);
+ OPENSSL_PUT_ERROR(EC, ERR_R_INTERNAL_ERROR);
goto err;
}
bit = 1 << w; /* at most 128 */
@@ -181,7 +181,7 @@ static signed char *compute_wNAF(const BIGNUM *scalar, int w, size_t *ret_len) {
}
if (scalar->d == NULL || scalar->top == 0) {
- OPENSSL_PUT_ERROR(EC, compute_wNAF, ERR_R_INTERNAL_ERROR);
+ OPENSSL_PUT_ERROR(EC, ERR_R_INTERNAL_ERROR);
goto err;
}
@@ -192,7 +192,7 @@ static signed char *compute_wNAF(const BIGNUM *scalar, int w, size_t *ret_len) {
* (*ret_len will be set to the actual length, i.e. at most
* BN_num_bits(scalar) + 1) */
if (r == NULL) {
- OPENSSL_PUT_ERROR(EC, compute_wNAF, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE);
goto err;
}
window_val = scalar->d[0] & mask;
@@ -225,7 +225,7 @@ static signed char *compute_wNAF(const BIGNUM *scalar, int w, size_t *ret_len) {
}
if (digit <= -bit || digit >= bit || !(digit & 1)) {
- OPENSSL_PUT_ERROR(EC, compute_wNAF, ERR_R_INTERNAL_ERROR);
+ OPENSSL_PUT_ERROR(EC, ERR_R_INTERNAL_ERROR);
goto err;
}
@@ -235,7 +235,7 @@ static signed char *compute_wNAF(const BIGNUM *scalar, int w, size_t *ret_len) {
* for modified window NAFs, it may also be 2^w
*/
if (window_val != 0 && window_val != next_bit && window_val != bit) {
- OPENSSL_PUT_ERROR(EC, compute_wNAF, ERR_R_INTERNAL_ERROR);
+ OPENSSL_PUT_ERROR(EC, ERR_R_INTERNAL_ERROR);
goto err;
}
}
@@ -246,13 +246,13 @@ static signed char *compute_wNAF(const BIGNUM *scalar, int w, size_t *ret_len) {
window_val += bit * BN_is_bit_set(scalar, j + w);
if (window_val > next_bit) {
- OPENSSL_PUT_ERROR(EC, compute_wNAF, ERR_R_INTERNAL_ERROR);
+ OPENSSL_PUT_ERROR(EC, ERR_R_INTERNAL_ERROR);
goto err;
}
}
if (j > len + 1) {
- OPENSSL_PUT_ERROR(EC, compute_wNAF, ERR_R_INTERNAL_ERROR);
+ OPENSSL_PUT_ERROR(EC, ERR_R_INTERNAL_ERROR);
goto err;
}
len = j;
@@ -316,7 +316,7 @@ int ec_wNAF_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
int ret = 0;
if (group->meth != r->meth) {
- OPENSSL_PUT_ERROR(EC, ec_wNAF_mul, EC_R_INCOMPATIBLE_OBJECTS);
+ OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
return 0;
}
@@ -326,7 +326,7 @@ int ec_wNAF_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
for (i = 0; i < num; i++) {
if (group->meth != points[i]->meth) {
- OPENSSL_PUT_ERROR(EC, ec_wNAF_mul, EC_R_INCOMPATIBLE_OBJECTS);
+ OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS);
return 0;
}
}
@@ -341,7 +341,7 @@ int ec_wNAF_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
if (scalar != NULL) {
generator = EC_GROUP_get0_generator(group);
if (generator == NULL) {
- OPENSSL_PUT_ERROR(EC, ec_wNAF_mul, EC_R_UNDEFINED_GENERATOR);
+ OPENSSL_PUT_ERROR(EC, EC_R_UNDEFINED_GENERATOR);
goto err;
}
@@ -366,7 +366,7 @@ int ec_wNAF_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
/* check that pre_comp looks sane */
if (pre_comp->num != (pre_comp->numblocks * pre_points_per_block)) {
- OPENSSL_PUT_ERROR(EC, ec_wNAF_mul, ERR_R_INTERNAL_ERROR);
+ OPENSSL_PUT_ERROR(EC, ERR_R_INTERNAL_ERROR);
goto err;
}
} else {
@@ -391,7 +391,7 @@ int ec_wNAF_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
}
if (!wsize || !wNAF_len || !wNAF || !val_sub) {
- OPENSSL_PUT_ERROR(EC, ec_wNAF_mul, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE);
goto err;
}
@@ -420,7 +420,7 @@ int ec_wNAF_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
if (pre_comp == NULL) {
if (num_scalar != 1) {
- OPENSSL_PUT_ERROR(EC, ec_wNAF_mul, ERR_R_INTERNAL_ERROR);
+ OPENSSL_PUT_ERROR(EC, ERR_R_INTERNAL_ERROR);
goto err;
}
/* we have already generated a wNAF for 'scalar' */
@@ -429,7 +429,7 @@ int ec_wNAF_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
size_t tmp_len = 0;
if (num_scalar != 0) {
- OPENSSL_PUT_ERROR(EC, ec_wNAF_mul, ERR_R_INTERNAL_ERROR);
+ OPENSSL_PUT_ERROR(EC, ERR_R_INTERNAL_ERROR);
goto err;
}
@@ -463,7 +463,8 @@ int ec_wNAF_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
/* possibly we can do with fewer blocks than estimated */
numblocks = (tmp_len + blocksize - 1) / blocksize;
if (numblocks > pre_comp->numblocks) {
- OPENSSL_PUT_ERROR(EC, ec_wNAF_mul, ERR_R_INTERNAL_ERROR);
+ OPENSSL_PUT_ERROR(EC, ERR_R_INTERNAL_ERROR);
+ OPENSSL_free(tmp_wNAF);
goto err;
}
totalnum = num + numblocks;
@@ -477,7 +478,8 @@ int ec_wNAF_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
if (i < totalnum - 1) {
wNAF_len[i] = blocksize;
if (tmp_len < blocksize) {
- OPENSSL_PUT_ERROR(EC, ec_wNAF_mul, ERR_R_INTERNAL_ERROR);
+ OPENSSL_PUT_ERROR(EC, ERR_R_INTERNAL_ERROR);
+ OPENSSL_free(tmp_wNAF);
goto err;
}
tmp_len -= blocksize;
@@ -490,7 +492,7 @@ int ec_wNAF_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
wNAF[i + 1] = NULL;
wNAF[i] = OPENSSL_malloc(wNAF_len[i]);
if (wNAF[i] == NULL) {
- OPENSSL_PUT_ERROR(EC, ec_wNAF_mul, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE);
OPENSSL_free(tmp_wNAF);
goto err;
}
@@ -500,7 +502,7 @@ int ec_wNAF_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
}
if (*tmp_points == NULL) {
- OPENSSL_PUT_ERROR(EC, ec_wNAF_mul, ERR_R_INTERNAL_ERROR);
+ OPENSSL_PUT_ERROR(EC, ERR_R_INTERNAL_ERROR);
OPENSSL_free(tmp_wNAF);
goto err;
}
@@ -519,7 +521,7 @@ int ec_wNAF_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
*/
val = OPENSSL_malloc((num_val + 1) * sizeof val[0]);
if (val == NULL) {
- OPENSSL_PUT_ERROR(EC, ec_wNAF_mul, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE);
goto err;
}
val[num_val] = NULL; /* pivot element */
@@ -537,7 +539,7 @@ int ec_wNAF_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar,
}
}
if (!(v == val + num_val)) {
- OPENSSL_PUT_ERROR(EC, ec_wNAF_mul, ERR_R_INTERNAL_ERROR);
+ OPENSSL_PUT_ERROR(EC, ERR_R_INTERNAL_ERROR);
goto err;
}
@@ -695,7 +697,7 @@ int ec_wNAF_precompute_mult(EC_GROUP *group, BN_CTX *ctx) {
generator = EC_GROUP_get0_generator(group);
if (generator == NULL) {
- OPENSSL_PUT_ERROR(EC, ec_wNAF_precompute_mult, EC_R_UNDEFINED_GENERATOR);
+ OPENSSL_PUT_ERROR(EC, EC_R_UNDEFINED_GENERATOR);
return 0;
}
@@ -721,7 +723,7 @@ int ec_wNAF_precompute_mult(EC_GROUP *group, BN_CTX *ctx) {
goto err;
}
if (BN_is_zero(order)) {
- OPENSSL_PUT_ERROR(EC, ec_wNAF_precompute_mult, EC_R_UNKNOWN_ORDER);
+ OPENSSL_PUT_ERROR(EC, EC_R_UNKNOWN_ORDER);
goto err;
}
@@ -749,7 +751,7 @@ int ec_wNAF_precompute_mult(EC_GROUP *group, BN_CTX *ctx) {
points = OPENSSL_malloc(sizeof(EC_POINT *) * (num + 1));
if (!points) {
- OPENSSL_PUT_ERROR(EC, ec_wNAF_precompute_mult, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE);
goto err;
}
@@ -757,13 +759,13 @@ int ec_wNAF_precompute_mult(EC_GROUP *group, BN_CTX *ctx) {
var[num] = NULL; /* pivot */
for (i = 0; i < num; i++) {
if ((var[i] = EC_POINT_new(group)) == NULL) {
- OPENSSL_PUT_ERROR(EC, ec_wNAF_precompute_mult, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE);
goto err;
}
}
if (!(tmp_point = EC_POINT_new(group)) || !(base = EC_POINT_new(group))) {
- OPENSSL_PUT_ERROR(EC, ec_wNAF_precompute_mult, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE);
goto err;
}
@@ -795,7 +797,7 @@ int ec_wNAF_precompute_mult(EC_GROUP *group, BN_CTX *ctx) {
size_t k;
if (blocksize <= 2) {
- OPENSSL_PUT_ERROR(EC, ec_wNAF_precompute_mult, ERR_R_INTERNAL_ERROR);
+ OPENSSL_PUT_ERROR(EC, ERR_R_INTERNAL_ERROR);
goto err;
}
diff --git a/src/crypto/ecdh/CMakeLists.txt b/src/crypto/ecdh/CMakeLists.txt
index 346e72d..8eaeae5 100644
--- a/src/crypto/ecdh/CMakeLists.txt
+++ b/src/crypto/ecdh/CMakeLists.txt
@@ -1,4 +1,4 @@
-include_directories(. .. ../../include)
+include_directories(../../include)
add_library(
ecdh
diff --git a/src/crypto/ecdh/ecdh.c b/src/crypto/ecdh/ecdh.c
index a011bab..14856db 100644
--- a/src/crypto/ecdh/ecdh.c
+++ b/src/crypto/ecdh/ecdh.c
@@ -95,7 +95,7 @@ int ECDH_compute_key(void *out, size_t outlen, const EC_POINT *pub_key,
priv = EC_KEY_get0_private_key(priv_key);
if (priv == NULL) {
- OPENSSL_PUT_ERROR(ECDH, ECDH_compute_key, ECDH_R_NO_PRIVATE_VALUE);
+ OPENSSL_PUT_ERROR(ECDH, ECDH_R_NO_PRIVATE_VALUE);
goto err;
}
@@ -103,35 +103,35 @@ int ECDH_compute_key(void *out, size_t outlen, const EC_POINT *pub_key,
tmp = EC_POINT_new(group);
if (tmp == NULL) {
- OPENSSL_PUT_ERROR(ECDH, ECDH_compute_key, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(ECDH, ERR_R_MALLOC_FAILURE);
goto err;
}
if (!EC_POINT_mul(group, tmp, NULL, pub_key, priv, ctx)) {
- OPENSSL_PUT_ERROR(ECDH, ECDH_compute_key, ECDH_R_POINT_ARITHMETIC_FAILURE);
+ OPENSSL_PUT_ERROR(ECDH, ECDH_R_POINT_ARITHMETIC_FAILURE);
goto err;
}
if (!EC_POINT_get_affine_coordinates_GFp(group, tmp, x, y, ctx)) {
- OPENSSL_PUT_ERROR(ECDH, ECDH_compute_key, ECDH_R_POINT_ARITHMETIC_FAILURE);
+ OPENSSL_PUT_ERROR(ECDH, ECDH_R_POINT_ARITHMETIC_FAILURE);
goto err;
}
buflen = (EC_GROUP_get_degree(group) + 7) / 8;
buf = OPENSSL_malloc(buflen);
if (buf == NULL) {
- OPENSSL_PUT_ERROR(ECDH, ECDH_compute_key, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(ECDH, ERR_R_MALLOC_FAILURE);
goto err;
}
if (!BN_bn2bin_padded(buf, buflen, x)) {
- OPENSSL_PUT_ERROR(ECDH, ECDH_compute_key, ERR_R_INTERNAL_ERROR);
+ OPENSSL_PUT_ERROR(ECDH, ERR_R_INTERNAL_ERROR);
goto err;
}
if (KDF != 0) {
if (KDF(buf, buflen, out, &outlen) == NULL) {
- OPENSSL_PUT_ERROR(ECDH, ECDH_compute_key, ECDH_R_KDF_FAILED);
+ OPENSSL_PUT_ERROR(ECDH, ECDH_R_KDF_FAILED);
goto err;
}
ret = outlen;
diff --git a/src/crypto/ecdsa/CMakeLists.txt b/src/crypto/ecdsa/CMakeLists.txt
index f431e59..e7581be 100644
--- a/src/crypto/ecdsa/CMakeLists.txt
+++ b/src/crypto/ecdsa/CMakeLists.txt
@@ -1,4 +1,4 @@
-include_directories(. .. ../../include)
+include_directories(../../include)
add_library(
ecdsa
diff --git a/src/crypto/ecdsa/ecdsa.c b/src/crypto/ecdsa/ecdsa.c
index b71799e..8403d60 100644
--- a/src/crypto/ecdsa/ecdsa.c
+++ b/src/crypto/ecdsa/ecdsa.c
@@ -52,9 +52,11 @@
#include <openssl/ecdsa.h>
+#include <assert.h>
#include <string.h>
#include <openssl/bn.h>
+#include <openssl/bytestring.h>
#include <openssl/err.h>
#include <openssl/mem.h>
@@ -81,16 +83,18 @@ int ECDSA_verify(int type, const uint8_t *digest, size_t digest_len,
return eckey->ecdsa_meth->verify(digest, digest_len, sig, sig_len, eckey);
}
- s = ECDSA_SIG_new();
- const uint8_t *sigp = sig;
- if (s == NULL || d2i_ECDSA_SIG(&s, &sigp, sig_len) == NULL ||
- sigp != sig + sig_len) {
+ /* Decode the ECDSA signature. */
+ s = ECDSA_SIG_from_bytes(sig, sig_len);
+ if (s == NULL) {
goto err;
}
- /* Ensure that the signature uses DER and doesn't have trailing garbage. */
- const int der_len = i2d_ECDSA_SIG(s, &der);
- if (der_len < 0 || (size_t) der_len != sig_len || memcmp(sig, der, sig_len)) {
+ /* Defend against potential laxness in the DER parser. */
+ size_t der_len;
+ if (!ECDSA_SIG_to_bytes(&der, &der_len, s) ||
+ der_len != sig_len || memcmp(sig, der, sig_len) != 0) {
+ /* This should never happen. crypto/bytestring is strictly DER. */
+ OPENSSL_PUT_ERROR(ECDSA, ERR_R_INTERNAL_ERROR);
goto err;
}
@@ -116,14 +120,14 @@ static int digest_to_bn(BIGNUM *out, const uint8_t *digest, size_t digest_len,
digest_len = (num_bits + 7) / 8;
}
if (!BN_bin2bn(digest, digest_len, out)) {
- OPENSSL_PUT_ERROR(ECDSA, digest_to_bn, ERR_R_BN_LIB);
+ OPENSSL_PUT_ERROR(ECDSA, ERR_R_BN_LIB);
return 0;
}
/* If still too long truncate remaining bits with a shift */
if ((8 * digest_len > num_bits) &&
!BN_rshift(out, out, 8 - (num_bits & 0x7))) {
- OPENSSL_PUT_ERROR(ECDSA, digest_to_bn, ERR_R_BN_LIB);
+ OPENSSL_PUT_ERROR(ECDSA, ERR_R_BN_LIB);
return 0;
}
@@ -145,7 +149,7 @@ int ECDSA_do_verify(const uint8_t *digest, size_t digest_len,
const EC_POINT *pub_key;
if (eckey->ecdsa_meth && eckey->ecdsa_meth->verify) {
- OPENSSL_PUT_ERROR(ECDSA, ECDSA_do_verify, ECDSA_R_NOT_IMPLEMENTED);
+ OPENSSL_PUT_ERROR(ECDSA, ECDSA_R_NOT_IMPLEMENTED);
return 0;
}
@@ -153,13 +157,13 @@ int ECDSA_do_verify(const uint8_t *digest, size_t digest_len,
if ((group = EC_KEY_get0_group(eckey)) == NULL ||
(pub_key = EC_KEY_get0_public_key(eckey)) == NULL ||
sig == NULL) {
- OPENSSL_PUT_ERROR(ECDSA, ECDSA_do_verify, ECDSA_R_MISSING_PARAMETERS);
+ OPENSSL_PUT_ERROR(ECDSA, ECDSA_R_MISSING_PARAMETERS);
return 0;
}
ctx = BN_CTX_new();
if (!ctx) {
- OPENSSL_PUT_ERROR(ECDSA, ECDSA_do_verify, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(ECDSA, ERR_R_MALLOC_FAILURE);
return 0;
}
BN_CTX_start(ctx);
@@ -168,26 +172,26 @@ int ECDSA_do_verify(const uint8_t *digest, size_t digest_len,
u2 = BN_CTX_get(ctx);
m = BN_CTX_get(ctx);
X = BN_CTX_get(ctx);
- if (!X) {
- OPENSSL_PUT_ERROR(ECDSA, ECDSA_do_verify, ERR_R_BN_LIB);
+ if (order == NULL || u1 == NULL || u2 == NULL || m == NULL || X == NULL) {
+ OPENSSL_PUT_ERROR(ECDSA, ERR_R_BN_LIB);
goto err;
}
if (!EC_GROUP_get_order(group, order, ctx)) {
- OPENSSL_PUT_ERROR(ECDSA, ECDSA_do_verify, ERR_R_EC_LIB);
+ OPENSSL_PUT_ERROR(ECDSA, ERR_R_EC_LIB);
goto err;
}
if (BN_is_zero(sig->r) || BN_is_negative(sig->r) ||
BN_ucmp(sig->r, order) >= 0 || BN_is_zero(sig->s) ||
BN_is_negative(sig->s) || BN_ucmp(sig->s, order) >= 0) {
- OPENSSL_PUT_ERROR(ECDSA, ECDSA_do_verify, ECDSA_R_BAD_SIGNATURE);
+ OPENSSL_PUT_ERROR(ECDSA, ECDSA_R_BAD_SIGNATURE);
ret = 0; /* signature is invalid */
goto err;
}
/* calculate tmp1 = inv(S) mod order */
if (!BN_mod_inverse(u2, sig->s, order, ctx)) {
- OPENSSL_PUT_ERROR(ECDSA, ECDSA_do_verify, ERR_R_BN_LIB);
+ OPENSSL_PUT_ERROR(ECDSA, ERR_R_BN_LIB);
goto err;
}
if (!digest_to_bn(m, digest, digest_len, order)) {
@@ -195,30 +199,30 @@ int ECDSA_do_verify(const uint8_t *digest, size_t digest_len,
}
/* u1 = m * tmp mod order */
if (!BN_mod_mul(u1, m, u2, order, ctx)) {
- OPENSSL_PUT_ERROR(ECDSA, ECDSA_do_verify, ERR_R_BN_LIB);
+ OPENSSL_PUT_ERROR(ECDSA, ERR_R_BN_LIB);
goto err;
}
/* u2 = r * w mod q */
if (!BN_mod_mul(u2, sig->r, u2, order, ctx)) {
- OPENSSL_PUT_ERROR(ECDSA, ECDSA_do_verify, ERR_R_BN_LIB);
+ OPENSSL_PUT_ERROR(ECDSA, ERR_R_BN_LIB);
goto err;
}
point = EC_POINT_new(group);
if (point == NULL) {
- OPENSSL_PUT_ERROR(ECDSA, ECDSA_do_verify, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(ECDSA, ERR_R_MALLOC_FAILURE);
goto err;
}
if (!EC_POINT_mul(group, point, u1, pub_key, u2, ctx)) {
- OPENSSL_PUT_ERROR(ECDSA, ECDSA_do_verify, ERR_R_EC_LIB);
+ OPENSSL_PUT_ERROR(ECDSA, ERR_R_EC_LIB);
goto err;
}
if (!EC_POINT_get_affine_coordinates_GFp(group, point, X, NULL, ctx)) {
- OPENSSL_PUT_ERROR(ECDSA, ECDSA_do_verify, ERR_R_EC_LIB);
+ OPENSSL_PUT_ERROR(ECDSA, ERR_R_EC_LIB);
goto err;
}
if (!BN_nnmod(u1, X, order, ctx)) {
- OPENSSL_PUT_ERROR(ECDSA, ECDSA_do_verify, ERR_R_BN_LIB);
+ OPENSSL_PUT_ERROR(ECDSA, ERR_R_BN_LIB);
goto err;
}
/* if the signature is correct u1 is equal to sig->r */
@@ -241,13 +245,13 @@ static int ecdsa_sign_setup(EC_KEY *eckey, BN_CTX *ctx_in, BIGNUM **kinvp,
int ret = 0;
if (eckey == NULL || (group = EC_KEY_get0_group(eckey)) == NULL) {
- OPENSSL_PUT_ERROR(ECDSA, ecdsa_sign_setup, ERR_R_PASSED_NULL_PARAMETER);
+ OPENSSL_PUT_ERROR(ECDSA, ERR_R_PASSED_NULL_PARAMETER);
return 0;
}
if (ctx_in == NULL) {
if ((ctx = BN_CTX_new()) == NULL) {
- OPENSSL_PUT_ERROR(ECDSA, ecdsa_sign_setup, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(ECDSA, ERR_R_MALLOC_FAILURE);
return 0;
}
} else {
@@ -259,16 +263,16 @@ static int ecdsa_sign_setup(EC_KEY *eckey, BN_CTX *ctx_in, BIGNUM **kinvp,
order = BN_new();
X = BN_new();
if (!k || !r || !order || !X) {
- OPENSSL_PUT_ERROR(ECDSA, ecdsa_sign_setup, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(ECDSA, ERR_R_MALLOC_FAILURE);
goto err;
}
tmp_point = EC_POINT_new(group);
if (tmp_point == NULL) {
- OPENSSL_PUT_ERROR(ECDSA, ecdsa_sign_setup, ERR_R_EC_LIB);
+ OPENSSL_PUT_ERROR(ECDSA, ERR_R_EC_LIB);
goto err;
}
if (!EC_GROUP_get_order(group, order, ctx)) {
- OPENSSL_PUT_ERROR(ECDSA, ecdsa_sign_setup, ERR_R_EC_LIB);
+ OPENSSL_PUT_ERROR(ECDSA, ERR_R_EC_LIB);
goto err;
}
@@ -286,8 +290,7 @@ static int ecdsa_sign_setup(EC_KEY *eckey, BN_CTX *ctx_in, BIGNUM **kinvp,
ok = BN_rand_range(k, order);
}
if (!ok) {
- OPENSSL_PUT_ERROR(ECDSA, ecdsa_sign_setup,
- ECDSA_R_RANDOM_NUMBER_GENERATION_FAILED);
+ OPENSSL_PUT_ERROR(ECDSA, ECDSA_R_RANDOM_NUMBER_GENERATION_FAILED);
goto err;
}
} while (BN_is_zero(k));
@@ -307,23 +310,23 @@ static int ecdsa_sign_setup(EC_KEY *eckey, BN_CTX *ctx_in, BIGNUM **kinvp,
/* compute r the x-coordinate of generator * k */
if (!EC_POINT_mul(group, tmp_point, k, NULL, NULL, ctx)) {
- OPENSSL_PUT_ERROR(ECDSA, ecdsa_sign_setup, ERR_R_EC_LIB);
+ OPENSSL_PUT_ERROR(ECDSA, ERR_R_EC_LIB);
goto err;
}
if (!EC_POINT_get_affine_coordinates_GFp(group, tmp_point, X, NULL, ctx)) {
- OPENSSL_PUT_ERROR(ECDSA, ecdsa_sign_setup, ERR_R_EC_LIB);
+ OPENSSL_PUT_ERROR(ECDSA, ERR_R_EC_LIB);
goto err;
}
if (!BN_nnmod(r, X, order, ctx)) {
- OPENSSL_PUT_ERROR(ECDSA, ecdsa_sign_setup, ERR_R_BN_LIB);
+ OPENSSL_PUT_ERROR(ECDSA, ERR_R_BN_LIB);
goto err;
}
} while (BN_is_zero(r));
/* compute the inverse of k */
if (!BN_mod_inverse(k, k, order, ctx)) {
- OPENSSL_PUT_ERROR(ECDSA, ecdsa_sign_setup, ERR_R_BN_LIB);
+ OPENSSL_PUT_ERROR(ECDSA, ERR_R_BN_LIB);
goto err;
}
/* clear old values if necessary */
@@ -365,7 +368,7 @@ ECDSA_SIG *ECDSA_do_sign_ex(const uint8_t *digest, size_t digest_len,
const BIGNUM *priv_key;
if (eckey->ecdsa_meth && eckey->ecdsa_meth->sign) {
- OPENSSL_PUT_ERROR(ECDSA, ECDSA_do_sign_ex, ECDSA_R_NOT_IMPLEMENTED);
+ OPENSSL_PUT_ERROR(ECDSA, ECDSA_R_NOT_IMPLEMENTED);
return NULL;
}
@@ -373,25 +376,25 @@ ECDSA_SIG *ECDSA_do_sign_ex(const uint8_t *digest, size_t digest_len,
priv_key = EC_KEY_get0_private_key(eckey);
if (group == NULL || priv_key == NULL) {
- OPENSSL_PUT_ERROR(ECDSA, ECDSA_do_sign_ex, ERR_R_PASSED_NULL_PARAMETER);
+ OPENSSL_PUT_ERROR(ECDSA, ERR_R_PASSED_NULL_PARAMETER);
return NULL;
}
ret = ECDSA_SIG_new();
if (!ret) {
- OPENSSL_PUT_ERROR(ECDSA, ECDSA_do_sign_ex, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(ECDSA, ERR_R_MALLOC_FAILURE);
return NULL;
}
s = ret->s;
if ((ctx = BN_CTX_new()) == NULL || (order = BN_new()) == NULL ||
(tmp = BN_new()) == NULL || (m = BN_new()) == NULL) {
- OPENSSL_PUT_ERROR(ECDSA, ECDSA_do_sign_ex, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(ECDSA, ERR_R_MALLOC_FAILURE);
goto err;
}
if (!EC_GROUP_get_order(group, order, ctx)) {
- OPENSSL_PUT_ERROR(ECDSA, ECDSA_do_sign_ex, ERR_R_EC_LIB);
+ OPENSSL_PUT_ERROR(ECDSA, ERR_R_EC_LIB);
goto err;
}
if (!digest_to_bn(m, digest, digest_len, order)) {
@@ -400,35 +403,35 @@ ECDSA_SIG *ECDSA_do_sign_ex(const uint8_t *digest, size_t digest_len,
for (;;) {
if (in_kinv == NULL || in_r == NULL) {
if (!ecdsa_sign_setup(eckey, ctx, &kinv, &ret->r, digest, digest_len)) {
- OPENSSL_PUT_ERROR(ECDSA, ECDSA_do_sign_ex, ERR_R_ECDSA_LIB);
+ OPENSSL_PUT_ERROR(ECDSA, ERR_R_ECDSA_LIB);
goto err;
}
ckinv = kinv;
} else {
ckinv = in_kinv;
if (BN_copy(ret->r, in_r) == NULL) {
- OPENSSL_PUT_ERROR(ECDSA, ECDSA_do_sign_ex, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(ECDSA, ERR_R_MALLOC_FAILURE);
goto err;
}
}
if (!BN_mod_mul(tmp, priv_key, ret->r, order, ctx)) {
- OPENSSL_PUT_ERROR(ECDSA, ECDSA_do_sign_ex, ERR_R_BN_LIB);
+ OPENSSL_PUT_ERROR(ECDSA, ERR_R_BN_LIB);
goto err;
}
if (!BN_mod_add_quick(s, tmp, m, order)) {
- OPENSSL_PUT_ERROR(ECDSA, ECDSA_do_sign_ex, ERR_R_BN_LIB);
+ OPENSSL_PUT_ERROR(ECDSA, ERR_R_BN_LIB);
goto err;
}
if (!BN_mod_mul(s, s, ckinv, order, ctx)) {
- OPENSSL_PUT_ERROR(ECDSA, ECDSA_do_sign_ex, ERR_R_BN_LIB);
+ OPENSSL_PUT_ERROR(ECDSA, ERR_R_BN_LIB);
goto err;
}
if (BN_is_zero(s)) {
/* if kinv and r have been supplied by the caller
* don't to generate new kinv and r values */
if (in_kinv != NULL && in_r != NULL) {
- OPENSSL_PUT_ERROR(ECDSA, ECDSA_do_sign_ex, ECDSA_R_NEED_NEW_SETUP_VALUES);
+ OPENSSL_PUT_ERROR(ECDSA, ECDSA_R_NEED_NEW_SETUP_VALUES);
goto err;
}
} else {
@@ -455,20 +458,36 @@ err:
int ECDSA_sign_ex(int type, const uint8_t *digest, size_t digest_len,
uint8_t *sig, unsigned int *sig_len, const BIGNUM *kinv,
const BIGNUM *r, EC_KEY *eckey) {
+ int ret = 0;
ECDSA_SIG *s = NULL;
if (eckey->ecdsa_meth && eckey->ecdsa_meth->sign) {
- OPENSSL_PUT_ERROR(ECDSA, ECDSA_sign_ex, ECDSA_R_NOT_IMPLEMENTED);
+ OPENSSL_PUT_ERROR(ECDSA, ECDSA_R_NOT_IMPLEMENTED);
*sig_len = 0;
- return 0;
+ goto err;
}
s = ECDSA_do_sign_ex(digest, digest_len, kinv, r, eckey);
if (s == NULL) {
*sig_len = 0;
- return 0;
+ goto err;
}
- *sig_len = i2d_ECDSA_SIG(s, &sig);
+
+ CBB cbb;
+ CBB_zero(&cbb);
+ size_t len;
+ if (!CBB_init_fixed(&cbb, sig, ECDSA_size(eckey)) ||
+ !ECDSA_SIG_marshal(&cbb, s) ||
+ !CBB_finish(&cbb, NULL, &len)) {
+ OPENSSL_PUT_ERROR(ECDSA, ECDSA_R_ENCODE_ERROR);
+ CBB_cleanup(&cbb);
+ *sig_len = 0;
+ goto err;
+ }
+ *sig_len = (unsigned)len;
+ ret = 1;
+
+err:
ECDSA_SIG_free(s);
- return 1;
+ return ret;
}
diff --git a/src/crypto/ecdsa/ecdsa_asn1.c b/src/crypto/ecdsa/ecdsa_asn1.c
index f557ca7..f2d7c36 100644
--- a/src/crypto/ecdsa/ecdsa_asn1.c
+++ b/src/crypto/ecdsa/ecdsa_asn1.c
@@ -52,45 +52,33 @@
#include <openssl/ecdsa.h>
-#include <openssl/asn1.h>
-#include <openssl/asn1t.h>
+#include <limits.h>
+#include <string.h>
+
+#include <openssl/bn.h>
+#include <openssl/bytestring.h>
+#include <openssl/err.h>
#include <openssl/ec_key.h>
#include <openssl/mem.h>
#include "../ec/internal.h"
-DECLARE_ASN1_FUNCTIONS_const(ECDSA_SIG);
-DECLARE_ASN1_ENCODE_FUNCTIONS_const(ECDSA_SIG, ECDSA_SIG);
-
-ASN1_SEQUENCE(ECDSA_SIG) = {
- ASN1_SIMPLE(ECDSA_SIG, r, CBIGNUM),
- ASN1_SIMPLE(ECDSA_SIG, s, CBIGNUM),
-} ASN1_SEQUENCE_END(ECDSA_SIG);
-
-IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(ECDSA_SIG, ECDSA_SIG, ECDSA_SIG);
-
size_t ECDSA_size(const EC_KEY *key) {
- size_t ret, i, group_order_size;
- ASN1_INTEGER bs;
- BIGNUM *order = NULL;
- unsigned char buf[4];
- const EC_GROUP *group;
+ if (key == NULL) {
+ return 0;
+ }
+ size_t group_order_size;
if (key->ecdsa_meth && key->ecdsa_meth->group_order_size) {
group_order_size = key->ecdsa_meth->group_order_size(key);
} else {
- size_t num_bits;
-
- if (key == NULL) {
- return 0;
- }
- group = EC_KEY_get0_group(key);
+ const EC_GROUP *group = EC_KEY_get0_group(key);
if (group == NULL) {
return 0;
}
- order = BN_new();
+ BIGNUM *order = BN_new();
if (order == NULL) {
return 0;
}
@@ -99,21 +87,11 @@ size_t ECDSA_size(const EC_KEY *key) {
return 0;
}
- num_bits = BN_num_bits(order);
- group_order_size = (num_bits + 7) / 8;
+ group_order_size = BN_num_bytes(order);
+ BN_clear_free(order);
}
- bs.length = group_order_size;
- bs.data = buf;
- bs.type = V_ASN1_INTEGER;
- /* If the top bit is set the ASN.1 encoding is 1 larger. */
- buf[0] = 0xff;
-
- i = i2d_ASN1_INTEGER(&bs, NULL);
- i += i; /* r and s */
- ret = ASN1_object_size(1, i, V_ASN1_SEQUENCE);
- BN_clear_free(order);
- return ret;
+ return ECDSA_SIG_max_len(group_order_size);
}
ECDSA_SIG *ECDSA_SIG_new(void) {
@@ -139,3 +117,134 @@ void ECDSA_SIG_free(ECDSA_SIG *sig) {
BN_free(sig->s);
OPENSSL_free(sig);
}
+
+ECDSA_SIG *ECDSA_SIG_parse(CBS *cbs) {
+ ECDSA_SIG *ret = ECDSA_SIG_new();
+ if (ret == NULL) {
+ return NULL;
+ }
+ CBS child;
+ if (!CBS_get_asn1(cbs, &child, CBS_ASN1_SEQUENCE) ||
+ !BN_cbs2unsigned(&child, ret->r) ||
+ !BN_cbs2unsigned(&child, ret->s) ||
+ CBS_len(&child) != 0) {
+ OPENSSL_PUT_ERROR(ECDSA, ECDSA_R_BAD_SIGNATURE);
+ ECDSA_SIG_free(ret);
+ return NULL;
+ }
+ return ret;
+}
+
+ECDSA_SIG *ECDSA_SIG_from_bytes(const uint8_t *in, size_t in_len) {
+ CBS cbs;
+ CBS_init(&cbs, in, in_len);
+ ECDSA_SIG *ret = ECDSA_SIG_parse(&cbs);
+ if (ret == NULL || CBS_len(&cbs) != 0) {
+ OPENSSL_PUT_ERROR(ECDSA, ECDSA_R_BAD_SIGNATURE);
+ ECDSA_SIG_free(ret);
+ return NULL;
+ }
+ return ret;
+}
+
+int ECDSA_SIG_marshal(CBB *cbb, const ECDSA_SIG *sig) {
+ CBB child;
+ if (!CBB_add_asn1(cbb, &child, CBS_ASN1_SEQUENCE) ||
+ !BN_bn2cbb(&child, sig->r) ||
+ !BN_bn2cbb(&child, sig->s) ||
+ !CBB_flush(cbb)) {
+ OPENSSL_PUT_ERROR(ECDSA, ECDSA_R_ENCODE_ERROR);
+ return 0;
+ }
+ return 1;
+}
+
+int ECDSA_SIG_to_bytes(uint8_t **out_bytes, size_t *out_len,
+ const ECDSA_SIG *sig) {
+ CBB cbb;
+ CBB_zero(&cbb);
+ if (!CBB_init(&cbb, 0) ||
+ !ECDSA_SIG_marshal(&cbb, sig) ||
+ !CBB_finish(&cbb, out_bytes, out_len)) {
+ OPENSSL_PUT_ERROR(ECDSA, ECDSA_R_ENCODE_ERROR);
+ CBB_cleanup(&cbb);
+ return 0;
+ }
+ return 1;
+}
+
+/* der_len_len returns the number of bytes needed to represent a length of |len|
+ * in DER. */
+static size_t der_len_len(size_t len) {
+ if (len < 0x80) {
+ return 1;
+ }
+ size_t ret = 1;
+ while (len > 0) {
+ ret++;
+ len >>= 8;
+ }
+ return ret;
+}
+
+size_t ECDSA_SIG_max_len(size_t order_len) {
+ /* Compute the maximum length of an |order_len| byte integer. Defensively
+ * assume that the leading 0x00 is included. */
+ size_t integer_len = 1 /* tag */ + der_len_len(order_len + 1) + 1 + order_len;
+ if (integer_len < order_len) {
+ return 0;
+ }
+ /* An ECDSA signature is two INTEGERs. */
+ size_t value_len = 2 * integer_len;
+ if (value_len < integer_len) {
+ return 0;
+ }
+ /* Add the header. */
+ size_t ret = 1 /* tag */ + der_len_len(value_len) + value_len;
+ if (ret < value_len) {
+ return 0;
+ }
+ return ret;
+}
+
+ECDSA_SIG *d2i_ECDSA_SIG(ECDSA_SIG **out, const uint8_t **inp, long len) {
+ if (len < 0) {
+ return NULL;
+ }
+ CBS cbs;
+ CBS_init(&cbs, *inp, (size_t)len);
+ ECDSA_SIG *ret = ECDSA_SIG_parse(&cbs);
+ if (ret == NULL) {
+ return NULL;
+ }
+ if (out != NULL) {
+ ECDSA_SIG_free(*out);
+ *out = ret;
+ }
+ *inp += (size_t)len - CBS_len(&cbs);
+ return ret;
+}
+
+int i2d_ECDSA_SIG(const ECDSA_SIG *sig, uint8_t **outp) {
+ uint8_t *der;
+ size_t der_len;
+ if (!ECDSA_SIG_to_bytes(&der, &der_len, sig)) {
+ return -1;
+ }
+ if (der_len > INT_MAX) {
+ OPENSSL_PUT_ERROR(ECDSA, ERR_R_OVERFLOW);
+ OPENSSL_free(der);
+ return -1;
+ }
+ if (outp != NULL) {
+ if (*outp == NULL) {
+ *outp = der;
+ der = NULL;
+ } else {
+ memcpy(*outp, der, der_len);
+ *outp += der_len;
+ }
+ }
+ OPENSSL_free(der);
+ return (int)der_len;
+}
diff --git a/src/crypto/ecdsa/ecdsa_test.cc b/src/crypto/ecdsa/ecdsa_test.cc
index a6bd7a1..b916509 100644
--- a/src/crypto/ecdsa/ecdsa_test.cc
+++ b/src/crypto/ecdsa/ecdsa_test.cc
@@ -78,18 +78,13 @@ static bool VerifyECDSASig(Api api, const uint8_t *digest,
switch (api) {
case kEncodedApi: {
- int sig_len = i2d_ECDSA_SIG(ecdsa_sig, NULL);
- if (sig_len <= 0) {
+ uint8_t *der;
+ size_t der_len;
+ if (!ECDSA_SIG_to_bytes(&der, &der_len, ecdsa_sig)) {
return false;
}
- std::vector<uint8_t> signature(static_cast<size_t>(sig_len));
- uint8_t *sig_ptr = bssl::vector_data(&signature);
- sig_len = i2d_ECDSA_SIG(ecdsa_sig, &sig_ptr);
- if (sig_len <= 0) {
- return false;
- }
- actual_result = ECDSA_verify(0, digest, digest_len, bssl::vector_data(&signature),
- signature.size(), eckey);
+ ScopedOpenSSLBytes delete_der(der);
+ actual_result = ECDSA_verify(0, digest, digest_len, der, der_len, eckey);
break;
}
@@ -267,8 +262,8 @@ static bool TestBuiltin(FILE *out) {
fprintf(out, ".");
fflush(out);
// Verify a tampered signature.
- const uint8_t *sig_ptr = bssl::vector_data(&signature);
- ScopedECDSA_SIG ecdsa_sig(d2i_ECDSA_SIG(NULL, &sig_ptr, signature.size()));
+ ScopedECDSA_SIG ecdsa_sig(ECDSA_SIG_from_bytes(
+ bssl::vector_data(&signature), signature.size()));
if (!ecdsa_sig ||
!TestTamperedSig(out, kEncodedApi, digest, 20, ecdsa_sig.get(),
eckey.get(), order.get())) {
@@ -325,11 +320,45 @@ static bool TestBuiltin(FILE *out) {
return true;
}
+static bool TestECDSA_SIG_max_len(size_t order_len) {
+ /* Create the largest possible |ECDSA_SIG| of the given constraints. */
+ ScopedECDSA_SIG sig(ECDSA_SIG_new());
+ if (!sig) {
+ return false;
+ }
+ std::vector<uint8_t> bytes(order_len, 0xff);
+ if (!BN_bin2bn(bssl::vector_data(&bytes), bytes.size(), sig->r) ||
+ !BN_bin2bn(bssl::vector_data(&bytes), bytes.size(), sig->s)) {
+ return false;
+ }
+ /* Serialize it. */
+ uint8_t *der;
+ size_t der_len;
+ if (!ECDSA_SIG_to_bytes(&der, &der_len, sig.get())) {
+ return false;
+ }
+ ScopedOpenSSLBytes delete_der(der);
+
+ size_t max_len = ECDSA_SIG_max_len(order_len);
+ if (max_len != der_len) {
+ fprintf(stderr, "ECDSA_SIG_max_len(%u) returned %u, wanted %u\n",
+ static_cast<unsigned>(order_len), static_cast<unsigned>(max_len),
+ static_cast<unsigned>(der_len));
+ return false;
+ }
+ return true;
+}
+
int main(void) {
CRYPTO_library_init();
ERR_load_crypto_strings();
- if (!TestBuiltin(stdout)) {
+ if (!TestBuiltin(stdout) ||
+ !TestECDSA_SIG_max_len(224/8) ||
+ !TestECDSA_SIG_max_len(256/8) ||
+ !TestECDSA_SIG_max_len(384/8) ||
+ !TestECDSA_SIG_max_len(512/8) ||
+ !TestECDSA_SIG_max_len(10000)) {
printf("\nECDSA test failed\n");
ERR_print_errors_fp(stdout);
return 1;
diff --git a/src/crypto/engine/CMakeLists.txt b/src/crypto/engine/CMakeLists.txt
index e03650e..5667f02 100644
--- a/src/crypto/engine/CMakeLists.txt
+++ b/src/crypto/engine/CMakeLists.txt
@@ -1,4 +1,4 @@
-include_directories(. .. ../../include)
+include_directories(../../include)
add_library(
engine
diff --git a/src/crypto/err/CMakeLists.txt b/src/crypto/err/CMakeLists.txt
index 5215eec..8519e51 100644
--- a/src/crypto/err/CMakeLists.txt
+++ b/src/crypto/err/CMakeLists.txt
@@ -1,4 +1,4 @@
-include_directories(. .. ../../include)
+include_directories(../../include)
add_custom_command(
OUTPUT err_data.c
@@ -8,10 +8,8 @@ add_custom_command(
asn1.errordata
bio.errordata
bn.errordata
- buf.errordata
cipher.errordata
conf.errordata
- crypto.errordata
dh.errordata
digest.errordata
dsa.errordata
diff --git a/src/crypto/err/asn1.errordata b/src/crypto/err/asn1.errordata
index 44b9c73..55342a0 100644
--- a/src/crypto/err/asn1.errordata
+++ b/src/crypto/err/asn1.errordata
@@ -1,152 +1,88 @@
-ASN1,function,100,ASN1_BIT_STRING_set_bit
-ASN1,function,101,ASN1_ENUMERATED_set
-ASN1,function,102,ASN1_ENUMERATED_to_BN
-ASN1,function,103,ASN1_GENERALIZEDTIME_adj
-ASN1,function,104,ASN1_INTEGER_set
-ASN1,function,105,ASN1_INTEGER_to_BN
-ASN1,function,106,ASN1_OBJECT_new
-ASN1,function,107,ASN1_PCTX_new
-ASN1,function,108,ASN1_STRING_TABLE_add
-ASN1,function,109,ASN1_STRING_set
-ASN1,function,110,ASN1_STRING_type_new
-ASN1,function,111,ASN1_TIME_adj
-ASN1,function,112,ASN1_UTCTIME_adj
-ASN1,function,113,ASN1_d2i_fp
-ASN1,function,114,ASN1_dup
-ASN1,function,115,ASN1_generate_v3
-ASN1,function,116,ASN1_get_object
-ASN1,function,117,ASN1_i2d_bio
-ASN1,function,118,ASN1_i2d_fp
-ASN1,function,119,ASN1_item_d2i_fp
-ASN1,function,120,ASN1_item_dup
-ASN1,function,121,ASN1_item_ex_d2i
-ASN1,function,122,ASN1_item_i2d_bio
-ASN1,function,123,ASN1_item_i2d_fp
-ASN1,function,124,ASN1_item_pack
-ASN1,function,125,ASN1_item_unpack
-ASN1,function,126,ASN1_mbstring_ncopy
-ASN1,function,127,ASN1_template_new
-ASN1,function,128,BIO_new_NDEF
-ASN1,function,129,BN_to_ASN1_ENUMERATED
-ASN1,function,130,BN_to_ASN1_INTEGER
-ASN1,function,131,a2d_ASN1_OBJECT
-ASN1,function,132,a2i_ASN1_ENUMERATED
-ASN1,function,133,a2i_ASN1_INTEGER
-ASN1,function,134,a2i_ASN1_STRING
-ASN1,function,135,append_exp
-ASN1,function,136,asn1_cb
-ASN1,function,137,asn1_check_tlen
-ASN1,function,138,asn1_collate_primitive
-ASN1,function,139,asn1_collect
-ASN1,function,140,asn1_d2i_ex_primitive
-ASN1,function,141,asn1_d2i_read_bio
-ASN1,function,142,asn1_do_adb
-ASN1,function,143,asn1_ex_c2i
-ASN1,function,144,asn1_find_end
-ASN1,function,145,asn1_item_ex_combine_new
-ASN1,function,146,asn1_str2type
-ASN1,function,147,asn1_template_ex_d2i
-ASN1,function,148,asn1_template_noexp_d2i
-ASN1,function,149,bitstr_cb
-ASN1,function,150,c2i_ASN1_BIT_STRING
-ASN1,function,151,c2i_ASN1_INTEGER
-ASN1,function,152,c2i_ASN1_OBJECT
-ASN1,function,153,collect_data
-ASN1,function,154,d2i_ASN1_BOOLEAN
-ASN1,function,155,d2i_ASN1_OBJECT
-ASN1,function,156,d2i_ASN1_UINTEGER
-ASN1,function,157,d2i_ASN1_UTCTIME
-ASN1,function,158,d2i_ASN1_bytes
-ASN1,function,159,d2i_ASN1_type_bytes
-ASN1,function,160,i2d_ASN1_TIME
-ASN1,function,161,i2d_PrivateKey
-ASN1,function,162,long_c2i
-ASN1,function,163,parse_tagging
-ASN1,reason,100,ASN1_LENGTH_MISMATCH
-ASN1,reason,101,AUX_ERROR
-ASN1,reason,102,BAD_GET_ASN1_OBJECT_CALL
-ASN1,reason,103,BAD_OBJECT_HEADER
-ASN1,reason,104,BMPSTRING_IS_WRONG_LENGTH
-ASN1,reason,105,BN_LIB
-ASN1,reason,106,BOOLEAN_IS_WRONG_LENGTH
-ASN1,reason,107,BUFFER_TOO_SMALL
-ASN1,reason,108,DECODE_ERROR
-ASN1,reason,109,DEPTH_EXCEEDED
-ASN1,reason,110,ENCODE_ERROR
-ASN1,reason,111,ERROR_GETTING_TIME
-ASN1,reason,112,EXPECTING_AN_ASN1_SEQUENCE
-ASN1,reason,113,EXPECTING_AN_INTEGER
-ASN1,reason,114,EXPECTING_AN_OBJECT
-ASN1,reason,115,EXPECTING_A_BOOLEAN
-ASN1,reason,116,EXPECTING_A_TIME
-ASN1,reason,117,EXPLICIT_LENGTH_MISMATCH
-ASN1,reason,118,EXPLICIT_TAG_NOT_CONSTRUCTED
-ASN1,reason,119,FIELD_MISSING
-ASN1,reason,120,FIRST_NUM_TOO_LARGE
-ASN1,reason,121,HEADER_TOO_LONG
-ASN1,reason,122,ILLEGAL_BITSTRING_FORMAT
-ASN1,reason,123,ILLEGAL_BOOLEAN
-ASN1,reason,124,ILLEGAL_CHARACTERS
-ASN1,reason,125,ILLEGAL_FORMAT
-ASN1,reason,126,ILLEGAL_HEX
-ASN1,reason,127,ILLEGAL_IMPLICIT_TAG
-ASN1,reason,128,ILLEGAL_INTEGER
-ASN1,reason,129,ILLEGAL_NESTED_TAGGING
-ASN1,reason,130,ILLEGAL_NULL
-ASN1,reason,131,ILLEGAL_NULL_VALUE
-ASN1,reason,132,ILLEGAL_OBJECT
-ASN1,reason,133,ILLEGAL_OPTIONAL_ANY
-ASN1,reason,134,ILLEGAL_OPTIONS_ON_ITEM_TEMPLATE
-ASN1,reason,135,ILLEGAL_TAGGED_ANY
-ASN1,reason,136,ILLEGAL_TIME_VALUE
-ASN1,reason,137,INTEGER_NOT_ASCII_FORMAT
-ASN1,reason,138,INTEGER_TOO_LARGE_FOR_LONG
-ASN1,reason,139,INVALID_BIT_STRING_BITS_LEFT
-ASN1,reason,140,INVALID_BMPSTRING_LENGTH
-ASN1,reason,141,INVALID_DIGIT
-ASN1,reason,142,INVALID_MODIFIER
-ASN1,reason,143,INVALID_NUMBER
-ASN1,reason,144,INVALID_OBJECT_ENCODING
-ASN1,reason,145,INVALID_SEPARATOR
-ASN1,reason,146,INVALID_TIME_FORMAT
-ASN1,reason,147,INVALID_UNIVERSALSTRING_LENGTH
-ASN1,reason,148,INVALID_UTF8STRING
-ASN1,reason,149,LIST_ERROR
-ASN1,reason,150,MALLOC_FAILURE
-ASN1,reason,151,MISSING_ASN1_EOS
-ASN1,reason,152,MISSING_EOC
-ASN1,reason,153,MISSING_SECOND_NUMBER
-ASN1,reason,154,MISSING_VALUE
-ASN1,reason,155,MSTRING_NOT_UNIVERSAL
-ASN1,reason,156,MSTRING_WRONG_TAG
-ASN1,reason,157,NESTED_ASN1_ERROR
-ASN1,reason,158,NESTED_ASN1_STRING
-ASN1,reason,159,NON_HEX_CHARACTERS
-ASN1,reason,160,NOT_ASCII_FORMAT
-ASN1,reason,161,NOT_ENOUGH_DATA
-ASN1,reason,162,NO_MATCHING_CHOICE_TYPE
-ASN1,reason,163,NULL_IS_WRONG_LENGTH
-ASN1,reason,164,OBJECT_NOT_ASCII_FORMAT
-ASN1,reason,165,ODD_NUMBER_OF_CHARS
-ASN1,reason,166,SECOND_NUMBER_TOO_LARGE
-ASN1,reason,167,SEQUENCE_LENGTH_MISMATCH
-ASN1,reason,168,SEQUENCE_NOT_CONSTRUCTED
-ASN1,reason,169,SEQUENCE_OR_SET_NEEDS_CONFIG
-ASN1,reason,170,SHORT_LINE
-ASN1,reason,171,STREAMING_NOT_SUPPORTED
-ASN1,reason,172,STRING_TOO_LONG
-ASN1,reason,173,STRING_TOO_SHORT
-ASN1,reason,174,TAG_VALUE_TOO_HIGH
-ASN1,reason,175,TIME_NOT_ASCII_FORMAT
-ASN1,reason,176,TOO_LONG
-ASN1,reason,177,TYPE_NOT_CONSTRUCTED
-ASN1,reason,178,TYPE_NOT_PRIMITIVE
-ASN1,reason,179,UNEXPECTED_EOC
-ASN1,reason,180,UNIVERSALSTRING_IS_WRONG_LENGTH
-ASN1,reason,181,UNKNOWN_FORMAT
-ASN1,reason,182,UNKNOWN_TAG
-ASN1,reason,183,UNSUPPORTED_ANY_DEFINED_BY_TYPE
-ASN1,reason,184,UNSUPPORTED_PUBLIC_KEY_TYPE
-ASN1,reason,185,UNSUPPORTED_TYPE
-ASN1,reason,186,WRONG_TAG
-ASN1,reason,187,WRONG_TYPE
+ASN1,100,ASN1_LENGTH_MISMATCH
+ASN1,101,AUX_ERROR
+ASN1,102,BAD_GET_ASN1_OBJECT_CALL
+ASN1,103,BAD_OBJECT_HEADER
+ASN1,104,BMPSTRING_IS_WRONG_LENGTH
+ASN1,105,BN_LIB
+ASN1,106,BOOLEAN_IS_WRONG_LENGTH
+ASN1,107,BUFFER_TOO_SMALL
+ASN1,108,DECODE_ERROR
+ASN1,109,DEPTH_EXCEEDED
+ASN1,110,ENCODE_ERROR
+ASN1,111,ERROR_GETTING_TIME
+ASN1,112,EXPECTING_AN_ASN1_SEQUENCE
+ASN1,113,EXPECTING_AN_INTEGER
+ASN1,114,EXPECTING_AN_OBJECT
+ASN1,115,EXPECTING_A_BOOLEAN
+ASN1,116,EXPECTING_A_TIME
+ASN1,117,EXPLICIT_LENGTH_MISMATCH
+ASN1,118,EXPLICIT_TAG_NOT_CONSTRUCTED
+ASN1,119,FIELD_MISSING
+ASN1,120,FIRST_NUM_TOO_LARGE
+ASN1,121,HEADER_TOO_LONG
+ASN1,122,ILLEGAL_BITSTRING_FORMAT
+ASN1,123,ILLEGAL_BOOLEAN
+ASN1,124,ILLEGAL_CHARACTERS
+ASN1,125,ILLEGAL_FORMAT
+ASN1,126,ILLEGAL_HEX
+ASN1,127,ILLEGAL_IMPLICIT_TAG
+ASN1,128,ILLEGAL_INTEGER
+ASN1,129,ILLEGAL_NESTED_TAGGING
+ASN1,130,ILLEGAL_NULL
+ASN1,131,ILLEGAL_NULL_VALUE
+ASN1,132,ILLEGAL_OBJECT
+ASN1,133,ILLEGAL_OPTIONAL_ANY
+ASN1,134,ILLEGAL_OPTIONS_ON_ITEM_TEMPLATE
+ASN1,135,ILLEGAL_TAGGED_ANY
+ASN1,136,ILLEGAL_TIME_VALUE
+ASN1,137,INTEGER_NOT_ASCII_FORMAT
+ASN1,138,INTEGER_TOO_LARGE_FOR_LONG
+ASN1,139,INVALID_BIT_STRING_BITS_LEFT
+ASN1,140,INVALID_BMPSTRING_LENGTH
+ASN1,141,INVALID_DIGIT
+ASN1,142,INVALID_MODIFIER
+ASN1,143,INVALID_NUMBER
+ASN1,144,INVALID_OBJECT_ENCODING
+ASN1,145,INVALID_SEPARATOR
+ASN1,146,INVALID_TIME_FORMAT
+ASN1,147,INVALID_UNIVERSALSTRING_LENGTH
+ASN1,148,INVALID_UTF8STRING
+ASN1,149,LIST_ERROR
+ASN1,150,MALLOC_FAILURE
+ASN1,151,MISSING_ASN1_EOS
+ASN1,152,MISSING_EOC
+ASN1,153,MISSING_SECOND_NUMBER
+ASN1,154,MISSING_VALUE
+ASN1,155,MSTRING_NOT_UNIVERSAL
+ASN1,156,MSTRING_WRONG_TAG
+ASN1,157,NESTED_ASN1_ERROR
+ASN1,158,NESTED_ASN1_STRING
+ASN1,159,NON_HEX_CHARACTERS
+ASN1,160,NOT_ASCII_FORMAT
+ASN1,161,NOT_ENOUGH_DATA
+ASN1,162,NO_MATCHING_CHOICE_TYPE
+ASN1,163,NULL_IS_WRONG_LENGTH
+ASN1,164,OBJECT_NOT_ASCII_FORMAT
+ASN1,165,ODD_NUMBER_OF_CHARS
+ASN1,166,SECOND_NUMBER_TOO_LARGE
+ASN1,167,SEQUENCE_LENGTH_MISMATCH
+ASN1,168,SEQUENCE_NOT_CONSTRUCTED
+ASN1,169,SEQUENCE_OR_SET_NEEDS_CONFIG
+ASN1,170,SHORT_LINE
+ASN1,171,STREAMING_NOT_SUPPORTED
+ASN1,172,STRING_TOO_LONG
+ASN1,173,STRING_TOO_SHORT
+ASN1,174,TAG_VALUE_TOO_HIGH
+ASN1,175,TIME_NOT_ASCII_FORMAT
+ASN1,176,TOO_LONG
+ASN1,177,TYPE_NOT_CONSTRUCTED
+ASN1,178,TYPE_NOT_PRIMITIVE
+ASN1,179,UNEXPECTED_EOC
+ASN1,180,UNIVERSALSTRING_IS_WRONG_LENGTH
+ASN1,181,UNKNOWN_FORMAT
+ASN1,182,UNKNOWN_TAG
+ASN1,183,UNSUPPORTED_ANY_DEFINED_BY_TYPE
+ASN1,184,UNSUPPORTED_PUBLIC_KEY_TYPE
+ASN1,185,UNSUPPORTED_TYPE
+ASN1,186,WRONG_TAG
+ASN1,187,WRONG_TYPE
diff --git a/src/crypto/err/bio.errordata b/src/crypto/err/bio.errordata
index 9f2af02..94b3c97 100644
--- a/src/crypto/err/bio.errordata
+++ b/src/crypto/err/bio.errordata
@@ -1,36 +1,17 @@
-BIO,function,100,BIO_callback_ctrl
-BIO,function,101,BIO_ctrl
-BIO,function,102,BIO_new
-BIO,function,103,BIO_new_file
-BIO,function,104,BIO_new_mem_buf
-BIO,function,118,BIO_printf
-BIO,function,105,BIO_zero_copy_get_read_buf
-BIO,function,106,BIO_zero_copy_get_read_buf_done
-BIO,function,107,BIO_zero_copy_get_write_buf
-BIO,function,108,BIO_zero_copy_get_write_buf_done
-BIO,function,109,bio_io
-BIO,function,110,bio_make_pair
-BIO,function,111,bio_write
-BIO,function,112,buffer_ctrl
-BIO,function,113,conn_ctrl
-BIO,function,114,conn_state
-BIO,function,115,file_ctrl
-BIO,function,116,file_read
-BIO,function,117,mem_write
-BIO,reason,100,BAD_FOPEN_MODE
-BIO,reason,101,BROKEN_PIPE
-BIO,reason,102,CONNECT_ERROR
-BIO,reason,103,ERROR_SETTING_NBIO
-BIO,reason,104,INVALID_ARGUMENT
-BIO,reason,105,IN_USE
-BIO,reason,106,KEEPALIVE
-BIO,reason,107,NBIO_CONNECT_ERROR
-BIO,reason,108,NO_HOSTNAME_SPECIFIED
-BIO,reason,109,NO_PORT_SPECIFIED
-BIO,reason,110,NO_SUCH_FILE
-BIO,reason,111,NULL_PARAMETER
-BIO,reason,112,SYS_LIB
-BIO,reason,113,UNABLE_TO_CREATE_SOCKET
-BIO,reason,114,UNINITIALIZED
-BIO,reason,115,UNSUPPORTED_METHOD
-BIO,reason,116,WRITE_TO_READ_ONLY_BIO
+BIO,100,BAD_FOPEN_MODE
+BIO,101,BROKEN_PIPE
+BIO,102,CONNECT_ERROR
+BIO,103,ERROR_SETTING_NBIO
+BIO,104,INVALID_ARGUMENT
+BIO,105,IN_USE
+BIO,106,KEEPALIVE
+BIO,107,NBIO_CONNECT_ERROR
+BIO,108,NO_HOSTNAME_SPECIFIED
+BIO,109,NO_PORT_SPECIFIED
+BIO,110,NO_SUCH_FILE
+BIO,111,NULL_PARAMETER
+BIO,112,SYS_LIB
+BIO,113,UNABLE_TO_CREATE_SOCKET
+BIO,114,UNINITIALIZED
+BIO,115,UNSUPPORTED_METHOD
+BIO,116,WRITE_TO_READ_ONLY_BIO
diff --git a/src/crypto/err/bn.errordata b/src/crypto/err/bn.errordata
index 6fd4968..76b6392 100644
--- a/src/crypto/err/bn.errordata
+++ b/src/crypto/err/bn.errordata
@@ -1,44 +1,19 @@
-BN,function,100,BN_CTX_get
-BN,function,101,BN_CTX_new
-BN,function,102,BN_CTX_start
-BN,function,103,BN_bn2dec
-BN,function,104,BN_bn2hex
-BN,function,105,BN_div
-BN,function,106,BN_div_recp
-BN,function,107,BN_exp
-BN,function,108,BN_generate_dsa_nonce
-BN,function,109,BN_generate_prime_ex
-BN,function,125,BN_lshift
-BN,function,110,BN_mod_exp2_mont
-BN,function,111,BN_mod_exp_mont
-BN,function,112,BN_mod_exp_mont_consttime
-BN,function,113,BN_mod_exp_mont_word
-BN,function,114,BN_mod_inverse
-BN,function,115,BN_mod_inverse_no_branch
-BN,function,116,BN_mod_lshift_quick
-BN,function,117,BN_mod_sqrt
-BN,function,118,BN_new
-BN,function,119,BN_rand
-BN,function,120,BN_rand_range
-BN,function,126,BN_rshift
-BN,function,121,BN_sqrt
-BN,function,122,BN_usub
-BN,function,123,bn_wexpand
-BN,function,124,mod_exp_recp
-BN,reason,100,ARG2_LT_ARG3
-BN,reason,101,BAD_RECIPROCAL
-BN,reason,102,BIGNUM_TOO_LONG
-BN,reason,103,BITS_TOO_SMALL
-BN,reason,104,CALLED_WITH_EVEN_MODULUS
-BN,reason,105,DIV_BY_ZERO
-BN,reason,106,EXPAND_ON_STATIC_BIGNUM_DATA
-BN,reason,107,INPUT_NOT_REDUCED
-BN,reason,108,INVALID_RANGE
-BN,reason,109,NEGATIVE_NUMBER
-BN,reason,110,NOT_A_SQUARE
-BN,reason,111,NOT_INITIALIZED
-BN,reason,112,NO_INVERSE
-BN,reason,113,PRIVATE_KEY_TOO_LARGE
-BN,reason,114,P_IS_NOT_PRIME
-BN,reason,115,TOO_MANY_ITERATIONS
-BN,reason,116,TOO_MANY_TEMPORARY_VARIABLES
+BN,100,ARG2_LT_ARG3
+BN,117,BAD_ENCODING
+BN,101,BAD_RECIPROCAL
+BN,102,BIGNUM_TOO_LONG
+BN,103,BITS_TOO_SMALL
+BN,104,CALLED_WITH_EVEN_MODULUS
+BN,105,DIV_BY_ZERO
+BN,118,ENCODE_ERROR
+BN,106,EXPAND_ON_STATIC_BIGNUM_DATA
+BN,107,INPUT_NOT_REDUCED
+BN,108,INVALID_RANGE
+BN,109,NEGATIVE_NUMBER
+BN,110,NOT_A_SQUARE
+BN,111,NOT_INITIALIZED
+BN,112,NO_INVERSE
+BN,113,PRIVATE_KEY_TOO_LARGE
+BN,114,P_IS_NOT_PRIME
+BN,115,TOO_MANY_ITERATIONS
+BN,116,TOO_MANY_TEMPORARY_VARIABLES
diff --git a/src/crypto/err/buf.errordata b/src/crypto/err/buf.errordata
deleted file mode 100644
index 01b6c9a..0000000
--- a/src/crypto/err/buf.errordata
+++ /dev/null
@@ -1,4 +0,0 @@
-BUF,function,100,BUF_MEM_new
-BUF,function,101,BUF_memdup
-BUF,function,102,BUF_strndup
-BUF,function,103,buf_mem_grow
diff --git a/src/crypto/err/cipher.errordata b/src/crypto/err/cipher.errordata
index ce8459b..1037505 100644
--- a/src/crypto/err/cipher.errordata
+++ b/src/crypto/err/cipher.errordata
@@ -1,60 +1,25 @@
-CIPHER,function,100,EVP_AEAD_CTX_init
-CIPHER,function,131,EVP_AEAD_CTX_init_with_direction
-CIPHER,function,101,EVP_AEAD_CTX_open
-CIPHER,function,102,EVP_AEAD_CTX_seal
-CIPHER,function,103,EVP_CIPHER_CTX_copy
-CIPHER,function,104,EVP_CIPHER_CTX_ctrl
-CIPHER,function,105,EVP_CIPHER_CTX_set_key_length
-CIPHER,function,106,EVP_CipherInit_ex
-CIPHER,function,107,EVP_DecryptFinal_ex
-CIPHER,function,108,EVP_EncryptFinal_ex
-CIPHER,function,132,aead_aes_ctr_hmac_sha256_init
-CIPHER,function,133,aead_aes_ctr_hmac_sha256_open
-CIPHER,function,134,aead_aes_ctr_hmac_sha256_seal
-CIPHER,function,109,aead_aes_gcm_init
-CIPHER,function,110,aead_aes_gcm_open
-CIPHER,function,111,aead_aes_gcm_seal
-CIPHER,function,112,aead_aes_key_wrap_init
-CIPHER,function,113,aead_aes_key_wrap_open
-CIPHER,function,114,aead_aes_key_wrap_seal
-CIPHER,function,115,aead_chacha20_poly1305_init
-CIPHER,function,116,aead_chacha20_poly1305_open
-CIPHER,function,117,aead_chacha20_poly1305_seal
-CIPHER,function,118,aead_rc4_md5_tls_init
-CIPHER,function,119,aead_rc4_md5_tls_open
-CIPHER,function,120,aead_rc4_md5_tls_seal
-CIPHER,function,121,aead_ssl3_ensure_cipher_init
-CIPHER,function,122,aead_ssl3_init
-CIPHER,function,123,aead_ssl3_open
-CIPHER,function,124,aead_ssl3_seal
-CIPHER,function,125,aead_tls_ensure_cipher_init
-CIPHER,function,126,aead_tls_init
-CIPHER,function,127,aead_tls_open
-CIPHER,function,128,aead_tls_seal
-CIPHER,function,129,aes_init_key
-CIPHER,function,130,aesni_init_key
-CIPHER,reason,100,AES_KEY_SETUP_FAILED
-CIPHER,reason,101,BAD_DECRYPT
-CIPHER,reason,102,BAD_KEY_LENGTH
-CIPHER,reason,103,BUFFER_TOO_SMALL
-CIPHER,reason,104,CTRL_NOT_IMPLEMENTED
-CIPHER,reason,105,CTRL_OPERATION_NOT_IMPLEMENTED
-CIPHER,reason,106,DATA_NOT_MULTIPLE_OF_BLOCK_LENGTH
-CIPHER,reason,107,INITIALIZATION_ERROR
-CIPHER,reason,108,INPUT_NOT_INITIALIZED
-CIPHER,reason,109,INVALID_AD_SIZE
-CIPHER,reason,110,INVALID_KEY_LENGTH
-CIPHER,reason,111,INVALID_NONCE_SIZE
-CIPHER,reason,112,INVALID_OPERATION
-CIPHER,reason,113,IV_TOO_LARGE
-CIPHER,reason,114,NO_CIPHER_SET
-CIPHER,reason,124,NO_DIRECTION_SET
-CIPHER,reason,115,OUTPUT_ALIASES_INPUT
-CIPHER,reason,116,TAG_TOO_LARGE
-CIPHER,reason,117,TOO_LARGE
-CIPHER,reason,118,UNSUPPORTED_AD_SIZE
-CIPHER,reason,119,UNSUPPORTED_INPUT_SIZE
-CIPHER,reason,120,UNSUPPORTED_KEY_SIZE
-CIPHER,reason,121,UNSUPPORTED_NONCE_SIZE
-CIPHER,reason,122,UNSUPPORTED_TAG_SIZE
-CIPHER,reason,123,WRONG_FINAL_BLOCK_LENGTH
+CIPHER,100,AES_KEY_SETUP_FAILED
+CIPHER,101,BAD_DECRYPT
+CIPHER,102,BAD_KEY_LENGTH
+CIPHER,103,BUFFER_TOO_SMALL
+CIPHER,104,CTRL_NOT_IMPLEMENTED
+CIPHER,105,CTRL_OPERATION_NOT_IMPLEMENTED
+CIPHER,106,DATA_NOT_MULTIPLE_OF_BLOCK_LENGTH
+CIPHER,107,INITIALIZATION_ERROR
+CIPHER,108,INPUT_NOT_INITIALIZED
+CIPHER,109,INVALID_AD_SIZE
+CIPHER,110,INVALID_KEY_LENGTH
+CIPHER,111,INVALID_NONCE_SIZE
+CIPHER,112,INVALID_OPERATION
+CIPHER,113,IV_TOO_LARGE
+CIPHER,114,NO_CIPHER_SET
+CIPHER,124,NO_DIRECTION_SET
+CIPHER,115,OUTPUT_ALIASES_INPUT
+CIPHER,116,TAG_TOO_LARGE
+CIPHER,117,TOO_LARGE
+CIPHER,118,UNSUPPORTED_AD_SIZE
+CIPHER,119,UNSUPPORTED_INPUT_SIZE
+CIPHER,120,UNSUPPORTED_KEY_SIZE
+CIPHER,121,UNSUPPORTED_NONCE_SIZE
+CIPHER,122,UNSUPPORTED_TAG_SIZE
+CIPHER,123,WRONG_FINAL_BLOCK_LENGTH
diff --git a/src/crypto/err/conf.errordata b/src/crypto/err/conf.errordata
index 0b96a32..651fabe 100644
--- a/src/crypto/err/conf.errordata
+++ b/src/crypto/err/conf.errordata
@@ -1,10 +1,6 @@
-CONF,function,100,CONF_parse_list
-CONF,function,101,NCONF_load
-CONF,function,102,def_load_bio
-CONF,function,103,str_copy
-CONF,reason,100,LIST_CANNOT_BE_NULL
-CONF,reason,101,MISSING_CLOSE_SQUARE_BRACKET
-CONF,reason,102,MISSING_EQUAL_SIGN
-CONF,reason,103,NO_CLOSE_BRACE
-CONF,reason,104,UNABLE_TO_CREATE_NEW_SECTION
-CONF,reason,105,VARIABLE_HAS_NO_VALUE
+CONF,100,LIST_CANNOT_BE_NULL
+CONF,101,MISSING_CLOSE_SQUARE_BRACKET
+CONF,102,MISSING_EQUAL_SIGN
+CONF,103,NO_CLOSE_BRACE
+CONF,104,UNABLE_TO_CREATE_NEW_SECTION
+CONF,105,VARIABLE_HAS_NO_VALUE
diff --git a/src/crypto/err/crypto.errordata b/src/crypto/err/crypto.errordata
deleted file mode 100644
index 1e0e9d5..0000000
--- a/src/crypto/err/crypto.errordata
+++ /dev/null
@@ -1,4 +0,0 @@
-CRYPTO,function,100,CRYPTO_get_ex_new_index
-CRYPTO,function,101,CRYPTO_set_ex_data
-CRYPTO,function,102,get_class
-CRYPTO,function,103,get_func_pointers
diff --git a/src/crypto/err/dh.errordata b/src/crypto/err/dh.errordata
index 1fd675b..571e218 100644
--- a/src/crypto/err/dh.errordata
+++ b/src/crypto/err/dh.errordata
@@ -1,8 +1,4 @@
-DH,function,100,DH_new_method
-DH,function,101,compute_key
-DH,function,102,generate_key
-DH,function,103,generate_parameters
-DH,reason,100,BAD_GENERATOR
-DH,reason,101,INVALID_PUBKEY
-DH,reason,102,MODULUS_TOO_LARGE
-DH,reason,103,NO_PRIVATE_VALUE
+DH,100,BAD_GENERATOR
+DH,101,INVALID_PUBKEY
+DH,102,MODULUS_TOO_LARGE
+DH,103,NO_PRIVATE_VALUE
diff --git a/src/crypto/err/digest.errordata b/src/crypto/err/digest.errordata
index 95a3622..411e778 100644
--- a/src/crypto/err/digest.errordata
+++ b/src/crypto/err/digest.errordata
@@ -1,3 +1 @@
-DIGEST,function,100,EVP_DigestInit_ex
-DIGEST,function,101,EVP_MD_CTX_copy_ex
-DIGEST,reason,100,INPUT_NOT_INITIALIZED
+DIGEST,100,INPUT_NOT_INITIALIZED
diff --git a/src/crypto/err/dsa.errordata b/src/crypto/err/dsa.errordata
index c2dff23..3c5764a 100644
--- a/src/crypto/err/dsa.errordata
+++ b/src/crypto/err/dsa.errordata
@@ -1,9 +1,4 @@
-DSA,function,100,DSA_new_method
-DSA,function,101,dsa_sig_cb
-DSA,function,102,sign
-DSA,function,103,sign_setup
-DSA,function,104,verify
-DSA,reason,100,BAD_Q_VALUE
-DSA,reason,101,MISSING_PARAMETERS
-DSA,reason,102,MODULUS_TOO_LARGE
-DSA,reason,103,NEED_NEW_SETUP_VALUES
+DSA,100,BAD_Q_VALUE
+DSA,101,MISSING_PARAMETERS
+DSA,102,MODULUS_TOO_LARGE
+DSA,103,NEED_NEW_SETUP_VALUES
diff --git a/src/crypto/err/ec.errordata b/src/crypto/err/ec.errordata
index 252f7ab..e7b4175 100644
--- a/src/crypto/err/ec.errordata
+++ b/src/crypto/err/ec.errordata
@@ -1,95 +1,28 @@
-EC,function,159,BN_to_felem
-EC,function,100,EC_GROUP_copy
-EC,function,101,EC_GROUP_get_curve_GFp
-EC,function,102,EC_GROUP_get_degree
-EC,function,103,EC_GROUP_new_by_curve_name
-EC,function,166,EC_GROUP_new_curve_GFp
-EC,function,104,EC_KEY_check_key
-EC,function,105,EC_KEY_copy
-EC,function,106,EC_KEY_generate_key
-EC,function,165,EC_KEY_new_by_curve_name
-EC,function,107,EC_KEY_new_method
-EC,function,108,EC_KEY_set_public_key_affine_coordinates
-EC,function,109,EC_POINT_add
-EC,function,110,EC_POINT_cmp
-EC,function,111,EC_POINT_copy
-EC,function,112,EC_POINT_dbl
-EC,function,113,EC_POINT_dup
-EC,function,114,EC_POINT_get_affine_coordinates_GFp
-EC,function,115,EC_POINT_invert
-EC,function,116,EC_POINT_is_at_infinity
-EC,function,117,EC_POINT_is_on_curve
-EC,function,118,EC_POINT_make_affine
-EC,function,119,EC_POINT_new
-EC,function,120,EC_POINT_oct2point
-EC,function,121,EC_POINT_point2oct
-EC,function,122,EC_POINT_set_affine_coordinates_GFp
-EC,function,123,EC_POINT_set_compressed_coordinates_GFp
-EC,function,124,EC_POINT_set_to_infinity
-EC,function,125,EC_POINTs_make_affine
-EC,function,126,compute_wNAF
-EC,function,127,d2i_ECPKParameters
-EC,function,128,d2i_ECParameters
-EC,function,129,d2i_ECPrivateKey
-EC,function,130,ec_GFp_mont_field_decode
-EC,function,131,ec_GFp_mont_field_encode
-EC,function,132,ec_GFp_mont_field_mul
-EC,function,133,ec_GFp_mont_field_set_to_one
-EC,function,134,ec_GFp_mont_field_sqr
-EC,function,135,ec_GFp_mont_group_set_curve
-EC,function,160,ec_GFp_nistp256_group_set_curve
-EC,function,161,ec_GFp_nistp256_point_get_affine_coordinates
-EC,function,162,ec_GFp_nistp256_points_mul
-EC,function,136,ec_GFp_simple_group_check_discriminant
-EC,function,137,ec_GFp_simple_group_set_curve
-EC,function,138,ec_GFp_simple_make_affine
-EC,function,139,ec_GFp_simple_oct2point
-EC,function,140,ec_GFp_simple_point2oct
-EC,function,141,ec_GFp_simple_point_get_affine_coordinates
-EC,function,142,ec_GFp_simple_point_set_affine_coordinates
-EC,function,143,ec_GFp_simple_points_make_affine
-EC,function,144,ec_GFp_simple_set_compressed_coordinates
-EC,function,145,ec_asn1_group2pkparameters
-EC,function,146,ec_asn1_pkparameters2group
-EC,function,163,ec_group_copy
-EC,function,147,ec_group_new
-EC,function,148,ec_group_new_curve_GFp
-EC,function,149,ec_group_new_from_data
-EC,function,150,ec_point_set_Jprojective_coordinates_GFp
-EC,function,151,ec_pre_comp_new
-EC,function,152,ec_wNAF_mul
-EC,function,153,ec_wNAF_precompute_mult
-EC,function,154,i2d_ECPKParameters
-EC,function,155,i2d_ECParameters
-EC,function,156,i2d_ECPrivateKey
-EC,function,157,i2o_ECPublicKey
-EC,function,164,nistp256_pre_comp_new
-EC,function,158,o2i_ECPublicKey
-EC,reason,126,BIGNUM_OUT_OF_RANGE
-EC,reason,100,BUFFER_TOO_SMALL
-EC,reason,101,COORDINATES_OUT_OF_RANGE
-EC,reason,102,D2I_ECPKPARAMETERS_FAILURE
-EC,reason,103,EC_GROUP_NEW_BY_NAME_FAILURE
-EC,reason,104,GROUP2PKPARAMETERS_FAILURE
-EC,reason,105,I2D_ECPKPARAMETERS_FAILURE
-EC,reason,106,INCOMPATIBLE_OBJECTS
-EC,reason,107,INVALID_COMPRESSED_POINT
-EC,reason,108,INVALID_COMPRESSION_BIT
-EC,reason,109,INVALID_ENCODING
-EC,reason,110,INVALID_FIELD
-EC,reason,111,INVALID_FORM
-EC,reason,112,INVALID_GROUP_ORDER
-EC,reason,113,INVALID_PRIVATE_KEY
-EC,reason,114,MISSING_PARAMETERS
-EC,reason,115,MISSING_PRIVATE_KEY
-EC,reason,116,NON_NAMED_CURVE
-EC,reason,117,NOT_INITIALIZED
-EC,reason,118,PKPARAMETERS2GROUP_FAILURE
-EC,reason,119,POINT_AT_INFINITY
-EC,reason,120,POINT_IS_NOT_ON_CURVE
-EC,reason,121,SLOT_FULL
-EC,reason,122,UNDEFINED_GENERATOR
-EC,reason,123,UNKNOWN_GROUP
-EC,reason,124,UNKNOWN_ORDER
-EC,reason,127,WRONG_CURVE_PARAMETERS
-EC,reason,125,WRONG_ORDER
+EC,126,BIGNUM_OUT_OF_RANGE
+EC,100,BUFFER_TOO_SMALL
+EC,101,COORDINATES_OUT_OF_RANGE
+EC,102,D2I_ECPKPARAMETERS_FAILURE
+EC,103,EC_GROUP_NEW_BY_NAME_FAILURE
+EC,104,GROUP2PKPARAMETERS_FAILURE
+EC,105,I2D_ECPKPARAMETERS_FAILURE
+EC,106,INCOMPATIBLE_OBJECTS
+EC,107,INVALID_COMPRESSED_POINT
+EC,108,INVALID_COMPRESSION_BIT
+EC,109,INVALID_ENCODING
+EC,110,INVALID_FIELD
+EC,111,INVALID_FORM
+EC,112,INVALID_GROUP_ORDER
+EC,113,INVALID_PRIVATE_KEY
+EC,114,MISSING_PARAMETERS
+EC,115,MISSING_PRIVATE_KEY
+EC,116,NON_NAMED_CURVE
+EC,117,NOT_INITIALIZED
+EC,118,PKPARAMETERS2GROUP_FAILURE
+EC,119,POINT_AT_INFINITY
+EC,120,POINT_IS_NOT_ON_CURVE
+EC,121,SLOT_FULL
+EC,122,UNDEFINED_GENERATOR
+EC,123,UNKNOWN_GROUP
+EC,124,UNKNOWN_ORDER
+EC,127,WRONG_CURVE_PARAMETERS
+EC,125,WRONG_ORDER
diff --git a/src/crypto/err/ecdh.errordata b/src/crypto/err/ecdh.errordata
index 0f1215e..f714c30 100644
--- a/src/crypto/err/ecdh.errordata
+++ b/src/crypto/err/ecdh.errordata
@@ -1,4 +1,3 @@
-ECDH,function,100,ECDH_compute_key
-ECDH,reason,100,KDF_FAILED
-ECDH,reason,101,NO_PRIVATE_VALUE
-ECDH,reason,102,POINT_ARITHMETIC_FAILURE
+ECDH,100,KDF_FAILED
+ECDH,101,NO_PRIVATE_VALUE
+ECDH,102,POINT_ARITHMETIC_FAILURE
diff --git a/src/crypto/err/ecdsa.errordata b/src/crypto/err/ecdsa.errordata
index 97c213e..58ba591 100644
--- a/src/crypto/err/ecdsa.errordata
+++ b/src/crypto/err/ecdsa.errordata
@@ -1,10 +1,6 @@
-ECDSA,function,100,ECDSA_do_sign_ex
-ECDSA,function,101,ECDSA_do_verify
-ECDSA,function,102,ECDSA_sign_ex
-ECDSA,function,103,digest_to_bn
-ECDSA,function,104,ecdsa_sign_setup
-ECDSA,reason,100,BAD_SIGNATURE
-ECDSA,reason,101,MISSING_PARAMETERS
-ECDSA,reason,102,NEED_NEW_SETUP_VALUES
-ECDSA,reason,103,NOT_IMPLEMENTED
-ECDSA,reason,104,RANDOM_NUMBER_GENERATION_FAILED
+ECDSA,100,BAD_SIGNATURE
+ECDSA,105,ENCODE_ERROR
+ECDSA,101,MISSING_PARAMETERS
+ECDSA,102,NEED_NEW_SETUP_VALUES
+ECDSA,103,NOT_IMPLEMENTED
+ECDSA,104,RANDOM_NUMBER_GENERATION_FAILED
diff --git a/src/crypto/err/engine.errordata b/src/crypto/err/engine.errordata
index 1185e88..edbd7b9 100644
--- a/src/crypto/err/engine.errordata
+++ b/src/crypto/err/engine.errordata
@@ -1 +1 @@
-ENGINE,reason,100,OPERATION_NOT_SUPPORTED
+ENGINE,100,OPERATION_NOT_SUPPORTED
diff --git a/src/crypto/err/err.c b/src/crypto/err/err.c
index de1b4a7..24824e8 100644
--- a/src/crypto/err/err.c
+++ b/src/crypto/err/err.c
@@ -125,10 +125,6 @@
#include "../internal.h"
-extern const uint32_t kOpenSSLFunctionValues[];
-extern const size_t kOpenSSLFunctionValuesLen;
-extern const char kOpenSSLFunctionStringData[];
-
extern const uint32_t kOpenSSLReasonValues[];
extern const size_t kOpenSSLReasonValuesLen;
extern const char kOpenSSLReasonStringData[];
@@ -259,42 +255,51 @@ static uint32_t get_error_values(int inc, int top, const char **file, int *line,
}
uint32_t ERR_get_error(void) {
- return get_error_values(1, 0, NULL, NULL, NULL, NULL);
+ return get_error_values(1 /* inc */, 0 /* bottom */, NULL, NULL, NULL, NULL);
}
uint32_t ERR_get_error_line(const char **file, int *line) {
- return get_error_values(1, 0, file, line, NULL, NULL);
+ return get_error_values(1 /* inc */, 0 /* bottom */, file, line, NULL, NULL);
}
uint32_t ERR_get_error_line_data(const char **file, int *line,
const char **data, int *flags) {
- return get_error_values(1, 0, file, line, data, flags);
+ return get_error_values(1 /* inc */, 0 /* bottom */, file, line, data, flags);
}
uint32_t ERR_peek_error(void) {
- return get_error_values(0, 0, NULL, NULL, NULL, NULL);
+ return get_error_values(0 /* peek */, 0 /* bottom */, NULL, NULL, NULL, NULL);
}
uint32_t ERR_peek_error_line(const char **file, int *line) {
- return get_error_values(0, 0, file, line, NULL, NULL);
+ return get_error_values(0 /* peek */, 0 /* bottom */, file, line, NULL, NULL);
}
uint32_t ERR_peek_error_line_data(const char **file, int *line,
const char **data, int *flags) {
- return get_error_values(0, 0, file, line, data, flags);
+ return get_error_values(0 /* peek */, 0 /* bottom */, file, line, data,
+ flags);
+}
+
+const char *ERR_peek_function(void) {
+ ERR_STATE *state = err_get_state();
+ if (state == NULL || state->bottom == state->top) {
+ return NULL;
+ }
+ return state->errors[(state->bottom + 1) % ERR_NUM_ERRORS].function;
}
uint32_t ERR_peek_last_error(void) {
- return get_error_values(0, 1, NULL, NULL, NULL, NULL);
+ return get_error_values(0 /* peek */, 1 /* top */, NULL, NULL, NULL, NULL);
}
uint32_t ERR_peek_last_error_line(const char **file, int *line) {
- return get_error_values(0, 1, file, line, NULL, NULL);
+ return get_error_values(0 /* peek */, 1 /* top */, file, line, NULL, NULL);
}
uint32_t ERR_peek_last_error_line_data(const char **file, int *line,
const char **data, int *flags) {
- return get_error_values(0, 1, file, line, data, flags);
+ return get_error_values(0 /* peek */, 1 /* top */, file, line, data, flags);
}
void ERR_clear_error(void) {
@@ -341,40 +346,20 @@ void ERR_clear_system_error(void) {
errno = 0;
}
-char *ERR_error_string(uint32_t packed_error, char *ret) {
- static char buf[ERR_ERROR_STRING_BUF_LEN];
-
- if (ret == NULL) {
- /* TODO(fork): remove this. */
- ret = buf;
- }
-
-#if !defined(NDEBUG)
- /* This is aimed to help catch callers who don't provide
- * |ERR_ERROR_STRING_BUF_LEN| bytes of space. */
- memset(ret, 0, ERR_ERROR_STRING_BUF_LEN);
-#endif
-
- ERR_error_string_n(packed_error, ret, ERR_ERROR_STRING_BUF_LEN);
-
- return ret;
-}
-
-void ERR_error_string_n(uint32_t packed_error, char *buf, size_t len) {
- char lib_buf[64], func_buf[64], reason_buf[64];
- const char *lib_str, *func_str, *reason_str;
- unsigned lib, func, reason;
+static void err_error_string(uint32_t packed_error, const char *func_str,
+ char *buf, size_t len) {
+ char lib_buf[64], reason_buf[64];
+ const char *lib_str, *reason_str;
+ unsigned lib, reason;
if (len == 0) {
return;
}
lib = ERR_GET_LIB(packed_error);
- func = ERR_GET_FUNC(packed_error);
reason = ERR_GET_REASON(packed_error);
lib_str = ERR_lib_error_string(packed_error);
- func_str = ERR_func_error_string(packed_error);
reason_str = ERR_reason_error_string(packed_error);
if (lib_str == NULL) {
@@ -383,8 +368,7 @@ void ERR_error_string_n(uint32_t packed_error, char *buf, size_t len) {
}
if (func_str == NULL) {
- BIO_snprintf(func_buf, sizeof(func_buf), "func(%u)", func);
- func_str = func_buf;
+ func_str = "OPENSSL_internal";
}
if (reason_str == NULL) {
@@ -426,6 +410,29 @@ void ERR_error_string_n(uint32_t packed_error, char *buf, size_t len) {
}
}
+char *ERR_error_string(uint32_t packed_error, char *ret) {
+ static char buf[ERR_ERROR_STRING_BUF_LEN];
+
+ if (ret == NULL) {
+ /* TODO(fork): remove this. */
+ ret = buf;
+ }
+
+#if !defined(NDEBUG)
+ /* This is aimed to help catch callers who don't provide
+ * |ERR_ERROR_STRING_BUF_LEN| bytes of space. */
+ memset(ret, 0, ERR_ERROR_STRING_BUF_LEN);
+#endif
+
+ ERR_error_string_n(packed_error, ret, ERR_ERROR_STRING_BUF_LEN);
+
+ return ret;
+}
+
+void ERR_error_string_n(uint32_t packed_error, char *buf, size_t len) {
+ err_error_string(packed_error, NULL, buf, len);
+}
+
// err_string_cmp is a compare function for searching error values with
// |bsearch| in |err_string_lookup|.
static int err_string_cmp(const void *a, const void *b) {
@@ -505,8 +512,8 @@ static const char *const kLibraryNames[ERR_NUM_LIBS] = {
"HMAC routines", /* ERR_LIB_HMAC */
"Digest functions", /* ERR_LIB_DIGEST */
"Cipher functions", /* ERR_LIB_CIPHER */
- "User defined functions", /* ERR_LIB_USER */
"HKDF functions", /* ERR_LIB_HKDF */
+ "User defined functions", /* ERR_LIB_USER */
};
const char *ERR_lib_error_string(uint32_t packed_error) {
@@ -519,36 +526,7 @@ const char *ERR_lib_error_string(uint32_t packed_error) {
}
const char *ERR_func_error_string(uint32_t packed_error) {
- const uint32_t lib = ERR_GET_LIB(packed_error);
- const uint32_t func = ERR_GET_FUNC(packed_error);
-
- if (lib == ERR_LIB_SYS) {
- switch (func) {
- case SYS_F_fopen:
- return "fopen";
- case SYS_F_fclose:
- return "fclose";
- case SYS_F_fread:
- return "fread";
- case SYS_F_fwrite:
- return "fwrite";
- case SYS_F_socket:
- return "socket";
- case SYS_F_setsockopt:
- return "setsockopt";
- case SYS_F_connect:
- return "connect";
- case SYS_F_getaddrinfo:
- return "getaddrinfo";
- default:
- return NULL;
- }
- }
-
- return err_string_lookup(ERR_GET_LIB(packed_error),
- ERR_GET_FUNC(packed_error), kOpenSSLFunctionValues,
- kOpenSSLFunctionValuesLen,
- kOpenSSLFunctionStringData);
+ return "OPENSSL_internal";
}
const char *ERR_reason_error_string(uint32_t packed_error) {
@@ -599,12 +577,13 @@ void ERR_print_errors_cb(ERR_print_errors_callback_t callback, void *ctx) {
const unsigned long thread_hash = (uintptr_t) err_get_state();
for (;;) {
+ const char *function = ERR_peek_function();
packed_error = ERR_get_error_line_data(&file, &line, &data, &flags);
if (packed_error == 0) {
break;
}
- ERR_error_string_n(packed_error, buf, sizeof(buf));
+ err_error_string(packed_error, function, buf, sizeof(buf));
BIO_snprintf(buf2, sizeof(buf2), "%lu:%s:%s:%d:%s\n", thread_hash, buf,
file, line, (flags & ERR_FLAG_STRING) ? data : "");
if (callback(buf2, strlen(buf2), ctx) <= 0) {
@@ -644,8 +623,8 @@ static void err_set_error_data(char *data, int flags) {
error->flags = flags;
}
-void ERR_put_error(int library, int func, int reason, const char *file,
- unsigned line) {
+void ERR_put_error(int library, int reason, const char *function,
+ const char *file, unsigned line) {
ERR_STATE *const state = err_get_state();
struct err_error_st *error;
@@ -654,7 +633,7 @@ void ERR_put_error(int library, int func, int reason, const char *file,
}
if (library == ERR_LIB_SYS && reason == 0) {
-#if defined(WIN32)
+#if defined(OPENSSL_WINDOWS)
reason = GetLastError();
#else
reason = errno;
@@ -668,9 +647,10 @@ void ERR_put_error(int library, int func, int reason, const char *file,
error = &state->errors[state->top];
err_clear(error);
+ error->function = function;
error->file = file;
error->line = line;
- error->packed = ERR_PACK(library, func, reason);
+ error->packed = ERR_PACK(library, reason);
}
/* ERR_add_error_data_vdata takes a variable number of const char* pointers,
diff --git a/src/crypto/err/err_data_generate.go b/src/crypto/err/err_data_generate.go
index a5b4cb5..24e0d66 100644
--- a/src/crypto/err/err_data_generate.go
+++ b/src/crypto/err/err_data_generate.go
@@ -59,8 +59,8 @@ var libraryNames = []string{
"HMAC",
"DIGEST",
"CIPHER",
- "USER",
"HKDF",
+ "USER",
}
// stringList is a map from uint32 -> string which can output data for a sorted
@@ -69,7 +69,7 @@ type stringList struct {
// entries is an array of keys and offsets into |stringData|. The
// offsets are in the bottom 15 bits of each uint32 and the key is the
// top 17 bits.
- entries []uint32
+ entries []uint32
// internedStrings contains the same strings as are in |stringData|,
// but allows for easy deduplication. It maps a string to its offset in
// |stringData|.
@@ -146,7 +146,7 @@ func (st *stringList) WriteTo(out stringWriter, name string) {
fmt.Fprintf(out, " 0x%x,\n", v)
}
out.WriteString("};\n\n")
- out.WriteString("const size_t " + values + "Len = sizeof(" + values + ") / sizeof(" + values + "[0]);\n\n");
+ out.WriteString("const size_t " + values + "Len = sizeof(" + values + ") / sizeof(" + values + "[0]);\n\n")
stringData := "kOpenSSL" + name + "StringData"
out.WriteString("const char " + stringData + "[] =\n \"")
@@ -161,8 +161,8 @@ func (st *stringList) WriteTo(out stringWriter, name string) {
}
type errorData struct {
- functions, reasons *stringList
- libraryMap map[string]uint32
+ reasons *stringList
+ libraryMap map[string]uint32
}
func (e *errorData) readErrorDataFile(filename string) error {
@@ -184,8 +184,8 @@ func (e *errorData) readErrorDataFile(filename string) error {
continue
}
parts := bytes.Split(line, comma)
- if len(parts) != 4 {
- return fmt.Errorf("bad line %d in %s: found %d values but want 4", lineNo, filename, len(parts))
+ if len(parts) != 3 {
+ return fmt.Errorf("bad line %d in %s: found %d values but want 3", lineNo, filename, len(parts))
}
libNum, ok := e.libraryMap[string(parts[0])]
if !ok {
@@ -194,26 +194,18 @@ func (e *errorData) readErrorDataFile(filename string) error {
if libNum >= 64 {
return fmt.Errorf("bad line %d in %s: library value too large", lineNo, filename)
}
- key, err := strconv.ParseUint(string(parts[2]), 10 /* base */, 32 /* bit size */)
+ key, err := strconv.ParseUint(string(parts[1]), 10 /* base */, 32 /* bit size */)
if err != nil {
return fmt.Errorf("bad line %d in %s: %s", lineNo, filename, err)
}
if key >= 2048 {
return fmt.Errorf("bad line %d in %s: key too large", lineNo, filename)
}
- value := string(parts[3])
+ value := string(parts[2])
listKey := libNum<<26 | uint32(key)<<15
- switch string(parts[1]) {
- case "function":
- err = e.functions.Add(listKey, value)
- case "reason":
- err = e.reasons.Add(listKey, value)
- default:
- return fmt.Errorf("bad line %d in %s: bad value type", lineNo, filename)
- }
-
+ err = e.reasons.Add(listKey, value)
if err != nil {
return err
}
@@ -224,7 +216,6 @@ func (e *errorData) readErrorDataFile(filename string) error {
func main() {
e := &errorData{
- functions: newStringList(),
reasons: newStringList(),
libraryMap: make(map[string]uint32),
}
@@ -279,9 +270,8 @@ func main() {
for i, name := range libraryNames {
fmt.Fprintf(out, "OPENSSL_COMPILE_ASSERT(ERR_LIB_%s == %d, library_values_changed_%d);\n", name, i+1, i+1)
}
- fmt.Fprintf(out, "OPENSSL_COMPILE_ASSERT(ERR_NUM_LIBS == %d, library_values_changed_num);\n", len(libraryNames) + 1)
+ fmt.Fprintf(out, "OPENSSL_COMPILE_ASSERT(ERR_NUM_LIBS == %d, library_values_changed_num);\n", len(libraryNames)+1)
out.WriteString("\n")
- e.functions.WriteTo(out, "Function")
e.reasons.WriteTo(out, "Reason")
}
diff --git a/src/crypto/err/err_test.cc b/src/crypto/err/err_test.cc
index 98dfb85..6643c68 100644
--- a/src/crypto/err/err_test.cc
+++ b/src/crypto/err/err_test.cc
@@ -22,7 +22,7 @@
static bool TestOverflow() {
for (unsigned i = 0; i < ERR_NUM_ERRORS*2; i++) {
- ERR_put_error(1, 2, i+1, "test", 1);
+ ERR_put_error(1, i+1, "function", "test", 1);
}
for (unsigned i = 0; i < ERR_NUM_ERRORS - 1; i++) {
@@ -50,7 +50,7 @@ static bool TestPutError() {
return false;
}
- ERR_put_error(1, 2, 3, "test", 4);
+ ERR_put_error(1, 2, "function", "test", 4);
ERR_add_error_data(1, "testing");
int peeked_line, line, peeked_flags, flags;
@@ -58,6 +58,7 @@ static bool TestPutError() {
uint32_t peeked_packed_error =
ERR_peek_error_line_data(&peeked_file, &peeked_line, &peeked_data,
&peeked_flags);
+ const char *function = ERR_peek_function();
uint32_t packed_error = ERR_get_error_line_data(&file, &line, &data, &flags);
if (peeked_packed_error != packed_error ||
@@ -68,12 +69,12 @@ static bool TestPutError() {
return false;
}
- if (strcmp(file, "test") != 0 ||
+ if (strcmp(function, "function") != 0 ||
+ strcmp(file, "test") != 0 ||
line != 4 ||
(flags & ERR_FLAG_STRING) == 0 ||
ERR_GET_LIB(packed_error) != 1 ||
- ERR_GET_FUNC(packed_error) != 2 ||
- ERR_GET_REASON(packed_error) != 3 ||
+ ERR_GET_REASON(packed_error) != 2 ||
strcmp(data, "testing") != 0) {
fprintf(stderr, "Bad error data returned.\n");
return false;
@@ -88,7 +89,7 @@ static bool TestClearError() {
return false;
}
- ERR_put_error(1, 2, 3, "test", 4);
+ ERR_put_error(1, 2, "function", "test", 4);
ERR_clear_error();
if (ERR_get_error() != 0) {
@@ -100,7 +101,7 @@ static bool TestClearError() {
}
static bool TestPrint() {
- ERR_put_error(1, 2, 3, "test", 4);
+ ERR_put_error(1, 2, "function", "test", 4);
ERR_add_error_data(1, "testing");
uint32_t packed_error = ERR_get_error();
@@ -113,11 +114,41 @@ static bool TestPrint() {
}
static bool TestRelease() {
- ERR_put_error(1, 2, 3, "test", 4);
+ ERR_put_error(1, 2, "function", "test", 4);
ERR_remove_thread_state(NULL);
return true;
}
+static bool HasSuffix(const char *str, const char *suffix) {
+ size_t suffix_len = strlen(suffix);
+ size_t str_len = strlen(str);
+ if (str_len < suffix_len) {
+ return false;
+ }
+ return strcmp(str + str_len - suffix_len, suffix) == 0;
+}
+
+static bool TestPutMacro() {
+ int expected_line = __LINE__ + 1;
+ OPENSSL_PUT_ERROR(USER, ERR_R_INTERNAL_ERROR);
+
+ int line;
+ const char *file;
+ const char *function = ERR_peek_function();
+ uint32_t error = ERR_get_error_line(&file, &line);
+
+ if (strcmp(function, "TestPutMacro") != 0 ||
+ !HasSuffix(file, "err_test.cc") ||
+ line != expected_line ||
+ ERR_GET_LIB(error) != ERR_LIB_USER ||
+ ERR_GET_REASON(error) != ERR_R_INTERNAL_ERROR) {
+ fprintf(stderr, "Bad error data returned.\n");
+ return false;
+ }
+
+ return true;
+}
+
int main() {
CRYPTO_library_init();
@@ -125,7 +156,8 @@ int main() {
!TestPutError() ||
!TestClearError() ||
!TestPrint() ||
- !TestRelease()) {
+ !TestRelease() ||
+ !TestPutMacro()) {
return 1;
}
diff --git a/src/crypto/err/evp.errordata b/src/crypto/err/evp.errordata
index 14dd27b..8f8dd48 100644
--- a/src/crypto/err/evp.errordata
+++ b/src/crypto/err/evp.errordata
@@ -1,114 +1,46 @@
-EVP,function,160,EVP_DigestSignAlgorithm
-EVP,function,161,EVP_DigestVerifyInitFromAlgorithm
-EVP,function,162,EVP_PKEY_CTX_ctrl
-EVP,function,163,EVP_PKEY_CTX_dup
-EVP,function,159,EVP_PKEY_CTX_get0_rsa_oaep_label
-EVP,function,164,EVP_PKEY_copy_parameters
-EVP,function,165,EVP_PKEY_decrypt
-EVP,function,166,EVP_PKEY_decrypt_init
-EVP,function,167,EVP_PKEY_derive
-EVP,function,108,EVP_PKEY_derive_init
-EVP,function,168,EVP_PKEY_derive_set_peer
-EVP,function,110,EVP_PKEY_encrypt
-EVP,function,111,EVP_PKEY_encrypt_init
-EVP,function,112,EVP_PKEY_get1_DH
-EVP,function,169,EVP_PKEY_get1_DSA
-EVP,function,114,EVP_PKEY_get1_EC_KEY
-EVP,function,115,EVP_PKEY_get1_RSA
-EVP,function,116,EVP_PKEY_keygen
-EVP,function,170,EVP_PKEY_keygen_init
-EVP,function,171,EVP_PKEY_new
-EVP,function,172,EVP_PKEY_set_type
-EVP,function,120,EVP_PKEY_sign
-EVP,function,121,EVP_PKEY_sign_init
-EVP,function,122,EVP_PKEY_verify
-EVP,function,123,EVP_PKEY_verify_init
-EVP,function,173,check_padding_md
-EVP,function,125,d2i_AutoPrivateKey
-EVP,function,126,d2i_PrivateKey
-EVP,function,127,do_EC_KEY_print
-EVP,function,174,do_dsa_print
-EVP,function,175,do_rsa_print
-EVP,function,129,do_sigver_init
-EVP,function,176,dsa_param_decode
-EVP,function,177,dsa_priv_decode
-EVP,function,178,dsa_priv_encode
-EVP,function,179,dsa_pub_decode
-EVP,function,180,dsa_pub_encode
-EVP,function,181,dsa_sig_print
-EVP,function,130,eckey_param2type
-EVP,function,131,eckey_param_decode
-EVP,function,132,eckey_priv_decode
-EVP,function,133,eckey_priv_encode
-EVP,function,134,eckey_pub_decode
-EVP,function,135,eckey_pub_encode
-EVP,function,136,eckey_type2param
-EVP,function,137,evp_pkey_ctx_new
-EVP,function,138,hmac_signctx
-EVP,function,139,i2d_PublicKey
-EVP,function,182,old_dsa_priv_decode
-EVP,function,140,old_ec_priv_decode
-EVP,function,141,old_rsa_priv_decode
-EVP,function,142,pkey_ec_ctrl
-EVP,function,143,pkey_ec_derive
-EVP,function,144,pkey_ec_keygen
-EVP,function,145,pkey_ec_paramgen
-EVP,function,146,pkey_ec_sign
-EVP,function,158,pkey_hmac_ctrl
-EVP,function,147,pkey_rsa_ctrl
-EVP,function,148,pkey_rsa_decrypt
-EVP,function,149,pkey_rsa_encrypt
-EVP,function,150,pkey_rsa_sign
-EVP,function,151,rsa_algor_to_md
-EVP,function,152,rsa_digest_verify_init_from_algorithm
-EVP,function,153,rsa_mgf1_to_md
-EVP,function,154,rsa_priv_decode
-EVP,function,155,rsa_priv_encode
-EVP,function,156,rsa_pss_to_ctx
-EVP,function,157,rsa_pub_decode
-EVP,reason,151,BN_DECODE_ERROR
-EVP,reason,100,BUFFER_TOO_SMALL
-EVP,reason,101,COMMAND_NOT_SUPPORTED
-EVP,reason,146,CONTEXT_NOT_INITIALISED
-EVP,reason,143,DECODE_ERROR
-EVP,reason,104,DIFFERENT_KEY_TYPES
-EVP,reason,105,DIFFERENT_PARAMETERS
-EVP,reason,147,DIGEST_AND_KEY_TYPE_NOT_SUPPORTED
-EVP,reason,107,EXPECTING_AN_EC_KEY_KEY
-EVP,reason,141,EXPECTING_AN_RSA_KEY
-EVP,reason,109,EXPECTING_A_DH_KEY
-EVP,reason,110,EXPECTING_A_DSA_KEY
-EVP,reason,111,ILLEGAL_OR_UNSUPPORTED_PADDING_MODE
-EVP,reason,112,INVALID_CURVE
-EVP,reason,113,INVALID_DIGEST_LENGTH
-EVP,reason,114,INVALID_DIGEST_TYPE
-EVP,reason,115,INVALID_KEYBITS
-EVP,reason,116,INVALID_MGF1_MD
-EVP,reason,142,INVALID_OPERATION
-EVP,reason,118,INVALID_PADDING_MODE
-EVP,reason,119,INVALID_PSS_PARAMETERS
-EVP,reason,144,INVALID_PSS_SALTLEN
-EVP,reason,121,INVALID_SALT_LENGTH
-EVP,reason,122,INVALID_TRAILER
-EVP,reason,123,KEYS_NOT_SET
-EVP,reason,124,MISSING_PARAMETERS
-EVP,reason,125,NO_DEFAULT_DIGEST
-EVP,reason,126,NO_KEY_SET
-EVP,reason,127,NO_MDC2_SUPPORT
-EVP,reason,128,NO_NID_FOR_CURVE
-EVP,reason,129,NO_OPERATION_SET
-EVP,reason,130,NO_PARAMETERS_SET
-EVP,reason,131,OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE
-EVP,reason,132,OPERATON_NOT_INITIALIZED
-EVP,reason,152,PARAMETER_ENCODING_ERROR
-EVP,reason,133,UNKNOWN_DIGEST
-EVP,reason,134,UNKNOWN_MASK_DIGEST
-EVP,reason,150,UNKNOWN_MESSAGE_DIGEST_ALGORITHM
-EVP,reason,145,UNKNOWN_PUBLIC_KEY_TYPE
-EVP,reason,149,UNKNOWN_SIGNATURE_ALGORITHM
-EVP,reason,138,UNSUPPORTED_ALGORITHM
-EVP,reason,139,UNSUPPORTED_MASK_ALGORITHM
-EVP,reason,140,UNSUPPORTED_MASK_PARAMETER
-EVP,reason,153,UNSUPPORTED_PUBLIC_KEY_TYPE
-EVP,reason,154,UNSUPPORTED_SIGNATURE_TYPE
-EVP,reason,148,WRONG_PUBLIC_KEY_TYPE
+EVP,151,BN_DECODE_ERROR
+EVP,100,BUFFER_TOO_SMALL
+EVP,101,COMMAND_NOT_SUPPORTED
+EVP,146,CONTEXT_NOT_INITIALISED
+EVP,143,DECODE_ERROR
+EVP,104,DIFFERENT_KEY_TYPES
+EVP,105,DIFFERENT_PARAMETERS
+EVP,147,DIGEST_AND_KEY_TYPE_NOT_SUPPORTED
+EVP,107,EXPECTING_AN_EC_KEY_KEY
+EVP,141,EXPECTING_AN_RSA_KEY
+EVP,109,EXPECTING_A_DH_KEY
+EVP,110,EXPECTING_A_DSA_KEY
+EVP,111,ILLEGAL_OR_UNSUPPORTED_PADDING_MODE
+EVP,112,INVALID_CURVE
+EVP,113,INVALID_DIGEST_LENGTH
+EVP,114,INVALID_DIGEST_TYPE
+EVP,115,INVALID_KEYBITS
+EVP,116,INVALID_MGF1_MD
+EVP,142,INVALID_OPERATION
+EVP,118,INVALID_PADDING_MODE
+EVP,119,INVALID_PSS_PARAMETERS
+EVP,144,INVALID_PSS_SALTLEN
+EVP,121,INVALID_SALT_LENGTH
+EVP,122,INVALID_TRAILER
+EVP,123,KEYS_NOT_SET
+EVP,124,MISSING_PARAMETERS
+EVP,125,NO_DEFAULT_DIGEST
+EVP,126,NO_KEY_SET
+EVP,127,NO_MDC2_SUPPORT
+EVP,128,NO_NID_FOR_CURVE
+EVP,129,NO_OPERATION_SET
+EVP,130,NO_PARAMETERS_SET
+EVP,131,OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE
+EVP,132,OPERATON_NOT_INITIALIZED
+EVP,152,PARAMETER_ENCODING_ERROR
+EVP,133,UNKNOWN_DIGEST
+EVP,134,UNKNOWN_MASK_DIGEST
+EVP,150,UNKNOWN_MESSAGE_DIGEST_ALGORITHM
+EVP,145,UNKNOWN_PUBLIC_KEY_TYPE
+EVP,149,UNKNOWN_SIGNATURE_ALGORITHM
+EVP,138,UNSUPPORTED_ALGORITHM
+EVP,139,UNSUPPORTED_MASK_ALGORITHM
+EVP,140,UNSUPPORTED_MASK_PARAMETER
+EVP,153,UNSUPPORTED_PUBLIC_KEY_TYPE
+EVP,154,UNSUPPORTED_SIGNATURE_TYPE
+EVP,148,WRONG_PUBLIC_KEY_TYPE
diff --git a/src/crypto/err/hkdf.errordata b/src/crypto/err/hkdf.errordata
index 878a802..84866de 100644
--- a/src/crypto/err/hkdf.errordata
+++ b/src/crypto/err/hkdf.errordata
@@ -1,2 +1 @@
-HKDF,function,100,HKDF
-HKDF,reason,100,OUTPUT_TOO_LARGE
+HKDF,100,OUTPUT_TOO_LARGE
diff --git a/src/crypto/err/obj.errordata b/src/crypto/err/obj.errordata
index 74e4629..c54435e 100644
--- a/src/crypto/err/obj.errordata
+++ b/src/crypto/err/obj.errordata
@@ -1,5 +1 @@
-OBJ,function,100,OBJ_create
-OBJ,function,101,OBJ_dup
-OBJ,function,102,OBJ_nid2obj
-OBJ,function,103,OBJ_txt2obj
-OBJ,reason,100,UNKNOWN_NID
+OBJ,100,UNKNOWN_NID
diff --git a/src/crypto/err/pem.errordata b/src/crypto/err/pem.errordata
index 42216a7..2a4b73a 100644
--- a/src/crypto/err/pem.errordata
+++ b/src/crypto/err/pem.errordata
@@ -1,39 +1,15 @@
-PEM,function,100,PEM_ASN1_read
-PEM,function,101,PEM_ASN1_read_bio
-PEM,function,102,PEM_ASN1_write
-PEM,function,103,PEM_ASN1_write_bio
-PEM,function,104,PEM_X509_INFO_read
-PEM,function,105,PEM_X509_INFO_read_bio
-PEM,function,106,PEM_X509_INFO_write_bio
-PEM,function,107,PEM_do_header
-PEM,function,108,PEM_get_EVP_CIPHER_INFO
-PEM,function,109,PEM_read
-PEM,function,110,PEM_read_DHparams
-PEM,function,111,PEM_read_PrivateKey
-PEM,function,112,PEM_read_bio
-PEM,function,113,PEM_read_bio_DHparams
-PEM,function,114,PEM_read_bio_Parameters
-PEM,function,115,PEM_read_bio_PrivateKey
-PEM,function,116,PEM_write
-PEM,function,117,PEM_write_PrivateKey
-PEM,function,118,PEM_write_bio
-PEM,function,119,d2i_PKCS8PrivateKey_bio
-PEM,function,120,d2i_PKCS8PrivateKey_fp
-PEM,function,121,do_pk8pkey
-PEM,function,122,do_pk8pkey_fp
-PEM,function,123,load_iv
-PEM,reason,100,BAD_BASE64_DECODE
-PEM,reason,101,BAD_DECRYPT
-PEM,reason,102,BAD_END_LINE
-PEM,reason,103,BAD_IV_CHARS
-PEM,reason,104,BAD_PASSWORD_READ
-PEM,reason,105,CIPHER_IS_NULL
-PEM,reason,106,ERROR_CONVERTING_PRIVATE_KEY
-PEM,reason,107,NOT_DEK_INFO
-PEM,reason,108,NOT_ENCRYPTED
-PEM,reason,109,NOT_PROC_TYPE
-PEM,reason,110,NO_START_LINE
-PEM,reason,111,READ_KEY
-PEM,reason,112,SHORT_HEADER
-PEM,reason,113,UNSUPPORTED_CIPHER
-PEM,reason,114,UNSUPPORTED_ENCRYPTION
+PEM,100,BAD_BASE64_DECODE
+PEM,101,BAD_DECRYPT
+PEM,102,BAD_END_LINE
+PEM,103,BAD_IV_CHARS
+PEM,104,BAD_PASSWORD_READ
+PEM,105,CIPHER_IS_NULL
+PEM,106,ERROR_CONVERTING_PRIVATE_KEY
+PEM,107,NOT_DEK_INFO
+PEM,108,NOT_ENCRYPTED
+PEM,109,NOT_PROC_TYPE
+PEM,110,NO_START_LINE
+PEM,111,READ_KEY
+PEM,112,SHORT_HEADER
+PEM,113,UNSUPPORTED_CIPHER
+PEM,114,UNSUPPORTED_ENCRYPTION
diff --git a/src/crypto/err/pkcs8.errordata b/src/crypto/err/pkcs8.errordata
index 936f3c5..0eb5083 100644
--- a/src/crypto/err/pkcs8.errordata
+++ b/src/crypto/err/pkcs8.errordata
@@ -1,43 +1,25 @@
-PKCS8,function,100,EVP_PKCS82PKEY
-PKCS8,function,101,EVP_PKEY2PKCS8
-PKCS8,function,102,PKCS12_get_key_and_certs
-PKCS8,function,103,PKCS12_handle_content_info
-PKCS8,function,104,PKCS12_handle_content_infos
-PKCS8,function,105,PKCS5_pbe2_set_iv
-PKCS8,function,106,PKCS5_pbe_set
-PKCS8,function,107,PKCS5_pbe_set0_algor
-PKCS8,function,108,PKCS5_pbkdf2_set
-PKCS8,function,109,PKCS8_decrypt
-PKCS8,function,110,PKCS8_encrypt
-PKCS8,function,111,PKCS8_encrypt_pbe
-PKCS8,function,112,pbe_cipher_init
-PKCS8,function,113,pbe_crypt
-PKCS8,function,114,pkcs12_item_decrypt_d2i
-PKCS8,function,115,pkcs12_item_i2d_encrypt
-PKCS8,function,116,pkcs12_key_gen_raw
-PKCS8,function,117,pkcs12_pbe_keyivgen
-PKCS8,reason,100,BAD_PKCS12_DATA
-PKCS8,reason,101,BAD_PKCS12_VERSION
-PKCS8,reason,102,CIPHER_HAS_NO_OBJECT_IDENTIFIER
-PKCS8,reason,103,CRYPT_ERROR
-PKCS8,reason,104,DECODE_ERROR
-PKCS8,reason,105,ENCODE_ERROR
-PKCS8,reason,106,ENCRYPT_ERROR
-PKCS8,reason,107,ERROR_SETTING_CIPHER_PARAMS
-PKCS8,reason,108,INCORRECT_PASSWORD
-PKCS8,reason,109,KEYGEN_FAILURE
-PKCS8,reason,110,KEY_GEN_ERROR
-PKCS8,reason,111,METHOD_NOT_SUPPORTED
-PKCS8,reason,112,MISSING_MAC
-PKCS8,reason,113,MULTIPLE_PRIVATE_KEYS_IN_PKCS12
-PKCS8,reason,114,PKCS12_PUBLIC_KEY_INTEGRITY_NOT_SUPPORTED
-PKCS8,reason,115,PKCS12_TOO_DEEPLY_NESTED
-PKCS8,reason,116,PRIVATE_KEY_DECODE_ERROR
-PKCS8,reason,117,PRIVATE_KEY_ENCODE_ERROR
-PKCS8,reason,118,TOO_LONG
-PKCS8,reason,119,UNKNOWN_ALGORITHM
-PKCS8,reason,120,UNKNOWN_CIPHER
-PKCS8,reason,121,UNKNOWN_CIPHER_ALGORITHM
-PKCS8,reason,122,UNKNOWN_DIGEST
-PKCS8,reason,123,UNKNOWN_HASH
-PKCS8,reason,124,UNSUPPORTED_PRIVATE_KEY_ALGORITHM
+PKCS8,100,BAD_PKCS12_DATA
+PKCS8,101,BAD_PKCS12_VERSION
+PKCS8,102,CIPHER_HAS_NO_OBJECT_IDENTIFIER
+PKCS8,103,CRYPT_ERROR
+PKCS8,104,DECODE_ERROR
+PKCS8,105,ENCODE_ERROR
+PKCS8,106,ENCRYPT_ERROR
+PKCS8,107,ERROR_SETTING_CIPHER_PARAMS
+PKCS8,108,INCORRECT_PASSWORD
+PKCS8,109,KEYGEN_FAILURE
+PKCS8,110,KEY_GEN_ERROR
+PKCS8,111,METHOD_NOT_SUPPORTED
+PKCS8,112,MISSING_MAC
+PKCS8,113,MULTIPLE_PRIVATE_KEYS_IN_PKCS12
+PKCS8,114,PKCS12_PUBLIC_KEY_INTEGRITY_NOT_SUPPORTED
+PKCS8,115,PKCS12_TOO_DEEPLY_NESTED
+PKCS8,116,PRIVATE_KEY_DECODE_ERROR
+PKCS8,117,PRIVATE_KEY_ENCODE_ERROR
+PKCS8,118,TOO_LONG
+PKCS8,119,UNKNOWN_ALGORITHM
+PKCS8,120,UNKNOWN_CIPHER
+PKCS8,121,UNKNOWN_CIPHER_ALGORITHM
+PKCS8,122,UNKNOWN_DIGEST
+PKCS8,123,UNKNOWN_HASH
+PKCS8,124,UNSUPPORTED_PRIVATE_KEY_ALGORITHM
diff --git a/src/crypto/err/rsa.errordata b/src/crypto/err/rsa.errordata
index 64b390d..c19f73c 100644
--- a/src/crypto/err/rsa.errordata
+++ b/src/crypto/err/rsa.errordata
@@ -1,69 +1,46 @@
-RSA,function,100,BN_BLINDING_convert_ex
-RSA,function,101,BN_BLINDING_create_param
-RSA,function,102,BN_BLINDING_invert_ex
-RSA,function,103,BN_BLINDING_new
-RSA,function,104,BN_BLINDING_update
-RSA,function,105,RSA_check_key
-RSA,function,106,RSA_new_method
-RSA,function,107,RSA_padding_add_PKCS1_OAEP_mgf1
-RSA,function,108,RSA_padding_add_PKCS1_PSS_mgf1
-RSA,function,109,RSA_padding_add_PKCS1_type_1
-RSA,function,110,RSA_padding_add_PKCS1_type_2
-RSA,function,111,RSA_padding_add_none
-RSA,function,112,RSA_padding_check_PKCS1_OAEP_mgf1
-RSA,function,113,RSA_padding_check_PKCS1_type_1
-RSA,function,114,RSA_padding_check_PKCS1_type_2
-RSA,function,115,RSA_padding_check_none
-RSA,function,116,RSA_recover_crt_params
-RSA,function,117,RSA_sign
-RSA,function,118,RSA_verify
-RSA,function,119,RSA_verify_PKCS1_PSS_mgf1
-RSA,function,120,decrypt
-RSA,function,121,encrypt
-RSA,function,122,keygen
-RSA,function,123,pkcs1_prefixed_msg
-RSA,function,124,private_transform
-RSA,function,125,rsa_setup_blinding
-RSA,function,126,sign_raw
-RSA,function,127,verify_raw
-RSA,reason,100,BAD_E_VALUE
-RSA,reason,101,BAD_FIXED_HEADER_DECRYPT
-RSA,reason,102,BAD_PAD_BYTE_COUNT
-RSA,reason,103,BAD_RSA_PARAMETERS
-RSA,reason,104,BAD_SIGNATURE
-RSA,reason,105,BLOCK_TYPE_IS_NOT_01
-RSA,reason,106,BN_NOT_INITIALIZED
-RSA,reason,107,CRT_PARAMS_ALREADY_GIVEN
-RSA,reason,108,CRT_VALUES_INCORRECT
-RSA,reason,109,DATA_LEN_NOT_EQUAL_TO_MOD_LEN
-RSA,reason,110,DATA_TOO_LARGE
-RSA,reason,111,DATA_TOO_LARGE_FOR_KEY_SIZE
-RSA,reason,112,DATA_TOO_LARGE_FOR_MODULUS
-RSA,reason,113,DATA_TOO_SMALL
-RSA,reason,114,DATA_TOO_SMALL_FOR_KEY_SIZE
-RSA,reason,115,DIGEST_TOO_BIG_FOR_RSA_KEY
-RSA,reason,116,D_E_NOT_CONGRUENT_TO_1
-RSA,reason,117,EMPTY_PUBLIC_KEY
-RSA,reason,118,FIRST_OCTET_INVALID
-RSA,reason,119,INCONSISTENT_SET_OF_CRT_VALUES
-RSA,reason,120,INTERNAL_ERROR
-RSA,reason,121,INVALID_MESSAGE_LENGTH
-RSA,reason,122,KEY_SIZE_TOO_SMALL
-RSA,reason,123,LAST_OCTET_INVALID
-RSA,reason,124,MODULUS_TOO_LARGE
-RSA,reason,125,NO_PUBLIC_EXPONENT
-RSA,reason,126,NULL_BEFORE_BLOCK_MISSING
-RSA,reason,127,N_NOT_EQUAL_P_Q
-RSA,reason,128,OAEP_DECODING_ERROR
-RSA,reason,129,ONLY_ONE_OF_P_Q_GIVEN
-RSA,reason,130,OUTPUT_BUFFER_TOO_SMALL
-RSA,reason,131,PADDING_CHECK_FAILED
-RSA,reason,132,PKCS_DECODING_ERROR
-RSA,reason,133,SLEN_CHECK_FAILED
-RSA,reason,134,SLEN_RECOVERY_FAILED
-RSA,reason,135,TOO_LONG
-RSA,reason,136,TOO_MANY_ITERATIONS
-RSA,reason,137,UNKNOWN_ALGORITHM_TYPE
-RSA,reason,138,UNKNOWN_PADDING_TYPE
-RSA,reason,139,VALUE_MISSING
-RSA,reason,140,WRONG_SIGNATURE_LENGTH
+RSA,143,BAD_ENCODING
+RSA,100,BAD_E_VALUE
+RSA,101,BAD_FIXED_HEADER_DECRYPT
+RSA,102,BAD_PAD_BYTE_COUNT
+RSA,103,BAD_RSA_PARAMETERS
+RSA,104,BAD_SIGNATURE
+RSA,145,BAD_VERSION
+RSA,105,BLOCK_TYPE_IS_NOT_01
+RSA,106,BN_NOT_INITIALIZED
+RSA,142,CANNOT_RECOVER_MULTI_PRIME_KEY
+RSA,107,CRT_PARAMS_ALREADY_GIVEN
+RSA,108,CRT_VALUES_INCORRECT
+RSA,109,DATA_LEN_NOT_EQUAL_TO_MOD_LEN
+RSA,110,DATA_TOO_LARGE
+RSA,111,DATA_TOO_LARGE_FOR_KEY_SIZE
+RSA,112,DATA_TOO_LARGE_FOR_MODULUS
+RSA,113,DATA_TOO_SMALL
+RSA,114,DATA_TOO_SMALL_FOR_KEY_SIZE
+RSA,115,DIGEST_TOO_BIG_FOR_RSA_KEY
+RSA,116,D_E_NOT_CONGRUENT_TO_1
+RSA,117,EMPTY_PUBLIC_KEY
+RSA,144,ENCODE_ERROR
+RSA,118,FIRST_OCTET_INVALID
+RSA,119,INCONSISTENT_SET_OF_CRT_VALUES
+RSA,120,INTERNAL_ERROR
+RSA,121,INVALID_MESSAGE_LENGTH
+RSA,122,KEY_SIZE_TOO_SMALL
+RSA,123,LAST_OCTET_INVALID
+RSA,124,MODULUS_TOO_LARGE
+RSA,141,MUST_HAVE_AT_LEAST_TWO_PRIMES
+RSA,125,NO_PUBLIC_EXPONENT
+RSA,126,NULL_BEFORE_BLOCK_MISSING
+RSA,127,N_NOT_EQUAL_P_Q
+RSA,128,OAEP_DECODING_ERROR
+RSA,129,ONLY_ONE_OF_P_Q_GIVEN
+RSA,130,OUTPUT_BUFFER_TOO_SMALL
+RSA,131,PADDING_CHECK_FAILED
+RSA,132,PKCS_DECODING_ERROR
+RSA,133,SLEN_CHECK_FAILED
+RSA,134,SLEN_RECOVERY_FAILED
+RSA,135,TOO_LONG
+RSA,136,TOO_MANY_ITERATIONS
+RSA,137,UNKNOWN_ALGORITHM_TYPE
+RSA,138,UNKNOWN_PADDING_TYPE
+RSA,139,VALUE_MISSING
+RSA,140,WRONG_SIGNATURE_LENGTH
diff --git a/src/crypto/err/ssl.errordata b/src/crypto/err/ssl.errordata
index 9464c3d..0b30b13 100644
--- a/src/crypto/err/ssl.errordata
+++ b/src/crypto/err/ssl.errordata
@@ -1,387 +1,217 @@
-SSL,function,276,SSL_AEAD_CTX_new
-SSL,function,277,SSL_AEAD_CTX_open
-SSL,function,278,SSL_AEAD_CTX_seal
-SSL,function,100,SSL_CTX_check_private_key
-SSL,function,101,SSL_CTX_new
-SSL,function,272,SSL_CTX_set1_tls_channel_id
-SSL,function,102,SSL_CTX_set_cipher_list
-SSL,function,103,SSL_CTX_set_cipher_list_tls11
-SSL,function,104,SSL_CTX_set_session_id_context
-SSL,function,268,SSL_CTX_set_tmp_dh
-SSL,function,269,SSL_CTX_set_tmp_ecdh
-SSL,function,105,SSL_CTX_use_PrivateKey
-SSL,function,106,SSL_CTX_use_PrivateKey_ASN1
-SSL,function,107,SSL_CTX_use_PrivateKey_file
-SSL,function,108,SSL_CTX_use_RSAPrivateKey
-SSL,function,109,SSL_CTX_use_RSAPrivateKey_ASN1
-SSL,function,110,SSL_CTX_use_RSAPrivateKey_file
-SSL,function,111,SSL_CTX_use_certificate
-SSL,function,112,SSL_CTX_use_certificate_ASN1
-SSL,function,113,SSL_CTX_use_certificate_chain_file
-SSL,function,114,SSL_CTX_use_certificate_file
-SSL,function,115,SSL_CTX_use_psk_identity_hint
-SSL,function,280,SSL_SESSION_from_bytes
-SSL,function,116,SSL_SESSION_new
-SSL,function,281,SSL_SESSION_parse
-SSL,function,150,SSL_SESSION_parse_octet_string
-SSL,function,151,SSL_SESSION_parse_string
-SSL,function,117,SSL_SESSION_print_fp
-SSL,function,118,SSL_SESSION_set1_id_context
-SSL,function,119,SSL_SESSION_to_bytes_full
-SSL,function,120,SSL_accept
-SSL,function,121,SSL_add_dir_cert_subjects_to_stack
-SSL,function,122,SSL_add_file_cert_subjects_to_stack
-SSL,function,123,SSL_check_private_key
-SSL,function,124,SSL_clear
-SSL,function,125,SSL_connect
-SSL,function,126,SSL_do_handshake
-SSL,function,127,SSL_load_client_CA_file
-SSL,function,128,SSL_new
-SSL,function,129,SSL_peek
-SSL,function,130,SSL_read
-SSL,function,131,SSL_renegotiate
-SSL,function,273,SSL_set1_tls_channel_id
-SSL,function,132,SSL_set_cipher_list
-SSL,function,133,SSL_set_fd
-SSL,function,134,SSL_set_rfd
-SSL,function,135,SSL_set_session_id_context
-SSL,function,274,SSL_set_tlsext_host_name
-SSL,function,270,SSL_set_tmp_dh
-SSL,function,271,SSL_set_tmp_ecdh
-SSL,function,136,SSL_set_wfd
-SSL,function,137,SSL_shutdown
-SSL,function,138,SSL_use_PrivateKey
-SSL,function,139,SSL_use_PrivateKey_ASN1
-SSL,function,140,SSL_use_PrivateKey_file
-SSL,function,141,SSL_use_RSAPrivateKey
-SSL,function,142,SSL_use_RSAPrivateKey_ASN1
-SSL,function,143,SSL_use_RSAPrivateKey_file
-SSL,function,144,SSL_use_certificate
-SSL,function,145,SSL_use_certificate_ASN1
-SSL,function,146,SSL_use_certificate_file
-SSL,function,147,SSL_use_psk_identity_hint
-SSL,function,148,SSL_write
-SSL,function,149,d2i_SSL_SESSION
-SSL,function,152,do_ssl3_write
-SSL,function,153,dtls1_accept
-SSL,function,154,dtls1_buffer_record
-SSL,function,155,dtls1_check_timeout_num
-SSL,function,156,dtls1_connect
-SSL,function,157,dtls1_do_write
-SSL,function,263,dtls1_get_buffered_message
-SSL,function,158,dtls1_get_hello_verify
-SSL,function,159,dtls1_get_message
-SSL,function,160,dtls1_get_message_fragment
-SSL,function,265,dtls1_hm_fragment_new
-SSL,function,161,dtls1_preprocess_fragment
-SSL,function,264,dtls1_process_fragment
-SSL,function,162,dtls1_process_record
-SSL,function,163,dtls1_read_bytes
-SSL,function,279,dtls1_seal_record
-SSL,function,164,dtls1_send_hello_verify_request
-SSL,function,165,dtls1_write_app_data
-SSL,function,166,i2d_SSL_SESSION
-SSL,function,167,ssl3_accept
-SSL,function,169,ssl3_cert_verify_hash
-SSL,function,170,ssl3_check_cert_and_algorithm
-SSL,function,282,ssl3_check_certificate_for_cipher
-SSL,function,171,ssl3_connect
-SSL,function,172,ssl3_ctrl
-SSL,function,173,ssl3_ctx_ctrl
-SSL,function,174,ssl3_digest_cached_records
-SSL,function,175,ssl3_do_change_cipher_spec
-SSL,function,176,ssl3_expect_change_cipher_spec
-SSL,function,177,ssl3_get_cert_status
-SSL,function,178,ssl3_get_cert_verify
-SSL,function,179,ssl3_get_certificate_request
-SSL,function,180,ssl3_get_channel_id
-SSL,function,181,ssl3_get_client_certificate
-SSL,function,182,ssl3_get_client_hello
-SSL,function,183,ssl3_get_client_key_exchange
-SSL,function,184,ssl3_get_finished
-SSL,function,185,ssl3_get_initial_bytes
-SSL,function,186,ssl3_get_message
-SSL,function,187,ssl3_get_new_session_ticket
-SSL,function,188,ssl3_get_next_proto
-SSL,function,189,ssl3_get_record
-SSL,function,190,ssl3_get_server_certificate
-SSL,function,191,ssl3_get_server_done
-SSL,function,192,ssl3_get_server_hello
-SSL,function,193,ssl3_get_server_key_exchange
-SSL,function,194,ssl3_get_v2_client_hello
-SSL,function,195,ssl3_handshake_mac
-SSL,function,275,ssl3_output_cert_chain
-SSL,function,196,ssl3_prf
-SSL,function,197,ssl3_read_bytes
-SSL,function,198,ssl3_read_n
-SSL,function,267,ssl3_record_sequence_update
-SSL,function,266,ssl3_seal_record
-SSL,function,199,ssl3_send_cert_verify
-SSL,function,200,ssl3_send_certificate_request
-SSL,function,201,ssl3_send_channel_id
-SSL,function,202,ssl3_send_client_certificate
-SSL,function,203,ssl3_send_client_hello
-SSL,function,204,ssl3_send_client_key_exchange
-SSL,function,205,ssl3_send_server_certificate
-SSL,function,206,ssl3_send_server_hello
-SSL,function,207,ssl3_send_server_key_exchange
-SSL,function,208,ssl3_setup_read_buffer
-SSL,function,209,ssl3_setup_write_buffer
-SSL,function,210,ssl3_write_bytes
-SSL,function,211,ssl3_write_pending
-SSL,function,212,ssl_add_cert_chain
-SSL,function,213,ssl_add_cert_to_buf
-SSL,function,214,ssl_add_clienthello_renegotiate_ext
-SSL,function,215,ssl_add_clienthello_tlsext
-SSL,function,216,ssl_add_clienthello_use_srtp_ext
-SSL,function,217,ssl_add_serverhello_renegotiate_ext
-SSL,function,218,ssl_add_serverhello_tlsext
-SSL,function,219,ssl_add_serverhello_use_srtp_ext
-SSL,function,220,ssl_build_cert_chain
-SSL,function,221,ssl_bytes_to_cipher_list
-SSL,function,222,ssl_cert_dup
-SSL,function,223,ssl_cert_inst
-SSL,function,224,ssl_cert_new
-SSL,function,225,ssl_check_serverhello_tlsext
-SSL,function,226,ssl_check_srvr_ecc_cert_and_alg
-SSL,function,227,ssl_cipher_process_rulestr
-SSL,function,228,ssl_cipher_strength_sort
-SSL,function,229,ssl_create_cipher_list
-SSL,function,230,ssl_ctx_log_master_secret
-SSL,function,231,ssl_ctx_log_rsa_client_key_exchange
-SSL,function,232,ssl_ctx_make_profiles
-SSL,function,233,ssl_get_new_session
-SSL,function,234,ssl_get_prev_session
-SSL,function,235,ssl_get_server_cert_index
-SSL,function,236,ssl_get_sign_pkey
-SSL,function,237,ssl_init_wbio_buffer
-SSL,function,238,ssl_parse_clienthello_renegotiate_ext
-SSL,function,239,ssl_parse_clienthello_tlsext
-SSL,function,240,ssl_parse_clienthello_use_srtp_ext
-SSL,function,241,ssl_parse_serverhello_renegotiate_ext
-SSL,function,242,ssl_parse_serverhello_tlsext
-SSL,function,243,ssl_parse_serverhello_use_srtp_ext
-SSL,function,244,ssl_scan_clienthello_tlsext
-SSL,function,245,ssl_scan_serverhello_tlsext
-SSL,function,246,ssl_sess_cert_new
-SSL,function,247,ssl_set_cert
-SSL,function,248,ssl_set_pkey
-SSL,function,252,ssl_verify_cert_chain
-SSL,function,253,tls12_check_peer_sigalg
-SSL,function,254,tls1_aead_ctx_init
-SSL,function,255,tls1_cert_verify_mac
-SSL,function,256,tls1_change_cipher_state
-SSL,function,257,tls1_change_cipher_state_aead
-SSL,function,258,tls1_check_duplicate_extensions
-SSL,function,259,tls1_enc
-SSL,function,260,tls1_export_keying_material
-SSL,function,261,tls1_prf
-SSL,function,262,tls1_setup_key_block
-SSL,reason,100,APP_DATA_IN_HANDSHAKE
-SSL,reason,101,ATTEMPT_TO_REUSE_SESSION_IN_DIFFERENT_CONTEXT
-SSL,reason,102,BAD_ALERT
-SSL,reason,103,BAD_CHANGE_CIPHER_SPEC
-SSL,reason,104,BAD_DATA_RETURNED_BY_CALLBACK
-SSL,reason,105,BAD_DH_P_LENGTH
-SSL,reason,106,BAD_DIGEST_LENGTH
-SSL,reason,107,BAD_ECC_CERT
-SSL,reason,108,BAD_ECPOINT
-SSL,reason,109,BAD_HANDSHAKE_LENGTH
-SSL,reason,110,BAD_HANDSHAKE_RECORD
-SSL,reason,111,BAD_HELLO_REQUEST
-SSL,reason,112,BAD_LENGTH
-SSL,reason,113,BAD_PACKET_LENGTH
-SSL,reason,114,BAD_RSA_ENCRYPT
-SSL,reason,115,BAD_SIGNATURE
-SSL,reason,116,BAD_SRTP_MKI_VALUE
-SSL,reason,117,BAD_SRTP_PROTECTION_PROFILE_LIST
-SSL,reason,118,BAD_SSL_FILETYPE
-SSL,reason,119,BAD_WRITE_RETRY
-SSL,reason,120,BIO_NOT_SET
-SSL,reason,121,BN_LIB
-SSL,reason,272,BUFFER_TOO_SMALL
-SSL,reason,122,CANNOT_SERIALIZE_PUBLIC_KEY
-SSL,reason,123,CA_DN_LENGTH_MISMATCH
-SSL,reason,124,CA_DN_TOO_LONG
-SSL,reason,125,CCS_RECEIVED_EARLY
-SSL,reason,126,CERTIFICATE_VERIFY_FAILED
-SSL,reason,127,CERT_CB_ERROR
-SSL,reason,128,CERT_LENGTH_MISMATCH
-SSL,reason,129,CHANNEL_ID_NOT_P256
-SSL,reason,130,CHANNEL_ID_SIGNATURE_INVALID
-SSL,reason,131,CIPHER_CODE_WRONG_LENGTH
-SSL,reason,132,CIPHER_OR_HASH_UNAVAILABLE
-SSL,reason,133,CLIENTHELLO_PARSE_FAILED
-SSL,reason,134,CLIENTHELLO_TLSEXT
-SSL,reason,135,CONNECTION_REJECTED
-SSL,reason,136,CONNECTION_TYPE_NOT_SET
-SSL,reason,137,COOKIE_MISMATCH
-SSL,reason,138,D2I_ECDSA_SIG
-SSL,reason,139,DATA_BETWEEN_CCS_AND_FINISHED
-SSL,reason,140,DATA_LENGTH_TOO_LONG
-SSL,reason,141,DECODE_ERROR
-SSL,reason,142,DECRYPTION_FAILED
-SSL,reason,143,DECRYPTION_FAILED_OR_BAD_RECORD_MAC
-SSL,reason,144,DH_PUBLIC_VALUE_LENGTH_IS_WRONG
-SSL,reason,145,DIGEST_CHECK_FAILED
-SSL,reason,146,DTLS_MESSAGE_TOO_BIG
-SSL,reason,147,ECC_CERT_NOT_FOR_SIGNING
-SSL,reason,148,EMPTY_SRTP_PROTECTION_PROFILE_LIST
-SSL,reason,276,EMS_STATE_INCONSISTENT
-SSL,reason,149,ENCRYPTED_LENGTH_TOO_LONG
-SSL,reason,150,ERROR_IN_RECEIVED_CIPHER_LIST
-SSL,reason,151,EVP_DIGESTSIGNFINAL_FAILED
-SSL,reason,152,EVP_DIGESTSIGNINIT_FAILED
-SSL,reason,153,EXCESSIVE_MESSAGE_SIZE
-SSL,reason,154,EXTRA_DATA_IN_MESSAGE
-SSL,reason,271,FRAGMENT_MISMATCH
-SSL,reason,155,GOT_A_FIN_BEFORE_A_CCS
-SSL,reason,156,GOT_CHANNEL_ID_BEFORE_A_CCS
-SSL,reason,157,GOT_NEXT_PROTO_BEFORE_A_CCS
-SSL,reason,158,GOT_NEXT_PROTO_WITHOUT_EXTENSION
-SSL,reason,159,HANDSHAKE_FAILURE_ON_CLIENT_HELLO
-SSL,reason,160,HANDSHAKE_RECORD_BEFORE_CCS
-SSL,reason,161,HTTPS_PROXY_REQUEST
-SSL,reason,162,HTTP_REQUEST
-SSL,reason,163,INAPPROPRIATE_FALLBACK
-SSL,reason,164,INVALID_COMMAND
-SSL,reason,165,INVALID_MESSAGE
-SSL,reason,166,INVALID_SSL_SESSION
-SSL,reason,167,INVALID_TICKET_KEYS_LENGTH
-SSL,reason,168,LENGTH_MISMATCH
-SSL,reason,169,LIBRARY_HAS_NO_CIPHERS
-SSL,reason,170,MISSING_DH_KEY
-SSL,reason,171,MISSING_ECDSA_SIGNING_CERT
-SSL,reason,172,MISSING_RSA_CERTIFICATE
-SSL,reason,173,MISSING_RSA_ENCRYPTING_CERT
-SSL,reason,174,MISSING_RSA_SIGNING_CERT
-SSL,reason,175,MISSING_TMP_DH_KEY
-SSL,reason,176,MISSING_TMP_ECDH_KEY
-SSL,reason,177,MIXED_SPECIAL_OPERATOR_WITH_GROUPS
-SSL,reason,178,MTU_TOO_SMALL
-SSL,reason,179,NESTED_GROUP
-SSL,reason,180,NO_CERTIFICATES_RETURNED
-SSL,reason,181,NO_CERTIFICATE_ASSIGNED
-SSL,reason,182,NO_CERTIFICATE_SET
-SSL,reason,183,NO_CIPHERS_AVAILABLE
-SSL,reason,184,NO_CIPHERS_PASSED
-SSL,reason,185,NO_CIPHERS_SPECIFIED
-SSL,reason,186,NO_CIPHER_MATCH
-SSL,reason,187,NO_COMPRESSION_SPECIFIED
-SSL,reason,188,NO_METHOD_SPECIFIED
-SSL,reason,189,NO_P256_SUPPORT
-SSL,reason,190,NO_PRIVATE_KEY_ASSIGNED
-SSL,reason,191,NO_RENEGOTIATION
-SSL,reason,192,NO_REQUIRED_DIGEST
-SSL,reason,193,NO_SHARED_CIPHER
-SSL,reason,194,NO_SHARED_SIGATURE_ALGORITHMS
-SSL,reason,195,NO_SRTP_PROFILES
-SSL,reason,196,NULL_SSL_CTX
-SSL,reason,197,NULL_SSL_METHOD_PASSED
-SSL,reason,198,OLD_SESSION_CIPHER_NOT_RETURNED
-SSL,reason,273,OLD_SESSION_VERSION_NOT_RETURNED
-SSL,reason,274,OUTPUT_ALIASES_INPUT
-SSL,reason,199,PACKET_LENGTH_TOO_LONG
-SSL,reason,200,PARSE_TLSEXT
-SSL,reason,201,PATH_TOO_LONG
-SSL,reason,202,PEER_DID_NOT_RETURN_A_CERTIFICATE
-SSL,reason,203,PEER_ERROR_UNSUPPORTED_CERTIFICATE_TYPE
-SSL,reason,204,PROTOCOL_IS_SHUTDOWN
-SSL,reason,205,PSK_IDENTITY_NOT_FOUND
-SSL,reason,206,PSK_NO_CLIENT_CB
-SSL,reason,207,PSK_NO_SERVER_CB
-SSL,reason,208,READ_BIO_NOT_SET
-SSL,reason,209,READ_TIMEOUT_EXPIRED
-SSL,reason,210,RECORD_LENGTH_MISMATCH
-SSL,reason,211,RECORD_TOO_LARGE
-SSL,reason,212,RENEGOTIATE_EXT_TOO_LONG
-SSL,reason,213,RENEGOTIATION_ENCODING_ERR
-SSL,reason,214,RENEGOTIATION_MISMATCH
-SSL,reason,215,REQUIRED_CIPHER_MISSING
-SSL,reason,275,RESUMED_EMS_SESSION_WITHOUT_EMS_EXTENSION
-SSL,reason,277,RESUMED_NON_EMS_SESSION_WITH_EMS_EXTENSION
-SSL,reason,216,SCSV_RECEIVED_WHEN_RENEGOTIATING
-SSL,reason,217,SERVERHELLO_TLSEXT
-SSL,reason,218,SESSION_ID_CONTEXT_UNINITIALIZED
-SSL,reason,219,SESSION_MAY_NOT_BE_CREATED
-SSL,reason,220,SIGNATURE_ALGORITHMS_ERROR
-SSL,reason,221,SRTP_COULD_NOT_ALLOCATE_PROFILES
-SSL,reason,222,SRTP_PROTECTION_PROFILE_LIST_TOO_LONG
-SSL,reason,223,SRTP_UNKNOWN_PROTECTION_PROFILE
-SSL,reason,224,SSL3_EXT_INVALID_SERVERNAME
-SSL,reason,225,SSL3_EXT_INVALID_SERVERNAME_TYPE
-SSL,reason,1042,SSLV3_ALERT_BAD_CERTIFICATE
-SSL,reason,1020,SSLV3_ALERT_BAD_RECORD_MAC
-SSL,reason,1045,SSLV3_ALERT_CERTIFICATE_EXPIRED
-SSL,reason,1044,SSLV3_ALERT_CERTIFICATE_REVOKED
-SSL,reason,1046,SSLV3_ALERT_CERTIFICATE_UNKNOWN
-SSL,reason,1000,SSLV3_ALERT_CLOSE_NOTIFY
-SSL,reason,1030,SSLV3_ALERT_DECOMPRESSION_FAILURE
-SSL,reason,1040,SSLV3_ALERT_HANDSHAKE_FAILURE
-SSL,reason,1047,SSLV3_ALERT_ILLEGAL_PARAMETER
-SSL,reason,1041,SSLV3_ALERT_NO_CERTIFICATE
-SSL,reason,1010,SSLV3_ALERT_UNEXPECTED_MESSAGE
-SSL,reason,1043,SSLV3_ALERT_UNSUPPORTED_CERTIFICATE
-SSL,reason,226,SSL_CTX_HAS_NO_DEFAULT_SSL_VERSION
-SSL,reason,227,SSL_HANDSHAKE_FAILURE
-SSL,reason,228,SSL_SESSION_ID_CALLBACK_FAILED
-SSL,reason,229,SSL_SESSION_ID_CONFLICT
-SSL,reason,230,SSL_SESSION_ID_CONTEXT_TOO_LONG
-SSL,reason,231,SSL_SESSION_ID_HAS_BAD_LENGTH
-SSL,reason,1049,TLSV1_ALERT_ACCESS_DENIED
-SSL,reason,1050,TLSV1_ALERT_DECODE_ERROR
-SSL,reason,1021,TLSV1_ALERT_DECRYPTION_FAILED
-SSL,reason,1051,TLSV1_ALERT_DECRYPT_ERROR
-SSL,reason,1060,TLSV1_ALERT_EXPORT_RESTRICTION
-SSL,reason,1086,TLSV1_ALERT_INAPPROPRIATE_FALLBACK
-SSL,reason,1071,TLSV1_ALERT_INSUFFICIENT_SECURITY
-SSL,reason,1080,TLSV1_ALERT_INTERNAL_ERROR
-SSL,reason,1100,TLSV1_ALERT_NO_RENEGOTIATION
-SSL,reason,1070,TLSV1_ALERT_PROTOCOL_VERSION
-SSL,reason,1022,TLSV1_ALERT_RECORD_OVERFLOW
-SSL,reason,1048,TLSV1_ALERT_UNKNOWN_CA
-SSL,reason,1090,TLSV1_ALERT_USER_CANCELLED
-SSL,reason,1114,TLSV1_BAD_CERTIFICATE_HASH_VALUE
-SSL,reason,1113,TLSV1_BAD_CERTIFICATE_STATUS_RESPONSE
-SSL,reason,1111,TLSV1_CERTIFICATE_UNOBTAINABLE
-SSL,reason,1112,TLSV1_UNRECOGNIZED_NAME
-SSL,reason,1110,TLSV1_UNSUPPORTED_EXTENSION
-SSL,reason,232,TLS_CLIENT_CERT_REQ_WITH_ANON_CIPHER
-SSL,reason,233,TLS_ILLEGAL_EXPORTER_LABEL
-SSL,reason,234,TLS_INVALID_ECPOINTFORMAT_LIST
-SSL,reason,235,TLS_PEER_DID_NOT_RESPOND_WITH_CERTIFICATE_LIST
-SSL,reason,236,TLS_RSA_ENCRYPTED_VALUE_LENGTH_IS_WRONG
-SSL,reason,237,TOO_MANY_EMPTY_FRAGMENTS
-SSL,reason,238,UNABLE_TO_FIND_ECDH_PARAMETERS
-SSL,reason,239,UNABLE_TO_FIND_PUBLIC_KEY_PARAMETERS
-SSL,reason,240,UNEXPECTED_GROUP_CLOSE
-SSL,reason,241,UNEXPECTED_MESSAGE
-SSL,reason,242,UNEXPECTED_OPERATOR_IN_GROUP
-SSL,reason,243,UNEXPECTED_RECORD
-SSL,reason,244,UNINITIALIZED
-SSL,reason,245,UNKNOWN_ALERT_TYPE
-SSL,reason,246,UNKNOWN_CERTIFICATE_TYPE
-SSL,reason,247,UNKNOWN_CIPHER_RETURNED
-SSL,reason,248,UNKNOWN_CIPHER_TYPE
-SSL,reason,249,UNKNOWN_DIGEST
-SSL,reason,250,UNKNOWN_KEY_EXCHANGE_TYPE
-SSL,reason,251,UNKNOWN_PROTOCOL
-SSL,reason,252,UNKNOWN_SSL_VERSION
-SSL,reason,253,UNKNOWN_STATE
-SSL,reason,254,UNPROCESSED_HANDSHAKE_DATA
-SSL,reason,255,UNSAFE_LEGACY_RENEGOTIATION_DISABLED
-SSL,reason,256,UNSUPPORTED_CIPHER
-SSL,reason,257,UNSUPPORTED_COMPRESSION_ALGORITHM
-SSL,reason,258,UNSUPPORTED_ELLIPTIC_CURVE
-SSL,reason,259,UNSUPPORTED_PROTOCOL
-SSL,reason,260,UNSUPPORTED_SSL_VERSION
-SSL,reason,261,USE_SRTP_NOT_NEGOTIATED
-SSL,reason,262,WRONG_CERTIFICATE_TYPE
-SSL,reason,263,WRONG_CIPHER_RETURNED
-SSL,reason,264,WRONG_CURVE
-SSL,reason,265,WRONG_MESSAGE_TYPE
-SSL,reason,266,WRONG_SIGNATURE_TYPE
-SSL,reason,267,WRONG_SSL_VERSION
-SSL,reason,268,WRONG_VERSION_NUMBER
-SSL,reason,269,X509_LIB
-SSL,reason,270,X509_VERIFICATION_SETUP_PROBLEMS
+SSL,100,APP_DATA_IN_HANDSHAKE
+SSL,101,ATTEMPT_TO_REUSE_SESSION_IN_DIFFERENT_CONTEXT
+SSL,102,BAD_ALERT
+SSL,103,BAD_CHANGE_CIPHER_SPEC
+SSL,104,BAD_DATA_RETURNED_BY_CALLBACK
+SSL,105,BAD_DH_P_LENGTH
+SSL,106,BAD_DIGEST_LENGTH
+SSL,107,BAD_ECC_CERT
+SSL,108,BAD_ECPOINT
+SSL,109,BAD_HANDSHAKE_LENGTH
+SSL,110,BAD_HANDSHAKE_RECORD
+SSL,111,BAD_HELLO_REQUEST
+SSL,112,BAD_LENGTH
+SSL,113,BAD_PACKET_LENGTH
+SSL,114,BAD_RSA_ENCRYPT
+SSL,115,BAD_SIGNATURE
+SSL,116,BAD_SRTP_MKI_VALUE
+SSL,117,BAD_SRTP_PROTECTION_PROFILE_LIST
+SSL,118,BAD_SSL_FILETYPE
+SSL,119,BAD_WRITE_RETRY
+SSL,120,BIO_NOT_SET
+SSL,121,BN_LIB
+SSL,272,BUFFER_TOO_SMALL
+SSL,122,CANNOT_SERIALIZE_PUBLIC_KEY
+SSL,123,CA_DN_LENGTH_MISMATCH
+SSL,124,CA_DN_TOO_LONG
+SSL,125,CCS_RECEIVED_EARLY
+SSL,126,CERTIFICATE_VERIFY_FAILED
+SSL,127,CERT_CB_ERROR
+SSL,128,CERT_LENGTH_MISMATCH
+SSL,129,CHANNEL_ID_NOT_P256
+SSL,130,CHANNEL_ID_SIGNATURE_INVALID
+SSL,131,CIPHER_CODE_WRONG_LENGTH
+SSL,132,CIPHER_OR_HASH_UNAVAILABLE
+SSL,133,CLIENTHELLO_PARSE_FAILED
+SSL,134,CLIENTHELLO_TLSEXT
+SSL,135,CONNECTION_REJECTED
+SSL,136,CONNECTION_TYPE_NOT_SET
+SSL,137,COOKIE_MISMATCH
+SSL,284,CUSTOM_EXTENSION_CONTENTS_TOO_LARGE
+SSL,285,CUSTOM_EXTENSION_ERROR
+SSL,138,D2I_ECDSA_SIG
+SSL,139,DATA_BETWEEN_CCS_AND_FINISHED
+SSL,140,DATA_LENGTH_TOO_LONG
+SSL,141,DECODE_ERROR
+SSL,142,DECRYPTION_FAILED
+SSL,143,DECRYPTION_FAILED_OR_BAD_RECORD_MAC
+SSL,144,DH_PUBLIC_VALUE_LENGTH_IS_WRONG
+SSL,145,DIGEST_CHECK_FAILED
+SSL,146,DTLS_MESSAGE_TOO_BIG
+SSL,147,ECC_CERT_NOT_FOR_SIGNING
+SSL,148,EMPTY_SRTP_PROTECTION_PROFILE_LIST
+SSL,276,EMS_STATE_INCONSISTENT
+SSL,149,ENCRYPTED_LENGTH_TOO_LONG
+SSL,281,ERROR_ADDING_EXTENSION
+SSL,150,ERROR_IN_RECEIVED_CIPHER_LIST
+SSL,282,ERROR_PARSING_EXTENSION
+SSL,151,EVP_DIGESTSIGNFINAL_FAILED
+SSL,152,EVP_DIGESTSIGNINIT_FAILED
+SSL,153,EXCESSIVE_MESSAGE_SIZE
+SSL,154,EXTRA_DATA_IN_MESSAGE
+SSL,271,FRAGMENT_MISMATCH
+SSL,155,GOT_A_FIN_BEFORE_A_CCS
+SSL,156,GOT_CHANNEL_ID_BEFORE_A_CCS
+SSL,157,GOT_NEXT_PROTO_BEFORE_A_CCS
+SSL,158,GOT_NEXT_PROTO_WITHOUT_EXTENSION
+SSL,159,HANDSHAKE_FAILURE_ON_CLIENT_HELLO
+SSL,160,HANDSHAKE_RECORD_BEFORE_CCS
+SSL,161,HTTPS_PROXY_REQUEST
+SSL,162,HTTP_REQUEST
+SSL,163,INAPPROPRIATE_FALLBACK
+SSL,164,INVALID_COMMAND
+SSL,165,INVALID_MESSAGE
+SSL,166,INVALID_SSL_SESSION
+SSL,167,INVALID_TICKET_KEYS_LENGTH
+SSL,168,LENGTH_MISMATCH
+SSL,169,LIBRARY_HAS_NO_CIPHERS
+SSL,170,MISSING_DH_KEY
+SSL,171,MISSING_ECDSA_SIGNING_CERT
+SSL,283,MISSING_EXTENSION
+SSL,172,MISSING_RSA_CERTIFICATE
+SSL,173,MISSING_RSA_ENCRYPTING_CERT
+SSL,174,MISSING_RSA_SIGNING_CERT
+SSL,175,MISSING_TMP_DH_KEY
+SSL,176,MISSING_TMP_ECDH_KEY
+SSL,177,MIXED_SPECIAL_OPERATOR_WITH_GROUPS
+SSL,178,MTU_TOO_SMALL
+SSL,286,NEGOTIATED_BOTH_NPN_AND_ALPN
+SSL,179,NESTED_GROUP
+SSL,180,NO_CERTIFICATES_RETURNED
+SSL,181,NO_CERTIFICATE_ASSIGNED
+SSL,182,NO_CERTIFICATE_SET
+SSL,183,NO_CIPHERS_AVAILABLE
+SSL,184,NO_CIPHERS_PASSED
+SSL,185,NO_CIPHERS_SPECIFIED
+SSL,186,NO_CIPHER_MATCH
+SSL,187,NO_COMPRESSION_SPECIFIED
+SSL,188,NO_METHOD_SPECIFIED
+SSL,189,NO_P256_SUPPORT
+SSL,190,NO_PRIVATE_KEY_ASSIGNED
+SSL,191,NO_RENEGOTIATION
+SSL,192,NO_REQUIRED_DIGEST
+SSL,193,NO_SHARED_CIPHER
+SSL,194,NO_SHARED_SIGATURE_ALGORITHMS
+SSL,195,NO_SRTP_PROFILES
+SSL,196,NULL_SSL_CTX
+SSL,197,NULL_SSL_METHOD_PASSED
+SSL,198,OLD_SESSION_CIPHER_NOT_RETURNED
+SSL,273,OLD_SESSION_VERSION_NOT_RETURNED
+SSL,274,OUTPUT_ALIASES_INPUT
+SSL,199,PACKET_LENGTH_TOO_LONG
+SSL,200,PARSE_TLSEXT
+SSL,201,PATH_TOO_LONG
+SSL,202,PEER_DID_NOT_RETURN_A_CERTIFICATE
+SSL,203,PEER_ERROR_UNSUPPORTED_CERTIFICATE_TYPE
+SSL,204,PROTOCOL_IS_SHUTDOWN
+SSL,205,PSK_IDENTITY_NOT_FOUND
+SSL,206,PSK_NO_CLIENT_CB
+SSL,207,PSK_NO_SERVER_CB
+SSL,208,READ_BIO_NOT_SET
+SSL,209,READ_TIMEOUT_EXPIRED
+SSL,210,RECORD_LENGTH_MISMATCH
+SSL,211,RECORD_TOO_LARGE
+SSL,212,RENEGOTIATE_EXT_TOO_LONG
+SSL,213,RENEGOTIATION_ENCODING_ERR
+SSL,214,RENEGOTIATION_MISMATCH
+SSL,215,REQUIRED_CIPHER_MISSING
+SSL,275,RESUMED_EMS_SESSION_WITHOUT_EMS_EXTENSION
+SSL,277,RESUMED_NON_EMS_SESSION_WITH_EMS_EXTENSION
+SSL,216,SCSV_RECEIVED_WHEN_RENEGOTIATING
+SSL,217,SERVERHELLO_TLSEXT
+SSL,218,SESSION_ID_CONTEXT_UNINITIALIZED
+SSL,219,SESSION_MAY_NOT_BE_CREATED
+SSL,220,SIGNATURE_ALGORITHMS_ERROR
+SSL,280,SIGNATURE_ALGORITHMS_EXTENSION_SENT_BY_SERVER
+SSL,221,SRTP_COULD_NOT_ALLOCATE_PROFILES
+SSL,222,SRTP_PROTECTION_PROFILE_LIST_TOO_LONG
+SSL,223,SRTP_UNKNOWN_PROTECTION_PROFILE
+SSL,224,SSL3_EXT_INVALID_SERVERNAME
+SSL,225,SSL3_EXT_INVALID_SERVERNAME_TYPE
+SSL,1042,SSLV3_ALERT_BAD_CERTIFICATE
+SSL,1020,SSLV3_ALERT_BAD_RECORD_MAC
+SSL,1045,SSLV3_ALERT_CERTIFICATE_EXPIRED
+SSL,1044,SSLV3_ALERT_CERTIFICATE_REVOKED
+SSL,1046,SSLV3_ALERT_CERTIFICATE_UNKNOWN
+SSL,1000,SSLV3_ALERT_CLOSE_NOTIFY
+SSL,1030,SSLV3_ALERT_DECOMPRESSION_FAILURE
+SSL,1040,SSLV3_ALERT_HANDSHAKE_FAILURE
+SSL,1047,SSLV3_ALERT_ILLEGAL_PARAMETER
+SSL,1041,SSLV3_ALERT_NO_CERTIFICATE
+SSL,1010,SSLV3_ALERT_UNEXPECTED_MESSAGE
+SSL,1043,SSLV3_ALERT_UNSUPPORTED_CERTIFICATE
+SSL,226,SSL_CTX_HAS_NO_DEFAULT_SSL_VERSION
+SSL,227,SSL_HANDSHAKE_FAILURE
+SSL,228,SSL_SESSION_ID_CALLBACK_FAILED
+SSL,229,SSL_SESSION_ID_CONFLICT
+SSL,230,SSL_SESSION_ID_CONTEXT_TOO_LONG
+SSL,231,SSL_SESSION_ID_HAS_BAD_LENGTH
+SSL,1049,TLSV1_ALERT_ACCESS_DENIED
+SSL,1050,TLSV1_ALERT_DECODE_ERROR
+SSL,1021,TLSV1_ALERT_DECRYPTION_FAILED
+SSL,1051,TLSV1_ALERT_DECRYPT_ERROR
+SSL,1060,TLSV1_ALERT_EXPORT_RESTRICTION
+SSL,1086,TLSV1_ALERT_INAPPROPRIATE_FALLBACK
+SSL,1071,TLSV1_ALERT_INSUFFICIENT_SECURITY
+SSL,1080,TLSV1_ALERT_INTERNAL_ERROR
+SSL,1100,TLSV1_ALERT_NO_RENEGOTIATION
+SSL,1070,TLSV1_ALERT_PROTOCOL_VERSION
+SSL,1022,TLSV1_ALERT_RECORD_OVERFLOW
+SSL,1048,TLSV1_ALERT_UNKNOWN_CA
+SSL,1090,TLSV1_ALERT_USER_CANCELLED
+SSL,1114,TLSV1_BAD_CERTIFICATE_HASH_VALUE
+SSL,1113,TLSV1_BAD_CERTIFICATE_STATUS_RESPONSE
+SSL,1111,TLSV1_CERTIFICATE_UNOBTAINABLE
+SSL,1112,TLSV1_UNRECOGNIZED_NAME
+SSL,1110,TLSV1_UNSUPPORTED_EXTENSION
+SSL,232,TLS_CLIENT_CERT_REQ_WITH_ANON_CIPHER
+SSL,233,TLS_ILLEGAL_EXPORTER_LABEL
+SSL,234,TLS_INVALID_ECPOINTFORMAT_LIST
+SSL,235,TLS_PEER_DID_NOT_RESPOND_WITH_CERTIFICATE_LIST
+SSL,236,TLS_RSA_ENCRYPTED_VALUE_LENGTH_IS_WRONG
+SSL,237,TOO_MANY_EMPTY_FRAGMENTS
+SSL,278,TOO_MANY_WARNING_ALERTS
+SSL,238,UNABLE_TO_FIND_ECDH_PARAMETERS
+SSL,239,UNABLE_TO_FIND_PUBLIC_KEY_PARAMETERS
+SSL,279,UNEXPECTED_EXTENSION
+SSL,240,UNEXPECTED_GROUP_CLOSE
+SSL,241,UNEXPECTED_MESSAGE
+SSL,242,UNEXPECTED_OPERATOR_IN_GROUP
+SSL,243,UNEXPECTED_RECORD
+SSL,244,UNINITIALIZED
+SSL,245,UNKNOWN_ALERT_TYPE
+SSL,246,UNKNOWN_CERTIFICATE_TYPE
+SSL,247,UNKNOWN_CIPHER_RETURNED
+SSL,248,UNKNOWN_CIPHER_TYPE
+SSL,249,UNKNOWN_DIGEST
+SSL,250,UNKNOWN_KEY_EXCHANGE_TYPE
+SSL,251,UNKNOWN_PROTOCOL
+SSL,252,UNKNOWN_SSL_VERSION
+SSL,253,UNKNOWN_STATE
+SSL,254,UNPROCESSED_HANDSHAKE_DATA
+SSL,255,UNSAFE_LEGACY_RENEGOTIATION_DISABLED
+SSL,256,UNSUPPORTED_CIPHER
+SSL,257,UNSUPPORTED_COMPRESSION_ALGORITHM
+SSL,258,UNSUPPORTED_ELLIPTIC_CURVE
+SSL,259,UNSUPPORTED_PROTOCOL
+SSL,260,UNSUPPORTED_SSL_VERSION
+SSL,261,USE_SRTP_NOT_NEGOTIATED
+SSL,262,WRONG_CERTIFICATE_TYPE
+SSL,263,WRONG_CIPHER_RETURNED
+SSL,264,WRONG_CURVE
+SSL,265,WRONG_MESSAGE_TYPE
+SSL,266,WRONG_SIGNATURE_TYPE
+SSL,267,WRONG_SSL_VERSION
+SSL,268,WRONG_VERSION_NUMBER
+SSL,269,X509_LIB
+SSL,270,X509_VERIFICATION_SETUP_PROBLEMS
diff --git a/src/crypto/err/x509.errordata b/src/crypto/err/x509.errordata
index 1b50e36..f4828ce 100644
--- a/src/crypto/err/x509.errordata
+++ b/src/crypto/err/x509.errordata
@@ -1,96 +1,37 @@
-X509,function,100,ASN1_digest
-X509,function,101,ASN1_item_sign_ctx
-X509,function,102,ASN1_item_verify
-X509,function,103,NETSCAPE_SPKI_b64_decode
-X509,function,104,NETSCAPE_SPKI_b64_encode
-X509,function,158,PKCS7_get_CRLs
-X509,function,105,PKCS7_get_certificates
-X509,function,106,X509_ATTRIBUTE_create_by_NID
-X509,function,107,X509_ATTRIBUTE_create_by_OBJ
-X509,function,108,X509_ATTRIBUTE_create_by_txt
-X509,function,109,X509_ATTRIBUTE_get0_data
-X509,function,110,X509_ATTRIBUTE_set1_data
-X509,function,111,X509_CRL_add0_revoked
-X509,function,112,X509_CRL_diff
-X509,function,113,X509_CRL_print_fp
-X509,function,114,X509_EXTENSION_create_by_NID
-X509,function,115,X509_EXTENSION_create_by_OBJ
-X509,function,116,X509_INFO_new
-X509,function,117,X509_NAME_ENTRY_create_by_NID
-X509,function,118,X509_NAME_ENTRY_create_by_txt
-X509,function,119,X509_NAME_ENTRY_set_object
-X509,function,120,X509_NAME_add_entry
-X509,function,121,X509_NAME_oneline
-X509,function,122,X509_NAME_print
-X509,function,123,X509_PKEY_new
-X509,function,124,X509_PUBKEY_get
-X509,function,125,X509_PUBKEY_set
-X509,function,126,X509_REQ_check_private_key
-X509,function,127,X509_REQ_to_X509
-X509,function,128,X509_STORE_CTX_get1_issuer
-X509,function,129,X509_STORE_CTX_init
-X509,function,130,X509_STORE_CTX_new
-X509,function,131,X509_STORE_CTX_purpose_inherit
-X509,function,132,X509_STORE_add_cert
-X509,function,133,X509_STORE_add_crl
-X509,function,134,X509_TRUST_add
-X509,function,135,X509_TRUST_set
-X509,function,136,X509_check_private_key
-X509,function,137,X509_get_pubkey_parameters
-X509,function,138,X509_load_cert_crl_file
-X509,function,139,X509_load_cert_file
-X509,function,140,X509_load_crl_file
-X509,function,141,X509_print_ex_fp
-X509,function,142,X509_to_X509_REQ
-X509,function,143,X509_verify_cert
-X509,function,144,X509at_add1_attr
-X509,function,145,X509v3_add_ext
-X509,function,146,add_cert_dir
-X509,function,147,by_file_ctrl
-X509,function,148,check_policy
-X509,function,149,dir_ctrl
-X509,function,150,get_cert_by_subject
-X509,function,151,i2d_DSA_PUBKEY
-X509,function,152,i2d_EC_PUBKEY
-X509,function,153,i2d_RSA_PUBKEY
-X509,function,157,pkcs7_parse_header
-X509,function,154,x509_name_encode
-X509,function,155,x509_name_ex_d2i
-X509,function,156,x509_name_ex_new
-X509,reason,100,AKID_MISMATCH
-X509,reason,101,BAD_PKCS7_VERSION
-X509,reason,102,BAD_X509_FILETYPE
-X509,reason,103,BASE64_DECODE_ERROR
-X509,reason,104,CANT_CHECK_DH_KEY
-X509,reason,105,CERT_ALREADY_IN_HASH_TABLE
-X509,reason,106,CRL_ALREADY_DELTA
-X509,reason,107,CRL_VERIFY_FAILURE
-X509,reason,108,IDP_MISMATCH
-X509,reason,109,INVALID_BIT_STRING_BITS_LEFT
-X509,reason,110,INVALID_DIRECTORY
-X509,reason,111,INVALID_FIELD_NAME
-X509,reason,112,INVALID_TRUST
-X509,reason,113,ISSUER_MISMATCH
-X509,reason,114,KEY_TYPE_MISMATCH
-X509,reason,115,KEY_VALUES_MISMATCH
-X509,reason,116,LOADING_CERT_DIR
-X509,reason,117,LOADING_DEFAULTS
-X509,reason,118,METHOD_NOT_SUPPORTED
-X509,reason,119,NEWER_CRL_NOT_NEWER
-X509,reason,120,NOT_PKCS7_SIGNED_DATA
-X509,reason,121,NO_CERTIFICATES_INCLUDED
-X509,reason,122,NO_CERT_SET_FOR_US_TO_VERIFY
-X509,reason,136,NO_CRLS_INCLUDED
-X509,reason,123,NO_CRL_NUMBER
-X509,reason,124,PUBLIC_KEY_DECODE_ERROR
-X509,reason,125,PUBLIC_KEY_ENCODE_ERROR
-X509,reason,126,SHOULD_RETRY
-X509,reason,127,UNABLE_TO_FIND_PARAMETERS_IN_CHAIN
-X509,reason,128,UNABLE_TO_GET_CERTS_PUBLIC_KEY
-X509,reason,129,UNKNOWN_KEY_TYPE
-X509,reason,130,UNKNOWN_NID
-X509,reason,131,UNKNOWN_PURPOSE_ID
-X509,reason,132,UNKNOWN_TRUST_ID
-X509,reason,133,UNSUPPORTED_ALGORITHM
-X509,reason,134,WRONG_LOOKUP_TYPE
-X509,reason,135,WRONG_TYPE
+X509,100,AKID_MISMATCH
+X509,101,BAD_PKCS7_VERSION
+X509,102,BAD_X509_FILETYPE
+X509,103,BASE64_DECODE_ERROR
+X509,104,CANT_CHECK_DH_KEY
+X509,105,CERT_ALREADY_IN_HASH_TABLE
+X509,106,CRL_ALREADY_DELTA
+X509,107,CRL_VERIFY_FAILURE
+X509,108,IDP_MISMATCH
+X509,109,INVALID_BIT_STRING_BITS_LEFT
+X509,110,INVALID_DIRECTORY
+X509,111,INVALID_FIELD_NAME
+X509,112,INVALID_TRUST
+X509,113,ISSUER_MISMATCH
+X509,114,KEY_TYPE_MISMATCH
+X509,115,KEY_VALUES_MISMATCH
+X509,116,LOADING_CERT_DIR
+X509,117,LOADING_DEFAULTS
+X509,118,METHOD_NOT_SUPPORTED
+X509,119,NEWER_CRL_NOT_NEWER
+X509,120,NOT_PKCS7_SIGNED_DATA
+X509,121,NO_CERTIFICATES_INCLUDED
+X509,122,NO_CERT_SET_FOR_US_TO_VERIFY
+X509,136,NO_CRLS_INCLUDED
+X509,123,NO_CRL_NUMBER
+X509,124,PUBLIC_KEY_DECODE_ERROR
+X509,125,PUBLIC_KEY_ENCODE_ERROR
+X509,126,SHOULD_RETRY
+X509,127,UNABLE_TO_FIND_PARAMETERS_IN_CHAIN
+X509,128,UNABLE_TO_GET_CERTS_PUBLIC_KEY
+X509,129,UNKNOWN_KEY_TYPE
+X509,130,UNKNOWN_NID
+X509,131,UNKNOWN_PURPOSE_ID
+X509,132,UNKNOWN_TRUST_ID
+X509,133,UNSUPPORTED_ALGORITHM
+X509,134,WRONG_LOOKUP_TYPE
+X509,135,WRONG_TYPE
diff --git a/src/crypto/err/x509v3.errordata b/src/crypto/err/x509v3.errordata
index 059e677..e53b780 100644
--- a/src/crypto/err/x509v3.errordata
+++ b/src/crypto/err/x509v3.errordata
@@ -1,120 +1,63 @@
-X509V3,function,100,SXNET_add_id_INTEGER
-X509V3,function,101,SXNET_add_id_asc
-X509V3,function,102,SXNET_add_id_ulong
-X509V3,function,103,SXNET_get_id_asc
-X509V3,function,104,SXNET_get_id_ulong
-X509V3,function,105,X509V3_EXT_add
-X509V3,function,106,X509V3_EXT_add_alias
-X509V3,function,107,X509V3_EXT_free
-X509V3,function,108,X509V3_EXT_i2d
-X509V3,function,109,X509V3_EXT_nconf
-X509V3,function,110,X509V3_add1_i2d
-X509V3,function,111,X509V3_add_value
-X509V3,function,112,X509V3_get_section
-X509V3,function,113,X509V3_get_string
-X509V3,function,114,X509V3_get_value_bool
-X509V3,function,115,X509V3_parse_list
-X509V3,function,116,X509_PURPOSE_add
-X509V3,function,117,X509_PURPOSE_set
-X509V3,function,118,a2i_GENERAL_NAME
-X509V3,function,119,copy_email
-X509V3,function,120,copy_issuer
-X509V3,function,121,do_dirname
-X509V3,function,122,do_ext_i2d
-X509V3,function,123,do_ext_nconf
-X509V3,function,124,gnames_from_sectname
-X509V3,function,125,hex_to_string
-X509V3,function,126,i2s_ASN1_ENUMERATED
-X509V3,function,127,i2s_ASN1_IA5STRING
-X509V3,function,128,i2s_ASN1_INTEGER
-X509V3,function,129,i2v_AUTHORITY_INFO_ACCESS
-X509V3,function,130,notice_section
-X509V3,function,131,nref_nos
-X509V3,function,132,policy_section
-X509V3,function,133,process_pci_value
-X509V3,function,134,r2i_certpol
-X509V3,function,135,r2i_pci
-X509V3,function,136,s2i_ASN1_IA5STRING
-X509V3,function,137,s2i_ASN1_INTEGER
-X509V3,function,138,s2i_ASN1_OCTET_STRING
-X509V3,function,139,s2i_skey_id
-X509V3,function,140,set_dist_point_name
-X509V3,function,141,string_to_hex
-X509V3,function,142,v2i_ASN1_BIT_STRING
-X509V3,function,143,v2i_AUTHORITY_INFO_ACCESS
-X509V3,function,144,v2i_AUTHORITY_KEYID
-X509V3,function,145,v2i_BASIC_CONSTRAINTS
-X509V3,function,146,v2i_EXTENDED_KEY_USAGE
-X509V3,function,147,v2i_GENERAL_NAMES
-X509V3,function,148,v2i_GENERAL_NAME_ex
-X509V3,function,149,v2i_NAME_CONSTRAINTS
-X509V3,function,150,v2i_POLICY_CONSTRAINTS
-X509V3,function,151,v2i_POLICY_MAPPINGS
-X509V3,function,152,v2i_crld
-X509V3,function,153,v2i_idp
-X509V3,function,154,v2i_issuer_alt
-X509V3,function,155,v2i_subject_alt
-X509V3,function,156,v3_generic_extension
-X509V3,reason,100,BAD_IP_ADDRESS
-X509V3,reason,101,BAD_OBJECT
-X509V3,reason,102,BN_DEC2BN_ERROR
-X509V3,reason,103,BN_TO_ASN1_INTEGER_ERROR
-X509V3,reason,104,CANNOT_FIND_FREE_FUNCTION
-X509V3,reason,105,DIRNAME_ERROR
-X509V3,reason,106,DISTPOINT_ALREADY_SET
-X509V3,reason,107,DUPLICATE_ZONE_ID
-X509V3,reason,108,ERROR_CONVERTING_ZONE
-X509V3,reason,109,ERROR_CREATING_EXTENSION
-X509V3,reason,110,ERROR_IN_EXTENSION
-X509V3,reason,111,EXPECTED_A_SECTION_NAME
-X509V3,reason,112,EXTENSION_EXISTS
-X509V3,reason,113,EXTENSION_NAME_ERROR
-X509V3,reason,114,EXTENSION_NOT_FOUND
-X509V3,reason,115,EXTENSION_SETTING_NOT_SUPPORTED
-X509V3,reason,116,EXTENSION_VALUE_ERROR
-X509V3,reason,117,ILLEGAL_EMPTY_EXTENSION
-X509V3,reason,118,ILLEGAL_HEX_DIGIT
-X509V3,reason,119,INCORRECT_POLICY_SYNTAX_TAG
-X509V3,reason,120,INVALID_BOOLEAN_STRING
-X509V3,reason,121,INVALID_EXTENSION_STRING
-X509V3,reason,122,INVALID_MULTIPLE_RDNS
-X509V3,reason,123,INVALID_NAME
-X509V3,reason,124,INVALID_NULL_ARGUMENT
-X509V3,reason,125,INVALID_NULL_NAME
-X509V3,reason,126,INVALID_NULL_VALUE
-X509V3,reason,127,INVALID_NUMBER
-X509V3,reason,128,INVALID_NUMBERS
-X509V3,reason,129,INVALID_OBJECT_IDENTIFIER
-X509V3,reason,130,INVALID_OPTION
-X509V3,reason,131,INVALID_POLICY_IDENTIFIER
-X509V3,reason,132,INVALID_PROXY_POLICY_SETTING
-X509V3,reason,133,INVALID_PURPOSE
-X509V3,reason,134,INVALID_SECTION
-X509V3,reason,135,INVALID_SYNTAX
-X509V3,reason,136,ISSUER_DECODE_ERROR
-X509V3,reason,137,MISSING_VALUE
-X509V3,reason,138,NEED_ORGANIZATION_AND_NUMBERS
-X509V3,reason,139,NO_CONFIG_DATABASE
-X509V3,reason,140,NO_ISSUER_CERTIFICATE
-X509V3,reason,141,NO_ISSUER_DETAILS
-X509V3,reason,142,NO_POLICY_IDENTIFIER
-X509V3,reason,143,NO_PROXY_CERT_POLICY_LANGUAGE_DEFINED
-X509V3,reason,144,NO_PUBLIC_KEY
-X509V3,reason,145,NO_SUBJECT_DETAILS
-X509V3,reason,146,ODD_NUMBER_OF_DIGITS
-X509V3,reason,147,OPERATION_NOT_DEFINED
-X509V3,reason,148,OTHERNAME_ERROR
-X509V3,reason,149,POLICY_LANGUAGE_ALREADY_DEFINED
-X509V3,reason,150,POLICY_PATH_LENGTH
-X509V3,reason,151,POLICY_PATH_LENGTH_ALREADY_DEFINED
-X509V3,reason,152,POLICY_WHEN_PROXY_LANGUAGE_REQUIRES_NO_POLICY
-X509V3,reason,153,SECTION_NOT_FOUND
-X509V3,reason,154,UNABLE_TO_GET_ISSUER_DETAILS
-X509V3,reason,155,UNABLE_TO_GET_ISSUER_KEYID
-X509V3,reason,156,UNKNOWN_BIT_STRING_ARGUMENT
-X509V3,reason,157,UNKNOWN_EXTENSION
-X509V3,reason,158,UNKNOWN_EXTENSION_NAME
-X509V3,reason,159,UNKNOWN_OPTION
-X509V3,reason,160,UNSUPPORTED_OPTION
-X509V3,reason,161,UNSUPPORTED_TYPE
-X509V3,reason,162,USER_TOO_LONG
+X509V3,100,BAD_IP_ADDRESS
+X509V3,101,BAD_OBJECT
+X509V3,102,BN_DEC2BN_ERROR
+X509V3,103,BN_TO_ASN1_INTEGER_ERROR
+X509V3,104,CANNOT_FIND_FREE_FUNCTION
+X509V3,105,DIRNAME_ERROR
+X509V3,106,DISTPOINT_ALREADY_SET
+X509V3,107,DUPLICATE_ZONE_ID
+X509V3,108,ERROR_CONVERTING_ZONE
+X509V3,109,ERROR_CREATING_EXTENSION
+X509V3,110,ERROR_IN_EXTENSION
+X509V3,111,EXPECTED_A_SECTION_NAME
+X509V3,112,EXTENSION_EXISTS
+X509V3,113,EXTENSION_NAME_ERROR
+X509V3,114,EXTENSION_NOT_FOUND
+X509V3,115,EXTENSION_SETTING_NOT_SUPPORTED
+X509V3,116,EXTENSION_VALUE_ERROR
+X509V3,117,ILLEGAL_EMPTY_EXTENSION
+X509V3,118,ILLEGAL_HEX_DIGIT
+X509V3,119,INCORRECT_POLICY_SYNTAX_TAG
+X509V3,120,INVALID_BOOLEAN_STRING
+X509V3,121,INVALID_EXTENSION_STRING
+X509V3,122,INVALID_MULTIPLE_RDNS
+X509V3,123,INVALID_NAME
+X509V3,124,INVALID_NULL_ARGUMENT
+X509V3,125,INVALID_NULL_NAME
+X509V3,126,INVALID_NULL_VALUE
+X509V3,127,INVALID_NUMBER
+X509V3,128,INVALID_NUMBERS
+X509V3,129,INVALID_OBJECT_IDENTIFIER
+X509V3,130,INVALID_OPTION
+X509V3,131,INVALID_POLICY_IDENTIFIER
+X509V3,132,INVALID_PROXY_POLICY_SETTING
+X509V3,133,INVALID_PURPOSE
+X509V3,134,INVALID_SECTION
+X509V3,135,INVALID_SYNTAX
+X509V3,136,ISSUER_DECODE_ERROR
+X509V3,137,MISSING_VALUE
+X509V3,138,NEED_ORGANIZATION_AND_NUMBERS
+X509V3,139,NO_CONFIG_DATABASE
+X509V3,140,NO_ISSUER_CERTIFICATE
+X509V3,141,NO_ISSUER_DETAILS
+X509V3,142,NO_POLICY_IDENTIFIER
+X509V3,143,NO_PROXY_CERT_POLICY_LANGUAGE_DEFINED
+X509V3,144,NO_PUBLIC_KEY
+X509V3,145,NO_SUBJECT_DETAILS
+X509V3,146,ODD_NUMBER_OF_DIGITS
+X509V3,147,OPERATION_NOT_DEFINED
+X509V3,148,OTHERNAME_ERROR
+X509V3,149,POLICY_LANGUAGE_ALREADY_DEFINED
+X509V3,150,POLICY_PATH_LENGTH
+X509V3,151,POLICY_PATH_LENGTH_ALREADY_DEFINED
+X509V3,152,POLICY_WHEN_PROXY_LANGUAGE_REQUIRES_NO_POLICY
+X509V3,153,SECTION_NOT_FOUND
+X509V3,154,UNABLE_TO_GET_ISSUER_DETAILS
+X509V3,155,UNABLE_TO_GET_ISSUER_KEYID
+X509V3,156,UNKNOWN_BIT_STRING_ARGUMENT
+X509V3,157,UNKNOWN_EXTENSION
+X509V3,158,UNKNOWN_EXTENSION_NAME
+X509V3,159,UNKNOWN_OPTION
+X509V3,160,UNSUPPORTED_OPTION
+X509V3,161,UNSUPPORTED_TYPE
+X509V3,162,USER_TOO_LONG
diff --git a/src/crypto/evp/CMakeLists.txt b/src/crypto/evp/CMakeLists.txt
index 5769fa4..5d2e918 100644
--- a/src/crypto/evp/CMakeLists.txt
+++ b/src/crypto/evp/CMakeLists.txt
@@ -1,4 +1,4 @@
-include_directories(. .. ../../include)
+include_directories(../../include)
add_library(
evp
@@ -6,15 +6,13 @@ add_library(
OBJECT
algorithm.c
- asn1.c
digestsign.c
evp.c
+ evp_asn1.c
evp_ctx.c
p_dsa_asn1.c
p_ec.c
p_ec_asn1.c
- p_hmac.c
- p_hmac_asn1.c
p_rsa.c
p_rsa_asn1.c
pbkdf.c
diff --git a/src/crypto/evp/algorithm.c b/src/crypto/evp/algorithm.c
index ea28dfa..63bc77a 100644
--- a/src/crypto/evp/algorithm.c
+++ b/src/crypto/evp/algorithm.c
@@ -74,8 +74,7 @@ int EVP_DigestSignAlgorithm(EVP_MD_CTX *ctx, X509_ALGOR *algor) {
digest = EVP_MD_CTX_md(ctx);
pkey = EVP_PKEY_CTX_get0_pkey(ctx->pctx);
if (!digest || !pkey) {
- OPENSSL_PUT_ERROR(EVP, EVP_DigestSignAlgorithm,
- EVP_R_CONTEXT_NOT_INITIALISED);
+ OPENSSL_PUT_ERROR(EVP, EVP_R_CONTEXT_NOT_INITIALISED);
return 0;
}
@@ -97,8 +96,7 @@ int EVP_DigestSignAlgorithm(EVP_MD_CTX *ctx, X509_ALGOR *algor) {
* that. */
if (!OBJ_find_sigid_by_algs(&sign_nid, EVP_MD_type(digest),
pkey->ameth->pkey_id)) {
- OPENSSL_PUT_ERROR(EVP, EVP_DigestSignAlgorithm,
- EVP_R_DIGEST_AND_KEY_TYPE_NOT_SUPPORTED);
+ OPENSSL_PUT_ERROR(EVP, EVP_R_DIGEST_AND_KEY_TYPE_NOT_SUPPORTED);
return 0;
}
@@ -122,24 +120,21 @@ int EVP_DigestVerifyInitFromAlgorithm(EVP_MD_CTX *ctx,
/* Convert signature OID into digest and public key OIDs */
if (!OBJ_find_sigid_algs(OBJ_obj2nid(algor->algorithm), &digest_nid,
&pkey_nid)) {
- OPENSSL_PUT_ERROR(EVP, EVP_DigestVerifyInitFromAlgorithm,
- EVP_R_UNKNOWN_SIGNATURE_ALGORITHM);
+ OPENSSL_PUT_ERROR(EVP, EVP_R_UNKNOWN_SIGNATURE_ALGORITHM);
return 0;
}
/* Check public key OID matches public key type */
ameth = EVP_PKEY_asn1_find(NULL, pkey_nid);
if (ameth == NULL || ameth->pkey_id != pkey->ameth->pkey_id) {
- OPENSSL_PUT_ERROR(EVP, EVP_DigestVerifyInitFromAlgorithm,
- EVP_R_WRONG_PUBLIC_KEY_TYPE);
+ OPENSSL_PUT_ERROR(EVP, EVP_R_WRONG_PUBLIC_KEY_TYPE);
return 0;
}
/* NID_undef signals that there are custom parameters to set. */
if (digest_nid == NID_undef) {
if (!pkey->ameth || !pkey->ameth->digest_verify_init_from_algorithm) {
- OPENSSL_PUT_ERROR(EVP, EVP_DigestVerifyInitFromAlgorithm,
- EVP_R_UNKNOWN_SIGNATURE_ALGORITHM);
+ OPENSSL_PUT_ERROR(EVP, EVP_R_UNKNOWN_SIGNATURE_ALGORITHM);
return 0;
}
@@ -149,8 +144,7 @@ int EVP_DigestVerifyInitFromAlgorithm(EVP_MD_CTX *ctx,
/* Otherwise, initialize with the digest from the OID. */
digest = EVP_get_digestbynid(digest_nid);
if (digest == NULL) {
- OPENSSL_PUT_ERROR(EVP, EVP_DigestVerifyInitFromAlgorithm,
- EVP_R_UNKNOWN_MESSAGE_DIGEST_ALGORITHM);
+ OPENSSL_PUT_ERROR(EVP, EVP_R_UNKNOWN_MESSAGE_DIGEST_ALGORITHM);
return 0;
}
diff --git a/src/crypto/evp/digestsign.c b/src/crypto/evp/digestsign.c
index c163d40..ccb4de4 100644
--- a/src/crypto/evp/digestsign.c
+++ b/src/crypto/evp/digestsign.c
@@ -62,17 +62,9 @@
#include "../digest/internal.h"
-/* md_begin_digset is a callback from the |EVP_MD_CTX| code that is called when
- * a new digest is begun. */
-static int md_begin_digest(EVP_MD_CTX *ctx) {
- return EVP_PKEY_CTX_ctrl(ctx->pctx, -1, EVP_PKEY_OP_TYPE_SIG,
- EVP_PKEY_CTRL_DIGESTINIT, 0, ctx);
-}
-
static const struct evp_md_pctx_ops md_pctx_ops = {
EVP_PKEY_CTX_free,
EVP_PKEY_CTX_dup,
- md_begin_digest,
};
static int do_sigver_init(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx,
@@ -91,26 +83,16 @@ static int do_sigver_init(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx,
}
if (type == NULL) {
- OPENSSL_PUT_ERROR(EVP, do_sigver_init, EVP_R_NO_DEFAULT_DIGEST);
+ OPENSSL_PUT_ERROR(EVP, EVP_R_NO_DEFAULT_DIGEST);
return 0;
}
if (is_verify) {
- if (ctx->pctx->pmeth->verifyctx_init) {
- if (!ctx->pctx->pmeth->verifyctx_init(ctx->pctx, ctx)) {
- return 0;
- }
- ctx->pctx->operation = EVP_PKEY_OP_VERIFYCTX;
- } else if (!EVP_PKEY_verify_init(ctx->pctx)) {
+ if (!EVP_PKEY_verify_init(ctx->pctx)) {
return 0;
}
} else {
- if (ctx->pctx->pmeth->signctx_init) {
- if (!ctx->pctx->pmeth->signctx_init(ctx->pctx, ctx)) {
- return 0;
- }
- ctx->pctx->operation = EVP_PKEY_OP_SIGNCTX;
- } else if (!EVP_PKEY_sign_init(ctx->pctx)) {
+ if (!EVP_PKEY_sign_init(ctx->pctx)) {
return 0;
}
}
@@ -146,59 +128,37 @@ int EVP_DigestVerifyUpdate(EVP_MD_CTX *ctx, const void *data, size_t len) {
int EVP_DigestSignFinal(EVP_MD_CTX *ctx, uint8_t *out_sig,
size_t *out_sig_len) {
- int r = 0;
- const int has_signctx = ctx->pctx->pmeth->signctx != NULL;
-
if (out_sig) {
EVP_MD_CTX tmp_ctx;
+ int ret;
uint8_t md[EVP_MAX_MD_SIZE];
unsigned int mdlen;
EVP_MD_CTX_init(&tmp_ctx);
- if (!EVP_MD_CTX_copy_ex(&tmp_ctx, ctx)) {
- return 0;
- }
- if (has_signctx) {
- r = tmp_ctx.pctx->pmeth->signctx(tmp_ctx.pctx, out_sig, out_sig_len, &tmp_ctx);
- } else {
- r = EVP_DigestFinal_ex(&tmp_ctx, md, &mdlen);
- if (r) {
- r = EVP_PKEY_sign(ctx->pctx, out_sig, out_sig_len, md, mdlen);
- }
- }
+ ret = EVP_MD_CTX_copy_ex(&tmp_ctx, ctx) &&
+ EVP_DigestFinal_ex(&tmp_ctx, md, &mdlen) &&
+ EVP_PKEY_sign(ctx->pctx, out_sig, out_sig_len, md, mdlen);
EVP_MD_CTX_cleanup(&tmp_ctx);
- return r;
+
+ return ret;
} else {
- if (has_signctx) {
- return ctx->pctx->pmeth->signctx(ctx->pctx, out_sig, out_sig_len, ctx);
- } else {
- size_t s = EVP_MD_size(ctx->digest);
- return EVP_PKEY_sign(ctx->pctx, out_sig, out_sig_len, NULL, s);
- }
+ size_t s = EVP_MD_size(ctx->digest);
+ return EVP_PKEY_sign(ctx->pctx, out_sig, out_sig_len, NULL, s);
}
}
int EVP_DigestVerifyFinal(EVP_MD_CTX *ctx, const uint8_t *sig,
size_t sig_len) {
EVP_MD_CTX tmp_ctx;
+ int ret;
uint8_t md[EVP_MAX_MD_SIZE];
- int r;
unsigned int mdlen;
EVP_MD_CTX_init(&tmp_ctx);
- if (!EVP_MD_CTX_copy_ex(&tmp_ctx, ctx)) {
- return 0;
- }
- if (ctx->pctx->pmeth->verifyctx) {
- r = tmp_ctx.pctx->pmeth->verifyctx(tmp_ctx.pctx, sig, sig_len, &tmp_ctx);
- } else {
- r = EVP_DigestFinal_ex(&tmp_ctx, md, &mdlen);
- if (r) {
- r = EVP_PKEY_verify(ctx->pctx, sig, sig_len, md, mdlen);
- }
- }
-
+ ret = EVP_MD_CTX_copy_ex(&tmp_ctx, ctx) &&
+ EVP_DigestFinal_ex(&tmp_ctx, md, &mdlen) &&
+ EVP_PKEY_verify(ctx->pctx, sig, sig_len, md, mdlen);
EVP_MD_CTX_cleanup(&tmp_ctx);
- return r;
+ return ret;
}
diff --git a/src/crypto/evp/evp.c b/src/crypto/evp/evp.c
index 0ad5c27..5822379 100644
--- a/src/crypto/evp/evp.c
+++ b/src/crypto/evp/evp.c
@@ -75,7 +75,6 @@
extern const EVP_PKEY_ASN1_METHOD dsa_asn1_meth;
extern const EVP_PKEY_ASN1_METHOD ec_asn1_meth;
-extern const EVP_PKEY_ASN1_METHOD hmac_asn1_meth;
extern const EVP_PKEY_ASN1_METHOD rsa_asn1_meth;
EVP_PKEY *EVP_PKEY_new(void) {
@@ -83,7 +82,7 @@ EVP_PKEY *EVP_PKEY_new(void) {
ret = OPENSSL_malloc(sizeof(EVP_PKEY));
if (ret == NULL) {
- OPENSSL_PUT_ERROR(EVP, EVP_PKEY_new, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(EVP, ERR_R_MALLOC_FAILURE);
return NULL;
}
@@ -159,12 +158,12 @@ int EVP_PKEY_cmp(const EVP_PKEY *a, const EVP_PKEY *b) {
int EVP_PKEY_copy_parameters(EVP_PKEY *to, const EVP_PKEY *from) {
if (to->type != from->type) {
- OPENSSL_PUT_ERROR(EVP, EVP_PKEY_copy_parameters, EVP_R_DIFFERENT_KEY_TYPES);
+ OPENSSL_PUT_ERROR(EVP, EVP_R_DIFFERENT_KEY_TYPES);
goto err;
}
if (EVP_PKEY_missing_parameters(from)) {
- OPENSSL_PUT_ERROR(EVP, EVP_PKEY_copy_parameters, EVP_R_MISSING_PARAMETERS);
+ OPENSSL_PUT_ERROR(EVP, EVP_R_MISSING_PARAMETERS);
goto err;
}
@@ -207,8 +206,6 @@ const EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_find(ENGINE **pengine, int nid) {
case EVP_PKEY_RSA:
case EVP_PKEY_RSA2:
return &rsa_asn1_meth;
- case EVP_PKEY_HMAC:
- return &hmac_asn1_meth;
case EVP_PKEY_EC:
return &ec_asn1_meth;
case EVP_PKEY_DSA:
@@ -226,32 +223,6 @@ int EVP_PKEY_type(int nid) {
return meth->pkey_id;
}
-EVP_PKEY *EVP_PKEY_new_mac_key(int type, ENGINE *e, const uint8_t *mac_key,
- size_t mac_key_len) {
- EVP_PKEY_CTX *mac_ctx = NULL;
- EVP_PKEY *ret = NULL;
-
- mac_ctx = EVP_PKEY_CTX_new_id(type, e);
- if (!mac_ctx) {
- return NULL;
- }
-
- if (!EVP_PKEY_keygen_init(mac_ctx) ||
- !EVP_PKEY_CTX_ctrl(mac_ctx, -1, EVP_PKEY_OP_KEYGEN,
- EVP_PKEY_CTRL_SET_MAC_KEY, mac_key_len,
- (uint8_t *)mac_key) ||
- !EVP_PKEY_keygen(mac_ctx, &ret)) {
- ret = NULL;
- goto merr;
- }
-
-merr:
- if (mac_ctx) {
- EVP_PKEY_CTX_free(mac_ctx);
- }
- return ret;
-}
-
int EVP_PKEY_set1_RSA(EVP_PKEY *pkey, RSA *key) {
if (EVP_PKEY_assign_RSA(pkey, key)) {
RSA_up_ref(key);
@@ -266,7 +237,7 @@ int EVP_PKEY_assign_RSA(EVP_PKEY *pkey, RSA *key) {
RSA *EVP_PKEY_get1_RSA(EVP_PKEY *pkey) {
if (pkey->type != EVP_PKEY_RSA) {
- OPENSSL_PUT_ERROR(EVP, EVP_PKEY_get1_RSA, EVP_R_EXPECTING_AN_RSA_KEY);
+ OPENSSL_PUT_ERROR(EVP, EVP_R_EXPECTING_AN_RSA_KEY);
return NULL;
}
RSA_up_ref(pkey->pkey.rsa);
@@ -287,7 +258,7 @@ int EVP_PKEY_assign_DSA(EVP_PKEY *pkey, DSA *key) {
DSA *EVP_PKEY_get1_DSA(EVP_PKEY *pkey) {
if (pkey->type != EVP_PKEY_DSA) {
- OPENSSL_PUT_ERROR(EVP, EVP_PKEY_get1_DSA, EVP_R_EXPECTING_A_DSA_KEY);
+ OPENSSL_PUT_ERROR(EVP, EVP_R_EXPECTING_A_DSA_KEY);
return NULL;
}
DSA_up_ref(pkey->pkey.dsa);
@@ -308,7 +279,7 @@ int EVP_PKEY_assign_EC_KEY(EVP_PKEY *pkey, EC_KEY *key) {
EC_KEY *EVP_PKEY_get1_EC_KEY(EVP_PKEY *pkey) {
if (pkey->type != EVP_PKEY_EC) {
- OPENSSL_PUT_ERROR(EVP, EVP_PKEY_get1_EC_KEY, EVP_R_EXPECTING_AN_EC_KEY_KEY);
+ OPENSSL_PUT_ERROR(EVP, EVP_R_EXPECTING_AN_EC_KEY_KEY);
return NULL;
}
EC_KEY_up_ref(pkey->pkey.ec);
@@ -329,7 +300,7 @@ int EVP_PKEY_assign_DH(EVP_PKEY *pkey, DH *key) {
DH *EVP_PKEY_get1_DH(EVP_PKEY *pkey) {
if (pkey->type != EVP_PKEY_DH) {
- OPENSSL_PUT_ERROR(EVP, EVP_PKEY_get1_DH, EVP_R_EXPECTING_A_DH_KEY);
+ OPENSSL_PUT_ERROR(EVP, EVP_R_EXPECTING_A_DH_KEY);
return NULL;
}
DH_up_ref(pkey->pkey.dh);
@@ -349,10 +320,10 @@ const EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_find_str(ENGINE **pengine,
size_t len) {
if (len == 3 && memcmp(name, "RSA", 3) == 0) {
return &rsa_asn1_meth;
- } else if (len == 4 && memcmp(name, "HMAC", 4) == 0) {
- return &hmac_asn1_meth;
} if (len == 2 && memcmp(name, "EC", 2) == 0) {
return &ec_asn1_meth;
+ } else if (len == 3 && memcmp(name, "DSA", 3) == 0) {
+ return &dsa_asn1_meth;
}
return NULL;
}
@@ -366,7 +337,7 @@ int EVP_PKEY_set_type(EVP_PKEY *pkey, int type) {
ameth = EVP_PKEY_asn1_find(NULL, type);
if (ameth == NULL) {
- OPENSSL_PUT_ERROR(EVP, EVP_PKEY_set_type, EVP_R_UNSUPPORTED_ALGORITHM);
+ OPENSSL_PUT_ERROR(EVP, EVP_R_UNSUPPORTED_ALGORITHM);
ERR_add_error_dataf("algorithm %d (%s)", type, OBJ_nid2sn(type));
return 0;
}
@@ -436,10 +407,6 @@ int EVP_PKEY_CTX_get_signature_md(EVP_PKEY_CTX *ctx, const EVP_MD **out_md) {
0, (void *)out_md);
}
-EVP_PKEY *EVP_PKEY_dup(EVP_PKEY *pkey) {
- return EVP_PKEY_up_ref(pkey);
-}
-
void OpenSSL_add_all_algorithms(void) {}
void OpenSSL_add_all_ciphers(void) {}
diff --git a/src/crypto/evp/asn1.c b/src/crypto/evp/evp_asn1.c
index 3df9f52..356c62b 100644
--- a/src/crypto/evp/asn1.c
+++ b/src/crypto/evp/evp_asn1.c
@@ -71,7 +71,7 @@ EVP_PKEY *d2i_PrivateKey(int type, EVP_PKEY **out, const uint8_t **inp,
if (out == NULL || *out == NULL) {
ret = EVP_PKEY_new();
if (ret == NULL) {
- OPENSSL_PUT_ERROR(EVP, d2i_PrivateKey, ERR_R_EVP_LIB);
+ OPENSSL_PUT_ERROR(EVP, ERR_R_EVP_LIB);
return NULL;
}
} else {
@@ -79,7 +79,7 @@ EVP_PKEY *d2i_PrivateKey(int type, EVP_PKEY **out, const uint8_t **inp,
}
if (!EVP_PKEY_set_type(ret, type)) {
- OPENSSL_PUT_ERROR(EVP, d2i_PrivateKey, EVP_R_UNKNOWN_PUBLIC_KEY_TYPE);
+ OPENSSL_PUT_ERROR(EVP, EVP_R_UNKNOWN_PUBLIC_KEY_TYPE);
goto err;
}
@@ -94,7 +94,7 @@ EVP_PKEY *d2i_PrivateKey(int type, EVP_PKEY **out, const uint8_t **inp,
ret = EVP_PKCS82PKEY(p8);
PKCS8_PRIV_KEY_INFO_free(p8);
} else {
- OPENSSL_PUT_ERROR(EVP, d2i_PrivateKey, ERR_R_ASN1_LIB);
+ OPENSSL_PUT_ERROR(EVP, ERR_R_ASN1_LIB);
goto err;
}
}
@@ -134,8 +134,7 @@ EVP_PKEY *d2i_AutoPrivateKey(EVP_PKEY **out, const uint8_t **inp, long len) {
sk_ASN1_TYPE_pop_free(inkey, ASN1_TYPE_free);
if (!p8) {
- OPENSSL_PUT_ERROR(EVP, d2i_AutoPrivateKey,
- EVP_R_UNSUPPORTED_PUBLIC_KEY_TYPE);
+ OPENSSL_PUT_ERROR(EVP, EVP_R_UNSUPPORTED_PUBLIC_KEY_TYPE);
return NULL;
}
ret = EVP_PKCS82PKEY(p8);
@@ -161,7 +160,7 @@ int i2d_PublicKey(EVP_PKEY *key, uint8_t **outp) {
case EVP_PKEY_EC:
return i2o_ECPublicKey(key->pkey.ec, outp);
default:
- OPENSSL_PUT_ERROR(EVP, i2d_PublicKey, EVP_R_UNSUPPORTED_PUBLIC_KEY_TYPE);
+ OPENSSL_PUT_ERROR(EVP, EVP_R_UNSUPPORTED_PUBLIC_KEY_TYPE);
return -1;
}
}
diff --git a/src/crypto/evp/evp_ctx.c b/src/crypto/evp/evp_ctx.c
index 9f42274..a8e71fe 100644
--- a/src/crypto/evp/evp_ctx.c
+++ b/src/crypto/evp/evp_ctx.c
@@ -67,12 +67,10 @@
extern const EVP_PKEY_METHOD rsa_pkey_meth;
-extern const EVP_PKEY_METHOD hmac_pkey_meth;
extern const EVP_PKEY_METHOD ec_pkey_meth;
static const EVP_PKEY_METHOD *const evp_methods[] = {
&rsa_pkey_meth,
- &hmac_pkey_meth,
&ec_pkey_meth,
};
@@ -102,7 +100,7 @@ static EVP_PKEY_CTX *evp_pkey_ctx_new(EVP_PKEY *pkey, ENGINE *e, int id) {
pmeth = evp_pkey_meth_find(id);
if (pmeth == NULL) {
- OPENSSL_PUT_ERROR(EVP, evp_pkey_ctx_new, EVP_R_UNSUPPORTED_ALGORITHM);
+ OPENSSL_PUT_ERROR(EVP, EVP_R_UNSUPPORTED_ALGORITHM);
const char *name = OBJ_nid2sn(id);
ERR_add_error_dataf("algorithm %d (%s)", id, name);
return NULL;
@@ -110,7 +108,7 @@ static EVP_PKEY_CTX *evp_pkey_ctx_new(EVP_PKEY *pkey, ENGINE *e, int id) {
ret = OPENSSL_malloc(sizeof(EVP_PKEY_CTX));
if (!ret) {
- OPENSSL_PUT_ERROR(EVP, evp_pkey_ctx_new, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(EVP, ERR_R_MALLOC_FAILURE);
return NULL;
}
memset(ret, 0, sizeof(EVP_PKEY_CTX));
@@ -192,7 +190,7 @@ EVP_PKEY_CTX *EVP_PKEY_CTX_dup(EVP_PKEY_CTX *pctx) {
err:
EVP_PKEY_CTX_free(rctx);
- OPENSSL_PUT_ERROR(EVP, EVP_PKEY_CTX_dup, ERR_LIB_EVP);
+ OPENSSL_PUT_ERROR(EVP, ERR_LIB_EVP);
return NULL;
}
@@ -207,7 +205,7 @@ void *EVP_PKEY_CTX_get_app_data(EVP_PKEY_CTX *ctx) { return ctx->app_data; }
int EVP_PKEY_CTX_ctrl(EVP_PKEY_CTX *ctx, int keytype, int optype, int cmd,
int p1, void *p2) {
if (!ctx || !ctx->pmeth || !ctx->pmeth->ctrl) {
- OPENSSL_PUT_ERROR(EVP, EVP_PKEY_CTX_ctrl, EVP_R_COMMAND_NOT_SUPPORTED);
+ OPENSSL_PUT_ERROR(EVP, EVP_R_COMMAND_NOT_SUPPORTED);
return 0;
}
if (keytype != -1 && ctx->pmeth->pkey_id != keytype) {
@@ -215,12 +213,12 @@ int EVP_PKEY_CTX_ctrl(EVP_PKEY_CTX *ctx, int keytype, int optype, int cmd,
}
if (ctx->operation == EVP_PKEY_OP_UNDEFINED) {
- OPENSSL_PUT_ERROR(EVP, EVP_PKEY_CTX_ctrl, EVP_R_NO_OPERATION_SET);
+ OPENSSL_PUT_ERROR(EVP, EVP_R_NO_OPERATION_SET);
return 0;
}
if (optype != -1 && !(ctx->operation & optype)) {
- OPENSSL_PUT_ERROR(EVP, EVP_PKEY_CTX_ctrl, EVP_R_INVALID_OPERATION);
+ OPENSSL_PUT_ERROR(EVP, EVP_R_INVALID_OPERATION);
return 0;
}
@@ -229,8 +227,7 @@ int EVP_PKEY_CTX_ctrl(EVP_PKEY_CTX *ctx, int keytype, int optype, int cmd,
int EVP_PKEY_sign_init(EVP_PKEY_CTX *ctx) {
if (!ctx || !ctx->pmeth || !ctx->pmeth->sign) {
- OPENSSL_PUT_ERROR(EVP, EVP_PKEY_sign_init,
- EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
+ OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
return 0;
}
@@ -250,12 +247,11 @@ int EVP_PKEY_sign_init(EVP_PKEY_CTX *ctx) {
int EVP_PKEY_sign(EVP_PKEY_CTX *ctx, uint8_t *sig, size_t *sig_len,
const uint8_t *data, size_t data_len) {
if (!ctx || !ctx->pmeth || !ctx->pmeth->sign) {
- OPENSSL_PUT_ERROR(EVP, EVP_PKEY_sign,
- EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
+ OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
return 0;
}
if (ctx->operation != EVP_PKEY_OP_SIGN) {
- OPENSSL_PUT_ERROR(EVP, EVP_PKEY_sign, EVP_R_OPERATON_NOT_INITIALIZED);
+ OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATON_NOT_INITIALIZED);
return 0;
}
return ctx->pmeth->sign(ctx, sig, sig_len, data, data_len);
@@ -263,8 +259,7 @@ int EVP_PKEY_sign(EVP_PKEY_CTX *ctx, uint8_t *sig, size_t *sig_len,
int EVP_PKEY_verify_init(EVP_PKEY_CTX *ctx) {
if (!ctx || !ctx->pmeth || !ctx->pmeth->verify) {
- OPENSSL_PUT_ERROR(EVP, EVP_PKEY_verify_init,
- EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
+ OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
return 0;
}
ctx->operation = EVP_PKEY_OP_VERIFY;
@@ -282,12 +277,11 @@ int EVP_PKEY_verify_init(EVP_PKEY_CTX *ctx) {
int EVP_PKEY_verify(EVP_PKEY_CTX *ctx, const uint8_t *sig, size_t sig_len,
const uint8_t *data, size_t data_len) {
if (!ctx || !ctx->pmeth || !ctx->pmeth->verify) {
- OPENSSL_PUT_ERROR(EVP, EVP_PKEY_verify,
- EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
+ OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
return 0;
}
if (ctx->operation != EVP_PKEY_OP_VERIFY) {
- OPENSSL_PUT_ERROR(EVP, EVP_PKEY_verify, EVP_R_OPERATON_NOT_INITIALIZED);
+ OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATON_NOT_INITIALIZED);
return 0;
}
return ctx->pmeth->verify(ctx, sig, sig_len, data, data_len);
@@ -295,8 +289,7 @@ int EVP_PKEY_verify(EVP_PKEY_CTX *ctx, const uint8_t *sig, size_t sig_len,
int EVP_PKEY_encrypt_init(EVP_PKEY_CTX *ctx) {
if (!ctx || !ctx->pmeth || !ctx->pmeth->encrypt) {
- OPENSSL_PUT_ERROR(EVP, EVP_PKEY_encrypt_init,
- EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
+ OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
return 0;
}
ctx->operation = EVP_PKEY_OP_ENCRYPT;
@@ -313,12 +306,11 @@ int EVP_PKEY_encrypt_init(EVP_PKEY_CTX *ctx) {
int EVP_PKEY_encrypt(EVP_PKEY_CTX *ctx, uint8_t *out, size_t *outlen,
const uint8_t *in, size_t inlen) {
if (!ctx || !ctx->pmeth || !ctx->pmeth->encrypt) {
- OPENSSL_PUT_ERROR(EVP, EVP_PKEY_encrypt,
- EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
+ OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
return 0;
}
if (ctx->operation != EVP_PKEY_OP_ENCRYPT) {
- OPENSSL_PUT_ERROR(EVP, EVP_PKEY_encrypt, EVP_R_OPERATON_NOT_INITIALIZED);
+ OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATON_NOT_INITIALIZED);
return 0;
}
return ctx->pmeth->encrypt(ctx, out, outlen, in, inlen);
@@ -326,8 +318,7 @@ int EVP_PKEY_encrypt(EVP_PKEY_CTX *ctx, uint8_t *out, size_t *outlen,
int EVP_PKEY_decrypt_init(EVP_PKEY_CTX *ctx) {
if (!ctx || !ctx->pmeth || !ctx->pmeth->decrypt) {
- OPENSSL_PUT_ERROR(EVP, EVP_PKEY_decrypt_init,
- EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
+ OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
return 0;
}
ctx->operation = EVP_PKEY_OP_DECRYPT;
@@ -344,12 +335,11 @@ int EVP_PKEY_decrypt_init(EVP_PKEY_CTX *ctx) {
int EVP_PKEY_decrypt(EVP_PKEY_CTX *ctx, uint8_t *out, size_t *outlen,
const uint8_t *in, size_t inlen) {
if (!ctx || !ctx->pmeth || !ctx->pmeth->decrypt) {
- OPENSSL_PUT_ERROR(EVP, EVP_PKEY_decrypt,
- EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
+ OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
return 0;
}
if (ctx->operation != EVP_PKEY_OP_DECRYPT) {
- OPENSSL_PUT_ERROR(EVP, EVP_PKEY_decrypt, EVP_R_OPERATON_NOT_INITIALIZED);
+ OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATON_NOT_INITIALIZED);
return 0;
}
return ctx->pmeth->decrypt(ctx, out, outlen, in, inlen);
@@ -357,8 +347,7 @@ int EVP_PKEY_decrypt(EVP_PKEY_CTX *ctx, uint8_t *out, size_t *outlen,
int EVP_PKEY_derive_init(EVP_PKEY_CTX *ctx) {
if (!ctx || !ctx->pmeth || !ctx->pmeth->derive) {
- OPENSSL_PUT_ERROR(EVP, EVP_PKEY_derive_init,
- EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
+ OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
return 0;
}
ctx->operation = EVP_PKEY_OP_DERIVE;
@@ -377,15 +366,13 @@ int EVP_PKEY_derive_set_peer(EVP_PKEY_CTX *ctx, EVP_PKEY *peer) {
if (!ctx || !ctx->pmeth ||
!(ctx->pmeth->derive || ctx->pmeth->encrypt || ctx->pmeth->decrypt) ||
!ctx->pmeth->ctrl) {
- OPENSSL_PUT_ERROR(EVP, EVP_PKEY_derive_set_peer,
- EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
+ OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
return 0;
}
if (ctx->operation != EVP_PKEY_OP_DERIVE &&
ctx->operation != EVP_PKEY_OP_ENCRYPT &&
ctx->operation != EVP_PKEY_OP_DECRYPT) {
- OPENSSL_PUT_ERROR(EVP, EVP_PKEY_derive_set_peer,
- EVP_R_OPERATON_NOT_INITIALIZED);
+ OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATON_NOT_INITIALIZED);
return 0;
}
@@ -400,12 +387,12 @@ int EVP_PKEY_derive_set_peer(EVP_PKEY_CTX *ctx, EVP_PKEY *peer) {
}
if (!ctx->pkey) {
- OPENSSL_PUT_ERROR(EVP, EVP_PKEY_derive_set_peer, EVP_R_NO_KEY_SET);
+ OPENSSL_PUT_ERROR(EVP, EVP_R_NO_KEY_SET);
return 0;
}
if (ctx->pkey->type != peer->type) {
- OPENSSL_PUT_ERROR(EVP, EVP_PKEY_derive_set_peer, EVP_R_DIFFERENT_KEY_TYPES);
+ OPENSSL_PUT_ERROR(EVP, EVP_R_DIFFERENT_KEY_TYPES);
return 0;
}
@@ -416,8 +403,7 @@ int EVP_PKEY_derive_set_peer(EVP_PKEY_CTX *ctx, EVP_PKEY *peer) {
* -2 is OK for us here, as well as 1, so we can check for 0 only. */
if (!EVP_PKEY_missing_parameters(peer) &&
!EVP_PKEY_cmp_parameters(ctx->pkey, peer)) {
- OPENSSL_PUT_ERROR(EVP, EVP_PKEY_derive_set_peer,
- EVP_R_DIFFERENT_PARAMETERS);
+ OPENSSL_PUT_ERROR(EVP, EVP_R_DIFFERENT_PARAMETERS);
return 0;
}
@@ -437,12 +423,11 @@ int EVP_PKEY_derive_set_peer(EVP_PKEY_CTX *ctx, EVP_PKEY *peer) {
int EVP_PKEY_derive(EVP_PKEY_CTX *ctx, uint8_t *key, size_t *out_key_len) {
if (!ctx || !ctx->pmeth || !ctx->pmeth->derive) {
- OPENSSL_PUT_ERROR(EVP, EVP_PKEY_derive,
- EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
+ OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
return 0;
}
if (ctx->operation != EVP_PKEY_OP_DERIVE) {
- OPENSSL_PUT_ERROR(EVP, EVP_PKEY_derive, EVP_R_OPERATON_NOT_INITIALIZED);
+ OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATON_NOT_INITIALIZED);
return 0;
}
return ctx->pmeth->derive(ctx, key, out_key_len);
@@ -450,8 +435,7 @@ int EVP_PKEY_derive(EVP_PKEY_CTX *ctx, uint8_t *key, size_t *out_key_len) {
int EVP_PKEY_keygen_init(EVP_PKEY_CTX *ctx) {
if (!ctx || !ctx->pmeth || !ctx->pmeth->keygen) {
- OPENSSL_PUT_ERROR(EVP, EVP_PKEY_keygen_init,
- EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
+ OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
return 0;
}
ctx->operation = EVP_PKEY_OP_KEYGEN;
@@ -467,12 +451,11 @@ int EVP_PKEY_keygen_init(EVP_PKEY_CTX *ctx) {
int EVP_PKEY_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY **ppkey) {
if (!ctx || !ctx->pmeth || !ctx->pmeth->keygen) {
- OPENSSL_PUT_ERROR(EVP, EVP_PKEY_keygen,
- EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
+ OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE);
return 0;
}
if (ctx->operation != EVP_PKEY_OP_KEYGEN) {
- OPENSSL_PUT_ERROR(EVP, EVP_PKEY_keygen, EVP_R_OPERATON_NOT_INITIALIZED);
+ OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATON_NOT_INITIALIZED);
return 0;
}
@@ -483,7 +466,7 @@ int EVP_PKEY_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY **ppkey) {
if (!*ppkey) {
*ppkey = EVP_PKEY_new();
if (!*ppkey) {
- OPENSSL_PUT_ERROR(EVP, EVP_PKEY_keygen, ERR_LIB_EVP);
+ OPENSSL_PUT_ERROR(EVP, ERR_LIB_EVP);
return 0;
}
}
diff --git a/src/crypto/evp/evp_extra_test.cc b/src/crypto/evp/evp_extra_test.cc
index 674547d..9c955fa 100644
--- a/src/crypto/evp/evp_extra_test.cc
+++ b/src/crypto/evp/evp_extra_test.cc
@@ -322,8 +322,8 @@ static const uint8_t kExampleBadECKeyDER[] = {
};
static ScopedEVP_PKEY LoadExampleRSAKey() {
- const uint8_t *derp = kExampleRSAKeyDER;
- ScopedRSA rsa(d2i_RSAPrivateKey(nullptr, &derp, sizeof(kExampleRSAKeyDER)));
+ ScopedRSA rsa(RSA_private_key_from_bytes(kExampleRSAKeyDER,
+ sizeof(kExampleRSAKeyDER)));
if (!rsa) {
return nullptr;
}
diff --git a/src/crypto/evp/evp_test.cc b/src/crypto/evp/evp_test.cc
index 239f868..c7ac908 100644
--- a/src/crypto/evp/evp_test.cc
+++ b/src/crypto/evp/evp_test.cc
@@ -56,10 +56,19 @@
#include <stdlib.h>
#include <string.h>
+#if defined(_MSC_VER)
+#pragma warning(push)
+#pragma warning(disable: 4702)
+#endif
+
#include <map>
#include <string>
#include <vector>
+#if defined(_MSC_VER)
+#pragma warning(pop)
+#endif
+
#include <openssl/bio.h>
#include <openssl/crypto.h>
#include <openssl/digest.h>
@@ -72,11 +81,10 @@
#include "../test/stl_compat.h"
-// evp_test dispatches between multiple test types. HMAC tests test the legacy
-// EVP_PKEY_HMAC API. PrivateKey tests take a key name parameter and single
-// block, decode it as a PEM private key, and save it under that key name.
-// Decrypt, Sign, and Verify tests take a previously imported key name as
-// parameter and test their respective operations.
+// evp_test dispatches between multiple test types. PrivateKey tests take a key
+// name parameter and single block, decode it as a PEM private key, and save it
+// under that key name. Decrypt, Sign, and Verify tests take a previously
+// imported key name as parameter and test their respective operations.
static const EVP_MD *GetDigest(FileTest *t, const std::string &name) {
if (name == "MD5") {
@@ -120,54 +128,10 @@ static bool ImportPrivateKey(FileTest *t, KeyMap *key_map) {
return true;
}
-static bool TestHMAC(FileTest *t) {
- std::string digest_str;
- if (!t->GetAttribute(&digest_str, "HMAC")) {
- return false;
- }
- const EVP_MD *digest = GetDigest(t, digest_str);
- if (digest == nullptr) {
- return false;
- }
-
- std::vector<uint8_t> key, input, output;
- if (!t->GetBytes(&key, "Key") ||
- !t->GetBytes(&input, "Input") ||
- !t->GetBytes(&output, "Output")) {
- return false;
- }
-
- ScopedEVP_PKEY pkey(EVP_PKEY_new_mac_key(EVP_PKEY_HMAC, nullptr,
- bssl::vector_data(&key),
- key.size()));
- ScopedEVP_MD_CTX mctx;
- if (!pkey ||
- !EVP_DigestSignInit(mctx.get(), nullptr, digest, nullptr, pkey.get()) ||
- !EVP_DigestSignUpdate(mctx.get(), bssl::vector_data(&input),
- input.size())) {
- return false;
- }
-
- size_t len;
- std::vector<uint8_t> actual;
- if (!EVP_DigestSignFinal(mctx.get(), nullptr, &len)) {
- return false;
- }
- actual.resize(len);
- if (!EVP_DigestSignFinal(mctx.get(), bssl::vector_data(&actual), &len)) {
- return false;
- }
- actual.resize(len);
- return t->ExpectBytesEqual(bssl::vector_data(&output), output.size(),
- bssl::vector_data(&actual), actual.size());
-}
-
static bool TestEVP(FileTest *t, void *arg) {
KeyMap *key_map = reinterpret_cast<KeyMap*>(arg);
if (t->GetType() == "PrivateKey") {
return ImportPrivateKey(t, key_map);
- } else if (t->GetType() == "HMAC") {
- return TestHMAC(t);
}
int (*key_op_init)(EVP_PKEY_CTX *ctx);
@@ -219,7 +183,7 @@ static bool TestEVP(FileTest *t, void *arg) {
bssl::vector_data(&input), input.size())) {
// ECDSA sometimes doesn't push an error code. Push one on the error queue
// so it's distinguishable from other errors.
- ERR_put_error(ERR_LIB_USER, 0, ERR_R_EVP_LIB, __FILE__, __LINE__);
+ OPENSSL_PUT_ERROR(USER, ERR_R_EVP_LIB);
return false;
}
return true;
diff --git a/src/crypto/evp/evp_tests.txt b/src/crypto/evp/evp_tests.txt
index cccfa4f..97ddaa0 100644
--- a/src/crypto/evp/evp_tests.txt
+++ b/src/crypto/evp/evp_tests.txt
@@ -163,12 +163,11 @@ Digest = SHA1
Input = "0123456789ABCDEF1234"
Output = 3045022100b1d1cb1a577035bccdd5a86c6148c2cc7c633cd42b7234139b593076d041e15202201898cdd52b41ca502098184b409cf83a21bc945006746e3b7cea52234e043ec800
# This operation fails without an error code, so ERR_R_EVP_LIB is surfaced.
-Error = public key routines
+Error = BAD_SIGNATURE
# BER signature
Verify = P-256
Digest = SHA1
Input = "0123456789ABCDEF1234"
Output = 3080022100b1d1cb1a577035bccdd5a86c6148c2cc7c633cd42b7234139b593076d041e15202201898cdd52b41ca502098184b409cf83a21bc945006746e3b7cea52234e043ec80000
-# This operation fails without an error code, so ERR_R_EVP_LIB is surfaced.
-Error = public key routines
+Error = BAD_SIGNATURE
diff --git a/src/crypto/evp/internal.h b/src/crypto/evp/internal.h
index 08a7bfb..60881e3 100644
--- a/src/crypto/evp/internal.h
+++ b/src/crypto/evp/internal.h
@@ -89,8 +89,7 @@ struct evp_pkey_asn1_method_st {
int pkey_base_id;
unsigned long pkey_flags;
- char *pem_str;
- char *info;
+ const char *pem_str;
int (*pub_decode)(EVP_PKEY *pk, X509_PUBKEY *pub);
int (*pub_encode)(X509_PUBKEY *pub, const EVP_PKEY *pk);
@@ -115,8 +114,8 @@ struct evp_pkey_asn1_method_st {
int (*pkey_size)(const EVP_PKEY *pk);
int (*pkey_bits)(const EVP_PKEY *pk);
- int (*param_decode)(EVP_PKEY *pkey, const unsigned char **pder, int derlen);
- int (*param_encode)(const EVP_PKEY *pkey, unsigned char **pder);
+ int (*param_decode)(EVP_PKEY *pkey, const uint8_t **pder, int derlen);
+ int (*param_encode)(const EVP_PKEY *pkey, uint8_t **pder);
int (*param_missing)(const EVP_PKEY *pk);
int (*param_copy)(EVP_PKEY *to, const EVP_PKEY *from);
int (*param_cmp)(const EVP_PKEY *a, const EVP_PKEY *b);
@@ -130,9 +129,9 @@ struct evp_pkey_asn1_method_st {
/* Legacy functions for old PEM */
- int (*old_priv_decode)(EVP_PKEY *pkey, const unsigned char **pder,
+ int (*old_priv_decode)(EVP_PKEY *pkey, const uint8_t **pder,
int derlen);
- int (*old_priv_encode)(const EVP_PKEY *pkey, unsigned char **pder);
+ int (*old_priv_encode)(const EVP_PKEY *pkey, uint8_t **pder);
/* Converting parameters to/from AlgorithmIdentifier (X509_ALGOR). */
int (*digest_verify_init_from_algorithm)(EVP_MD_CTX *ctx,
@@ -153,15 +152,12 @@ typedef int EVP_PKEY_gen_cb(EVP_PKEY_CTX *ctx);
#define EVP_PKEY_OP_SIGN (1 << 3)
#define EVP_PKEY_OP_VERIFY (1 << 4)
#define EVP_PKEY_OP_VERIFYRECOVER (1 << 5)
-#define EVP_PKEY_OP_SIGNCTX (1 << 6)
-#define EVP_PKEY_OP_VERIFYCTX (1 << 7)
-#define EVP_PKEY_OP_ENCRYPT (1 << 8)
-#define EVP_PKEY_OP_DECRYPT (1 << 9)
-#define EVP_PKEY_OP_DERIVE (1 << 10)
+#define EVP_PKEY_OP_ENCRYPT (1 << 6)
+#define EVP_PKEY_OP_DECRYPT (1 << 7)
+#define EVP_PKEY_OP_DERIVE (1 << 8)
#define EVP_PKEY_OP_TYPE_SIG \
- (EVP_PKEY_OP_SIGN | EVP_PKEY_OP_VERIFY | EVP_PKEY_OP_VERIFYRECOVER | \
- EVP_PKEY_OP_SIGNCTX | EVP_PKEY_OP_VERIFYCTX)
+ (EVP_PKEY_OP_SIGN | EVP_PKEY_OP_VERIFY | EVP_PKEY_OP_VERIFYRECOVER)
#define EVP_PKEY_OP_TYPE_CRYPT (EVP_PKEY_OP_ENCRYPT | EVP_PKEY_OP_DECRYPT)
@@ -181,13 +177,8 @@ typedef int EVP_PKEY_gen_cb(EVP_PKEY_CTX *ctx);
OPENSSL_EXPORT int EVP_PKEY_CTX_ctrl(EVP_PKEY_CTX *ctx, int keytype, int optype,
int cmd, int p1, void *p2);
-/* EVP_PKEY_CTRL_DIGESTINIT is an internal value. It's called by
- * EVP_DigestInit_ex to signal the |EVP_PKEY| that a digest operation is
- * starting.
- *
- * TODO(davidben): This is only needed to support the deprecated HMAC |EVP_PKEY|
- * types. */
-#define EVP_PKEY_CTRL_DIGESTINIT 3
+#define EVP_PKEY_CTRL_MD 1
+#define EVP_PKEY_CTRL_GET_MD 2
/* EVP_PKEY_CTRL_PEER_KEY is called with different values of |p1|:
* 0: Is called from |EVP_PKEY_derive_set_peer| and |p2| contains a peer key.
@@ -198,21 +189,12 @@ OPENSSL_EXPORT int EVP_PKEY_CTX_ctrl(EVP_PKEY_CTX *ctx, int keytype, int optype,
* (EC)DH always return one in this case.
* 3: Is called with |p2| == NULL to set whether the peer's key was used.
* (EC)DH always return one in this case. This was only used for GOST. */
-#define EVP_PKEY_CTRL_PEER_KEY 4
-
-/* EVP_PKEY_CTRL_SET_MAC_KEY sets a MAC key. For example, this can be done an
- * |EVP_PKEY_CTX| prior to calling |EVP_PKEY_keygen| in order to generate an
- * HMAC |EVP_PKEY| with the given key. It returns one on success and zero on
- * error. */
-#define EVP_PKEY_CTRL_SET_MAC_KEY 5
+#define EVP_PKEY_CTRL_PEER_KEY 3
/* EVP_PKEY_ALG_CTRL is the base value from which key-type specific ctrl
* commands are numbered. */
#define EVP_PKEY_ALG_CTRL 0x1000
-#define EVP_PKEY_CTRL_MD 1
-#define EVP_PKEY_CTRL_GET_MD 2
-
#define EVP_PKEY_CTRL_RSA_PADDING (EVP_PKEY_ALG_CTRL + 1)
#define EVP_PKEY_CTRL_GET_RSA_PADDING (EVP_PKEY_ALG_CTRL + 2)
#define EVP_PKEY_CTRL_RSA_PSS_SALTLEN (EVP_PKEY_ALG_CTRL + 3)
@@ -260,34 +242,25 @@ struct evp_pkey_method_st {
int (*keygen)(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey);
int (*sign_init)(EVP_PKEY_CTX *ctx);
- int (*sign)(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen,
- const unsigned char *tbs, size_t tbslen);
+ int (*sign)(EVP_PKEY_CTX *ctx, uint8_t *sig, size_t *siglen,
+ const uint8_t *tbs, size_t tbslen);
int (*verify_init)(EVP_PKEY_CTX *ctx);
- int (*verify)(EVP_PKEY_CTX *ctx, const unsigned char *sig, size_t siglen,
- const unsigned char *tbs, size_t tbslen);
-
- int (*signctx_init)(EVP_PKEY_CTX *ctx, EVP_MD_CTX *mctx);
- int (*signctx)(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen,
- EVP_MD_CTX *mctx);
-
- int (*verifyctx_init)(EVP_PKEY_CTX *ctx, EVP_MD_CTX *mctx);
- int (*verifyctx)(EVP_PKEY_CTX *ctx, const unsigned char *sig, int siglen,
- EVP_MD_CTX *mctx);
+ int (*verify)(EVP_PKEY_CTX *ctx, const uint8_t *sig, size_t siglen,
+ const uint8_t *tbs, size_t tbslen);
int (*encrypt_init)(EVP_PKEY_CTX *ctx);
- int (*encrypt)(EVP_PKEY_CTX *ctx, unsigned char *out, size_t *outlen,
- const unsigned char *in, size_t inlen);
+ int (*encrypt)(EVP_PKEY_CTX *ctx, uint8_t *out, size_t *outlen,
+ const uint8_t *in, size_t inlen);
int (*decrypt_init)(EVP_PKEY_CTX *ctx);
- int (*decrypt)(EVP_PKEY_CTX *ctx, unsigned char *out, size_t *outlen,
- const unsigned char *in, size_t inlen);
+ int (*decrypt)(EVP_PKEY_CTX *ctx, uint8_t *out, size_t *outlen,
+ const uint8_t *in, size_t inlen);
int (*derive_init)(EVP_PKEY_CTX *ctx);
- int (*derive)(EVP_PKEY_CTX *ctx, unsigned char *key, size_t *keylen);
+ int (*derive)(EVP_PKEY_CTX *ctx, uint8_t *key, size_t *keylen);
int (*ctrl)(EVP_PKEY_CTX *ctx, int type, int p1, void *p2);
- int (*ctrl_str)(EVP_PKEY_CTX *ctx, const char *type, const char *value);
} /* EVP_PKEY_METHOD */;
diff --git a/src/crypto/evp/p_dsa_asn1.c b/src/crypto/evp/p_dsa_asn1.c
index 826d4e4..4790cf6 100644
--- a/src/crypto/evp/p_dsa_asn1.c
+++ b/src/crypto/evp/p_dsa_asn1.c
@@ -91,29 +91,29 @@ static int dsa_pub_decode(EVP_PKEY *pkey, X509_PUBKEY *pubkey) {
dsa = d2i_DSAparams(NULL, &pm, pmlen);
if (dsa == NULL) {
- OPENSSL_PUT_ERROR(EVP, dsa_pub_decode, EVP_R_DECODE_ERROR);
+ OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR);
goto err;
}
} else if (ptype == V_ASN1_NULL || ptype == V_ASN1_UNDEF) {
dsa = DSA_new();
if (dsa == NULL) {
- OPENSSL_PUT_ERROR(EVP, dsa_pub_decode, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(EVP, ERR_R_MALLOC_FAILURE);
goto err;
}
} else {
- OPENSSL_PUT_ERROR(EVP, dsa_pub_decode, EVP_R_PARAMETER_ENCODING_ERROR);
+ OPENSSL_PUT_ERROR(EVP, EVP_R_PARAMETER_ENCODING_ERROR);
goto err;
}
public_key = d2i_ASN1_INTEGER(NULL, &p, pklen);
if (public_key == NULL) {
- OPENSSL_PUT_ERROR(EVP, dsa_pub_decode, EVP_R_DECODE_ERROR);
+ OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR);
goto err;
}
dsa->pub_key = ASN1_INTEGER_to_BN(public_key, NULL);
if (dsa->pub_key == NULL) {
- OPENSSL_PUT_ERROR(EVP, dsa_pub_decode, EVP_R_BN_DECODE_ERROR);
+ OPENSSL_PUT_ERROR(EVP, EVP_R_BN_DECODE_ERROR);
goto err;
}
@@ -140,12 +140,12 @@ static int dsa_pub_encode(X509_PUBKEY *pk, const EVP_PKEY *pkey) {
if (dsa->p && dsa->q && dsa->g) {
pval = ASN1_STRING_new();
if (!pval) {
- OPENSSL_PUT_ERROR(EVP, dsa_pub_encode, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(EVP, ERR_R_MALLOC_FAILURE);
goto err;
}
pval->length = i2d_DSAparams(dsa, &pval->data);
if (pval->length <= 0) {
- OPENSSL_PUT_ERROR(EVP, dsa_pub_encode, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(EVP, ERR_R_MALLOC_FAILURE);
goto err;
}
ptype = V_ASN1_SEQUENCE;
@@ -155,7 +155,7 @@ static int dsa_pub_encode(X509_PUBKEY *pk, const EVP_PKEY *pkey) {
penclen = i2d_DSAPublicKey(dsa, &penc);
if (penclen <= 0) {
- OPENSSL_PUT_ERROR(EVP, dsa_pub_encode, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(EVP, ERR_R_MALLOC_FAILURE);
goto err;
}
@@ -252,23 +252,23 @@ static int dsa_priv_decode(EVP_PKEY *pkey, PKCS8_PRIV_KEY_INFO *p8) {
/* We have parameters. Now set private key */
dsa->priv_key = ASN1_INTEGER_to_BN(privkey, NULL);
if (dsa->priv_key == NULL) {
- OPENSSL_PUT_ERROR(EVP, dsa_priv_decode, ERR_LIB_BN);
+ OPENSSL_PUT_ERROR(EVP, ERR_LIB_BN);
goto dsaerr;
}
/* Calculate public key. */
dsa->pub_key = BN_new();
if (dsa->pub_key == NULL) {
- OPENSSL_PUT_ERROR(EVP, dsa_priv_decode, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(EVP, ERR_R_MALLOC_FAILURE);
goto dsaerr;
}
ctx = BN_CTX_new();
if (ctx == NULL) {
- OPENSSL_PUT_ERROR(EVP, dsa_priv_decode, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(EVP, ERR_R_MALLOC_FAILURE);
goto dsaerr;
}
if (!BN_mod_exp(dsa->pub_key, dsa->g, dsa->priv_key, dsa->p, ctx)) {
- OPENSSL_PUT_ERROR(EVP, dsa_priv_decode, ERR_LIB_BN);
+ OPENSSL_PUT_ERROR(EVP, ERR_LIB_BN);
goto dsaerr;
}
@@ -280,7 +280,7 @@ static int dsa_priv_decode(EVP_PKEY *pkey, PKCS8_PRIV_KEY_INFO *p8) {
return 1;
decerr:
- OPENSSL_PUT_ERROR(EVP, dsa_priv_decode, EVP_R_DECODE_ERROR);
+ OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR);
dsaerr:
BN_CTX_free(ctx);
@@ -297,19 +297,19 @@ static int dsa_priv_encode(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pkey) {
int dplen;
if (!pkey->pkey.dsa || !pkey->pkey.dsa->priv_key) {
- OPENSSL_PUT_ERROR(EVP, dsa_priv_encode, EVP_R_MISSING_PARAMETERS);
+ OPENSSL_PUT_ERROR(EVP, EVP_R_MISSING_PARAMETERS);
goto err;
}
params = ASN1_STRING_new();
if (!params) {
- OPENSSL_PUT_ERROR(EVP, dsa_priv_encode, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(EVP, ERR_R_MALLOC_FAILURE);
goto err;
}
params->length = i2d_DSAparams(pkey->pkey.dsa, &params->data);
if (params->length <= 0) {
- OPENSSL_PUT_ERROR(EVP, dsa_priv_encode, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(EVP, ERR_R_MALLOC_FAILURE);
goto err;
}
params->type = V_ASN1_SEQUENCE;
@@ -318,13 +318,14 @@ static int dsa_priv_encode(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pkey) {
prkey = BN_to_ASN1_INTEGER(pkey->pkey.dsa->priv_key, NULL);
if (!prkey) {
- OPENSSL_PUT_ERROR(EVP, dsa_priv_encode, ERR_LIB_BN);
+ OPENSSL_PUT_ERROR(EVP, ERR_LIB_BN);
goto err;
}
dplen = i2d_ASN1_INTEGER(prkey, &dp);
ASN1_INTEGER_free(prkey);
+ prkey = NULL;
if (!PKCS8_pkey_set0(p8, (ASN1_OBJECT *)OBJ_nid2obj(NID_dsa), 0,
V_ASN1_SEQUENCE, params, dp, dplen)) {
@@ -437,7 +438,7 @@ static int do_dsa_print(BIO *bp, const DSA *x, int off, int ptype) {
m = (uint8_t *)OPENSSL_malloc(buf_len + 10);
if (m == NULL) {
- OPENSSL_PUT_ERROR(EVP, do_dsa_print, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(EVP, ERR_R_MALLOC_FAILURE);
goto err;
}
@@ -466,7 +467,7 @@ static int dsa_param_decode(EVP_PKEY *pkey, const uint8_t **pder, int derlen) {
DSA *dsa;
dsa = d2i_DSAparams(NULL, pder, derlen);
if (dsa == NULL) {
- OPENSSL_PUT_ERROR(EVP, dsa_param_decode, ERR_R_DSA_LIB);
+ OPENSSL_PUT_ERROR(EVP, ERR_R_DSA_LIB);
return 0;
}
EVP_PKEY_assign_DSA(pkey, dsa);
@@ -497,7 +498,7 @@ static int old_dsa_priv_decode(EVP_PKEY *pkey, const uint8_t **pder,
DSA *dsa;
dsa = d2i_DSAPrivateKey(NULL, pder, derlen);
if (dsa == NULL) {
- OPENSSL_PUT_ERROR(EVP, old_dsa_priv_decode, ERR_R_DSA_LIB);
+ OPENSSL_PUT_ERROR(EVP, ERR_R_DSA_LIB);
return 0;
}
EVP_PKEY_assign_DSA(pkey, dsa);
@@ -531,7 +532,7 @@ static int dsa_sig_print(BIO *bp, const X509_ALGOR *sigalg,
update_buflen(dsa_sig->s, &buf_len);
m = OPENSSL_malloc(buf_len + 10);
if (m == NULL) {
- OPENSSL_PUT_ERROR(EVP, dsa_sig_print, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(EVP, ERR_R_MALLOC_FAILURE);
goto err;
}
@@ -554,7 +555,6 @@ const EVP_PKEY_ASN1_METHOD dsa_asn1_meth = {
0,
"DSA",
- "OpenSSL DSA method",
dsa_pub_decode,
dsa_pub_encode,
diff --git a/src/crypto/evp/p_ec.c b/src/crypto/evp/p_ec.c
index 73c00d8..77f213d 100644
--- a/src/crypto/evp/p_ec.c
+++ b/src/crypto/evp/p_ec.c
@@ -125,25 +125,18 @@ static void pkey_ec_cleanup(EVP_PKEY_CTX *ctx) {
static int pkey_ec_sign(EVP_PKEY_CTX *ctx, uint8_t *sig, size_t *siglen,
const uint8_t *tbs, size_t tbslen) {
- int type;
unsigned int sltmp;
- EC_PKEY_CTX *dctx = ctx->data;
EC_KEY *ec = ctx->pkey->pkey.ec;
if (!sig) {
*siglen = ECDSA_size(ec);
return 1;
} else if (*siglen < (size_t)ECDSA_size(ec)) {
- OPENSSL_PUT_ERROR(EVP, pkey_ec_sign, EVP_R_BUFFER_TOO_SMALL);
+ OPENSSL_PUT_ERROR(EVP, EVP_R_BUFFER_TOO_SMALL);
return 0;
}
- type = NID_sha1;
- if (dctx->md) {
- type = EVP_MD_type(dctx->md);
- }
-
- if (!ECDSA_sign(type, tbs, tbslen, sig, &sltmp, ec)) {
+ if (!ECDSA_sign(0, tbs, tbslen, sig, &sltmp, ec)) {
return 0;
}
*siglen = (size_t)sltmp;
@@ -152,16 +145,7 @@ static int pkey_ec_sign(EVP_PKEY_CTX *ctx, uint8_t *sig, size_t *siglen,
static int pkey_ec_verify(EVP_PKEY_CTX *ctx, const uint8_t *sig, size_t siglen,
const uint8_t *tbs, size_t tbslen) {
- int type;
- EC_PKEY_CTX *dctx = ctx->data;
- EC_KEY *ec = ctx->pkey->pkey.ec;
-
- type = NID_sha1;
- if (dctx->md) {
- type = EVP_MD_type(dctx->md);
- }
-
- return ECDSA_verify(type, tbs, tbslen, sig, siglen, ec);
+ return ECDSA_verify(0, tbs, tbslen, sig, siglen, ctx->pkey->pkey.ec);
}
static int pkey_ec_derive(EVP_PKEY_CTX *ctx, uint8_t *key,
@@ -172,7 +156,7 @@ static int pkey_ec_derive(EVP_PKEY_CTX *ctx, uint8_t *key,
EC_KEY *eckey;
if (!ctx->pkey || !ctx->peerkey) {
- OPENSSL_PUT_ERROR(EVP, pkey_ec_derive, EVP_R_KEYS_NOT_SET);
+ OPENSSL_PUT_ERROR(EVP, EVP_R_KEYS_NOT_SET);
return 0;
}
@@ -207,7 +191,7 @@ static int pkey_ec_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) {
case EVP_PKEY_CTRL_EC_PARAMGEN_CURVE_NID:
group = EC_GROUP_new_by_curve_name(p1);
if (group == NULL) {
- OPENSSL_PUT_ERROR(EVP, pkey_ec_ctrl, EVP_R_INVALID_CURVE);
+ OPENSSL_PUT_ERROR(EVP, EVP_R_INVALID_CURVE);
return 0;
}
EC_GROUP_free(dctx->gen_group);
@@ -221,7 +205,7 @@ static int pkey_ec_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) {
EVP_MD_type((const EVP_MD *)p2) != NID_sha256 &&
EVP_MD_type((const EVP_MD *)p2) != NID_sha384 &&
EVP_MD_type((const EVP_MD *)p2) != NID_sha512) {
- OPENSSL_PUT_ERROR(EVP, pkey_ec_ctrl, EVP_R_INVALID_DIGEST_TYPE);
+ OPENSSL_PUT_ERROR(EVP, EVP_R_INVALID_DIGEST_TYPE);
return 0;
}
dctx->md = p2;
@@ -232,12 +216,11 @@ static int pkey_ec_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) {
return 1;
case EVP_PKEY_CTRL_PEER_KEY:
- /* Default behaviour is OK */
- case EVP_PKEY_CTRL_DIGESTINIT:
+ /* Default behaviour is OK */
return 1;
default:
- OPENSSL_PUT_ERROR(EVP, pkey_ec_ctrl, EVP_R_COMMAND_NOT_SUPPORTED);
+ OPENSSL_PUT_ERROR(EVP, EVP_R_COMMAND_NOT_SUPPORTED);
return 0;
}
}
@@ -248,7 +231,7 @@ static int pkey_ec_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) {
int ret = 0;
if (dctx->gen_group == NULL) {
- OPENSSL_PUT_ERROR(EVP, pkey_ec_paramgen, EVP_R_NO_PARAMETERS_SET);
+ OPENSSL_PUT_ERROR(EVP, EVP_R_NO_PARAMETERS_SET);
return 0;
}
ec = EC_KEY_new();
@@ -268,7 +251,7 @@ static int pkey_ec_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) {
EC_KEY *ec = NULL;
EC_PKEY_CTX *dctx = ctx->data;
if (ctx->pkey == NULL && dctx->gen_group == NULL) {
- OPENSSL_PUT_ERROR(EVP, pkey_ec_keygen, EVP_R_NO_PARAMETERS_SET);
+ OPENSSL_PUT_ERROR(EVP, EVP_R_NO_PARAMETERS_SET);
return 0;
}
ec = EC_KEY_new();
@@ -290,12 +273,11 @@ static int pkey_ec_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) {
}
const EVP_PKEY_METHOD ec_pkey_meth = {
- EVP_PKEY_EC, 0 /* flags */, pkey_ec_init,
- pkey_ec_copy, pkey_ec_cleanup, 0 /* paramgen_init */,
- pkey_ec_paramgen, 0 /* keygen_init */, pkey_ec_keygen,
- 0 /* sign_init */, pkey_ec_sign, 0 /* verify_init */,
- pkey_ec_verify, 0 /* signctx_init */, 0 /* signctx */,
- 0 /* verifyctx_init */, 0 /* verifyctx */, 0 /* encrypt_init */,
- 0 /* encrypt */, 0 /* decrypt_init */, 0 /* decrypt */,
- 0 /* derive_init */, pkey_ec_derive, pkey_ec_ctrl,
+ EVP_PKEY_EC, 0 /* flags */, pkey_ec_init,
+ pkey_ec_copy, pkey_ec_cleanup, 0 /* paramgen_init */,
+ pkey_ec_paramgen, 0 /* keygen_init */, pkey_ec_keygen,
+ 0 /* sign_init */, pkey_ec_sign, 0 /* verify_init */,
+ pkey_ec_verify, 0 /* encrypt_init */, 0 /* encrypt */,
+ 0 /* decrypt_init */, 0 /* decrypt */, 0 /* derive_init */,
+ pkey_ec_derive, pkey_ec_ctrl,
};
diff --git a/src/crypto/evp/p_ec_asn1.c b/src/crypto/evp/p_ec_asn1.c
index fbbf4e7..9867947 100644
--- a/src/crypto/evp/p_ec_asn1.c
+++ b/src/crypto/evp/p_ec_asn1.c
@@ -71,13 +71,13 @@ static int eckey_param2type(int *pptype, void **ppval, EC_KEY *ec_key) {
int nid;
if (ec_key == NULL || (group = EC_KEY_get0_group(ec_key)) == NULL) {
- OPENSSL_PUT_ERROR(EVP, eckey_param2type, EVP_R_MISSING_PARAMETERS);
+ OPENSSL_PUT_ERROR(EVP, EVP_R_MISSING_PARAMETERS);
return 0;
}
nid = EC_GROUP_get_curve_name(group);
if (nid == NID_undef) {
- OPENSSL_PUT_ERROR(EVP, eckey_param2type, EVP_R_NO_NID_FOR_CURVE);
+ OPENSSL_PUT_ERROR(EVP, EVP_R_NO_NID_FOR_CURVE);
return 0;
}
@@ -94,7 +94,7 @@ static int eckey_pub_encode(X509_PUBKEY *pk, const EVP_PKEY *pkey) {
int penclen;
if (!eckey_param2type(&ptype, &pval, ec_key)) {
- OPENSSL_PUT_ERROR(EVP, eckey_pub_encode, ERR_R_EC_LIB);
+ OPENSSL_PUT_ERROR(EVP, ERR_R_EC_LIB);
return 0;
}
penclen = i2o_ECPublicKey(ec_key, NULL);
@@ -137,7 +137,7 @@ static EC_KEY *eckey_type2param(int ptype, void *pval) {
eckey = d2i_ECParameters(NULL, &pm, pmlen);
if (eckey == NULL) {
- OPENSSL_PUT_ERROR(EVP, eckey_type2param, EVP_R_DECODE_ERROR);
+ OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR);
goto err;
}
} else if (ptype == V_ASN1_OBJECT) {
@@ -150,7 +150,7 @@ static EC_KEY *eckey_type2param(int ptype, void *pval) {
goto err;
}
} else {
- OPENSSL_PUT_ERROR(EVP, eckey_type2param, EVP_R_DECODE_ERROR);
+ OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR);
goto err;
}
@@ -177,13 +177,13 @@ static int eckey_pub_decode(EVP_PKEY *pkey, X509_PUBKEY *pubkey) {
eckey = eckey_type2param(ptype, pval);
if (!eckey) {
- OPENSSL_PUT_ERROR(EVP, eckey_pub_decode, ERR_R_EC_LIB);
+ OPENSSL_PUT_ERROR(EVP, ERR_R_EC_LIB);
return 0;
}
/* We have parameters now set public key */
if (!o2i_ECPublicKey(&eckey, &p, pklen)) {
- OPENSSL_PUT_ERROR(EVP, eckey_pub_decode, EVP_R_DECODE_ERROR);
+ OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR);
goto err;
}
@@ -232,7 +232,7 @@ static int eckey_priv_decode(EVP_PKEY *pkey, PKCS8_PRIV_KEY_INFO *p8) {
/* We have parameters now set private key */
if (!d2i_ECPrivateKey(&eckey, &p, pklen)) {
- OPENSSL_PUT_ERROR(EVP, eckey_priv_decode, EVP_R_DECODE_ERROR);
+ OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR);
goto ecerr;
}
@@ -246,23 +246,23 @@ static int eckey_priv_decode(EVP_PKEY *pkey, PKCS8_PRIV_KEY_INFO *p8) {
group = EC_KEY_get0_group(eckey);
pub_key = EC_POINT_new(group);
if (pub_key == NULL) {
- OPENSSL_PUT_ERROR(EVP, eckey_priv_decode, ERR_R_EC_LIB);
+ OPENSSL_PUT_ERROR(EVP, ERR_R_EC_LIB);
goto ecliberr;
}
if (!EC_POINT_copy(pub_key, EC_GROUP_get0_generator(group))) {
EC_POINT_free(pub_key);
- OPENSSL_PUT_ERROR(EVP, eckey_priv_decode, ERR_R_EC_LIB);
+ OPENSSL_PUT_ERROR(EVP, ERR_R_EC_LIB);
goto ecliberr;
}
priv_key = EC_KEY_get0_private_key(eckey);
if (!EC_POINT_mul(group, pub_key, priv_key, NULL, NULL, NULL)) {
EC_POINT_free(pub_key);
- OPENSSL_PUT_ERROR(EVP, eckey_priv_decode, ERR_R_EC_LIB);
+ OPENSSL_PUT_ERROR(EVP, ERR_R_EC_LIB);
goto ecliberr;
}
if (EC_KEY_set_public_key(eckey, pub_key) == 0) {
EC_POINT_free(pub_key);
- OPENSSL_PUT_ERROR(EVP, eckey_priv_decode, ERR_R_EC_LIB);
+ OPENSSL_PUT_ERROR(EVP, ERR_R_EC_LIB);
goto ecliberr;
}
EC_POINT_free(pub_key);
@@ -272,7 +272,7 @@ static int eckey_priv_decode(EVP_PKEY *pkey, PKCS8_PRIV_KEY_INFO *p8) {
return 1;
ecliberr:
- OPENSSL_PUT_ERROR(EVP, eckey_priv_decode, ERR_R_EC_LIB);
+ OPENSSL_PUT_ERROR(EVP, ERR_R_EC_LIB);
ecerr:
if (eckey) {
EC_KEY_free(eckey);
@@ -290,7 +290,7 @@ static int eckey_priv_encode(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pkey) {
ec_key = pkey->pkey.ec;
if (!eckey_param2type(&ptype, &pval, ec_key)) {
- OPENSSL_PUT_ERROR(EVP, eckey_priv_encode, EVP_R_DECODE_ERROR);
+ OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR);
return 0;
}
@@ -304,20 +304,20 @@ static int eckey_priv_encode(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pkey) {
eplen = i2d_ECPrivateKey(ec_key, NULL);
if (!eplen) {
EC_KEY_set_enc_flags(ec_key, old_flags);
- OPENSSL_PUT_ERROR(EVP, eckey_priv_encode, ERR_R_EC_LIB);
+ OPENSSL_PUT_ERROR(EVP, ERR_R_EC_LIB);
return 0;
}
ep = (uint8_t *)OPENSSL_malloc(eplen);
if (!ep) {
EC_KEY_set_enc_flags(ec_key, old_flags);
- OPENSSL_PUT_ERROR(EVP, eckey_priv_encode, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(EVP, ERR_R_MALLOC_FAILURE);
return 0;
}
p = ep;
if (!i2d_ECPrivateKey(ec_key, &p)) {
EC_KEY_set_enc_flags(ec_key, old_flags);
OPENSSL_free(ep);
- OPENSSL_PUT_ERROR(EVP, eckey_priv_encode, ERR_R_EC_LIB);
+ OPENSSL_PUT_ERROR(EVP, ERR_R_EC_LIB);
return 0;
}
/* restore old encoding flags */
@@ -325,6 +325,7 @@ static int eckey_priv_encode(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pkey) {
if (!PKCS8_pkey_set0(p8, (ASN1_OBJECT *)OBJ_nid2obj(NID_X9_62_id_ecPublicKey),
0, ptype, pval, ep, eplen)) {
+ OPENSSL_free(ep);
return 0;
}
@@ -478,7 +479,7 @@ static int do_EC_KEY_print(BIO *bp, const EC_KEY *x, int off, int ktype) {
err:
if (!ret) {
- OPENSSL_PUT_ERROR(EVP, do_EC_KEY_print, reason);
+ OPENSSL_PUT_ERROR(EVP, reason);
}
OPENSSL_free(pub_key_bytes);
BN_free(order);
@@ -491,7 +492,7 @@ static int eckey_param_decode(EVP_PKEY *pkey, const uint8_t **pder,
int derlen) {
EC_KEY *eckey;
if (!(eckey = d2i_ECParameters(NULL, pder, derlen))) {
- OPENSSL_PUT_ERROR(EVP, eckey_param_decode, ERR_R_EC_LIB);
+ OPENSSL_PUT_ERROR(EVP, ERR_R_EC_LIB);
return 0;
}
EVP_PKEY_assign_EC_KEY(pkey, eckey);
@@ -526,7 +527,7 @@ static int old_ec_priv_decode(EVP_PKEY *pkey, const uint8_t **pder,
int derlen) {
EC_KEY *ec;
if (!(ec = d2i_ECPrivateKey(NULL, pder, derlen))) {
- OPENSSL_PUT_ERROR(EVP, old_ec_priv_decode, EVP_R_DECODE_ERROR);
+ OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR);
return 0;
}
EVP_PKEY_assign_EC_KEY(pkey, ec);
@@ -542,7 +543,6 @@ const EVP_PKEY_ASN1_METHOD ec_asn1_meth = {
EVP_PKEY_EC,
0,
"EC",
- "OpenSSL EC algorithm",
eckey_pub_decode,
eckey_pub_encode,
diff --git a/src/crypto/evp/p_hmac.c b/src/crypto/evp/p_hmac.c
deleted file mode 100644
index 7d3254a..0000000
--- a/src/crypto/evp/p_hmac.c
+++ /dev/null
@@ -1,223 +0,0 @@
-/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
- * project 2007.
- */
-/* ====================================================================
- * Copyright (c) 2007 The OpenSSL Project. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in
- * the documentation and/or other materials provided with the
- * distribution.
- *
- * 3. All advertising materials mentioning features or use of this
- * software must display the following acknowledgment:
- * "This product includes software developed by the OpenSSL Project
- * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
- *
- * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
- * endorse or promote products derived from this software without
- * prior written permission. For written permission, please contact
- * licensing@OpenSSL.org.
- *
- * 5. Products derived from this software may not be called "OpenSSL"
- * nor may "OpenSSL" appear in their names without prior written
- * permission of the OpenSSL Project.
- *
- * 6. Redistributions of any form whatsoever must retain the following
- * acknowledgment:
- * "This product includes software developed by the OpenSSL Project
- * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
- *
- * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
- * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
- * OF THE POSSIBILITY OF SUCH DAMAGE.
- * ====================================================================
- *
- * This product includes cryptographic software written by Eric Young
- * (eay@cryptsoft.com). This product includes software written by Tim
- * Hudson (tjh@cryptsoft.com). */
-
-#include <openssl/evp.h>
-
-#include <string.h>
-
-#include <openssl/asn1.h>
-#include <openssl/err.h>
-#include <openssl/hmac.h>
-#include <openssl/mem.h>
-#include <openssl/obj.h>
-
-#include "internal.h"
-#include "../digest/internal.h"
-
-
-typedef struct {
- const EVP_MD *md; /* MD for HMAC use */
- ASN1_OCTET_STRING ktmp; /* Temp storage for key */
- HMAC_CTX ctx;
-} HMAC_PKEY_CTX;
-
-static int pkey_hmac_init(EVP_PKEY_CTX *ctx) {
- HMAC_PKEY_CTX *hctx;
- hctx = OPENSSL_malloc(sizeof(HMAC_PKEY_CTX));
- if (!hctx) {
- return 0;
- }
- memset(hctx, 0, sizeof(HMAC_PKEY_CTX));
- hctx->ktmp.type = V_ASN1_OCTET_STRING;
- HMAC_CTX_init(&hctx->ctx);
-
- ctx->data = hctx;
-
- return 1;
-}
-
-static int pkey_hmac_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src) {
- HMAC_PKEY_CTX *sctx, *dctx;
- if (!pkey_hmac_init(dst)) {
- return 0;
- }
- sctx = src->data;
- dctx = dst->data;
- dctx->md = sctx->md;
- HMAC_CTX_init(&dctx->ctx);
- if (!HMAC_CTX_copy_ex(&dctx->ctx, &sctx->ctx)) {
- return 0;
- }
- if (sctx->ktmp.data) {
- if (!ASN1_OCTET_STRING_set(&dctx->ktmp, sctx->ktmp.data,
- sctx->ktmp.length)) {
- return 0;
- }
- }
- return 1;
-}
-
-static void pkey_hmac_cleanup(EVP_PKEY_CTX *ctx) {
- HMAC_PKEY_CTX *hctx = ctx->data;
-
- if (hctx == NULL) {
- return;
- }
-
- HMAC_CTX_cleanup(&hctx->ctx);
- if (hctx->ktmp.data) {
- if (hctx->ktmp.length) {
- OPENSSL_cleanse(hctx->ktmp.data, hctx->ktmp.length);
- }
- OPENSSL_free(hctx->ktmp.data);
- hctx->ktmp.data = NULL;
- }
- OPENSSL_free(hctx);
-}
-
-static int pkey_hmac_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) {
- ASN1_OCTET_STRING *hkey = NULL;
- HMAC_PKEY_CTX *hctx = ctx->data;
-
- if (!hctx->ktmp.data) {
- return 0;
- }
- hkey = ASN1_OCTET_STRING_dup(&hctx->ktmp);
- if (!hkey) {
- return 0;
- }
- EVP_PKEY_assign(pkey, EVP_PKEY_HMAC, hkey);
-
- return 1;
-}
-
-static void int_update(EVP_MD_CTX *ctx, const void *data, size_t count) {
- HMAC_PKEY_CTX *hctx = ctx->pctx->data;
- HMAC_Update(&hctx->ctx, data, count);
-}
-
-static int hmac_signctx_init(EVP_PKEY_CTX *ctx, EVP_MD_CTX *mctx) {
- /* |mctx| gets repurposed as a hook to call |HMAC_Update|. Suppress the
- * automatic setting of |mctx->update| and the rest of its initialization. */
- EVP_MD_CTX_set_flags(mctx, EVP_MD_CTX_FLAG_NO_INIT);
- mctx->update = int_update;
- return 1;
-}
-
-static int hmac_signctx(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen,
- EVP_MD_CTX *mctx) {
- unsigned int hlen;
- HMAC_PKEY_CTX *hctx = ctx->data;
- size_t md_size = EVP_MD_CTX_size(mctx);
-
- if (!sig) {
- *siglen = md_size;
- return 1;
- } else if (*siglen < md_size) {
- OPENSSL_PUT_ERROR(EVP, hmac_signctx, EVP_R_BUFFER_TOO_SMALL);
- return 0;
- }
-
- if (!HMAC_Final(&hctx->ctx, sig, &hlen)) {
- return 0;
- }
- *siglen = (size_t)hlen;
- return 1;
-}
-
-static int pkey_hmac_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) {
- HMAC_PKEY_CTX *hctx = ctx->data;
- ASN1_OCTET_STRING *key;
-
- switch (type) {
- case EVP_PKEY_CTRL_SET_MAC_KEY:
- if ((!p2 && p1 > 0) || (p1 < -1)) {
- return 0;
- }
- if (!ASN1_OCTET_STRING_set(&hctx->ktmp, p2, p1)) {
- return 0;
- }
- break;
-
- case EVP_PKEY_CTRL_MD:
- hctx->md = p2;
- break;
-
- case EVP_PKEY_CTRL_DIGESTINIT:
- key = (ASN1_OCTET_STRING *)ctx->pkey->pkey.ptr;
- if (!HMAC_Init_ex(&hctx->ctx, key->data, key->length, hctx->md,
- ctx->engine)) {
- return 0;
- }
- break;
-
- default:
- OPENSSL_PUT_ERROR(EVP, pkey_hmac_ctrl, EVP_R_COMMAND_NOT_SUPPORTED);
- return 0;
- }
- return 1;
-}
-
-const EVP_PKEY_METHOD hmac_pkey_meth = {
- EVP_PKEY_HMAC, 0 /* flags */, pkey_hmac_init,
- pkey_hmac_copy, pkey_hmac_cleanup, 0 /* paramgen_init */,
- 0 /* paramgen */, 0 /* keygen_init */, pkey_hmac_keygen,
- 0 /* sign_init */, 0 /* sign */, 0 /* verify_init */,
- 0 /* verify */, hmac_signctx_init, hmac_signctx,
- 0 /* verifyctx_init */, 0 /* verifyctx */, 0 /* encrypt_init */,
- 0 /* encrypt */, 0 /* decrypt_init */, 0 /* decrypt */,
- 0 /* derive_init */, 0 /* derive */, pkey_hmac_ctrl,
- 0,
-};
diff --git a/src/crypto/evp/p_hmac_asn1.c b/src/crypto/evp/p_hmac_asn1.c
deleted file mode 100644
index 8aa6676..0000000
--- a/src/crypto/evp/p_hmac_asn1.c
+++ /dev/null
@@ -1,89 +0,0 @@
-/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
- * project 2007.
- */
-/* ====================================================================
- * Copyright (c) 2007 The OpenSSL Project. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in
- * the documentation and/or other materials provided with the
- * distribution.
- *
- * 3. All advertising materials mentioning features or use of this
- * software must display the following acknowledgment:
- * "This product includes software developed by the OpenSSL Project
- * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
- *
- * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
- * endorse or promote products derived from this software without
- * prior written permission. For written permission, please contact
- * licensing@OpenSSL.org.
- *
- * 5. Products derived from this software may not be called "OpenSSL"
- * nor may "OpenSSL" appear in their names without prior written
- * permission of the OpenSSL Project.
- *
- * 6. Redistributions of any form whatsoever must retain the following
- * acknowledgment:
- * "This product includes software developed by the OpenSSL Project
- * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
- *
- * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
- * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
- * OF THE POSSIBILITY OF SUCH DAMAGE.
- * ====================================================================
- *
- * This product includes cryptographic software written by Eric Young
- * (eay@cryptsoft.com). This product includes software written by Tim
- * Hudson (tjh@cryptsoft.com). */
-
-#include <openssl/evp.h>
-
-#include <openssl/asn1.h>
-#include <openssl/digest.h>
-#include <openssl/mem.h>
-#include <openssl/obj.h>
-
-#include "internal.h"
-
-
-static int hmac_size(const EVP_PKEY *pkey) { return EVP_MAX_MD_SIZE; }
-
-static void hmac_key_free(EVP_PKEY *pkey) {
- ASN1_OCTET_STRING *os = (ASN1_OCTET_STRING *)pkey->pkey.ptr;
- if (os) {
- if (os->data) {
- OPENSSL_cleanse(os->data, os->length);
- }
- ASN1_OCTET_STRING_free(os);
- }
-}
-
-const EVP_PKEY_ASN1_METHOD hmac_asn1_meth = {
- EVP_PKEY_HMAC, EVP_PKEY_HMAC, 0 /* flags */,
- "HMAC", "OpenSSL HMAC method", 0 /* pub_decode */,
- 0 /* pub_encode */, 0 /* pub_cmp */, 0 /* pub_print */,
- 0 /*priv_decode */, 0 /* priv_encode */, 0 /* priv_print */,
- 0 /* pkey_opaque */, 0 /* pkey_supports_digest */,
- hmac_size, 0 /* pkey_bits */, 0 /* param_decode */,
- 0 /* param_encode*/, 0 /* param_missing*/, 0 /* param_copy*/,
- 0 /* param_cmp*/, 0 /* param_print*/, 0 /* sig_print*/,
- hmac_key_free, 0 /* old_priv_decode */,
- 0 /* old_priv_encode */
-};
diff --git a/src/crypto/evp/p_rsa.c b/src/crypto/evp/p_rsa.c
index 5abc075..cfecbfd 100644
--- a/src/crypto/evp/p_rsa.c
+++ b/src/crypto/evp/p_rsa.c
@@ -174,7 +174,7 @@ static int pkey_rsa_sign(EVP_PKEY_CTX *ctx, uint8_t *sig, size_t *siglen,
}
if (*siglen < key_len) {
- OPENSSL_PUT_ERROR(EVP, pkey_rsa_sign, EVP_R_BUFFER_TOO_SMALL);
+ OPENSSL_PUT_ERROR(EVP, EVP_R_BUFFER_TOO_SMALL);
return 0;
}
@@ -182,12 +182,12 @@ static int pkey_rsa_sign(EVP_PKEY_CTX *ctx, uint8_t *sig, size_t *siglen,
unsigned int out_len;
if (tbslen != EVP_MD_size(rctx->md)) {
- OPENSSL_PUT_ERROR(EVP, pkey_rsa_sign, EVP_R_INVALID_DIGEST_LENGTH);
+ OPENSSL_PUT_ERROR(EVP, EVP_R_INVALID_DIGEST_LENGTH);
return 0;
}
if (EVP_MD_type(rctx->md) == NID_mdc2) {
- OPENSSL_PUT_ERROR(EVP, pkey_rsa_sign, EVP_R_NO_MDC2_SUPPORT);
+ OPENSSL_PUT_ERROR(EVP, EVP_R_NO_MDC2_SUPPORT);
return 0;
}
@@ -268,7 +268,7 @@ static int pkey_rsa_encrypt(EVP_PKEY_CTX *ctx, uint8_t *out, size_t *outlen,
}
if (*outlen < key_len) {
- OPENSSL_PUT_ERROR(EVP, pkey_rsa_encrypt, EVP_R_BUFFER_TOO_SMALL);
+ OPENSSL_PUT_ERROR(EVP, EVP_R_BUFFER_TOO_SMALL);
return 0;
}
@@ -300,7 +300,7 @@ static int pkey_rsa_decrypt(EVP_PKEY_CTX *ctx, uint8_t *out,
}
if (*outlen < key_len) {
- OPENSSL_PUT_ERROR(EVP, pkey_rsa_decrypt, EVP_R_BUFFER_TOO_SMALL);
+ OPENSSL_PUT_ERROR(EVP, EVP_R_BUFFER_TOO_SMALL);
return 0;
}
@@ -333,7 +333,7 @@ static int check_padding_md(const EVP_MD *md, int padding) {
}
if (padding == RSA_NO_PADDING) {
- OPENSSL_PUT_ERROR(EVP, check_padding_md, EVP_R_INVALID_PADDING_MODE);
+ OPENSSL_PUT_ERROR(EVP, EVP_R_INVALID_PADDING_MODE);
return 0;
}
@@ -361,8 +361,7 @@ static int pkey_rsa_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) {
0 == (ctx->operation & (EVP_PKEY_OP_SIGN | EVP_PKEY_OP_VERIFY))) ||
(p1 == RSA_PKCS1_OAEP_PADDING &&
0 == (ctx->operation & EVP_PKEY_OP_TYPE_CRYPT))) {
- OPENSSL_PUT_ERROR(EVP, pkey_rsa_ctrl,
- EVP_R_ILLEGAL_OR_UNSUPPORTED_PADDING_MODE);
+ OPENSSL_PUT_ERROR(EVP, EVP_R_ILLEGAL_OR_UNSUPPORTED_PADDING_MODE);
return 0;
}
if ((p1 == RSA_PKCS1_PSS_PADDING || p1 == RSA_PKCS1_OAEP_PADDING) &&
@@ -379,7 +378,7 @@ static int pkey_rsa_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) {
case EVP_PKEY_CTRL_RSA_PSS_SALTLEN:
case EVP_PKEY_CTRL_GET_RSA_PSS_SALTLEN:
if (rctx->pad_mode != RSA_PKCS1_PSS_PADDING) {
- OPENSSL_PUT_ERROR(EVP, pkey_rsa_ctrl, EVP_R_INVALID_PSS_SALTLEN);
+ OPENSSL_PUT_ERROR(EVP, EVP_R_INVALID_PSS_SALTLEN);
return 0;
}
if (type == EVP_PKEY_CTRL_GET_RSA_PSS_SALTLEN) {
@@ -394,7 +393,7 @@ static int pkey_rsa_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) {
case EVP_PKEY_CTRL_RSA_KEYGEN_BITS:
if (p1 < 256) {
- OPENSSL_PUT_ERROR(EVP, pkey_rsa_ctrl, EVP_R_INVALID_KEYBITS);
+ OPENSSL_PUT_ERROR(EVP, EVP_R_INVALID_KEYBITS);
return 0;
}
rctx->nbits = p1;
@@ -411,7 +410,7 @@ static int pkey_rsa_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) {
case EVP_PKEY_CTRL_RSA_OAEP_MD:
case EVP_PKEY_CTRL_GET_RSA_OAEP_MD:
if (rctx->pad_mode != RSA_PKCS1_OAEP_PADDING) {
- OPENSSL_PUT_ERROR(EVP, pkey_rsa_ctrl, EVP_R_INVALID_PADDING_MODE);
+ OPENSSL_PUT_ERROR(EVP, EVP_R_INVALID_PADDING_MODE);
return 0;
}
if (type == EVP_PKEY_CTRL_GET_RSA_OAEP_MD) {
@@ -436,7 +435,7 @@ static int pkey_rsa_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) {
case EVP_PKEY_CTRL_GET_RSA_MGF1_MD:
if (rctx->pad_mode != RSA_PKCS1_PSS_PADDING &&
rctx->pad_mode != RSA_PKCS1_OAEP_PADDING) {
- OPENSSL_PUT_ERROR(EVP, pkey_rsa_ctrl, EVP_R_INVALID_MGF1_MD);
+ OPENSSL_PUT_ERROR(EVP, EVP_R_INVALID_MGF1_MD);
return 0;
}
if (type == EVP_PKEY_CTRL_GET_RSA_MGF1_MD) {
@@ -452,7 +451,7 @@ static int pkey_rsa_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) {
case EVP_PKEY_CTRL_RSA_OAEP_LABEL:
if (rctx->pad_mode != RSA_PKCS1_OAEP_PADDING) {
- OPENSSL_PUT_ERROR(EVP, pkey_rsa_ctrl, EVP_R_INVALID_PADDING_MODE);
+ OPENSSL_PUT_ERROR(EVP, EVP_R_INVALID_PADDING_MODE);
return 0;
}
OPENSSL_free(rctx->oaep_label);
@@ -469,17 +468,14 @@ static int pkey_rsa_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) {
case EVP_PKEY_CTRL_GET_RSA_OAEP_LABEL:
if (rctx->pad_mode != RSA_PKCS1_OAEP_PADDING) {
- OPENSSL_PUT_ERROR(EVP, pkey_rsa_ctrl, EVP_R_INVALID_PADDING_MODE);
+ OPENSSL_PUT_ERROR(EVP, EVP_R_INVALID_PADDING_MODE);
return 0;
}
CBS_init((CBS *)p2, rctx->oaep_label, rctx->oaep_labellen);
return 1;
- case EVP_PKEY_CTRL_DIGESTINIT:
- return 1;
-
default:
- OPENSSL_PUT_ERROR(EVP, pkey_rsa_ctrl, EVP_R_COMMAND_NOT_SUPPORTED);
+ OPENSSL_PUT_ERROR(EVP, EVP_R_COMMAND_NOT_SUPPORTED);
return 0;
}
}
@@ -509,14 +505,13 @@ static int pkey_rsa_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) {
}
const EVP_PKEY_METHOD rsa_pkey_meth = {
- EVP_PKEY_RSA, 0 /* flags */, pkey_rsa_init,
- pkey_rsa_copy, pkey_rsa_cleanup, 0 /* paramgen_init */,
- 0 /* paramgen */, 0 /* keygen_init */, pkey_rsa_keygen,
- 0 /* sign_init */, pkey_rsa_sign, 0 /* verify_init */,
- pkey_rsa_verify, 0 /* signctx_init */, 0 /* signctx */,
- 0 /* verifyctx_init */, 0 /* verifyctx */, 0 /* encrypt_init */,
- pkey_rsa_encrypt, 0 /* decrypt_init */, pkey_rsa_decrypt,
- 0 /* derive_init */, 0 /* derive */, pkey_rsa_ctrl,
+ EVP_PKEY_RSA, 0 /* flags */, pkey_rsa_init,
+ pkey_rsa_copy, pkey_rsa_cleanup, 0 /* paramgen_init */,
+ 0 /* paramgen */, 0 /* keygen_init */, pkey_rsa_keygen,
+ 0 /* sign_init */, pkey_rsa_sign, 0 /* verify_init */,
+ pkey_rsa_verify, 0 /* encrypt_init */, pkey_rsa_encrypt,
+ 0 /* decrypt_init */, pkey_rsa_decrypt, 0 /* derive_init */,
+ 0 /* derive */, pkey_rsa_ctrl,
};
int EVP_PKEY_CTX_set_rsa_padding(EVP_PKEY_CTX *ctx, int padding) {
@@ -593,7 +588,7 @@ int EVP_PKEY_CTX_get0_rsa_oaep_label(EVP_PKEY_CTX *ctx,
return -1;
}
if (CBS_len(&label) > INT_MAX) {
- OPENSSL_PUT_ERROR(EVP, EVP_PKEY_CTX_get0_rsa_oaep_label, ERR_R_OVERFLOW);
+ OPENSSL_PUT_ERROR(EVP, ERR_R_OVERFLOW);
return -1;
}
*out_label = CBS_data(&label);
diff --git a/src/crypto/evp/p_rsa_asn1.c b/src/crypto/evp/p_rsa_asn1.c
index 1e2d3f6..f60625b 100644
--- a/src/crypto/evp/p_rsa_asn1.c
+++ b/src/crypto/evp/p_rsa_asn1.c
@@ -57,6 +57,7 @@
#include <openssl/asn1.h>
#include <openssl/asn1t.h>
+#include <openssl/bytestring.h>
#include <openssl/digest.h>
#include <openssl/err.h>
#include <openssl/mem.h>
@@ -69,16 +70,14 @@
static int rsa_pub_encode(X509_PUBKEY *pk, const EVP_PKEY *pkey) {
- uint8_t *encoded = NULL;
- int len;
- len = i2d_RSAPublicKey(pkey->pkey.rsa, &encoded);
-
- if (len <= 0) {
+ uint8_t *encoded;
+ size_t encoded_len;
+ if (!RSA_public_key_to_bytes(&encoded, &encoded_len, pkey->pkey.rsa)) {
return 0;
}
if (!X509_PUBKEY_set0_param(pk, OBJ_nid2obj(EVP_PKEY_RSA), V_ASN1_NULL, NULL,
- encoded, len)) {
+ encoded, encoded_len)) {
OPENSSL_free(encoded);
return 0;
}
@@ -89,16 +88,25 @@ static int rsa_pub_encode(X509_PUBKEY *pk, const EVP_PKEY *pkey) {
static int rsa_pub_decode(EVP_PKEY *pkey, X509_PUBKEY *pubkey) {
const uint8_t *p;
int pklen;
- RSA *rsa;
-
if (!X509_PUBKEY_get0_param(NULL, &p, &pklen, NULL, pubkey)) {
return 0;
}
- rsa = d2i_RSAPublicKey(NULL, &p, pklen);
- if (rsa == NULL) {
- OPENSSL_PUT_ERROR(EVP, rsa_pub_decode, ERR_R_RSA_LIB);
+
+ /* Estonian IDs issued between September 2014 to September 2015 are
+ * broken. See https://crbug.com/532048 and https://crbug.com/534766.
+ *
+ * TODO(davidben): Switch this to the strict version in March 2016 or when
+ * Chromium can force client certificates down a different codepath, whichever
+ * comes first. */
+ CBS cbs;
+ CBS_init(&cbs, p, pklen);
+ RSA *rsa = RSA_parse_public_key_buggy(&cbs);
+ if (rsa == NULL || CBS_len(&cbs) != 0) {
+ OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR);
+ RSA_free(rsa);
return 0;
}
+
EVP_PKEY_assign_RSA(pkey, rsa);
return 1;
}
@@ -109,20 +117,17 @@ static int rsa_pub_cmp(const EVP_PKEY *a, const EVP_PKEY *b) {
}
static int rsa_priv_encode(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pkey) {
- uint8_t *rk = NULL;
- int rklen;
-
- rklen = i2d_RSAPrivateKey(pkey->pkey.rsa, &rk);
-
- if (rklen <= 0) {
- OPENSSL_PUT_ERROR(EVP, rsa_priv_encode, ERR_R_MALLOC_FAILURE);
+ uint8_t *encoded;
+ size_t encoded_len;
+ if (!RSA_private_key_to_bytes(&encoded, &encoded_len, pkey->pkey.rsa)) {
return 0;
}
/* TODO(fork): const correctness in next line. */
if (!PKCS8_pkey_set0(p8, (ASN1_OBJECT *)OBJ_nid2obj(NID_rsaEncryption), 0,
- V_ASN1_NULL, NULL, rk, rklen)) {
- OPENSSL_PUT_ERROR(EVP, rsa_priv_encode, ERR_R_MALLOC_FAILURE);
+ V_ASN1_NULL, NULL, encoded, encoded_len)) {
+ OPENSSL_free(encoded);
+ OPENSSL_PUT_ERROR(EVP, ERR_R_MALLOC_FAILURE);
return 0;
}
@@ -132,16 +137,14 @@ static int rsa_priv_encode(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pkey) {
static int rsa_priv_decode(EVP_PKEY *pkey, PKCS8_PRIV_KEY_INFO *p8) {
const uint8_t *p;
int pklen;
- RSA *rsa;
-
if (!PKCS8_pkey_get0(NULL, &p, &pklen, NULL, p8)) {
- OPENSSL_PUT_ERROR(EVP, rsa_priv_decode, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(EVP, ERR_R_MALLOC_FAILURE);
return 0;
}
- rsa = d2i_RSAPrivateKey(NULL, &p, pklen);
+ RSA *rsa = RSA_private_key_from_bytes(p, pklen);
if (rsa == NULL) {
- OPENSSL_PUT_ERROR(EVP, rsa_priv_decode, ERR_R_RSA_LIB);
+ OPENSSL_PUT_ERROR(EVP, ERR_R_RSA_LIB);
return 0;
}
@@ -198,11 +201,24 @@ static int do_rsa_print(BIO *out, const RSA *rsa, int off,
update_buflen(rsa->dmp1, &buf_len);
update_buflen(rsa->dmq1, &buf_len);
update_buflen(rsa->iqmp, &buf_len);
+
+ if (rsa->additional_primes != NULL) {
+ size_t i;
+
+ for (i = 0; i < sk_RSA_additional_prime_num(rsa->additional_primes);
+ i++) {
+ const RSA_additional_prime *ap =
+ sk_RSA_additional_prime_value(rsa->additional_primes, i);
+ update_buflen(ap->prime, &buf_len);
+ update_buflen(ap->exp, &buf_len);
+ update_buflen(ap->coeff, &buf_len);
+ }
+ }
}
m = (uint8_t *)OPENSSL_malloc(buf_len + 10);
if (m == NULL) {
- OPENSSL_PUT_ERROR(EVP, do_rsa_print, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(EVP, ERR_R_MALLOC_FAILURE);
goto err;
}
@@ -241,6 +257,28 @@ static int do_rsa_print(BIO *out, const RSA *rsa, int off,
!ASN1_bn_print(out, "coefficient:", rsa->iqmp, m, off)) {
goto err;
}
+
+ if (rsa->additional_primes != NULL &&
+ sk_RSA_additional_prime_num(rsa->additional_primes) > 0) {
+ size_t i;
+
+ if (BIO_printf(out, "otherPrimeInfos:\n") <= 0) {
+ goto err;
+ }
+ for (i = 0; i < sk_RSA_additional_prime_num(rsa->additional_primes);
+ i++) {
+ const RSA_additional_prime *ap =
+ sk_RSA_additional_prime_value(rsa->additional_primes, i);
+
+ if (BIO_printf(out, "otherPrimeInfo (prime %u):\n",
+ (unsigned)(i + 3)) <= 0 ||
+ !ASN1_bn_print(out, "prime:", ap->prime, m, off) ||
+ !ASN1_bn_print(out, "exponent:", ap->exp, m, off) ||
+ !ASN1_bn_print(out, "coeff:", ap->coeff, m, off)) {
+ goto err;
+ }
+ }
+ }
}
ret = 1;
@@ -407,18 +445,18 @@ static int rsa_sig_print(BIO *bp, const X509_ALGOR *sigalg,
return 1;
}
-static int old_rsa_priv_decode(EVP_PKEY *pkey, const unsigned char **pder,
+static int old_rsa_priv_decode(EVP_PKEY *pkey, const uint8_t **pder,
int derlen) {
RSA *rsa = d2i_RSAPrivateKey(NULL, pder, derlen);
if (rsa == NULL) {
- OPENSSL_PUT_ERROR(EVP, old_rsa_priv_decode, ERR_R_RSA_LIB);
+ OPENSSL_PUT_ERROR(EVP, ERR_R_RSA_LIB);
return 0;
}
EVP_PKEY_assign_RSA(pkey, rsa);
return 1;
}
-static int old_rsa_priv_encode(const EVP_PKEY *pkey, unsigned char **pder) {
+static int old_rsa_priv_encode(const EVP_PKEY *pkey, uint8_t **pder) {
return i2d_RSAPrivateKey(pkey->pkey.rsa, pder);
}
@@ -474,7 +512,7 @@ static const EVP_MD *rsa_algor_to_md(X509_ALGOR *alg) {
}
md = EVP_get_digestbyobj(alg->algorithm);
if (md == NULL) {
- OPENSSL_PUT_ERROR(EVP, rsa_algor_to_md, EVP_R_UNKNOWN_DIGEST);
+ OPENSSL_PUT_ERROR(EVP, EVP_R_UNKNOWN_DIGEST);
}
return md;
}
@@ -487,16 +525,16 @@ static const EVP_MD *rsa_mgf1_to_md(X509_ALGOR *alg, X509_ALGOR *maskHash) {
}
/* Check mask and lookup mask hash algorithm */
if (OBJ_obj2nid(alg->algorithm) != NID_mgf1) {
- OPENSSL_PUT_ERROR(EVP, rsa_mgf1_to_md, EVP_R_UNSUPPORTED_MASK_ALGORITHM);
+ OPENSSL_PUT_ERROR(EVP, EVP_R_UNSUPPORTED_MASK_ALGORITHM);
return NULL;
}
if (!maskHash) {
- OPENSSL_PUT_ERROR(EVP, rsa_mgf1_to_md, EVP_R_UNSUPPORTED_MASK_PARAMETER);
+ OPENSSL_PUT_ERROR(EVP, EVP_R_UNSUPPORTED_MASK_PARAMETER);
return NULL;
}
md = EVP_get_digestbyobj(maskHash->algorithm);
if (md == NULL) {
- OPENSSL_PUT_ERROR(EVP, rsa_mgf1_to_md, EVP_R_UNKNOWN_MASK_DIGEST);
+ OPENSSL_PUT_ERROR(EVP, EVP_R_UNKNOWN_MASK_DIGEST);
return NULL;
}
return md;
@@ -576,13 +614,13 @@ static int rsa_pss_to_ctx(EVP_MD_CTX *ctx, X509_ALGOR *sigalg, EVP_PKEY *pkey) {
/* Sanity check: make sure it is PSS */
if (OBJ_obj2nid(sigalg->algorithm) != NID_rsassaPss) {
- OPENSSL_PUT_ERROR(EVP, rsa_pss_to_ctx, EVP_R_UNSUPPORTED_SIGNATURE_TYPE);
+ OPENSSL_PUT_ERROR(EVP, EVP_R_UNSUPPORTED_SIGNATURE_TYPE);
return 0;
}
/* Decode PSS parameters */
pss = rsa_pss_decode(sigalg, &maskHash);
if (pss == NULL) {
- OPENSSL_PUT_ERROR(EVP, rsa_pss_to_ctx, EVP_R_INVALID_PSS_PARAMETERS);
+ OPENSSL_PUT_ERROR(EVP, EVP_R_INVALID_PSS_PARAMETERS);
goto err;
}
@@ -602,7 +640,7 @@ static int rsa_pss_to_ctx(EVP_MD_CTX *ctx, X509_ALGOR *sigalg, EVP_PKEY *pkey) {
/* Could perform more salt length sanity checks but the main
* RSA routines will trap other invalid values anyway. */
if (saltlen < 0) {
- OPENSSL_PUT_ERROR(EVP, rsa_pss_to_ctx, EVP_R_INVALID_SALT_LENGTH);
+ OPENSSL_PUT_ERROR(EVP, EVP_R_INVALID_SALT_LENGTH);
goto err;
}
}
@@ -610,7 +648,7 @@ static int rsa_pss_to_ctx(EVP_MD_CTX *ctx, X509_ALGOR *sigalg, EVP_PKEY *pkey) {
/* low-level routines support only trailer field 0xbc (value 1)
* and PKCS#1 says we should reject any other value anyway. */
if (pss->trailerField && ASN1_INTEGER_get(pss->trailerField) != 1) {
- OPENSSL_PUT_ERROR(EVP, rsa_pss_to_ctx, EVP_R_INVALID_TRAILER);
+ OPENSSL_PUT_ERROR(EVP, EVP_R_INVALID_TRAILER);
goto err;
}
@@ -638,8 +676,7 @@ static int rsa_digest_verify_init_from_algorithm(EVP_MD_CTX *ctx,
EVP_PKEY *pkey) {
/* Sanity check: make sure it is PSS */
if (OBJ_obj2nid(sigalg->algorithm) != NID_rsassaPss) {
- OPENSSL_PUT_ERROR(EVP, rsa_digest_verify_init_from_algorithm,
- EVP_R_UNSUPPORTED_SIGNATURE_TYPE);
+ OPENSSL_PUT_ERROR(EVP, EVP_R_UNSUPPORTED_SIGNATURE_TYPE);
return 0;
}
return rsa_pss_to_ctx(ctx, sigalg, pkey);
@@ -671,7 +708,6 @@ const EVP_PKEY_ASN1_METHOD rsa_asn1_meth = {
ASN1_PKEY_SIGPARAM_NULL,
"RSA",
- "OpenSSL RSA method",
rsa_pub_decode,
rsa_pub_encode,
diff --git a/src/crypto/ex_data.c b/src/crypto/ex_data.c
index 10fefc8..f562f17 100644
--- a/src/crypto/ex_data.c
+++ b/src/crypto/ex_data.c
@@ -138,7 +138,7 @@ int CRYPTO_get_ex_new_index(CRYPTO_EX_DATA_CLASS *ex_data_class, int *out_index,
funcs = OPENSSL_malloc(sizeof(CRYPTO_EX_DATA_FUNCS));
if (funcs == NULL) {
- OPENSSL_PUT_ERROR(CRYPTO, CRYPTO_get_ex_new_index, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(CRYPTO, ERR_R_MALLOC_FAILURE);
return 0;
}
@@ -156,12 +156,13 @@ int CRYPTO_get_ex_new_index(CRYPTO_EX_DATA_CLASS *ex_data_class, int *out_index,
if (ex_data_class->meth == NULL ||
!sk_CRYPTO_EX_DATA_FUNCS_push(ex_data_class->meth, funcs)) {
- OPENSSL_PUT_ERROR(CRYPTO, CRYPTO_get_ex_new_index, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(CRYPTO, ERR_R_MALLOC_FAILURE);
OPENSSL_free(funcs);
goto err;
}
- *out_index = sk_CRYPTO_EX_DATA_FUNCS_num(ex_data_class->meth) - 1;
+ *out_index = sk_CRYPTO_EX_DATA_FUNCS_num(ex_data_class->meth) - 1 +
+ ex_data_class->num_reserved;
ret = 1;
err:
@@ -175,7 +176,7 @@ int CRYPTO_set_ex_data(CRYPTO_EX_DATA *ad, int index, void *val) {
if (ad->sk == NULL) {
ad->sk = sk_void_new_null();
if (ad->sk == NULL) {
- OPENSSL_PUT_ERROR(CRYPTO, CRYPTO_set_ex_data, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(CRYPTO, ERR_R_MALLOC_FAILURE);
return 0;
}
}
@@ -185,7 +186,7 @@ int CRYPTO_set_ex_data(CRYPTO_EX_DATA *ad, int index, void *val) {
/* Add NULL values until the stack is long enough. */
for (i = n; i <= index; i++) {
if (!sk_void_push(ad->sk, NULL)) {
- OPENSSL_PUT_ERROR(CRYPTO, CRYPTO_set_ex_data, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(CRYPTO, ERR_R_MALLOC_FAILURE);
return 0;
}
}
@@ -222,7 +223,7 @@ static int get_func_pointers(STACK_OF(CRYPTO_EX_DATA_FUNCS) **out,
CRYPTO_STATIC_MUTEX_unlock(&ex_data_class->lock);
if (n > 0 && *out == NULL) {
- OPENSSL_PUT_ERROR(CRYPTO, get_func_pointers, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(CRYPTO, ERR_R_MALLOC_FAILURE);
return 0;
}
@@ -244,8 +245,8 @@ int CRYPTO_new_ex_data(CRYPTO_EX_DATA_CLASS *ex_data_class, void *obj,
CRYPTO_EX_DATA_FUNCS *func_pointer =
sk_CRYPTO_EX_DATA_FUNCS_value(func_pointers, i);
if (func_pointer->new_func) {
- func_pointer->new_func(obj, NULL, ad, i, func_pointer->argl,
- func_pointer->argp);
+ func_pointer->new_func(obj, NULL, ad, i + ex_data_class->num_reserved,
+ func_pointer->argl, func_pointer->argp);
}
}
@@ -272,12 +273,12 @@ int CRYPTO_dup_ex_data(CRYPTO_EX_DATA_CLASS *ex_data_class, CRYPTO_EX_DATA *to,
for (i = 0; i < sk_CRYPTO_EX_DATA_FUNCS_num(func_pointers); i++) {
CRYPTO_EX_DATA_FUNCS *func_pointer =
sk_CRYPTO_EX_DATA_FUNCS_value(func_pointers, i);
- void *ptr = CRYPTO_get_ex_data(from, i);
+ void *ptr = CRYPTO_get_ex_data(from, i + ex_data_class->num_reserved);
if (func_pointer->dup_func) {
- func_pointer->dup_func(to, from, &ptr, i, func_pointer->argl,
- func_pointer->argp);
+ func_pointer->dup_func(to, from, &ptr, i + ex_data_class->num_reserved,
+ func_pointer->argl, func_pointer->argp);
}
- CRYPTO_set_ex_data(to, i, ptr);
+ CRYPTO_set_ex_data(to, i + ex_data_class->num_reserved, ptr);
}
sk_CRYPTO_EX_DATA_FUNCS_free(func_pointers);
@@ -298,9 +299,9 @@ void CRYPTO_free_ex_data(CRYPTO_EX_DATA_CLASS *ex_data_class, void *obj,
CRYPTO_EX_DATA_FUNCS *func_pointer =
sk_CRYPTO_EX_DATA_FUNCS_value(func_pointers, i);
if (func_pointer->free_func) {
- void *ptr = CRYPTO_get_ex_data(ad, i);
- func_pointer->free_func(obj, ptr, ad, i, func_pointer->argl,
- func_pointer->argp);
+ void *ptr = CRYPTO_get_ex_data(ad, i + ex_data_class->num_reserved);
+ func_pointer->free_func(obj, ptr, ad, i + ex_data_class->num_reserved,
+ func_pointer->argl, func_pointer->argp);
}
}
diff --git a/src/crypto/hkdf/CMakeLists.txt b/src/crypto/hkdf/CMakeLists.txt
index 66d680a..53bf558 100644
--- a/src/crypto/hkdf/CMakeLists.txt
+++ b/src/crypto/hkdf/CMakeLists.txt
@@ -1,4 +1,4 @@
-include_directories(. .. ../../include)
+include_directories(../../include)
add_library(
hkdf
diff --git a/src/crypto/hkdf/hkdf.c b/src/crypto/hkdf/hkdf.c
index bb7f5a4..f9cdcb0 100644
--- a/src/crypto/hkdf/hkdf.c
+++ b/src/crypto/hkdf/hkdf.c
@@ -40,7 +40,7 @@ int HKDF(uint8_t *out_key, size_t out_len,
/* Expand key material to desired length. */
n = (out_len + digest_len - 1) / digest_len;
if (out_len + digest_len < out_len || n > 255) {
- OPENSSL_PUT_ERROR(HKDF, HKDF, HKDF_R_OUTPUT_TOO_LARGE);
+ OPENSSL_PUT_ERROR(HKDF, HKDF_R_OUTPUT_TOO_LARGE);
return 0;
}
@@ -83,7 +83,7 @@ int HKDF(uint8_t *out_key, size_t out_len,
out:
HMAC_CTX_cleanup(&hmac);
if (ret != 1) {
- OPENSSL_PUT_ERROR(HKDF, HKDF, ERR_R_HMAC_LIB);
+ OPENSSL_PUT_ERROR(HKDF, ERR_R_HMAC_LIB);
}
return ret;
}
diff --git a/src/crypto/hmac/CMakeLists.txt b/src/crypto/hmac/CMakeLists.txt
index 11d267f..392ce01 100644
--- a/src/crypto/hmac/CMakeLists.txt
+++ b/src/crypto/hmac/CMakeLists.txt
@@ -1,4 +1,4 @@
-include_directories(. .. ../../include)
+include_directories(../../include)
add_library(
hmac
diff --git a/src/crypto/hmac/hmac.c b/src/crypto/hmac/hmac.c
index 556e7f9..d37a249 100644
--- a/src/crypto/hmac/hmac.c
+++ b/src/crypto/hmac/hmac.c
@@ -97,7 +97,7 @@ void HMAC_CTX_cleanup(HMAC_CTX *ctx) {
EVP_MD_CTX_cleanup(&ctx->i_ctx);
EVP_MD_CTX_cleanup(&ctx->o_ctx);
EVP_MD_CTX_cleanup(&ctx->md_ctx);
- OPENSSL_cleanse(ctx, sizeof(ctx));
+ OPENSSL_cleanse(ctx, sizeof(HMAC_CTX));
}
int HMAC_Init_ex(HMAC_CTX *ctx, const void *key, size_t key_len,
diff --git a/src/crypto/hmac/hmac_tests.txt b/src/crypto/hmac/hmac_tests.txt
index 012f593..53f3f8f 100644
--- a/src/crypto/hmac/hmac_tests.txt
+++ b/src/crypto/hmac/hmac_tests.txt
@@ -1,6 +1,3 @@
-# This test file is shared between evp_test and hmac_test, to test the legacy
-# EVP_PKEY_HMAC API.
-
HMAC = MD5
# Note: The empty key results in passing NULL to HMAC_Init_ex, so this tests
# that HMAC_CTX and HMAC treat NULL as the empty key initially.
diff --git a/src/crypto/internal.h b/src/crypto/internal.h
index 59eddd0..713659d 100644
--- a/src/crypto/internal.h
+++ b/src/crypto/internal.h
@@ -452,6 +452,7 @@ OPENSSL_EXPORT void CRYPTO_STATIC_MUTEX_unlock(
typedef enum {
OPENSSL_THREAD_LOCAL_ERR = 0,
OPENSSL_THREAD_LOCAL_RAND,
+ OPENSSL_THREAD_LOCAL_URANDOM_BUF,
OPENSSL_THREAD_LOCAL_TEST,
NUM_OPENSSL_THREAD_LOCALS,
} thread_local_data_t;
@@ -493,9 +494,14 @@ typedef struct crypto_ex_data_func_st CRYPTO_EX_DATA_FUNCS;
typedef struct {
struct CRYPTO_STATIC_MUTEX lock;
STACK_OF(CRYPTO_EX_DATA_FUNCS) *meth;
+ /* num_reserved is one if the ex_data index zero is reserved for legacy
+ * |TYPE_get_app_data| functions. */
+ uint8_t num_reserved;
} CRYPTO_EX_DATA_CLASS;
-#define CRYPTO_EX_DATA_CLASS_INIT {CRYPTO_STATIC_MUTEX_INIT, NULL}
+#define CRYPTO_EX_DATA_CLASS_INIT {CRYPTO_STATIC_MUTEX_INIT, NULL, 0}
+#define CRYPTO_EX_DATA_CLASS_INIT_WITH_APP_DATA \
+ {CRYPTO_STATIC_MUTEX_INIT, NULL, 1}
/* CRYPTO_get_ex_new_index allocates a new index for |ex_data_class| and writes
* it to |*out_index|. Each class of object should provide a wrapper function
diff --git a/src/crypto/lhash/CMakeLists.txt b/src/crypto/lhash/CMakeLists.txt
index c71b8a1..ce785eb 100644
--- a/src/crypto/lhash/CMakeLists.txt
+++ b/src/crypto/lhash/CMakeLists.txt
@@ -1,4 +1,4 @@
-include_directories(. .. ../../include)
+include_directories(../../include)
add_library(
lhash
diff --git a/src/crypto/lhash/lhash.c b/src/crypto/lhash/lhash.c
index c282fa8..257900e 100644
--- a/src/crypto/lhash/lhash.c
+++ b/src/crypto/lhash/lhash.c
@@ -1,4 +1,5 @@
-/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved.
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
*
* This package is an SSL implementation written
* by Eric Young (eay@cryptsoft.com).
diff --git a/src/crypto/md4/CMakeLists.txt b/src/crypto/md4/CMakeLists.txt
index db7a187..59140a7 100644
--- a/src/crypto/md4/CMakeLists.txt
+++ b/src/crypto/md4/CMakeLists.txt
@@ -1,4 +1,4 @@
-include_directories(. .. ../../include)
+include_directories(../../include)
add_library(
md4
diff --git a/src/crypto/md5/CMakeLists.txt b/src/crypto/md5/CMakeLists.txt
index 6c5e80f..a37c47e 100644
--- a/src/crypto/md5/CMakeLists.txt
+++ b/src/crypto/md5/CMakeLists.txt
@@ -1,4 +1,4 @@
-include_directories(. .. ../../include)
+include_directories(../../include)
if (${ARCH} STREQUAL "x86_64")
set(
diff --git a/src/crypto/md5/md5.c b/src/crypto/md5/md5.c
index 5575efb..6ad8d12 100644
--- a/src/crypto/md5/md5.c
+++ b/src/crypto/md5/md5.c
@@ -1,4 +1,5 @@
-/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved.
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
*
* This package is an SSL implementation written
* by Eric Young (eay@cryptsoft.com).
diff --git a/src/crypto/mem.c b/src/crypto/mem.c
index ce41440..edd14a8 100644
--- a/src/crypto/mem.c
+++ b/src/crypto/mem.c
@@ -1,4 +1,5 @@
-/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved.
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
*
* This package is an SSL implementation written
* by Eric Young (eay@cryptsoft.com).
diff --git a/src/crypto/modes/CMakeLists.txt b/src/crypto/modes/CMakeLists.txt
index ffb29b6..6da5207 100644
--- a/src/crypto/modes/CMakeLists.txt
+++ b/src/crypto/modes/CMakeLists.txt
@@ -1,4 +1,4 @@
-include_directories(. .. ../../include)
+include_directories(../../include)
if (${ARCH} STREQUAL "x86_64")
set(
diff --git a/src/crypto/modes/asm/ghash-armv4.pl b/src/crypto/modes/asm/ghash-armv4.pl
index 25a4e27..dc5b99e 100644
--- a/src/crypto/modes/asm/ghash-armv4.pl
+++ b/src/crypto/modes/asm/ghash-armv4.pl
@@ -45,7 +45,7 @@
# processes one byte in 8.45 cycles, A9 - in 10.2, A15 - in 7.63,
# Snapdragon S4 - in 9.33.
#
-# Câmara, D.; Gouvêa, C. P. L.; López, J. & Dahab, R.: Fast Software
+# Câmara, D.; Gouvêa, C. P. L.; López, J. & Dahab, R.: Fast Software
# Polynomial Multiplication on ARM Processors using the NEON Engine.
#
# http://conradoplg.cryptoland.net/files/2010/12/mocrysen13.pdf
@@ -134,7 +134,7 @@ ___
$code=<<___;
#if defined(__arm__)
-#include "arm_arch.h"
+#include <openssl/arm_arch.h>
.syntax unified
@@ -457,12 +457,12 @@ gcm_ghash_neon:
veor $IN,$Xl @ inp^=Xi
.Lgmult_neon:
___
- &clmul64x64 ($Xl,$Hlo,"$IN#lo"); # H.lo·Xi.lo
+ &clmul64x64 ($Xl,$Hlo,"$IN#lo"); # H.lo·Xi.lo
$code.=<<___;
veor $IN#lo,$IN#lo,$IN#hi @ Karatsuba pre-processing
___
- &clmul64x64 ($Xm,$Hhl,"$IN#lo"); # (H.lo+H.hi)·(Xi.lo+Xi.hi)
- &clmul64x64 ($Xh,$Hhi,"$IN#hi"); # H.hi·Xi.hi
+ &clmul64x64 ($Xm,$Hhl,"$IN#lo"); # (H.lo+H.hi)·(Xi.lo+Xi.hi)
+ &clmul64x64 ($Xh,$Hhi,"$IN#hi"); # H.hi·Xi.hi
$code.=<<___;
veor $Xm,$Xm,$Xl @ Karatsuba post-processing
veor $Xm,$Xm,$Xh
diff --git a/src/crypto/modes/asm/ghash-x86.pl b/src/crypto/modes/asm/ghash-x86.pl
index 23a5527..0269169 100644
--- a/src/crypto/modes/asm/ghash-x86.pl
+++ b/src/crypto/modes/asm/ghash-x86.pl
@@ -358,7 +358,7 @@ $S=12; # shift factor for rem_4bit
# effective address calculation and finally merge of value to Z.hi.
# Reference to rem_4bit is scheduled so late that I had to >>4
# rem_4bit elements. This resulted in 20-45% procent improvement
-# on contemporary µ-archs.
+# on contemporary µ-archs.
{
my $cnt;
my $rem_4bit = "eax";
diff --git a/src/crypto/modes/asm/ghash-x86_64.pl b/src/crypto/modes/asm/ghash-x86_64.pl
index 6e656ca..5a7ce39 100644
--- a/src/crypto/modes/asm/ghash-x86_64.pl
+++ b/src/crypto/modes/asm/ghash-x86_64.pl
@@ -576,15 +576,15 @@ $code.=<<___ if (0 || (&reduction_alg9($Xhi,$Xi)&&0));
# experimental alternative. special thing about is that there
# no dependency between the two multiplications...
mov \$`0xE1<<1`,%eax
- mov \$0xA040608020C0E000,%r10 # ((7..0)·0xE0)&0xff
+ mov \$0xA040608020C0E000,%r10 # ((7..0)·0xE0)&0xff
mov \$0x07,%r11d
movq %rax,$T1
movq %r10,$T2
movq %r11,$T3 # borrow $T3
pand $Xi,$T3
- pshufb $T3,$T2 # ($Xi&7)·0xE0
+ pshufb $T3,$T2 # ($Xi&7)·0xE0
movq %rax,$T3
- pclmulqdq \$0x00,$Xi,$T1 # ·(0xE1<<1)
+ pclmulqdq \$0x00,$Xi,$T1 # ·(0xE1<<1)
pxor $Xi,$T2
pslldq \$15,$T2
paddd $T2,$T2 # <<(64+56+1)
@@ -657,7 +657,7 @@ $code.=<<___;
je .Lskip4x
sub \$0x30,$len
- mov \$0xA040608020C0E000,%rax # ((7..0)·0xE0)&0xff
+ mov \$0xA040608020C0E000,%rax # ((7..0)·0xE0)&0xff
movdqu 0x30($Htbl),$Hkey3
movdqu 0x40($Htbl),$Hkey4
diff --git a/src/crypto/modes/asm/ghashv8-armx.pl b/src/crypto/modes/asm/ghashv8-armx.pl
index 686951f..3a7b8d8 100644
--- a/src/crypto/modes/asm/ghashv8-armx.pl
+++ b/src/crypto/modes/asm/ghashv8-armx.pl
@@ -54,7 +54,7 @@ my ($Xl,$Xm,$Xh,$IN)=map("q$_",(0..3));
my ($t0,$t1,$t2,$xC2,$H,$Hhl,$H2)=map("q$_",(8..14));
$code=<<___;
-#include "arm_arch.h"
+#include <openssl/arm_arch.h>
.text
___
@@ -148,10 +148,10 @@ gcm_gmult_v8:
#endif
vext.8 $IN,$t1,$t1,#8
- vpmull.p64 $Xl,$H,$IN @ H.lo·Xi.lo
+ vpmull.p64 $Xl,$H,$IN @ H.lo·Xi.lo
veor $t1,$t1,$IN @ Karatsuba pre-processing
- vpmull2.p64 $Xh,$H,$IN @ H.hi·Xi.hi
- vpmull.p64 $Xm,$Hhl,$t1 @ (H.lo+H.hi)·(Xi.lo+Xi.hi)
+ vpmull2.p64 $Xh,$H,$IN @ H.hi·Xi.hi
+ vpmull.p64 $Xm,$Hhl,$t1 @ (H.lo+H.hi)·(Xi.lo+Xi.hi)
vext.8 $t1,$Xl,$Xh,#8 @ Karatsuba post-processing
veor $t2,$Xl,$Xh
@@ -239,7 +239,7 @@ $code.=<<___;
#endif
vext.8 $In,$t1,$t1,#8
veor $IN,$IN,$Xl @ I[i]^=Xi
- vpmull.p64 $Xln,$H,$In @ H·Ii+1
+ vpmull.p64 $Xln,$H,$In @ H·Ii+1
veor $t1,$t1,$In @ Karatsuba pre-processing
vpmull2.p64 $Xhn,$H,$In
b .Loop_mod2x_v8
@@ -248,14 +248,14 @@ $code.=<<___;
.Loop_mod2x_v8:
vext.8 $t2,$IN,$IN,#8
subs $len,$len,#32 @ is there more data?
- vpmull.p64 $Xl,$H2,$IN @ H^2.lo·Xi.lo
+ vpmull.p64 $Xl,$H2,$IN @ H^2.lo·Xi.lo
cclr $inc,lo @ is it time to zero $inc?
vpmull.p64 $Xmn,$Hhl,$t1
veor $t2,$t2,$IN @ Karatsuba pre-processing
- vpmull2.p64 $Xh,$H2,$IN @ H^2.hi·Xi.hi
+ vpmull2.p64 $Xh,$H2,$IN @ H^2.hi·Xi.hi
veor $Xl,$Xl,$Xln @ accumulate
- vpmull2.p64 $Xm,$Hhl,$t2 @ (H^2.lo+H^2.hi)·(Xi.lo+Xi.hi)
+ vpmull2.p64 $Xm,$Hhl,$t2 @ (H^2.lo+H^2.hi)·(Xi.lo+Xi.hi)
vld1.64 {$t0},[$inp],$inc @ load [rotated] I[i+2]
veor $Xh,$Xh,$Xhn
@@ -280,7 +280,7 @@ $code.=<<___;
vext.8 $In,$t1,$t1,#8
vext.8 $IN,$t0,$t0,#8
veor $Xl,$Xm,$t2
- vpmull.p64 $Xln,$H,$In @ H·Ii+1
+ vpmull.p64 $Xln,$H,$In @ H·Ii+1
veor $IN,$IN,$Xh @ accumulate $IN early
vext.8 $t2,$Xl,$Xl,#8 @ 2nd phase of reduction
@@ -304,10 +304,10 @@ $code.=<<___;
veor $IN,$IN,$Xl @ inp^=Xi
veor $t1,$t0,$t2 @ $t1 is rotated inp^Xi
- vpmull.p64 $Xl,$H,$IN @ H.lo·Xi.lo
+ vpmull.p64 $Xl,$H,$IN @ H.lo·Xi.lo
veor $t1,$t1,$IN @ Karatsuba pre-processing
- vpmull2.p64 $Xh,$H,$IN @ H.hi·Xi.hi
- vpmull.p64 $Xm,$Hhl,$t1 @ (H.lo+H.hi)·(Xi.lo+Xi.hi)
+ vpmull2.p64 $Xh,$H,$IN @ H.hi·Xi.hi
+ vpmull.p64 $Xm,$Hhl,$t1 @ (H.lo+H.hi)·(Xi.lo+Xi.hi)
vext.8 $t1,$Xl,$Xh,#8 @ Karatsuba post-processing
veor $t2,$Xl,$Xh
diff --git a/src/crypto/modes/gcm.c b/src/crypto/modes/gcm.c
index b1c10b3..593dce8 100644
--- a/src/crypto/modes/gcm.c
+++ b/src/crypto/modes/gcm.c
@@ -349,12 +349,12 @@ void gcm_ghash_4bit_x86(uint64_t Xi[2], const u128 Htable[16], const uint8_t *in
size_t len);
#endif
#elif defined(OPENSSL_ARM) || defined(OPENSSL_AARCH64)
-#include "../arm_arch.h"
+#include <openssl/arm_arch.h>
#if __ARM_ARCH__ >= 7
#define GHASH_ASM_ARM
#define GCM_FUNCREF_4BIT
-static int pmull_capable() {
+static int pmull_capable(void) {
return (OPENSSL_armcap_P & ARMV8_PMULL) != 0;
}
@@ -365,7 +365,7 @@ void gcm_ghash_v8(uint64_t Xi[2], const u128 Htable[16], const uint8_t *inp,
#if defined(OPENSSL_ARM)
/* 32-bit ARM also has support for doing GCM with NEON instructions. */
-static int neon_capable() {
+static int neon_capable(void) {
return CRYPTO_is_NEON_capable();
}
@@ -375,7 +375,7 @@ void gcm_ghash_neon(uint64_t Xi[2], const u128 Htable[16], const uint8_t *inp,
size_t len);
#else
/* AArch64 only has the ARMv8 versions of functions. */
-static int neon_capable() {
+static int neon_capable(void) {
return 0;
}
void gcm_init_neon(u128 Htable[16], const uint64_t Xi[2]) {
diff --git a/src/crypto/modes/gcm_test.c b/src/crypto/modes/gcm_test.c
index a8819ea..89ed792 100644
--- a/src/crypto/modes/gcm_test.c
+++ b/src/crypto/modes/gcm_test.c
@@ -55,6 +55,7 @@
#include <openssl/modes.h>
#include "internal.h"
+#include "../test/test_util.h"
struct test_case {
@@ -298,17 +299,6 @@ err:
return 0;
}
-void hexdump(const char *msg, const void *in, size_t len) {
- const uint8_t *data = in;
- size_t i;
-
- fprintf(stderr, "%s: ", msg);
- for (i = 0; i < len; i++) {
- fprintf(stderr, "%02x", data[i]);
- }
- fprintf(stderr, "\n");
-}
-
static int run_test_case(unsigned test_num, const struct test_case *test) {
size_t key_len, plaintext_len, additional_data_len, nonce_len, ciphertext_len,
tag_len;
@@ -367,8 +357,8 @@ static int run_test_case(unsigned test_num, const struct test_case *test) {
if (!CRYPTO_gcm128_finish(&ctx, tag, tag_len) ||
(ciphertext && memcmp(out, ciphertext, plaintext_len) != 0)) {
fprintf(stderr, "%u: encrypt failed.\n", test_num);
- hexdump("got ", out, plaintext_len);
- hexdump("want", ciphertext, plaintext_len);
+ hexdump(stderr, "got :", out, plaintext_len);
+ hexdump(stderr, "want:", ciphertext, plaintext_len);
goto out;
}
diff --git a/src/crypto/modes/internal.h b/src/crypto/modes/internal.h
index d12405e..caeac40 100644
--- a/src/crypto/modes/internal.h
+++ b/src/crypto/modes/internal.h
@@ -173,11 +173,6 @@ struct gcm128_context {
void *key;
};
-struct xts128_context {
- void *key1, *key2;
- block128_f block1, block2;
-};
-
struct ccm128_context {
union {
uint64_t u[2];
diff --git a/src/crypto/obj/CMakeLists.txt b/src/crypto/obj/CMakeLists.txt
index a27e504..b8a4ef3 100644
--- a/src/crypto/obj/CMakeLists.txt
+++ b/src/crypto/obj/CMakeLists.txt
@@ -1,4 +1,4 @@
-include_directories(. .. ../../include)
+include_directories(../../include)
add_library(
obj
diff --git a/src/crypto/obj/obj.c b/src/crypto/obj/obj.c
index bf16d17..94f739c 100644
--- a/src/crypto/obj/obj.c
+++ b/src/crypto/obj/obj.c
@@ -108,7 +108,7 @@ ASN1_OBJECT *OBJ_dup(const ASN1_OBJECT *o) {
r = ASN1_OBJECT_new();
if (r == NULL) {
- OPENSSL_PUT_ERROR(OBJ, OBJ_dup, ERR_R_ASN1_LIB);
+ OPENSSL_PUT_ERROR(OBJ, ERR_R_ASN1_LIB);
return NULL;
}
r->ln = r->sn = NULL;
@@ -149,7 +149,7 @@ ASN1_OBJECT *OBJ_dup(const ASN1_OBJECT *o) {
return r;
err:
- OPENSSL_PUT_ERROR(OBJ, OBJ_dup, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(OBJ, ERR_R_MALLOC_FAILURE);
OPENSSL_free(ln);
OPENSSL_free(sn);
OPENSSL_free(data);
@@ -337,7 +337,7 @@ const ASN1_OBJECT *OBJ_nid2obj(int nid) {
CRYPTO_STATIC_MUTEX_unlock(&global_added_lock);
err:
- OPENSSL_PUT_ERROR(OBJ, OBJ_nid2obj, OBJ_R_UNKNOWN_NID);
+ OPENSSL_PUT_ERROR(OBJ, OBJ_R_UNKNOWN_NID);
return NULL;
}
@@ -388,7 +388,7 @@ ASN1_OBJECT *OBJ_txt2obj(const char *s, int dont_search_names) {
buf = OPENSSL_malloc(total_len);
if (buf == NULL) {
- OPENSSL_PUT_ERROR(OBJ, OBJ_txt2obj, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(OBJ, ERR_R_MALLOC_FAILURE);
return NULL;
}
@@ -636,7 +636,7 @@ int OBJ_create(const char *oid, const char *short_name, const char *long_name) {
buf = OPENSSL_malloc(len);
if (buf == NULL) {
- OPENSSL_PUT_ERROR(OBJ, OBJ_create, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(OBJ, ERR_R_MALLOC_FAILURE);
goto err;
}
diff --git a/src/crypto/pem/CMakeLists.txt b/src/crypto/pem/CMakeLists.txt
index 720ba2f..30dd7c9 100644
--- a/src/crypto/pem/CMakeLists.txt
+++ b/src/crypto/pem/CMakeLists.txt
@@ -1,4 +1,4 @@
-include_directories(. .. ../../include)
+include_directories(../../include)
add_library(
pem
diff --git a/src/crypto/pem/pem_info.c b/src/crypto/pem/pem_info.c
index 3f02619..b4ae805 100644
--- a/src/crypto/pem/pem_info.c
+++ b/src/crypto/pem/pem_info.c
@@ -80,7 +80,7 @@ STACK_OF(X509_INFO) *PEM_X509_INFO_read(FILE *fp, STACK_OF(X509_INFO) *sk, pem_p
if ((b=BIO_new(BIO_s_file())) == NULL)
{
- OPENSSL_PUT_ERROR(PEM, PEM_X509_INFO_read, ERR_R_BUF_LIB);
+ OPENSSL_PUT_ERROR(PEM, ERR_R_BUF_LIB);
return(0);
}
BIO_set_fp(b,fp,BIO_NOCLOSE);
@@ -107,7 +107,7 @@ STACK_OF(X509_INFO) *PEM_X509_INFO_read_bio(BIO *bp, STACK_OF(X509_INFO) *sk, pe
{
if ((ret=sk_X509_INFO_new_null()) == NULL)
{
- OPENSSL_PUT_ERROR(PEM, PEM_X509_INFO_read_bio, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(PEM, ERR_R_MALLOC_FAILURE);
goto err;
}
}
@@ -248,13 +248,13 @@ start:
{
if (!d2i_PrivateKey(ptype, pp, &p, len))
{
- OPENSSL_PUT_ERROR(PEM, PEM_X509_INFO_read_bio, ERR_R_ASN1_LIB);
+ OPENSSL_PUT_ERROR(PEM, ERR_R_ASN1_LIB);
goto err;
}
}
else if (d2i(pp,&p,len) == NULL)
{
- OPENSSL_PUT_ERROR(PEM, PEM_X509_INFO_read_bio, ERR_R_ASN1_LIB);
+ OPENSSL_PUT_ERROR(PEM, ERR_R_ASN1_LIB);
goto err;
}
}
@@ -326,7 +326,7 @@ int PEM_X509_INFO_write_bio(BIO *bp, X509_INFO *xi, EVP_CIPHER *enc,
objstr=OBJ_nid2sn(EVP_CIPHER_nid(enc));
if (objstr == NULL)
{
- OPENSSL_PUT_ERROR(PEM, PEM_X509_INFO_write_bio, PEM_R_UNSUPPORTED_CIPHER);
+ OPENSSL_PUT_ERROR(PEM, PEM_R_UNSUPPORTED_CIPHER);
goto err;
}
}
@@ -342,7 +342,7 @@ int PEM_X509_INFO_write_bio(BIO *bp, X509_INFO *xi, EVP_CIPHER *enc,
{
if (enc == NULL)
{
- OPENSSL_PUT_ERROR(PEM, PEM_X509_INFO_write_bio, PEM_R_CIPHER_IS_NULL);
+ OPENSSL_PUT_ERROR(PEM, PEM_R_CIPHER_IS_NULL);
goto err;
}
@@ -360,7 +360,7 @@ int PEM_X509_INFO_write_bio(BIO *bp, X509_INFO *xi, EVP_CIPHER *enc,
EVP_CIPHER_nid(xi->enc_cipher.cipher));
if (objstr == NULL)
{
- OPENSSL_PUT_ERROR(PEM, PEM_X509_INFO_write_bio, PEM_R_UNSUPPORTED_CIPHER);
+ OPENSSL_PUT_ERROR(PEM, PEM_R_UNSUPPORTED_CIPHER);
goto err;
}
diff --git a/src/crypto/pem/pem_lib.c b/src/crypto/pem/pem_lib.c
index 5201467..5915696 100644
--- a/src/crypto/pem/pem_lib.c
+++ b/src/crypto/pem/pem_lib.c
@@ -128,7 +128,7 @@ void *PEM_ASN1_read(d2i_of_void *d2i, const char *name, FILE *fp, void **x,
if ((b=BIO_new(BIO_s_file())) == NULL)
{
- OPENSSL_PUT_ERROR(PEM, PEM_ASN1_read, ERR_R_BUF_LIB);
+ OPENSSL_PUT_ERROR(PEM, ERR_R_BUF_LIB);
return(0);
}
BIO_set_fp(b,fp,BIO_NOCLOSE);
@@ -275,7 +275,7 @@ int PEM_ASN1_write(i2d_of_void *i2d, const char *name, FILE *fp,
if ((b=BIO_new(BIO_s_file())) == NULL)
{
- OPENSSL_PUT_ERROR(PEM, PEM_ASN1_write, ERR_R_BUF_LIB);
+ OPENSSL_PUT_ERROR(PEM, ERR_R_BUF_LIB);
return(0);
}
BIO_set_fp(b,fp,BIO_NOCLOSE);
@@ -302,14 +302,14 @@ int PEM_ASN1_write_bio(i2d_of_void *i2d, const char *name, BIO *bp,
objstr=OBJ_nid2sn(EVP_CIPHER_nid(enc));
if (objstr == NULL)
{
- OPENSSL_PUT_ERROR(PEM, PEM_ASN1_write_bio, PEM_R_UNSUPPORTED_CIPHER);
+ OPENSSL_PUT_ERROR(PEM, PEM_R_UNSUPPORTED_CIPHER);
goto err;
}
}
if ((dsize=i2d(x,NULL)) < 0)
{
- OPENSSL_PUT_ERROR(PEM, PEM_ASN1_write_bio, ERR_R_ASN1_LIB);
+ OPENSSL_PUT_ERROR(PEM, ERR_R_ASN1_LIB);
dsize=0;
goto err;
}
@@ -318,7 +318,7 @@ int PEM_ASN1_write_bio(i2d_of_void *i2d, const char *name, BIO *bp,
data=(unsigned char *)OPENSSL_malloc((unsigned int)dsize+20);
if (data == NULL)
{
- OPENSSL_PUT_ERROR(PEM, PEM_ASN1_write_bio, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(PEM, ERR_R_MALLOC_FAILURE);
goto err;
}
p=data;
@@ -336,7 +336,7 @@ int PEM_ASN1_write_bio(i2d_of_void *i2d, const char *name, BIO *bp,
klen=(*callback)(buf,PEM_BUFSIZE,1,u);
if (klen <= 0)
{
- OPENSSL_PUT_ERROR(PEM, PEM_ASN1_write_bio, PEM_R_READ_KEY);
+ OPENSSL_PUT_ERROR(PEM, PEM_R_READ_KEY);
goto err;
}
kstr=(unsigned char *)buf;
@@ -408,7 +408,7 @@ int PEM_do_header(EVP_CIPHER_INFO *cipher, unsigned char *data, long *plen,
klen=callback(buf,PEM_BUFSIZE,0,u);
if (klen <= 0)
{
- OPENSSL_PUT_ERROR(PEM, PEM_do_header, PEM_R_BAD_PASSWORD_READ);
+ OPENSSL_PUT_ERROR(PEM, PEM_R_BAD_PASSWORD_READ);
return(0);
}
@@ -428,7 +428,7 @@ int PEM_do_header(EVP_CIPHER_INFO *cipher, unsigned char *data, long *plen,
OPENSSL_cleanse((char *)key,sizeof(key));
if (!o)
{
- OPENSSL_PUT_ERROR(PEM, PEM_do_header, PEM_R_BAD_DECRYPT);
+ OPENSSL_PUT_ERROR(PEM, PEM_R_BAD_DECRYPT);
return(0);
}
j+=i;
@@ -437,11 +437,18 @@ int PEM_do_header(EVP_CIPHER_INFO *cipher, unsigned char *data, long *plen,
}
static const EVP_CIPHER* cipher_by_name(const char *name) {
- if (strcmp(name, "DES-CBC") == 0) {
+ /* This is similar to the (deprecated) function |EVP_get_cipherbyname|. */
+ if (0 == strcmp(name, SN_rc4)) {
+ return EVP_rc4();
+ } else if (0 == strcmp(name, SN_des_cbc)) {
return EVP_des_cbc();
- } else if (strcmp(name, "AES-128-CBC") == 0) {
+ } else if (0 == strcmp(name, SN_des_ede3_cbc)) {
+ return EVP_des_ede3_cbc();
+ } else if (0 == strcmp(name, SN_aes_128_cbc)) {
return EVP_aes_128_cbc();
- } else if (strcmp(name, "AES-256-CBC") == 0) {
+ } else if (0 == strcmp(name, SN_aes_192_cbc)) {
+ return EVP_aes_192_cbc();
+ } else if (0 == strcmp(name, SN_aes_256_cbc)) {
return EVP_aes_256_cbc();
} else {
return NULL;
@@ -458,19 +465,19 @@ int PEM_get_EVP_CIPHER_INFO(char *header, EVP_CIPHER_INFO *cipher)
if ((header == NULL) || (*header == '\0') || (*header == '\n'))
return(1);
if (strncmp(header,"Proc-Type: ",11) != 0)
- { OPENSSL_PUT_ERROR(PEM, PEM_get_EVP_CIPHER_INFO, PEM_R_NOT_PROC_TYPE); return(0); }
+ { OPENSSL_PUT_ERROR(PEM, PEM_R_NOT_PROC_TYPE); return(0); }
header+=11;
if (*header != '4') return(0); header++;
if (*header != ',') return(0); header++;
if (strncmp(header,"ENCRYPTED",9) != 0)
- { OPENSSL_PUT_ERROR(PEM, PEM_get_EVP_CIPHER_INFO, PEM_R_NOT_ENCRYPTED); return(0); }
+ { OPENSSL_PUT_ERROR(PEM, PEM_R_NOT_ENCRYPTED); return(0); }
for (; (*header != '\n') && (*header != '\0'); header++)
;
if (*header == '\0')
- { OPENSSL_PUT_ERROR(PEM, PEM_get_EVP_CIPHER_INFO, PEM_R_SHORT_HEADER); return(0); }
+ { OPENSSL_PUT_ERROR(PEM, PEM_R_SHORT_HEADER); return(0); }
header++;
if (strncmp(header,"DEK-Info: ",10) != 0)
- { OPENSSL_PUT_ERROR(PEM, PEM_get_EVP_CIPHER_INFO, PEM_R_NOT_DEK_INFO); return(0); }
+ { OPENSSL_PUT_ERROR(PEM, PEM_R_NOT_DEK_INFO); return(0); }
header+=10;
p=header;
@@ -489,7 +496,7 @@ int PEM_get_EVP_CIPHER_INFO(char *header, EVP_CIPHER_INFO *cipher)
if (enc == NULL)
{
- OPENSSL_PUT_ERROR(PEM, PEM_get_EVP_CIPHER_INFO, PEM_R_UNSUPPORTED_ENCRYPTION);
+ OPENSSL_PUT_ERROR(PEM, PEM_R_UNSUPPORTED_ENCRYPTION);
return(0);
}
if (!load_iv(header_pp,&(cipher->iv[0]),EVP_CIPHER_iv_length(enc)))
@@ -516,7 +523,7 @@ static int load_iv(char **fromp, unsigned char *to, int num)
v= *from-'a'+10;
else
{
- OPENSSL_PUT_ERROR(PEM, load_iv, PEM_R_BAD_IV_CHARS);
+ OPENSSL_PUT_ERROR(PEM, PEM_R_BAD_IV_CHARS);
return(0);
}
from++;
@@ -536,7 +543,7 @@ int PEM_write(FILE *fp, const char *name, const char *header,
if ((b=BIO_new(BIO_s_file())) == NULL)
{
- OPENSSL_PUT_ERROR(PEM, PEM_write, ERR_R_BUF_LIB);
+ OPENSSL_PUT_ERROR(PEM, ERR_R_BUF_LIB);
return(0);
}
BIO_set_fp(b,fp,BIO_NOCLOSE);
@@ -603,7 +610,7 @@ err:
OPENSSL_cleanse(buf, PEM_BUFSIZE*8);
OPENSSL_free(buf);
}
- OPENSSL_PUT_ERROR(PEM, PEM_write_bio, reason);
+ OPENSSL_PUT_ERROR(PEM, reason);
return(0);
}
@@ -616,7 +623,7 @@ int PEM_read(FILE *fp, char **name, char **header, unsigned char **data,
if ((b=BIO_new(BIO_s_file())) == NULL)
{
- OPENSSL_PUT_ERROR(PEM, PEM_read, ERR_R_BUF_LIB);
+ OPENSSL_PUT_ERROR(PEM, ERR_R_BUF_LIB);
return(0);
}
BIO_set_fp(b,fp,BIO_NOCLOSE);
@@ -644,7 +651,7 @@ int PEM_read_bio(BIO *bp, char **name, char **header, unsigned char **data,
BUF_MEM_free(nameB);
BUF_MEM_free(headerB);
BUF_MEM_free(dataB);
- OPENSSL_PUT_ERROR(PEM, PEM_read_bio, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(PEM, ERR_R_MALLOC_FAILURE);
return(0);
}
@@ -655,7 +662,7 @@ int PEM_read_bio(BIO *bp, char **name, char **header, unsigned char **data,
if (i <= 0)
{
- OPENSSL_PUT_ERROR(PEM, PEM_read_bio, PEM_R_NO_START_LINE);
+ OPENSSL_PUT_ERROR(PEM, PEM_R_NO_START_LINE);
goto err;
}
@@ -670,7 +677,7 @@ int PEM_read_bio(BIO *bp, char **name, char **header, unsigned char **data,
continue;
if (!BUF_MEM_grow(nameB,i+9))
{
- OPENSSL_PUT_ERROR(PEM, PEM_read_bio, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(PEM, ERR_R_MALLOC_FAILURE);
goto err;
}
memcpy(nameB->data,&(buf[11]),i-6);
@@ -680,7 +687,7 @@ int PEM_read_bio(BIO *bp, char **name, char **header, unsigned char **data,
}
hl=0;
if (!BUF_MEM_grow(headerB,256))
- { OPENSSL_PUT_ERROR(PEM, PEM_read_bio, ERR_R_MALLOC_FAILURE); goto err; }
+ { OPENSSL_PUT_ERROR(PEM, ERR_R_MALLOC_FAILURE); goto err; }
headerB->data[0]='\0';
for (;;)
{
@@ -692,7 +699,7 @@ int PEM_read_bio(BIO *bp, char **name, char **header, unsigned char **data,
if (buf[0] == '\n') break;
if (!BUF_MEM_grow(headerB,hl+i+9))
- { OPENSSL_PUT_ERROR(PEM, PEM_read_bio, ERR_R_MALLOC_FAILURE); goto err; }
+ { OPENSSL_PUT_ERROR(PEM, ERR_R_MALLOC_FAILURE); goto err; }
if (strncmp(buf,"-----END ",9) == 0)
{
nohead=1;
@@ -705,7 +712,7 @@ int PEM_read_bio(BIO *bp, char **name, char **header, unsigned char **data,
bl=0;
if (!BUF_MEM_grow(dataB,1024))
- { OPENSSL_PUT_ERROR(PEM, PEM_read_bio, ERR_R_MALLOC_FAILURE); goto err; }
+ { OPENSSL_PUT_ERROR(PEM, ERR_R_MALLOC_FAILURE); goto err; }
dataB->data[0]='\0';
if (!nohead)
{
@@ -723,7 +730,7 @@ int PEM_read_bio(BIO *bp, char **name, char **header, unsigned char **data,
if (i > 65) break;
if (!BUF_MEM_grow_clean(dataB,i+bl+9))
{
- OPENSSL_PUT_ERROR(PEM, PEM_read_bio, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(PEM, ERR_R_MALLOC_FAILURE);
goto err;
}
memcpy(&(dataB->data[bl]),buf,i);
@@ -754,7 +761,7 @@ int PEM_read_bio(BIO *bp, char **name, char **header, unsigned char **data,
(strncmp(nameB->data,&(buf[9]),i) != 0) ||
(strncmp(&(buf[9+i]),"-----\n",6) != 0))
{
- OPENSSL_PUT_ERROR(PEM, PEM_read_bio, PEM_R_BAD_END_LINE);
+ OPENSSL_PUT_ERROR(PEM, PEM_R_BAD_END_LINE);
goto err;
}
@@ -764,13 +771,13 @@ int PEM_read_bio(BIO *bp, char **name, char **header, unsigned char **data,
(unsigned char *)dataB->data,bl);
if (i < 0)
{
- OPENSSL_PUT_ERROR(PEM, PEM_read_bio, PEM_R_BAD_BASE64_DECODE);
+ OPENSSL_PUT_ERROR(PEM, PEM_R_BAD_BASE64_DECODE);
goto err;
}
i=EVP_DecodeFinal(&ctx,(unsigned char *)&(dataB->data[bl]),&k);
if (i < 0)
{
- OPENSSL_PUT_ERROR(PEM, PEM_read_bio, PEM_R_BAD_BASE64_DECODE);
+ OPENSSL_PUT_ERROR(PEM, PEM_R_BAD_BASE64_DECODE);
goto err;
}
bl+=k;
diff --git a/src/crypto/pem/pem_oth.c b/src/crypto/pem/pem_oth.c
index 20d12b6..3e8f6bd 100644
--- a/src/crypto/pem/pem_oth.c
+++ b/src/crypto/pem/pem_oth.c
@@ -83,7 +83,7 @@ void *PEM_ASN1_read_bio(d2i_of_void *d2i, const char *name, BIO *bp, void **x,
p = data;
ret=d2i(x,&p,len);
if (ret == NULL)
- OPENSSL_PUT_ERROR(PEM, PEM_ASN1_read_bio, ERR_R_ASN1_LIB);
+ OPENSSL_PUT_ERROR(PEM, ERR_R_ASN1_LIB);
OPENSSL_free(data);
return ret;
}
diff --git a/src/crypto/pem/pem_pk8.c b/src/crypto/pem/pem_pk8.c
index 035038e..0824477 100644
--- a/src/crypto/pem/pem_pk8.c
+++ b/src/crypto/pem/pem_pk8.c
@@ -118,7 +118,7 @@ static int do_pk8pkey(BIO *bp, EVP_PKEY *x, int isder, int nid, const EVP_CIPHER
char buf[PEM_BUFSIZE];
int ret;
if(!(p8inf = EVP_PKEY2PKCS8(x))) {
- OPENSSL_PUT_ERROR(PEM, do_pk8pkey, PEM_R_ERROR_CONVERTING_PRIVATE_KEY);
+ OPENSSL_PUT_ERROR(PEM, PEM_R_ERROR_CONVERTING_PRIVATE_KEY);
return 0;
}
if(enc || (nid != -1)) {
@@ -127,7 +127,7 @@ static int do_pk8pkey(BIO *bp, EVP_PKEY *x, int isder, int nid, const EVP_CIPHER
if (!cb) cb = PEM_def_callback;
klen = cb(buf, PEM_BUFSIZE, 1, u);
if(klen <= 0) {
- OPENSSL_PUT_ERROR(PEM, do_pk8pkey, PEM_R_READ_KEY);
+ OPENSSL_PUT_ERROR(PEM, PEM_R_READ_KEY);
PKCS8_PRIV_KEY_INFO_free(p8inf);
return 0;
}
@@ -163,7 +163,7 @@ EVP_PKEY *d2i_PKCS8PrivateKey_bio(BIO *bp, EVP_PKEY **x, pem_password_cb *cb, vo
if (!cb) cb = PEM_def_callback;
klen=cb(psbuf,PEM_BUFSIZE,0,u);
if (klen <= 0) {
- OPENSSL_PUT_ERROR(PEM, d2i_PKCS8PrivateKey_bio, PEM_R_BAD_PASSWORD_READ);
+ OPENSSL_PUT_ERROR(PEM, PEM_R_BAD_PASSWORD_READ);
X509_SIG_free(p8);
return NULL;
}
@@ -216,7 +216,7 @@ static int do_pk8pkey_fp(FILE *fp, EVP_PKEY *x, int isder, int nid, const EVP_CI
BIO *bp;
int ret;
if(!(bp = BIO_new_fp(fp, BIO_NOCLOSE))) {
- OPENSSL_PUT_ERROR(PEM, do_pk8pkey_fp, ERR_R_BUF_LIB);
+ OPENSSL_PUT_ERROR(PEM, ERR_R_BUF_LIB);
return(0);
}
ret = do_pk8pkey(bp, x, isder, nid, enc, kstr, klen, cb, u);
@@ -229,7 +229,7 @@ EVP_PKEY *d2i_PKCS8PrivateKey_fp(FILE *fp, EVP_PKEY **x, pem_password_cb *cb, vo
BIO *bp;
EVP_PKEY *ret;
if(!(bp = BIO_new_fp(fp, BIO_NOCLOSE))) {
- OPENSSL_PUT_ERROR(PEM, d2i_PKCS8PrivateKey_fp, ERR_R_BUF_LIB);
+ OPENSSL_PUT_ERROR(PEM, ERR_R_BUF_LIB);
return NULL;
}
ret = d2i_PKCS8PrivateKey_bio(bp, x, cb, u);
diff --git a/src/crypto/pem/pem_pkey.c b/src/crypto/pem/pem_pkey.c
index fe58558..c462727 100644
--- a/src/crypto/pem/pem_pkey.c
+++ b/src/crypto/pem/pem_pkey.c
@@ -109,7 +109,7 @@ EVP_PKEY *PEM_read_bio_PrivateKey(BIO *bp, EVP_PKEY **x, pem_password_cb *cb, vo
if (!cb) cb = PEM_def_callback;
klen=cb(psbuf,PEM_BUFSIZE,0,u);
if (klen <= 0) {
- OPENSSL_PUT_ERROR(PEM, PEM_read_bio_PrivateKey, PEM_R_BAD_PASSWORD_READ);
+ OPENSSL_PUT_ERROR(PEM, PEM_R_BAD_PASSWORD_READ);
X509_SIG_free(p8);
goto err;
}
@@ -132,7 +132,7 @@ EVP_PKEY *PEM_read_bio_PrivateKey(BIO *bp, EVP_PKEY **x, pem_password_cb *cb, vo
}
p8err:
if (ret == NULL)
- OPENSSL_PUT_ERROR(PEM, PEM_read_bio_PrivateKey, ERR_R_ASN1_LIB);
+ OPENSSL_PUT_ERROR(PEM, ERR_R_ASN1_LIB);
err:
OPENSSL_free(nm);
@@ -210,7 +210,7 @@ EVP_PKEY *PEM_read_bio_Parameters(BIO *bp, EVP_PKEY **x)
}
err:
if (ret == NULL)
- OPENSSL_PUT_ERROR(PEM, PEM_read_bio_Parameters, ERR_R_ASN1_LIB);
+ OPENSSL_PUT_ERROR(PEM, ERR_R_ASN1_LIB);
OPENSSL_free(nm);
OPENSSL_free(data);
return(ret);
@@ -236,7 +236,7 @@ EVP_PKEY *PEM_read_PrivateKey(FILE *fp, EVP_PKEY **x, pem_password_cb *cb, void
if ((b=BIO_new(BIO_s_file())) == NULL)
{
- OPENSSL_PUT_ERROR(PEM, PEM_read_PrivateKey, ERR_R_BUF_LIB);
+ OPENSSL_PUT_ERROR(PEM, ERR_R_BUF_LIB);
return(0);
}
BIO_set_fp(b,fp,BIO_NOCLOSE);
@@ -254,7 +254,7 @@ int PEM_write_PrivateKey(FILE *fp, EVP_PKEY *x, const EVP_CIPHER *enc,
if ((b=BIO_new_fp(fp, BIO_NOCLOSE)) == NULL)
{
- OPENSSL_PUT_ERROR(PEM, PEM_write_PrivateKey, ERR_R_BUF_LIB);
+ OPENSSL_PUT_ERROR(PEM, ERR_R_BUF_LIB);
return 0;
}
ret=PEM_write_bio_PrivateKey(b, x, enc, kstr, klen, cb, u);
@@ -287,7 +287,7 @@ DH *PEM_read_bio_DHparams(BIO *bp, DH **x, pem_password_cb *cb, void *u)
ret = d2i_DHparams(x, &p, len);
if (ret == NULL)
- OPENSSL_PUT_ERROR(PEM, PEM_read_bio_DHparams, ERR_R_ASN1_LIB);
+ OPENSSL_PUT_ERROR(PEM, ERR_R_ASN1_LIB);
OPENSSL_free(nm);
OPENSSL_free(data);
return ret;
@@ -301,7 +301,7 @@ DH *PEM_read_DHparams(FILE *fp, DH **x, pem_password_cb *cb, void *u)
if ((b=BIO_new(BIO_s_file())) == NULL)
{
- OPENSSL_PUT_ERROR(PEM, PEM_read_DHparams, ERR_R_BUF_LIB);
+ OPENSSL_PUT_ERROR(PEM, ERR_R_BUF_LIB);
return(0);
}
BIO_set_fp(b,fp,BIO_NOCLOSE);
diff --git a/src/crypto/perlasm/arm-xlate.pl b/src/crypto/perlasm/arm-xlate.pl
index 81ceb31..706fa70 100755
--- a/src/crypto/perlasm/arm-xlate.pl
+++ b/src/crypto/perlasm/arm-xlate.pl
@@ -116,6 +116,9 @@ sub expand_line {
return $line;
}
+print "#if defined(__arm__)\n" if ($flavour eq "linux32");
+print "#if defined(__aarch64__)\n" if ($flavour eq "linux64");
+
while($line=<>) {
if ($line =~ m/^\s*(#|@|\/\/)/) { print $line; next; }
@@ -162,4 +165,6 @@ while($line=<>) {
print "\n";
}
+print "#endif" if ($flavour eq "linux32" || $flavour eq "linux64");
+
close STDOUT;
diff --git a/src/crypto/pkcs8/CMakeLists.txt b/src/crypto/pkcs8/CMakeLists.txt
index 4426f1e..ce5bce1 100644
--- a/src/crypto/pkcs8/CMakeLists.txt
+++ b/src/crypto/pkcs8/CMakeLists.txt
@@ -1,4 +1,4 @@
-include_directories(. .. ../../include)
+include_directories(../../include)
add_library(
pkcs8
@@ -19,4 +19,11 @@ add_executable(
$<TARGET_OBJECTS:test_support>
)
+add_executable(
+ pkcs8_test
+
+ pkcs8_test.cc
+)
+
+target_link_libraries(pkcs8_test crypto)
target_link_libraries(pkcs12_test crypto)
diff --git a/src/crypto/pkcs8/internal.h b/src/crypto/pkcs8/internal.h
index 44ca4f7..7995e78 100644
--- a/src/crypto/pkcs8/internal.h
+++ b/src/crypto/pkcs8/internal.h
@@ -66,6 +66,15 @@ extern "C" {
#define PKCS5_DEFAULT_ITERATIONS 2048
#define PKCS5_SALT_LEN 8
+/* PKCS5_v2_PBE_keyivgen intializes the supplied |ctx| for PBKDF v2, which must
+ * be specified by |param|. The password is specified by |pass_raw| and
+ * |pass_raw_len|. |cipher| and |md| are ignored.
+ *
+ * It returns one on success and zero on error. */
+int PKCS5_v2_PBE_keyivgen(EVP_CIPHER_CTX *ctx, const uint8_t *pass_raw,
+ size_t pass_raw_len, ASN1_TYPE *param,
+ const EVP_CIPHER *cipher, const EVP_MD *md, int enc);
+
#if defined(__cplusplus)
} /* extern C */
diff --git a/src/crypto/pkcs8/p5_pbe.c b/src/crypto/pkcs8/p5_pbe.c
index f30ae79..653cabf 100644
--- a/src/crypto/pkcs8/p5_pbe.c
+++ b/src/crypto/pkcs8/p5_pbe.c
@@ -86,21 +86,21 @@ int PKCS5_pbe_set0_algor(X509_ALGOR *algor, int alg, int iter,
pbe = PBEPARAM_new();
if (!pbe)
{
- OPENSSL_PUT_ERROR(PKCS8, PKCS5_pbe_set0_algor, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(PKCS8, ERR_R_MALLOC_FAILURE);
goto err;
}
if(iter <= 0)
iter = PKCS5_DEFAULT_ITERATIONS;
if (!ASN1_INTEGER_set(pbe->iter, iter))
{
- OPENSSL_PUT_ERROR(PKCS8, PKCS5_pbe_set0_algor, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(PKCS8, ERR_R_MALLOC_FAILURE);
goto err;
}
if (!saltlen)
saltlen = PKCS5_SALT_LEN;
if (!ASN1_STRING_set(pbe->salt, NULL, saltlen))
{
- OPENSSL_PUT_ERROR(PKCS8, PKCS5_pbe_set0_algor, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(PKCS8, ERR_R_MALLOC_FAILURE);
goto err;
}
sstr = ASN1_STRING_data(pbe->salt);
@@ -111,7 +111,7 @@ int PKCS5_pbe_set0_algor(X509_ALGOR *algor, int alg, int iter,
if(!ASN1_item_pack(pbe, ASN1_ITEM_rptr(PBEPARAM), &pbe_str))
{
- OPENSSL_PUT_ERROR(PKCS8, PKCS5_pbe_set0_algor, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(PKCS8, ERR_R_MALLOC_FAILURE);
goto err;
}
@@ -138,7 +138,7 @@ X509_ALGOR *PKCS5_pbe_set(int alg, int iter,
ret = X509_ALGOR_new();
if (!ret)
{
- OPENSSL_PUT_ERROR(PKCS8, PKCS5_pbe_set, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(PKCS8, ERR_R_MALLOC_FAILURE);
return NULL;
}
diff --git a/src/crypto/pkcs8/p5_pbev2.c b/src/crypto/pkcs8/p5_pbev2.c
index 9eb9848..f58aae7 100644
--- a/src/crypto/pkcs8/p5_pbev2.c
+++ b/src/crypto/pkcs8/p5_pbev2.c
@@ -53,6 +53,8 @@
* (eay@cryptsoft.com). This product includes software written by Tim
* Hudson (tjh@cryptsoft.com). */
+#include <assert.h>
+#include <limits.h>
#include <string.h>
#include <openssl/asn1t.h>
@@ -124,7 +126,7 @@ X509_ALGOR *PKCS5_pbe2_set_iv(const EVP_CIPHER *cipher, int iter,
alg_nid = EVP_CIPHER_nid(cipher);
if(alg_nid == NID_undef) {
- OPENSSL_PUT_ERROR(PKCS8, PKCS5_pbe2_set_iv, PKCS8_R_CIPHER_HAS_NO_OBJECT_IDENTIFIER);
+ OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_CIPHER_HAS_NO_OBJECT_IDENTIFIER);
goto err;
}
obj = OBJ_nid2obj(alg_nid);
@@ -152,7 +154,7 @@ X509_ALGOR *PKCS5_pbe2_set_iv(const EVP_CIPHER *cipher, int iter,
if (!EVP_CipherInit_ex(&ctx, cipher, NULL, NULL, iv, 0))
goto err;
if(param_to_asn1(&ctx, scheme->parameter) < 0) {
- OPENSSL_PUT_ERROR(PKCS8, PKCS5_pbe2_set_iv, PKCS8_R_ERROR_SETTING_CIPHER_PARAMS);
+ OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_ERROR_SETTING_CIPHER_PARAMS);
EVP_CIPHER_CTX_cleanup(&ctx);
goto err;
}
@@ -202,7 +204,7 @@ X509_ALGOR *PKCS5_pbe2_set_iv(const EVP_CIPHER *cipher, int iter,
return ret;
merr:
- OPENSSL_PUT_ERROR(PKCS8, PKCS5_pbe2_set_iv, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(PKCS8, ERR_R_MALLOC_FAILURE);
err:
PBE2PARAM_free(pbe2);
@@ -295,9 +297,143 @@ X509_ALGOR *PKCS5_pbkdf2_set(int iter, unsigned char *salt, int saltlen,
return keyfunc;
merr:
- OPENSSL_PUT_ERROR(PKCS8, PKCS5_pbkdf2_set, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(PKCS8, ERR_R_MALLOC_FAILURE);
PBKDF2PARAM_free(kdf);
X509_ALGOR_free(keyfunc);
return NULL;
}
+static int PKCS5_v2_PBKDF2_keyivgen(EVP_CIPHER_CTX *ctx,
+ const uint8_t *pass_raw,
+ size_t pass_raw_len, const ASN1_TYPE *param,
+ const ASN1_TYPE *iv, int enc) {
+ int rv = 0;
+ PBKDF2PARAM *pbkdf2param = NULL;
+
+ if (EVP_CIPHER_CTX_cipher(ctx) == NULL) {
+ OPENSSL_PUT_ERROR(PKCS8, CIPHER_R_NO_CIPHER_SET);
+ goto err;
+ }
+
+ /* Decode parameters. */
+ if (param == NULL || param->type != V_ASN1_SEQUENCE) {
+ OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_DECODE_ERROR);
+ goto err;
+ }
+
+ const uint8_t *pbuf = param->value.sequence->data;
+ int plen = param->value.sequence->length;
+ pbkdf2param = d2i_PBKDF2PARAM(NULL, &pbuf, plen);
+ if (pbkdf2param == NULL || pbuf != param->value.sequence->data + plen) {
+ OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_DECODE_ERROR);
+ goto err;
+ }
+
+ /* Now check the parameters. */
+ uint8_t key[EVP_MAX_KEY_LENGTH];
+ const size_t key_len = EVP_CIPHER_CTX_key_length(ctx);
+ assert(key_len <= sizeof(key));
+
+ if (pbkdf2param->keylength != NULL &&
+ ASN1_INTEGER_get(pbkdf2param->keylength) != (int) key_len) {
+ OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_UNSUPPORTED_KEYLENGTH);
+ goto err;
+ }
+
+ if (pbkdf2param->prf != NULL &&
+ OBJ_obj2nid(pbkdf2param->prf->algorithm) != NID_hmacWithSHA1) {
+ OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_UNSUPPORTED_PRF);
+ goto err;
+ }
+
+ if (pbkdf2param->salt->type != V_ASN1_OCTET_STRING) {
+ OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_UNSUPPORTED_SALT_TYPE);
+ goto err;
+ }
+
+ if (pbkdf2param->iter->type != V_ASN1_INTEGER) {
+ OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_BAD_ITERATION_COUNT);
+ goto err;
+ }
+ long iterations = ASN1_INTEGER_get(pbkdf2param->iter);
+ if (iterations < 0 || iterations > UINT_MAX) {
+ OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_BAD_ITERATION_COUNT);
+ goto err;
+ }
+
+ if (iv->type != V_ASN1_OCTET_STRING || iv->value.octet_string == NULL) {
+ OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_ERROR_SETTING_CIPHER_PARAMS);
+ goto err;
+ }
+
+ const size_t iv_len = EVP_CIPHER_CTX_iv_length(ctx);
+ if (iv->value.octet_string->length != iv_len) {
+ OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_ERROR_SETTING_CIPHER_PARAMS);
+ goto err;
+ }
+
+ if (!PKCS5_PBKDF2_HMAC_SHA1((const char *) pass_raw, pass_raw_len,
+ pbkdf2param->salt->value.octet_string->data,
+ pbkdf2param->salt->value.octet_string->length,
+ iterations, key_len, key)) {
+ goto err;
+ }
+
+ rv = EVP_CipherInit_ex(ctx, NULL /* cipher */, NULL /* engine */, key,
+ iv->value.octet_string->data, enc);
+
+ err:
+ PBKDF2PARAM_free(pbkdf2param);
+ return rv;
+}
+
+int PKCS5_v2_PBE_keyivgen(EVP_CIPHER_CTX *ctx, const uint8_t *pass_raw,
+ size_t pass_raw_len, ASN1_TYPE *param,
+ const EVP_CIPHER *unused, const EVP_MD *unused2,
+ int enc) {
+ PBE2PARAM *pbe2param = NULL;
+ int rv = 0;
+
+ if (param == NULL ||
+ param->type != V_ASN1_SEQUENCE ||
+ param->value.sequence == NULL) {
+ OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_DECODE_ERROR);
+ goto err;
+ }
+
+ const uint8_t *pbuf = param->value.sequence->data;
+ int plen = param->value.sequence->length;
+ pbe2param = d2i_PBE2PARAM(NULL, &pbuf, plen);
+ if (pbe2param == NULL || pbuf != param->value.sequence->data + plen) {
+ OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_DECODE_ERROR);
+ goto err;
+ }
+
+ /* Check that the key derivation function is PBKDF2. */
+ if (OBJ_obj2nid(pbe2param->keyfunc->algorithm) != NID_id_pbkdf2) {
+ OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_UNSUPPORTED_KEY_DERIVATION_FUNCTION);
+ goto err;
+ }
+
+ /* See if we recognise the encryption algorithm. */
+ const EVP_CIPHER *cipher =
+ EVP_get_cipherbynid(OBJ_obj2nid(pbe2param->encryption->algorithm));
+ if (cipher == NULL) {
+ OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_UNSUPPORTED_CIPHER);
+ goto err;
+ }
+
+ /* Fixup cipher based on AlgorithmIdentifier. */
+ if (!EVP_CipherInit_ex(ctx, cipher, NULL /* engine */, NULL /* key */,
+ NULL /* iv */, enc)) {
+ goto err;
+ }
+
+ rv = PKCS5_v2_PBKDF2_keyivgen(ctx, pass_raw, pass_raw_len,
+ pbe2param->keyfunc->parameter,
+ pbe2param->encryption->parameter, enc);
+
+ err:
+ PBE2PARAM_free(pbe2param);
+ return rv;
+}
diff --git a/src/crypto/pkcs8/pkcs8.c b/src/crypto/pkcs8/pkcs8.c
index 843c74d..8067c91 100644
--- a/src/crypto/pkcs8/pkcs8.c
+++ b/src/crypto/pkcs8/pkcs8.c
@@ -69,6 +69,7 @@
#include <openssl/mem.h>
#include <openssl/x509.h>
+#include "internal.h"
#include "../bytestring/internal.h"
#include "../evp/internal.h"
@@ -200,7 +201,7 @@ static int pkcs12_key_gen_raw(const uint8_t *pass_raw, size_t pass_raw_len,
}
err:
- OPENSSL_PUT_ERROR(PKCS8, pkcs12_key_gen_raw, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(PKCS8, ERR_R_MALLOC_FAILURE);
end:
OPENSSL_free(Ai);
@@ -227,14 +228,14 @@ static int pkcs12_pbe_keyivgen(EVP_CIPHER_CTX *ctx, const uint8_t *pass_raw,
/* Extract useful info from parameter */
if (param == NULL || param->type != V_ASN1_SEQUENCE ||
param->value.sequence == NULL) {
- OPENSSL_PUT_ERROR(PKCS8, pkcs12_pbe_keyivgen, PKCS8_R_DECODE_ERROR);
+ OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_DECODE_ERROR);
return 0;
}
pbuf = param->value.sequence->data;
pbe = d2i_PBEPARAM(NULL, &pbuf, param->value.sequence->length);
if (pbe == NULL) {
- OPENSSL_PUT_ERROR(PKCS8, pkcs12_pbe_keyivgen, PKCS8_R_DECODE_ERROR);
+ OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_DECODE_ERROR);
return 0;
}
@@ -247,13 +248,13 @@ static int pkcs12_pbe_keyivgen(EVP_CIPHER_CTX *ctx, const uint8_t *pass_raw,
salt_len = pbe->salt->length;
if (!pkcs12_key_gen_raw(pass_raw, pass_raw_len, salt, salt_len, PKCS12_KEY_ID,
iterations, EVP_CIPHER_key_length(cipher), key, md)) {
- OPENSSL_PUT_ERROR(PKCS8, pkcs12_pbe_keyivgen, PKCS8_R_KEY_GEN_ERROR);
+ OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_KEY_GEN_ERROR);
PBEPARAM_free(pbe);
return 0;
}
if (!pkcs12_key_gen_raw(pass_raw, pass_raw_len, salt, salt_len, PKCS12_IV_ID,
iterations, EVP_CIPHER_iv_length(cipher), iv, md)) {
- OPENSSL_PUT_ERROR(PKCS8, pkcs12_pbe_keyivgen, PKCS8_R_KEY_GEN_ERROR);
+ OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_KEY_GEN_ERROR);
PBEPARAM_free(pbe);
return 0;
}
@@ -274,42 +275,93 @@ struct pbe_suite {
const EVP_CIPHER* (*cipher_func)(void);
const EVP_MD* (*md_func)(void);
keygen_func keygen;
+ int flags;
};
+#define PBE_UCS2_CONVERT_PASSWORD 0x1
+
static const struct pbe_suite kBuiltinPBE[] = {
{
- NID_pbe_WithSHA1And40BitRC2_CBC, EVP_rc2_40_cbc, EVP_sha1, pkcs12_pbe_keyivgen,
+ NID_pbe_WithSHA1And40BitRC2_CBC, EVP_rc2_40_cbc, EVP_sha1,
+ pkcs12_pbe_keyivgen, PBE_UCS2_CONVERT_PASSWORD
},
{
NID_pbe_WithSHA1And128BitRC4, EVP_rc4, EVP_sha1, pkcs12_pbe_keyivgen,
+ PBE_UCS2_CONVERT_PASSWORD
},
{
NID_pbe_WithSHA1And3_Key_TripleDES_CBC, EVP_des_ede3_cbc, EVP_sha1,
- pkcs12_pbe_keyivgen,
+ pkcs12_pbe_keyivgen, PBE_UCS2_CONVERT_PASSWORD
+ },
+ {
+ NID_pbes2, NULL, NULL, PKCS5_v2_PBE_keyivgen, 0
},
};
+static const struct pbe_suite *get_pbe_suite(int pbe_nid) {
+ unsigned i;
+ for (i = 0; i < sizeof(kBuiltinPBE) / sizeof(kBuiltinPBE[0]); i++) {
+ if (kBuiltinPBE[i].pbe_nid == pbe_nid) {
+ return &kBuiltinPBE[i];
+ }
+ }
+
+ return NULL;
+}
+
+/* pass_to_pass_raw performs a password conversion (possibly a no-op)
+ * appropriate to the supplied |pbe_nid|. The input |pass| is treated as a
+ * NUL-terminated string if |pass_len| is -1, otherwise it is treated as a
+ * buffer of the specified length. If the supplied PBE NID sets the
+ * |PBE_UCS2_CONVERT_PASSWORD| flag, the supplied |pass| will be converted to
+ * UCS-2.
+ *
+ * It sets |*out_pass_raw| to a new buffer that must be freed by the caller. It
+ * returns one on success and zero on error. */
+static int pass_to_pass_raw(int pbe_nid, const char *pass, int pass_len,
+ uint8_t **out_pass_raw, size_t *out_pass_raw_len) {
+ if (pass == NULL) {
+ *out_pass_raw = NULL;
+ *out_pass_raw_len = 0;
+ return 1;
+ }
+
+ if (pass_len == -1) {
+ pass_len = strlen(pass);
+ } else if (pass_len < 0 || pass_len > 2000000000) {
+ OPENSSL_PUT_ERROR(PKCS8, ERR_R_OVERFLOW);
+ return 0;
+ }
+
+ const struct pbe_suite *suite = get_pbe_suite(pbe_nid);
+ if (suite != NULL && (suite->flags & PBE_UCS2_CONVERT_PASSWORD)) {
+ if (!ascii_to_ucs2(pass, pass_len, out_pass_raw, out_pass_raw_len)) {
+ OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_DECODE_ERROR);
+ return 0;
+ }
+ } else {
+ *out_pass_raw = BUF_memdup(pass, pass_len);
+ if (*out_pass_raw == NULL) {
+ OPENSSL_PUT_ERROR(PKCS8, ERR_R_MALLOC_FAILURE);
+ return 0;
+ }
+ *out_pass_raw_len = (size_t)pass_len;
+ }
+
+ return 1;
+}
+
static int pbe_cipher_init(ASN1_OBJECT *pbe_obj,
const uint8_t *pass_raw, size_t pass_raw_len,
ASN1_TYPE *param,
EVP_CIPHER_CTX *ctx, int is_encrypt) {
const EVP_CIPHER *cipher;
const EVP_MD *md;
- unsigned i;
-
- const struct pbe_suite *suite = NULL;
- const int pbe_nid = OBJ_obj2nid(pbe_obj);
-
- for (i = 0; i < sizeof(kBuiltinPBE) / sizeof(struct pbe_suite); i++) {
- if (kBuiltinPBE[i].pbe_nid == pbe_nid) {
- suite = &kBuiltinPBE[i];
- break;
- }
- }
+ const struct pbe_suite *suite = get_pbe_suite(OBJ_obj2nid(pbe_obj));
if (suite == NULL) {
char obj_str[80];
- OPENSSL_PUT_ERROR(PKCS8, pbe_cipher_init, PKCS8_R_UNKNOWN_ALGORITHM);
+ OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_UNKNOWN_ALGORITHM);
if (!pbe_obj) {
strncpy(obj_str, "NULL", sizeof(obj_str));
} else {
@@ -324,7 +376,7 @@ static int pbe_cipher_init(ASN1_OBJECT *pbe_obj,
} else {
cipher = suite->cipher_func();
if (!cipher) {
- OPENSSL_PUT_ERROR(PKCS8, pbe_cipher_init, PKCS8_R_UNKNOWN_CIPHER);
+ OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_UNKNOWN_CIPHER);
return 0;
}
}
@@ -334,14 +386,14 @@ static int pbe_cipher_init(ASN1_OBJECT *pbe_obj,
} else {
md = suite->md_func();
if (!md) {
- OPENSSL_PUT_ERROR(PKCS8, pbe_cipher_init, PKCS8_R_UNKNOWN_DIGEST);
+ OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_UNKNOWN_DIGEST);
return 0;
}
}
if (!suite->keygen(ctx, pass_raw, pass_raw_len, param, cipher, md,
is_encrypt)) {
- OPENSSL_PUT_ERROR(PKCS8, pbe_cipher_init, PKCS8_R_KEYGEN_FAILURE);
+ OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_KEYGEN_FAILURE);
return 0;
}
@@ -362,32 +414,32 @@ static int pbe_crypt(const X509_ALGOR *algor,
if (!pbe_cipher_init(algor->algorithm, pass_raw, pass_raw_len,
algor->parameter, &ctx, is_encrypt)) {
- OPENSSL_PUT_ERROR(PKCS8, pbe_crypt, PKCS8_R_UNKNOWN_CIPHER_ALGORITHM);
+ OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_UNKNOWN_CIPHER_ALGORITHM);
return 0;
}
block_size = EVP_CIPHER_CTX_block_size(&ctx);
if (in_len + block_size < in_len) {
- OPENSSL_PUT_ERROR(PKCS8, pbe_crypt, PKCS8_R_TOO_LONG);
+ OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_TOO_LONG);
goto err;
}
buf = OPENSSL_malloc(in_len + block_size);
if (buf == NULL) {
- OPENSSL_PUT_ERROR(PKCS8, pbe_crypt, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(PKCS8, ERR_R_MALLOC_FAILURE);
goto err;
}
if (!EVP_CipherUpdate(&ctx, buf, &n, in, in_len)) {
OPENSSL_free(buf);
- OPENSSL_PUT_ERROR(PKCS8, pbe_crypt, ERR_R_EVP_LIB);
+ OPENSSL_PUT_ERROR(PKCS8, ERR_R_EVP_LIB);
goto err;
}
*out_len = n;
if (!EVP_CipherFinal_ex(&ctx, buf + n, &n)) {
OPENSSL_free(buf);
- OPENSSL_PUT_ERROR(PKCS8, pbe_crypt, ERR_R_EVP_LIB);
+ OPENSSL_PUT_ERROR(PKCS8, ERR_R_EVP_LIB);
goto err;
}
*out_len += n;
@@ -410,14 +462,14 @@ static void *pkcs12_item_decrypt_d2i(X509_ALGOR *algor, const ASN1_ITEM *it,
if (!pbe_crypt(algor, pass_raw, pass_raw_len, oct->data, oct->length,
&out, &out_len, 0 /* decrypt */)) {
- OPENSSL_PUT_ERROR(PKCS8, pkcs12_item_decrypt_d2i, PKCS8_R_CRYPT_ERROR);
+ OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_CRYPT_ERROR);
return NULL;
}
p = out;
ret = ASN1_item_d2i(NULL, &p, out_len, it);
OPENSSL_cleanse(out, out_len);
if (!ret) {
- OPENSSL_PUT_ERROR(PKCS8, pkcs12_item_decrypt_d2i, PKCS8_R_DECODE_ERROR);
+ OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_DECODE_ERROR);
}
OPENSSL_free(out);
return ret;
@@ -427,19 +479,12 @@ PKCS8_PRIV_KEY_INFO *PKCS8_decrypt(X509_SIG *pkcs8, const char *pass,
int pass_len) {
uint8_t *pass_raw = NULL;
size_t pass_raw_len = 0;
- PKCS8_PRIV_KEY_INFO *ret;
-
- if (pass) {
- if (pass_len == -1) {
- pass_len = strlen(pass);
- }
- if (!ascii_to_ucs2(pass, pass_len, &pass_raw, &pass_raw_len)) {
- OPENSSL_PUT_ERROR(PKCS8, PKCS8_decrypt, PKCS8_R_DECODE_ERROR);
- return NULL;
- }
+ if (!pass_to_pass_raw(OBJ_obj2nid(pkcs8->algor->algorithm), pass, pass_len,
+ &pass_raw, &pass_raw_len)) {
+ return NULL;
}
- ret = PKCS8_decrypt_pbe(pkcs8, pass_raw, pass_raw_len);
+ PKCS8_PRIV_KEY_INFO *ret = PKCS8_decrypt_pbe(pkcs8, pass_raw, pass_raw_len);
if (pass_raw) {
OPENSSL_cleanse(pass_raw, pass_raw_len);
@@ -466,17 +511,17 @@ static ASN1_OCTET_STRING *pkcs12_item_i2d_encrypt(X509_ALGOR *algor,
oct = M_ASN1_OCTET_STRING_new();
if (oct == NULL) {
- OPENSSL_PUT_ERROR(PKCS8, pkcs12_item_i2d_encrypt, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(PKCS8, ERR_R_MALLOC_FAILURE);
return NULL;
}
in_len = ASN1_item_i2d(obj, &in, it);
if (!in) {
- OPENSSL_PUT_ERROR(PKCS8, pkcs12_item_i2d_encrypt, PKCS8_R_ENCODE_ERROR);
+ OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_ENCODE_ERROR);
return NULL;
}
if (!pbe_crypt(algor, pass_raw, pass_raw_len, in, in_len, &oct->data, &crypt_len,
1 /* encrypt */)) {
- OPENSSL_PUT_ERROR(PKCS8, pkcs12_item_i2d_encrypt, PKCS8_R_ENCRYPT_ERROR);
+ OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_ENCRYPT_ERROR);
OPENSSL_free(in);
return NULL;
}
@@ -491,20 +536,12 @@ X509_SIG *PKCS8_encrypt(int pbe_nid, const EVP_CIPHER *cipher, const char *pass,
int iterations, PKCS8_PRIV_KEY_INFO *p8inf) {
uint8_t *pass_raw = NULL;
size_t pass_raw_len = 0;
- X509_SIG *ret;
-
- if (pass) {
- if (pass_len == -1) {
- pass_len = strlen(pass);
- }
- if (!ascii_to_ucs2(pass, pass_len, &pass_raw, &pass_raw_len)) {
- OPENSSL_PUT_ERROR(PKCS8, PKCS8_encrypt, PKCS8_R_DECODE_ERROR);
- return NULL;
- }
+ if (!pass_to_pass_raw(pbe_nid, pass, pass_len, &pass_raw, &pass_raw_len)) {
+ return NULL;
}
- ret = PKCS8_encrypt_pbe(pbe_nid, pass_raw, pass_raw_len,
- salt, salt_len, iterations, p8inf);
+ X509_SIG *ret = PKCS8_encrypt_pbe(pbe_nid, cipher, pass_raw, pass_raw_len,
+ salt, salt_len, iterations, p8inf);
if (pass_raw) {
OPENSSL_cleanse(pass_raw, pass_raw_len);
@@ -513,7 +550,7 @@ X509_SIG *PKCS8_encrypt(int pbe_nid, const EVP_CIPHER *cipher, const char *pass,
return ret;
}
-X509_SIG *PKCS8_encrypt_pbe(int pbe_nid,
+X509_SIG *PKCS8_encrypt_pbe(int pbe_nid, const EVP_CIPHER *cipher,
const uint8_t *pass_raw, size_t pass_raw_len,
uint8_t *salt, size_t salt_len,
int iterations, PKCS8_PRIV_KEY_INFO *p8inf) {
@@ -522,13 +559,17 @@ X509_SIG *PKCS8_encrypt_pbe(int pbe_nid,
pkcs8 = X509_SIG_new();
if (pkcs8 == NULL) {
- OPENSSL_PUT_ERROR(PKCS8, PKCS8_encrypt_pbe, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(PKCS8, ERR_R_MALLOC_FAILURE);
goto err;
}
- pbe = PKCS5_pbe_set(pbe_nid, iterations, salt, salt_len);
+ if (pbe_nid == -1) {
+ pbe = PKCS5_pbe2_set(cipher, iterations, salt, salt_len);
+ } else {
+ pbe = PKCS5_pbe_set(pbe_nid, iterations, salt, salt_len);
+ }
if (!pbe) {
- OPENSSL_PUT_ERROR(PKCS8, PKCS8_encrypt_pbe, ERR_R_ASN1_LIB);
+ OPENSSL_PUT_ERROR(PKCS8, ERR_R_ASN1_LIB);
goto err;
}
@@ -538,7 +579,7 @@ X509_SIG *PKCS8_encrypt_pbe(int pbe_nid,
pkcs8->digest = pkcs12_item_i2d_encrypt(
pbe, ASN1_ITEM_rptr(PKCS8_PRIV_KEY_INFO), pass_raw, pass_raw_len, p8inf);
if (!pkcs8->digest) {
- OPENSSL_PUT_ERROR(PKCS8, PKCS8_encrypt_pbe, PKCS8_R_ENCRYPT_ERROR);
+ OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_ENCRYPT_ERROR);
goto err;
}
@@ -560,13 +601,12 @@ EVP_PKEY *EVP_PKCS82PKEY(PKCS8_PRIV_KEY_INFO *p8) {
pkey = EVP_PKEY_new();
if (pkey == NULL) {
- OPENSSL_PUT_ERROR(PKCS8, EVP_PKCS82PKEY, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(PKCS8, ERR_R_MALLOC_FAILURE);
return NULL;
}
if (!EVP_PKEY_set_type(pkey, OBJ_obj2nid(algoid))) {
- OPENSSL_PUT_ERROR(PKCS8, EVP_PKCS82PKEY,
- PKCS8_R_UNSUPPORTED_PRIVATE_KEY_ALGORITHM);
+ OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_UNSUPPORTED_PRIVATE_KEY_ALGORITHM);
i2t_ASN1_OBJECT(obj_tmp, 80, algoid);
ERR_add_error_data(2, "TYPE=", obj_tmp);
goto error;
@@ -574,11 +614,11 @@ EVP_PKEY *EVP_PKCS82PKEY(PKCS8_PRIV_KEY_INFO *p8) {
if (pkey->ameth->priv_decode) {
if (!pkey->ameth->priv_decode(pkey, p8)) {
- OPENSSL_PUT_ERROR(PKCS8, EVP_PKCS82PKEY, PKCS8_R_PRIVATE_KEY_DECODE_ERROR);
+ OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_PRIVATE_KEY_DECODE_ERROR);
goto error;
}
} else {
- OPENSSL_PUT_ERROR(PKCS8, EVP_PKCS82PKEY, PKCS8_R_METHOD_NOT_SUPPORTED);
+ OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_METHOD_NOT_SUPPORTED);
goto error;
}
@@ -594,7 +634,7 @@ PKCS8_PRIV_KEY_INFO *EVP_PKEY2PKCS8(EVP_PKEY *pkey) {
p8 = PKCS8_PRIV_KEY_INFO_new();
if (p8 == NULL) {
- OPENSSL_PUT_ERROR(PKCS8, EVP_PKEY2PKCS8, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(PKCS8, ERR_R_MALLOC_FAILURE);
return NULL;
}
p8->broken = PKCS8_OK;
@@ -602,17 +642,15 @@ PKCS8_PRIV_KEY_INFO *EVP_PKEY2PKCS8(EVP_PKEY *pkey) {
if (pkey->ameth) {
if (pkey->ameth->priv_encode) {
if (!pkey->ameth->priv_encode(p8, pkey)) {
- OPENSSL_PUT_ERROR(PKCS8, EVP_PKEY2PKCS8,
- PKCS8_R_PRIVATE_KEY_ENCODE_ERROR);
+ OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_PRIVATE_KEY_ENCODE_ERROR);
goto error;
}
} else {
- OPENSSL_PUT_ERROR(PKCS8, EVP_PKEY2PKCS8, PKCS8_R_METHOD_NOT_SUPPORTED);
+ OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_METHOD_NOT_SUPPORTED);
goto error;
}
} else {
- OPENSSL_PUT_ERROR(PKCS8, EVP_PKEY2PKCS8,
- PKCS8_R_UNSUPPORTED_PRIVATE_KEY_ALGORITHM);
+ OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_UNSUPPORTED_PRIVATE_KEY_ALGORITHM);
goto error;
}
return p8;
@@ -646,8 +684,7 @@ static int PKCS12_handle_content_infos(CBS *content_infos,
* pkcs7-encryptedData and a pkcs7-data) and depth 1 (the various PKCS#12
* bags). */
if (depth > 3) {
- OPENSSL_PUT_ERROR(PKCS8, PKCS12_handle_content_infos,
- PKCS8_R_PKCS12_TOO_DEEPLY_NESTED);
+ OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_PKCS12_TOO_DEEPLY_NESTED);
return 0;
}
@@ -656,6 +693,7 @@ static int PKCS12_handle_content_infos(CBS *content_infos,
* conversion cannot see through those wrappings. So each time we step
* through one we need to convert to DER again. */
if (!CBS_asn1_ber_to_der(content_infos, &der_bytes, &der_len)) {
+ OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_BAD_PKCS12_DATA);
return 0;
}
@@ -666,16 +704,14 @@ static int PKCS12_handle_content_infos(CBS *content_infos,
}
if (!CBS_get_asn1(&in, &in, CBS_ASN1_SEQUENCE)) {
- OPENSSL_PUT_ERROR(PKCS8, PKCS12_handle_content_infos,
- PKCS8_R_BAD_PKCS12_DATA);
+ OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_BAD_PKCS12_DATA);
goto err;
}
while (CBS_len(&in) > 0) {
CBS content_info;
if (!CBS_get_asn1(&in, &content_info, CBS_ASN1_SEQUENCE)) {
- OPENSSL_PUT_ERROR(PKCS8, PKCS12_handle_content_infos,
- PKCS8_R_BAD_PKCS12_DATA);
+ OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_BAD_PKCS12_DATA);
goto err;
}
@@ -705,8 +741,7 @@ static int PKCS12_handle_content_info(CBS *content_info, unsigned depth,
if (!CBS_get_asn1(content_info, &content_type, CBS_ASN1_OBJECT) ||
!CBS_get_asn1(content_info, &wrapped_contents,
CBS_ASN1_CONTEXT_SPECIFIC | CBS_ASN1_CONSTRUCTED | 0)) {
- OPENSSL_PUT_ERROR(PKCS8, PKCS12_handle_content_info,
- PKCS8_R_BAD_PKCS12_DATA);
+ OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_BAD_PKCS12_DATA);
goto err;
}
@@ -734,14 +769,12 @@ static int PKCS12_handle_content_info(CBS *content_info, unsigned depth,
!CBS_get_asn1_element(&eci, &ai, CBS_ASN1_SEQUENCE) ||
!CBS_get_asn1(&eci, &encrypted_contents,
CBS_ASN1_CONTEXT_SPECIFIC | 0)) {
- OPENSSL_PUT_ERROR(PKCS8, PKCS12_handle_content_info,
- PKCS8_R_BAD_PKCS12_DATA);
+ OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_BAD_PKCS12_DATA);
goto err;
}
if (OBJ_cbs2nid(&contents_type) != NID_pkcs7_data) {
- OPENSSL_PUT_ERROR(PKCS8, PKCS12_handle_content_info,
- PKCS8_R_BAD_PKCS12_DATA);
+ OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_BAD_PKCS12_DATA);
goto err;
}
@@ -752,8 +785,7 @@ static int PKCS12_handle_content_info(CBS *content_info, unsigned depth,
}
if (inp != CBS_data(&ai) + CBS_len(&ai)) {
X509_ALGOR_free(algor);
- OPENSSL_PUT_ERROR(PKCS8, PKCS12_handle_content_info,
- PKCS8_R_BAD_PKCS12_DATA);
+ OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_BAD_PKCS12_DATA);
goto err;
}
@@ -773,8 +805,7 @@ static int PKCS12_handle_content_info(CBS *content_info, unsigned depth,
if (!CBS_get_asn1(&wrapped_contents, &octet_string_contents,
CBS_ASN1_OCTETSTRING)) {
- OPENSSL_PUT_ERROR(PKCS8, PKCS12_handle_content_info,
- PKCS8_R_BAD_PKCS12_DATA);
+ OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_BAD_PKCS12_DATA);
goto err;
}
@@ -787,8 +818,7 @@ static int PKCS12_handle_content_info(CBS *content_info, unsigned depth,
X509_SIG *encrypted = NULL;
if (*ctx->out_key) {
- OPENSSL_PUT_ERROR(PKCS8, PKCS12_handle_content_info,
- PKCS8_R_MULTIPLE_PRIVATE_KEYS_IN_PKCS12);
+ OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_MULTIPLE_PRIVATE_KEYS_IN_PKCS12);
goto err;
}
@@ -796,13 +826,11 @@ static int PKCS12_handle_content_info(CBS *content_info, unsigned depth,
* structure as one and so |X509_SIG| is reused to store it. */
encrypted = d2i_X509_SIG(NULL, &inp, CBS_len(&wrapped_contents));
if (encrypted == NULL) {
- OPENSSL_PUT_ERROR(PKCS8, PKCS12_handle_content_info,
- PKCS8_R_BAD_PKCS12_DATA);
+ OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_BAD_PKCS12_DATA);
goto err;
}
if (inp != CBS_data(&wrapped_contents) + CBS_len(&wrapped_contents)) {
- OPENSSL_PUT_ERROR(PKCS8, PKCS12_handle_content_info,
- PKCS8_R_BAD_PKCS12_DATA);
+ OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_BAD_PKCS12_DATA);
X509_SIG_free(encrypted);
goto err;
}
@@ -828,8 +856,7 @@ static int PKCS12_handle_content_info(CBS *content_info, unsigned depth,
!CBS_get_asn1(&cert_bag, &wrapped_cert,
CBS_ASN1_CONTEXT_SPECIFIC | CBS_ASN1_CONSTRUCTED | 0) ||
!CBS_get_asn1(&wrapped_cert, &cert, CBS_ASN1_OCTETSTRING)) {
- OPENSSL_PUT_ERROR(PKCS8, PKCS12_handle_content_info,
- PKCS8_R_BAD_PKCS12_DATA);
+ OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_BAD_PKCS12_DATA);
goto err;
}
@@ -837,13 +864,11 @@ static int PKCS12_handle_content_info(CBS *content_info, unsigned depth,
const uint8_t *inp = CBS_data(&cert);
X509 *x509 = d2i_X509(NULL, &inp, CBS_len(&cert));
if (!x509) {
- OPENSSL_PUT_ERROR(PKCS8, PKCS12_handle_content_info,
- PKCS8_R_BAD_PKCS12_DATA);
+ OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_BAD_PKCS12_DATA);
goto err;
}
if (inp != CBS_data(&cert) + CBS_len(&cert)) {
- OPENSSL_PUT_ERROR(PKCS8, PKCS12_handle_content_info,
- PKCS8_R_BAD_PKCS12_DATA);
+ OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_BAD_PKCS12_DATA);
X509_free(x509);
goto err;
}
@@ -875,6 +900,7 @@ int PKCS12_get_key_and_certs(EVP_PKEY **out_key, STACK_OF(X509) *out_certs,
/* The input may be in BER format. */
if (!CBS_asn1_ber_to_der(ber_in, &der_bytes, &der_len)) {
+ OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_BAD_PKCS12_DATA);
return 0;
}
if (der_bytes != NULL) {
@@ -891,28 +917,27 @@ int PKCS12_get_key_and_certs(EVP_PKEY **out_key, STACK_OF(X509) *out_certs,
if (!CBS_get_asn1(&in, &pfx, CBS_ASN1_SEQUENCE) ||
CBS_len(&in) != 0 ||
!CBS_get_asn1_uint64(&pfx, &version)) {
- OPENSSL_PUT_ERROR(PKCS8, PKCS12_get_key_and_certs, PKCS8_R_BAD_PKCS12_DATA);
+ OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_BAD_PKCS12_DATA);
goto err;
}
if (version < 3) {
- OPENSSL_PUT_ERROR(PKCS8, PKCS12_get_key_and_certs,
- PKCS8_R_BAD_PKCS12_VERSION);
+ OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_BAD_PKCS12_VERSION);
goto err;
}
if (!CBS_get_asn1(&pfx, &authsafe, CBS_ASN1_SEQUENCE)) {
- OPENSSL_PUT_ERROR(PKCS8, PKCS12_get_key_and_certs, PKCS8_R_BAD_PKCS12_DATA);
+ OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_BAD_PKCS12_DATA);
goto err;
}
if (CBS_len(&pfx) == 0) {
- OPENSSL_PUT_ERROR(PKCS8, PKCS12_get_key_and_certs, PKCS8_R_MISSING_MAC);
+ OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_MISSING_MAC);
goto err;
}
if (!CBS_get_asn1(&pfx, &mac_data, CBS_ASN1_SEQUENCE)) {
- OPENSSL_PUT_ERROR(PKCS8, PKCS12_get_key_and_certs, PKCS8_R_BAD_PKCS12_DATA);
+ OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_BAD_PKCS12_DATA);
goto err;
}
@@ -921,7 +946,7 @@ int PKCS12_get_key_and_certs(EVP_PKEY **out_key, STACK_OF(X509) *out_certs,
if (!CBS_get_asn1(&authsafe, &content_type, CBS_ASN1_OBJECT) ||
!CBS_get_asn1(&authsafe, &wrapped_authsafes,
CBS_ASN1_CONTEXT_SPECIFIC | CBS_ASN1_CONSTRUCTED | 0)) {
- OPENSSL_PUT_ERROR(PKCS8, PKCS12_get_key_and_certs, PKCS8_R_BAD_PKCS12_DATA);
+ OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_BAD_PKCS12_DATA);
goto err;
}
@@ -929,13 +954,12 @@ int PKCS12_get_key_and_certs(EVP_PKEY **out_key, STACK_OF(X509) *out_certs,
* latter indicates that it's signed by a public key, which isn't
* supported. */
if (OBJ_cbs2nid(&content_type) != NID_pkcs7_data) {
- OPENSSL_PUT_ERROR(PKCS8, PKCS12_get_key_and_certs,
- PKCS8_R_PKCS12_PUBLIC_KEY_INTEGRITY_NOT_SUPPORTED);
+ OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_PKCS12_PUBLIC_KEY_INTEGRITY_NOT_SUPPORTED);
goto err;
}
if (!CBS_get_asn1(&wrapped_authsafes, &authsafes, CBS_ASN1_OCTETSTRING)) {
- OPENSSL_PUT_ERROR(PKCS8, PKCS12_get_key_and_certs, PKCS8_R_BAD_PKCS12_DATA);
+ OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_BAD_PKCS12_DATA);
goto err;
}
@@ -943,7 +967,7 @@ int PKCS12_get_key_and_certs(EVP_PKEY **out_key, STACK_OF(X509) *out_certs,
ctx.out_certs = out_certs;
if (!ascii_to_ucs2(password, strlen(password), &ctx.password,
&ctx.password_len)) {
- OPENSSL_PUT_ERROR(PKCS8, PKCS12_get_key_and_certs, PKCS8_R_DECODE_ERROR);
+ OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_DECODE_ERROR);
goto err;
}
@@ -962,7 +986,7 @@ int PKCS12_get_key_and_certs(EVP_PKEY **out_key, STACK_OF(X509) *out_certs,
!CBS_get_asn1(&hash_type_seq, &hash_oid, CBS_ASN1_OBJECT) ||
!CBS_get_asn1(&mac, &expected_mac, CBS_ASN1_OCTETSTRING) ||
!CBS_get_asn1(&mac_data, &salt, CBS_ASN1_OCTETSTRING)) {
- OPENSSL_PUT_ERROR(PKCS8, PKCS12_get_key_and_certs, PKCS8_R_BAD_PKCS12_DATA);
+ OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_BAD_PKCS12_DATA);
goto err;
}
@@ -971,8 +995,7 @@ int PKCS12_get_key_and_certs(EVP_PKEY **out_key, STACK_OF(X509) *out_certs,
if (CBS_len(&mac_data) > 0) {
if (!CBS_get_asn1_uint64(&mac_data, &iterations) ||
iterations > INT_MAX) {
- OPENSSL_PUT_ERROR(PKCS8, PKCS12_get_key_and_certs,
- PKCS8_R_BAD_PKCS12_DATA);
+ OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_BAD_PKCS12_DATA);
goto err;
}
}
@@ -980,7 +1003,7 @@ int PKCS12_get_key_and_certs(EVP_PKEY **out_key, STACK_OF(X509) *out_certs,
hash_nid = OBJ_cbs2nid(&hash_oid);
if (hash_nid == NID_undef ||
(md = EVP_get_digestbynid(hash_nid)) == NULL) {
- OPENSSL_PUT_ERROR(PKCS8, PKCS12_get_key_and_certs, PKCS8_R_UNKNOWN_HASH);
+ OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_UNKNOWN_HASH);
goto err;
}
@@ -996,8 +1019,7 @@ int PKCS12_get_key_and_certs(EVP_PKEY **out_key, STACK_OF(X509) *out_certs,
}
if (!CBS_mem_equal(&expected_mac, hmac, hmac_len)) {
- OPENSSL_PUT_ERROR(PKCS8, PKCS12_get_key_and_certs,
- PKCS8_R_INCORRECT_PASSWORD);
+ OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_INCORRECT_PASSWORD);
goto err;
}
}
@@ -1126,6 +1148,7 @@ int PKCS12_parse(const PKCS12 *p12, const char *password, EVP_PKEY **out_pkey,
if (!ca_certs) {
ca_certs = sk_X509_new_null();
if (ca_certs == NULL) {
+ OPENSSL_PUT_ERROR(PKCS8, ERR_R_MALLOC_FAILURE);
return 0;
}
ca_certs_alloced = 1;
diff --git a/src/crypto/pkcs8/pkcs8_test.cc b/src/crypto/pkcs8/pkcs8_test.cc
new file mode 100644
index 0000000..7a88ddf
--- /dev/null
+++ b/src/crypto/pkcs8/pkcs8_test.cc
@@ -0,0 +1,91 @@
+/* Copyright (c) 2015, Google Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <openssl/crypto.h>
+#include <openssl/err.h>
+#include <openssl/pkcs8.h>
+#include <openssl/x509.h>
+
+#include "../test/scoped_types.h"
+
+
+/* kDER is a PKCS#8 encrypted private key. It was generated with:
+ *
+ * openssl genrsa 512 > test.key
+ * openssl pkcs8 -topk8 -in test.key -out test.key.encrypted -v2 des3 -outform der
+ * hexdump -Cv test.key.encrypted
+ *
+ * The password is "testing".
+ */
+static const uint8_t kDER[] = {
+ 0x30, 0x82, 0x01, 0x9e, 0x30, 0x40, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x05,
+ 0x0d, 0x30, 0x33, 0x30, 0x1b, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x05, 0x0c,
+ 0x30, 0x0e, 0x04, 0x08, 0x06, 0xa5, 0x4b, 0x0c, 0x0c, 0x50, 0x8c, 0x19, 0x02, 0x02, 0x08, 0x00,
+ 0x30, 0x14, 0x06, 0x08, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x03, 0x07, 0x04, 0x08, 0x3a, 0xd0,
+ 0x70, 0x4b, 0x26, 0x50, 0x13, 0x7b, 0x04, 0x82, 0x01, 0x58, 0xa6, 0xee, 0x02, 0xf2, 0xf2, 0x7c,
+ 0x19, 0x91, 0xe3, 0xce, 0x32, 0x85, 0xc5, 0x01, 0xd9, 0xe3, 0x5e, 0x14, 0xb6, 0xb8, 0x78, 0xad,
+ 0xda, 0x01, 0xec, 0x9e, 0x42, 0xe8, 0xbf, 0x0b, 0x46, 0x03, 0xbc, 0x92, 0x6f, 0xe4, 0x0f, 0x0f,
+ 0x48, 0x30, 0x10, 0x10, 0x9b, 0xfb, 0x4b, 0xb9, 0x45, 0xf8, 0xcf, 0xab, 0xa1, 0x18, 0xdd, 0x19,
+ 0xa4, 0xa4, 0xe1, 0xf0, 0xa1, 0x8d, 0xc2, 0x23, 0xe7, 0x0d, 0x7a, 0x64, 0x21, 0x6b, 0xfa, 0x48,
+ 0xb9, 0x41, 0xc1, 0x0c, 0x4b, 0xce, 0x6f, 0x1a, 0x91, 0x9b, 0x9f, 0xdd, 0xcf, 0xa9, 0x8d, 0x33,
+ 0x2c, 0x45, 0x81, 0x5c, 0x5e, 0x67, 0xc6, 0x68, 0x43, 0x62, 0xff, 0x5e, 0x9b, 0x1a, 0x15, 0x3a,
+ 0x9d, 0x71, 0x3f, 0xbe, 0x32, 0x2f, 0xe5, 0x90, 0x65, 0x65, 0x9c, 0x22, 0xf6, 0x29, 0x2e, 0xcf,
+ 0x26, 0x16, 0x7b, 0x66, 0x48, 0x55, 0xad, 0x9a, 0x8d, 0x89, 0xf4, 0x48, 0x4f, 0x1f, 0x9d, 0xb8,
+ 0xfa, 0xe1, 0xf1, 0x3b, 0x39, 0x5c, 0x72, 0xc6, 0xb8, 0x3e, 0x98, 0xe8, 0x77, 0xe8, 0xb6, 0x71,
+ 0x84, 0xa8, 0x6e, 0xca, 0xaf, 0x62, 0x96, 0x49, 0x8a, 0x21, 0x6f, 0x9e, 0x78, 0x07, 0x97, 0x38,
+ 0x40, 0x66, 0x42, 0x5a, 0x1b, 0xe0, 0x9b, 0xe9, 0x91, 0x82, 0xe4, 0xea, 0x8f, 0x2a, 0xb2, 0x80,
+ 0xce, 0xe8, 0x57, 0xd3, 0xac, 0x11, 0x9d, 0xb2, 0x39, 0x0f, 0xe1, 0xce, 0x18, 0x96, 0x38, 0xa1,
+ 0x19, 0x80, 0x88, 0x81, 0x3d, 0xda, 0xaa, 0x8e, 0x15, 0x27, 0x19, 0x73, 0x0c, 0xf3, 0xaf, 0x45,
+ 0xe9, 0x1b, 0xad, 0x6c, 0x3d, 0xbf, 0x95, 0xf7, 0xa0, 0x87, 0x0e, 0xde, 0xf1, 0xd8, 0xee, 0xaa,
+ 0x92, 0x76, 0x8d, 0x32, 0x45, 0xa1, 0xe7, 0xf5, 0x05, 0xd6, 0x2c, 0x67, 0x63, 0x10, 0xfa, 0xde,
+ 0x80, 0xc7, 0x5b, 0x96, 0x0f, 0x24, 0x50, 0x78, 0x30, 0xe5, 0x89, 0xf3, 0x73, 0xfa, 0x40, 0x11,
+ 0xd5, 0x26, 0xb8, 0x36, 0x96, 0x98, 0xe6, 0xbd, 0x73, 0x62, 0x56, 0xb9, 0xea, 0x28, 0x16, 0x93,
+ 0x5b, 0x33, 0xae, 0x83, 0xf9, 0x1f, 0xee, 0xef, 0xc8, 0xbf, 0xc7, 0xb1, 0x47, 0x43, 0xa1, 0xc6,
+ 0x1a, 0x64, 0x47, 0x02, 0x40, 0x3e, 0xbc, 0x0f, 0x80, 0x71, 0x5c, 0x44, 0x60, 0xbc, 0x78, 0x2e,
+ 0xd2, 0x77, 0xf8, 0x6e, 0x12, 0x51, 0x89, 0xdb, 0x90, 0x64, 0xcd, 0x76, 0x10, 0x29, 0x73, 0xc2,
+ 0x2f, 0x94, 0x7b, 0x98, 0xcd, 0xbb, 0x61, 0x16, 0x1d, 0x52, 0x11, 0x73, 0x48, 0xe6, 0x39, 0xfc,
+ 0xd6, 0x2d,
+};
+
+static bool test(const uint8_t *der, size_t der_len) {
+ const uint8_t *data = der;
+ ScopedX509_SIG sig(d2i_X509_SIG(NULL, &data, der_len));
+ if (sig.get() == NULL || data != der + der_len) {
+ fprintf(stderr, "d2i_X509_SIG failed or did not consume all bytes.\n");
+ return false;
+ }
+
+ static const char kPassword[] = "testing";
+ ScopedPKCS8_PRIV_KEY_INFO keypair(PKCS8_decrypt(sig.get(), kPassword, -1));
+ if (!keypair) {
+ fprintf(stderr, "PKCS8_decrypt failed.\n");
+ ERR_print_errors_fp(stderr);
+ return false;
+ }
+
+ return true;
+}
+
+int main(int argc, char **argv) {
+ if (!test(kDER, sizeof(kDER))) {
+ return 1;
+ }
+
+ printf("PASS\n");
+ return 0;
+}
diff --git a/src/crypto/poly1305/CMakeLists.txt b/src/crypto/poly1305/CMakeLists.txt
index bb0c1e4..674d9f6 100644
--- a/src/crypto/poly1305/CMakeLists.txt
+++ b/src/crypto/poly1305/CMakeLists.txt
@@ -1,4 +1,4 @@
-include_directories(. .. ../../include)
+include_directories(../../include)
if (${ARCH} STREQUAL "arm")
set(
@@ -19,3 +19,12 @@ add_library(
${POLY1305_ARCH_SOURCES}
)
+
+add_executable(
+ poly1305_test
+
+ poly1305_test.cc
+ $<TARGET_OBJECTS:test_support>
+)
+
+target_link_libraries(poly1305_test crypto)
diff --git a/src/crypto/poly1305/poly1305_test.cc b/src/crypto/poly1305/poly1305_test.cc
new file mode 100644
index 0000000..0526075
--- /dev/null
+++ b/src/crypto/poly1305/poly1305_test.cc
@@ -0,0 +1,81 @@
+/* Copyright (c) 2015, Google Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
+
+#include <stdio.h>
+#include <string.h>
+
+#include <vector>
+
+#include <openssl/crypto.h>
+#include <openssl/poly1305.h>
+
+#include "../test/file_test.h"
+#include "../test/stl_compat.h"
+
+
+// |CRYPTO_poly1305_finish| requires a 16-byte-aligned output.
+#if defined(OPENSSL_WINDOWS)
+// MSVC doesn't support C++11 |alignas|.
+#define ALIGNED __declspec(align(16))
+#else
+#define ALIGNED alignas(16)
+#endif
+
+static bool TestPoly1305(FileTest *t, void *arg) {
+ std::vector<uint8_t> key, in, mac;
+ if (!t->GetBytes(&key, "Key") ||
+ !t->GetBytes(&in, "Input") ||
+ !t->GetBytes(&mac, "MAC")) {
+ return false;
+ }
+ if (key.size() != 32 || mac.size() != 16) {
+ t->PrintLine("Invalid test");
+ return false;
+ }
+
+ // Test single-shot operation.
+ poly1305_state state;
+ CRYPTO_poly1305_init(&state, bssl::vector_data(&key));
+ CRYPTO_poly1305_update(&state, bssl::vector_data(&in), in.size());
+ ALIGNED uint8_t out[16];
+ CRYPTO_poly1305_finish(&state, out);
+ if (!t->ExpectBytesEqual(out, 16, bssl::vector_data(&mac), mac.size())) {
+ t->PrintLine("Single-shot Poly1305 failed.");
+ return false;
+ }
+
+ // Test streaming byte-by-byte.
+ CRYPTO_poly1305_init(&state, bssl::vector_data(&key));
+ for (size_t i = 0; i < in.size(); i++) {
+ CRYPTO_poly1305_update(&state, &in[i], 1);
+ }
+ CRYPTO_poly1305_finish(&state, out);
+ if (!t->ExpectBytesEqual(out, 16, bssl::vector_data(&mac), mac.size())) {
+ t->PrintLine("Streaming Poly1305 failed.");
+ return false;
+ }
+
+ return true;
+}
+
+int main(int argc, char **argv) {
+ CRYPTO_library_init();
+
+ if (argc != 2) {
+ fprintf(stderr, "%s <test file>\n", argv[0]);
+ return 1;
+ }
+
+ return FileTestMain(TestPoly1305, nullptr, argv[1]);
+}
diff --git a/src/crypto/poly1305/poly1305_test.txt b/src/crypto/poly1305/poly1305_test.txt
new file mode 100644
index 0000000..6c5d403
--- /dev/null
+++ b/src/crypto/poly1305/poly1305_test.txt
@@ -0,0 +1,52 @@
+# RFC 7359, section 2.5.2.
+
+Key = 85d6be7857556d337f4452fe42d506a80103808afb0db2fd4abff6af4149f51b
+Input = "Cryptographic Forum Research Group"
+MAC = a8061dc1305136c6c22b8baf0c0127a9
+
+
+# RFC 7359, section A.3.
+
+Key = 0000000000000000000000000000000000000000000000000000000000000000
+Input = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
+MAC = 00000000000000000000000000000000
+
+Key = 0000000000000000000000000000000036e5f6b5c5e06070f0efca96227a863e
+Input = 416e79207375626d697373696f6e20746f20746865204945544620696e74656e6465642062792074686520436f6e7472696275746f7220666f72207075626c69636174696f6e20617320616c6c206f722070617274206f6620616e204945544620496e7465726e65742d4472616674206f722052464320616e6420616e792073746174656d656e74206d6164652077697468696e2074686520636f6e74657874206f6620616e204945544620616374697669747920697320636f6e7369646572656420616e20224945544620436f6e747269627574696f6e222e20537563682073746174656d656e747320696e636c756465206f72616c2073746174656d656e747320696e20494554462073657373696f6e732c2061732077656c6c206173207772697474656e20616e6420656c656374726f6e696320636f6d6d756e69636174696f6e73206d61646520617420616e792074696d65206f7220706c6163652c207768696368206172652061646472657373656420746f
+MAC = 36e5f6b5c5e06070f0efca96227a863e
+
+Key = 36e5f6b5c5e06070f0efca96227a863e00000000000000000000000000000000
+Input = 416e79207375626d697373696f6e20746f20746865204945544620696e74656e6465642062792074686520436f6e7472696275746f7220666f72207075626c69636174696f6e20617320616c6c206f722070617274206f6620616e204945544620496e7465726e65742d4472616674206f722052464320616e6420616e792073746174656d656e74206d6164652077697468696e2074686520636f6e74657874206f6620616e204945544620616374697669747920697320636f6e7369646572656420616e20224945544620436f6e747269627574696f6e222e20537563682073746174656d656e747320696e636c756465206f72616c2073746174656d656e747320696e20494554462073657373696f6e732c2061732077656c6c206173207772697474656e20616e6420656c656374726f6e696320636f6d6d756e69636174696f6e73206d61646520617420616e792074696d65206f7220706c6163652c207768696368206172652061646472657373656420746f
+MAC = f3477e7cd95417af89a6b8794c310cf0
+
+Key = 1c9240a5eb55d38af333888604f6b5f0473917c1402b80099dca5cbc207075c0
+Input = 2754776173206272696c6c69672c20616e642074686520736c6974687920746f7665730a446964206779726520616e642067696d626c6520696e2074686520776162653a0a416c6c206d696d737920776572652074686520626f726f676f7665732c0a416e6420746865206d6f6d65207261746873206f757467726162652e
+MAC = 4541669a7eaaee61e708dc7cbcc5eb62
+
+Key = 0200000000000000000000000000000000000000000000000000000000000000
+Input = ffffffffffffffffffffffffffffffff
+MAC = 03000000000000000000000000000000
+
+Key = 02000000000000000000000000000000ffffffffffffffffffffffffffffffff
+Input = 02000000000000000000000000000000
+MAC = 03000000000000000000000000000000
+
+Key = 0100000000000000000000000000000000000000000000000000000000000000
+Input = fffffffffffffffffffffffffffffffff0ffffffffffffffffffffffffffffff11000000000000000000000000000000
+MAC = 05000000000000000000000000000000
+
+Key = 0100000000000000000000000000000000000000000000000000000000000000
+Input = fffffffffffffffffffffffffffffffffbfefefefefefefefefefefefefefefe01010101010101010101010101010101
+MAC = 00000000000000000000000000000000
+
+Key = 0200000000000000000000000000000000000000000000000000000000000000
+Input = fdffffffffffffffffffffffffffffff
+MAC = faffffffffffffffffffffffffffffff
+
+Key = 0100000000000000040000000000000000000000000000000000000000000000
+Input = e33594d7505e43b900000000000000003394d7505e4379cd01000000000000000000000000000000000000000000000001000000000000000000000000000000
+MAC = 14000000000000005500000000000000
+
+Key = 0100000000000000040000000000000000000000000000000000000000000000
+Input = e33594d7505e43b900000000000000003394d7505e4379cd010000000000000000000000000000000000000000000000
+MAC = 13000000000000000000000000000000
diff --git a/src/crypto/rand/CMakeLists.txt b/src/crypto/rand/CMakeLists.txt
index 374d8f1..35d5290 100644
--- a/src/crypto/rand/CMakeLists.txt
+++ b/src/crypto/rand/CMakeLists.txt
@@ -1,4 +1,4 @@
-include_directories(. .. ../../include)
+include_directories(../../include)
if (${ARCH} STREQUAL "x86_64")
set(
diff --git a/src/crypto/rand/hwrand.c b/src/crypto/rand/hwrand.c
index 5f81f09..f0bbccd 100644
--- a/src/crypto/rand/hwrand.c
+++ b/src/crypto/rand/hwrand.c
@@ -15,23 +15,28 @@
#include <openssl/rand.h>
#include <assert.h>
-#include <stdlib.h>
#include <string.h>
#include <openssl/cpu.h>
+#include "internal.h"
-#if defined(OPENSSL_X86_64) && !defined(OPENSSL_NO_ASM)
-int CRYPTO_have_hwrand(void) {
- return (OPENSSL_ia32cap_P[1] & (1u << 30)) != 0;
-}
+#if defined(OPENSSL_X86_64) && !defined(OPENSSL_NO_ASM)
/* These functions are defined in asm/rdrand-x86_64.pl */
extern int CRYPTO_rdrand(uint8_t out[8]);
extern int CRYPTO_rdrand_multiple8_buf(uint8_t *buf, size_t len);
+static int have_rdrand(void) {
+ return (OPENSSL_ia32cap_P[1] & (1u << 30)) != 0;
+}
+
int CRYPTO_hwrand(uint8_t *buf, size_t len) {
+ if (!have_rdrand()) {
+ return 0;
+ }
+
const size_t len_multiple8 = len & ~7;
if (!CRYPTO_rdrand_multiple8_buf(buf, len_multiple8)) {
return 0;
@@ -53,12 +58,8 @@ int CRYPTO_hwrand(uint8_t *buf, size_t len) {
#else
-int CRYPTO_have_hwrand(void) {
+int CRYPTO_hwrand(uint8_t *buf, size_t len) {
return 0;
}
-void CRYPTO_hwrand(uint8_t *buf, size_t len) {
- abort();
-}
-
#endif
diff --git a/src/crypto/rand/internal.h b/src/crypto/rand/internal.h
index 5e6ea11..f35abbb 100644
--- a/src/crypto/rand/internal.h
+++ b/src/crypto/rand/internal.h
@@ -24,13 +24,9 @@ extern "C" {
* system. */
void CRYPTO_sysrand(uint8_t *buf, size_t len);
-/* CRYPTO_have_hwrand returns one iff |CRYPTO_hwrand| can be called to generate
- * hardware entropy. */
-int CRYPTO_have_hwrand(void);
-
-/* CRYPTO_hwrand fills |len| bytes at |buf| with entropy from the hardware.
- * This function can only be called if |CRYPTO_have_hwrand| returns one.
- * It returns one on success or zero on hardware failure. */
+/* CRYPTO_hwrand fills |len| bytes at |buf| with entropy from the hardware. It
+ * returns one on success or zero on hardware failure or if hardware support is
+ * unavailable. */
int CRYPTO_hwrand(uint8_t *buf, size_t len);
diff --git a/src/crypto/rand/rand.c b/src/crypto/rand/rand.c
index a96ac48..e76a120 100644
--- a/src/crypto/rand/rand.c
+++ b/src/crypto/rand/rand.c
@@ -17,6 +17,7 @@
#include <limits.h>
#include <string.h>
+#include <openssl/chacha.h>
#include <openssl/mem.h>
#include "internal.h"
@@ -69,17 +70,12 @@ static void rand_thread_state_free(void *state) {
OPENSSL_free(state);
}
-extern void CRYPTO_chacha_20(uint8_t *out, const uint8_t *in, size_t in_len,
- const uint8_t key[32], const uint8_t nonce[8],
- size_t counter);
-
int RAND_bytes(uint8_t *buf, size_t len) {
if (len == 0) {
return 1;
}
- if (!CRYPTO_have_hwrand() ||
- !CRYPTO_hwrand(buf, len)) {
+ if (!CRYPTO_hwrand(buf, len)) {
/* Without a hardware RNG to save us from address-space duplication, the OS
* entropy is used directly. */
CRYPTO_sysrand(buf, len);
@@ -162,6 +158,10 @@ int RAND_load_file(const char *path, long num) {
void RAND_add(const void *buf, int num, double entropy) {}
+int RAND_egd(const char *path) {
+ return 255;
+}
+
int RAND_poll(void) {
return 1;
}
@@ -169,3 +169,18 @@ int RAND_poll(void) {
int RAND_status(void) {
return 1;
}
+
+static const struct rand_meth_st kSSLeayMethod = {
+ RAND_seed,
+ RAND_bytes,
+ RAND_cleanup,
+ RAND_add,
+ RAND_pseudo_bytes,
+ RAND_status,
+};
+
+RAND_METHOD *RAND_SSLeay(void) {
+ return (RAND_METHOD*) &kSSLeayMethod;
+}
+
+void RAND_set_rand_method(const RAND_METHOD *method) {}
diff --git a/src/crypto/rand/urandom.c b/src/crypto/rand/urandom.c
index 788a979..1cc5260 100644
--- a/src/crypto/rand/urandom.c
+++ b/src/crypto/rand/urandom.c
@@ -30,92 +30,126 @@
/* This file implements a PRNG by reading from /dev/urandom, optionally with a
- * fork-safe buffer.
- *
- * If buffering is enabled then it maintains a global, linked list of buffers.
- * Threads which need random bytes grab a buffer from the list under a lock and
- * copy out the bytes that they need. In the rare case that the buffer is
- * empty, it's refilled from /dev/urandom outside of the lock.
- *
- * Large requests are always serviced from /dev/urandom directly.
- *
- * Each buffer contains the PID of the process that created it and it's tested
- * against the current PID each time. Thus processes that fork will discard all
- * the buffers filled by the parent process. There are two problems with this:
- *
- * 1) glibc maintains a cache of the current PID+PPID and, if this cache isn't
- * correctly invalidated, the getpid() will continue to believe that
- * it's the old process. Glibc depends on the glibc wrappers for fork,
- * vfork and clone being used in order to invalidate the getpid() cache.
- *
- * 2) If a process forks, dies and then its child forks, it's possible that
- * the third process will end up with the same PID as the original process.
- * If the second process never used any random values then this will mean
- * that the third process has stale, cached values and won't notice.
- */
-
-/* BUF_SIZE is intended to be a 4K allocation with malloc overhead. struct
- * rand_buffer also fits in this space and the remainder is entropy. */
-#define BUF_SIZE (4096 - 16)
-
-/* rand_buffer contains unused, random bytes. These structures form a linked
- * list via the |next| pointer, which is NULL in the final element. */
+ * buffer, which is unsafe across |fork|. */
+
+#define BUF_SIZE 4096
+
+/* rand_buffer contains unused, random bytes, some of which may have been
+ * consumed already. */
struct rand_buffer {
- size_t used; /* used contains the number of bytes of |rand| that have
- been consumed. */
- struct rand_buffer *next;
- pid_t pid; /* pid contains the pid at the time that the buffer was
- created so that data is not duplicated after a fork. */
- pid_t ppid; /* ppid contains the parent pid in order to try and reduce
- the possibility of duplicated PID confusing the
- detection of a fork. */
- uint8_t rand[];
+ size_t used;
+ uint8_t rand[BUF_SIZE];
};
-/* rand_bytes_per_buf is the number of actual entropy bytes in a buffer. */
-static const size_t rand_bytes_per_buf = BUF_SIZE - sizeof(struct rand_buffer);
-
-static struct CRYPTO_STATIC_MUTEX global_lock = CRYPTO_STATIC_MUTEX_INIT;
+/* requested_lock is used to protect the |*_requested| variables. */
+static struct CRYPTO_STATIC_MUTEX requested_lock = CRYPTO_STATIC_MUTEX_INIT;
-/* list_head is the start of a global, linked-list of rand_buffer objects. It's
- * protected by |global_lock|. */
-static struct rand_buffer *list_head;
+/* urandom_fd_requested is set by |RAND_set_urandom_fd|. It's protected by
+ * |requested_lock|. */
+static int urandom_fd_requested = -2;
-/* urandom_fd is a file descriptor to /dev/urandom. It's protected by
- * |global_lock|. */
+/* urandom_fd is a file descriptor to /dev/urandom. It's protected by |once|. */
static int urandom_fd = -2;
+/* urandom_buffering_requested is set by |RAND_enable_fork_unsafe_buffering|.
+ * It's protected by |requested_lock|. */
+static int urandom_buffering_requested = 0;
+
/* urandom_buffering controls whether buffering is enabled (1) or not (0). This
- * is protected by |global_lock|. */
+ * is protected by |once|. */
static int urandom_buffering = 0;
-/* urandom_get_fd_locked returns a file descriptor to /dev/urandom. The caller
- * of this function must hold |global_lock|. */
-static int urandom_get_fd_locked(void) {
- if (urandom_fd != -2) {
- return urandom_fd;
+static CRYPTO_once_t once = CRYPTO_ONCE_INIT;
+
+/* init_once initializes the state of this module to values previously
+ * requested. This is the only function that modifies |urandom_fd| and
+ * |urandom_buffering|, whose values may be read safely after calling the
+ * once. */
+static void init_once(void) {
+ CRYPTO_STATIC_MUTEX_lock_read(&requested_lock);
+ urandom_buffering = urandom_buffering_requested;
+ int fd = urandom_fd_requested;
+ CRYPTO_STATIC_MUTEX_unlock(&requested_lock);
+
+ if (fd == -2) {
+ do {
+ fd = open("/dev/urandom", O_RDONLY);
+ } while (fd == -1 && errno == EINTR);
}
- urandom_fd = open("/dev/urandom", O_RDONLY);
- return urandom_fd;
+ if (fd < 0) {
+ abort();
+ }
+
+ int flags = fcntl(fd, F_GETFD);
+ if (flags == -1) {
+ abort();
+ }
+ flags |= FD_CLOEXEC;
+ if (fcntl(fd, F_SETFD, flags) == -1) {
+ abort();
+ }
+ urandom_fd = fd;
}
-/* RAND_cleanup frees all buffers, closes any cached file descriptor
- * and resets the global state. */
-void RAND_cleanup(void) {
- struct rand_buffer *cur;
+void RAND_cleanup(void) {}
- CRYPTO_STATIC_MUTEX_lock_write(&global_lock);
- while ((cur = list_head)) {
- list_head = cur->next;
- OPENSSL_free(cur);
+void RAND_set_urandom_fd(int fd) {
+ fd = dup(fd);
+ if (fd < 0) {
+ abort();
}
- if (urandom_fd >= 0) {
- close(urandom_fd);
+
+ CRYPTO_STATIC_MUTEX_lock_write(&requested_lock);
+ urandom_fd_requested = fd;
+ CRYPTO_STATIC_MUTEX_unlock(&requested_lock);
+
+ CRYPTO_once(&once, init_once);
+ if (urandom_fd != fd) {
+ abort(); // Already initialized.
}
- urandom_fd = -2;
- list_head = NULL;
- CRYPTO_STATIC_MUTEX_unlock(&global_lock);
+}
+
+void RAND_enable_fork_unsafe_buffering(int fd) {
+ if (fd >= 0) {
+ fd = dup(fd);
+ if (fd < 0) {
+ abort();
+ }
+ } else {
+ fd = -2;
+ }
+
+ CRYPTO_STATIC_MUTEX_lock_write(&requested_lock);
+ urandom_buffering_requested = 1;
+ urandom_fd_requested = fd;
+ CRYPTO_STATIC_MUTEX_unlock(&requested_lock);
+
+ CRYPTO_once(&once, init_once);
+ if (urandom_buffering != 1 || (fd >= 0 && urandom_fd != fd)) {
+ abort(); // Already initialized.
+ }
+}
+
+static struct rand_buffer *get_thread_local_buffer(void) {
+ struct rand_buffer *buf =
+ CRYPTO_get_thread_local(OPENSSL_THREAD_LOCAL_URANDOM_BUF);
+ if (buf != NULL) {
+ return buf;
+ }
+
+ buf = OPENSSL_malloc(sizeof(struct rand_buffer));
+ if (buf == NULL) {
+ return NULL;
+ }
+ buf->used = BUF_SIZE; /* To trigger a |read_full| on first use. */
+ if (!CRYPTO_set_thread_local(OPENSSL_THREAD_LOCAL_URANDOM_BUF, buf,
+ OPENSSL_free)) {
+ OPENSSL_free(buf);
+ return NULL;
+ }
+
+ return buf;
}
/* read_full reads exactly |len| bytes from |fd| into |out| and returns 1. In
@@ -138,110 +172,48 @@ static char read_full(int fd, uint8_t *out, size_t len) {
return 1;
}
-/* CRYPTO_sysrand puts |num| random bytes into |out|. */
-void CRYPTO_sysrand(uint8_t *out, size_t requested) {
- int fd;
- struct rand_buffer *buf;
- size_t todo;
- pid_t pid, ppid;
-
- if (requested == 0) {
- return;
- }
+/* read_from_buffer reads |requested| random bytes from the buffer into |out|,
+ * refilling it if necessary to satisfy the request. */
+static void read_from_buffer(struct rand_buffer *buf,
+ uint8_t *out, size_t requested) {
+ size_t remaining = BUF_SIZE - buf->used;
- CRYPTO_STATIC_MUTEX_lock_write(&global_lock);
- fd = urandom_get_fd_locked();
+ while (requested > remaining) {
+ memcpy(out, &buf->rand[buf->used], remaining);
+ buf->used += remaining;
+ out += remaining;
+ requested -= remaining;
- if (fd < 0) {
- CRYPTO_STATIC_MUTEX_unlock(&global_lock);
- abort();
- return;
- }
-
- /* If buffering is not enabled, or if the request is large, then the
- * result comes directly from urandom. */
- if (!urandom_buffering || requested > BUF_SIZE / 2) {
- CRYPTO_STATIC_MUTEX_unlock(&global_lock);
- if (!read_full(fd, out, requested)) {
+ if (!read_full(urandom_fd, buf->rand, BUF_SIZE)) {
abort();
- }
- return;
- }
-
- pid = getpid();
- ppid = getppid();
-
- for (;;) {
- buf = list_head;
- if (buf && buf->pid == pid && buf->ppid == ppid &&
- rand_bytes_per_buf - buf->used >= requested) {
- memcpy(out, &buf->rand[buf->used], requested);
- buf->used += requested;
- CRYPTO_STATIC_MUTEX_unlock(&global_lock);
return;
}
-
- /* If we don't immediately have enough entropy with the correct
- * PID, remove the buffer from the list in order to gain
- * exclusive access and unlock. */
- if (buf) {
- list_head = buf->next;
- }
- CRYPTO_STATIC_MUTEX_unlock(&global_lock);
-
- if (!buf) {
- buf = (struct rand_buffer *)OPENSSL_malloc(BUF_SIZE);
- if (!buf) {
- abort();
- return;
- }
- /* The buffer doesn't contain any random bytes yet
- * so we mark it as fully used so that it will be
- * filled below. */
- buf->used = rand_bytes_per_buf;
- buf->next = NULL;
- buf->pid = pid;
- buf->ppid = ppid;
- }
-
- if (buf->pid == pid && buf->ppid == ppid) {
- break;
- }
-
- /* We have forked and so cannot use these bytes as they
- * may have been used in another process. */
- OPENSSL_free(buf);
- CRYPTO_STATIC_MUTEX_lock_write(&global_lock);
+ buf->used = 0;
+ remaining = BUF_SIZE;
}
- while (requested > 0) {
- todo = rand_bytes_per_buf - buf->used;
- if (todo > requested) {
- todo = requested;
- }
- memcpy(out, &buf->rand[buf->used], todo);
- requested -= todo;
- out += todo;
- buf->used += todo;
+ memcpy(out, &buf->rand[buf->used], requested);
+ buf->used += requested;
+}
- if (buf->used < rand_bytes_per_buf) {
- break;
- }
+/* CRYPTO_sysrand puts |requested| random bytes into |out|. */
+void CRYPTO_sysrand(uint8_t *out, size_t requested) {
+ if (requested == 0) {
+ return;
+ }
- if (!read_full(fd, buf->rand, rand_bytes_per_buf)) {
- OPENSSL_free(buf);
- abort();
+ CRYPTO_once(&once, init_once);
+ if (urandom_buffering && requested < BUF_SIZE) {
+ struct rand_buffer *buf = get_thread_local_buffer();
+ if (buf != NULL) {
+ read_from_buffer(buf, out, requested);
return;
}
-
- buf->used = 0;
}
- CRYPTO_STATIC_MUTEX_lock_write(&global_lock);
- assert(list_head != buf);
- buf->next = list_head;
- list_head = buf;
- CRYPTO_STATIC_MUTEX_unlock(&global_lock);
+ if (!read_full(urandom_fd, out, requested)) {
+ abort();
+ }
}
#endif /* !OPENSSL_WINDOWS */
diff --git a/src/crypto/rc4/CMakeLists.txt b/src/crypto/rc4/CMakeLists.txt
index fe2d0c6..a208e96 100644
--- a/src/crypto/rc4/CMakeLists.txt
+++ b/src/crypto/rc4/CMakeLists.txt
@@ -1,4 +1,4 @@
-include_directories(. .. ../../include)
+include_directories(../../include)
if (${ARCH} STREQUAL "x86_64")
set(
diff --git a/src/crypto/rc4/asm/rc4-x86_64.pl b/src/crypto/rc4/asm/rc4-x86_64.pl
index db46242..cef6268 100644
--- a/src/crypto/rc4/asm/rc4-x86_64.pl
+++ b/src/crypto/rc4/asm/rc4-x86_64.pl
@@ -56,7 +56,7 @@
# achieves respectful 432MBps on 2.8GHz processor now. For reference.
# If executed on Xeon, current RC4_CHAR code-path is 2.7x faster than
# RC4_INT code-path. While if executed on Opteron, it's only 25%
-# slower than the RC4_INT one [meaning that if CPU µ-arch detection
+# slower than the RC4_INT one [meaning that if CPU µ-arch detection
# is not implemented, then this final RC4_CHAR code-path should be
# preferred, as it provides better *all-round* performance].
diff --git a/src/crypto/rsa/CMakeLists.txt b/src/crypto/rsa/CMakeLists.txt
index 0ea12c8..bd8ad3b 100644
--- a/src/crypto/rsa/CMakeLists.txt
+++ b/src/crypto/rsa/CMakeLists.txt
@@ -1,4 +1,4 @@
-include_directories(. .. ../../include)
+include_directories(../../include)
add_library(
rsa
@@ -15,7 +15,7 @@ add_library(
add_executable(
rsa_test
- rsa_test.c
+ rsa_test.cc
$<TARGET_OBJECTS:test_support>
)
diff --git a/src/crypto/rsa/blinding.c b/src/crypto/rsa/blinding.c
index 245142b..c93cee1 100644
--- a/src/crypto/rsa/blinding.c
+++ b/src/crypto/rsa/blinding.c
@@ -137,7 +137,7 @@ BN_BLINDING *BN_BLINDING_new(const BIGNUM *A, const BIGNUM *Ai, BIGNUM *mod) {
ret = (BN_BLINDING*) OPENSSL_malloc(sizeof(BN_BLINDING));
if (ret == NULL) {
- OPENSSL_PUT_ERROR(RSA, BN_BLINDING_new, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE);
return NULL;
}
memset(ret, 0, sizeof(BN_BLINDING));
@@ -190,7 +190,7 @@ int BN_BLINDING_update(BN_BLINDING *b, BN_CTX *ctx) {
int ret = 0;
if (b->A == NULL || b->Ai == NULL) {
- OPENSSL_PUT_ERROR(RSA, BN_BLINDING_update, RSA_R_BN_NOT_INITIALIZED);
+ OPENSSL_PUT_ERROR(RSA, RSA_R_BN_NOT_INITIALIZED);
goto err;
}
@@ -230,7 +230,7 @@ int BN_BLINDING_convert_ex(BIGNUM *n, BIGNUM *r, BN_BLINDING *b, BN_CTX *ctx) {
int ret = 1;
if (b->A == NULL || b->Ai == NULL) {
- OPENSSL_PUT_ERROR(RSA, BN_BLINDING_convert_ex, RSA_R_BN_NOT_INITIALIZED);
+ OPENSSL_PUT_ERROR(RSA, RSA_R_BN_NOT_INITIALIZED);
return 0;
}
@@ -266,7 +266,7 @@ int BN_BLINDING_invert_ex(BIGNUM *n, const BIGNUM *r, BN_BLINDING *b,
ret = BN_mod_mul(n, n, r, b->mod, ctx);
} else {
if (b->Ai == NULL) {
- OPENSSL_PUT_ERROR(RSA, BN_BLINDING_invert_ex, RSA_R_BN_NOT_INITIALIZED);
+ OPENSSL_PUT_ERROR(RSA, RSA_R_BN_NOT_INITIALIZED);
return 0;
}
ret = BN_mod_mul(n, n, b->Ai, b->mod, ctx);
@@ -325,13 +325,13 @@ BN_BLINDING *BN_BLINDING_create_param(
if (!BN_rand_range(ret->A, ret->mod)) {
goto err;
}
- if (BN_mod_inverse(ret->Ai, ret->A, ret->mod, ctx) == NULL) {
+
+ int no_inverse;
+ if (BN_mod_inverse_ex(ret->Ai, &no_inverse, ret->A, ret->mod, ctx) == NULL) {
/* this should almost never happen for good RSA keys */
- uint32_t error = ERR_peek_last_error();
- if (ERR_GET_REASON(error) == BN_R_NO_INVERSE) {
+ if (no_inverse) {
if (retry_counter-- == 0) {
- OPENSSL_PUT_ERROR(RSA, BN_BLINDING_create_param,
- RSA_R_TOO_MANY_ITERATIONS);
+ OPENSSL_PUT_ERROR(RSA, RSA_R_TOO_MANY_ITERATIONS);
goto err;
}
ERR_clear_error();
@@ -416,14 +416,14 @@ BN_BLINDING *rsa_setup_blinding(RSA *rsa, BN_CTX *in_ctx) {
BN_CTX_start(ctx);
e = BN_CTX_get(ctx);
if (e == NULL) {
- OPENSSL_PUT_ERROR(RSA, rsa_setup_blinding, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE);
goto err;
}
if (rsa->e == NULL) {
e = rsa_get_public_exp(rsa->d, rsa->p, rsa->q, ctx);
if (e == NULL) {
- OPENSSL_PUT_ERROR(RSA, rsa_setup_blinding, RSA_R_NO_PUBLIC_EXPONENT);
+ OPENSSL_PUT_ERROR(RSA, RSA_R_NO_PUBLIC_EXPONENT);
goto err;
}
} else {
@@ -444,7 +444,7 @@ BN_BLINDING *rsa_setup_blinding(RSA *rsa, BN_CTX *in_ctx) {
ret = BN_BLINDING_create_param(NULL, e, n, ctx, rsa->meth->bn_mod_exp,
mont_ctx);
if (ret == NULL) {
- OPENSSL_PUT_ERROR(RSA, rsa_setup_blinding, ERR_R_BN_LIB);
+ OPENSSL_PUT_ERROR(RSA, ERR_R_BN_LIB);
goto err;
}
diff --git a/src/crypto/rsa/internal.h b/src/crypto/rsa/internal.h
index d15f2a5..c0044c3 100644
--- a/src/crypto/rsa/internal.h
+++ b/src/crypto/rsa/internal.h
@@ -59,8 +59,6 @@
#include <openssl/base.h>
-#include <openssl/asn1.h>
-
#if defined(__cplusplus)
extern "C" {
@@ -109,8 +107,6 @@ int RSA_padding_check_PKCS1_OAEP_mgf1(uint8_t *to, unsigned to_len,
const EVP_MD *md, const EVP_MD *mgf1md);
int RSA_padding_add_none(uint8_t *to, unsigned to_len, const uint8_t *from,
unsigned from_len);
-int RSA_padding_check_none(uint8_t *to, unsigned to_len, const uint8_t *from,
- unsigned from_len);
/* RSA_private_transform calls either the method-specific |private_transform|
* function (if given) or the generic one. See the comment for
@@ -118,20 +114,26 @@ int RSA_padding_check_none(uint8_t *to, unsigned to_len, const uint8_t *from,
int RSA_private_transform(RSA *rsa, uint8_t *out, const uint8_t *in,
size_t len);
-typedef struct rsa_pss_params_st {
- X509_ALGOR *hashAlgorithm;
- X509_ALGOR *maskGenAlgorithm;
- ASN1_INTEGER *saltLength;
- ASN1_INTEGER *trailerField;
-} RSA_PSS_PARAMS;
-DECLARE_ASN1_FUNCTIONS(RSA_PSS_PARAMS)
+/* RSA_additional_prime contains information about the third, forth etc prime
+ * in a multi-prime RSA key. */
+typedef struct RSA_additional_prime_st {
+ BIGNUM *prime;
+ /* exp is d^{prime-1} mod prime */
+ BIGNUM *exp;
+ /* coeff is such that r×coeff ≡ 1 mod prime. */
+ BIGNUM *coeff;
+
+ /* Values below here are not in the ASN.1 serialisation. */
+
+ /* r is the product of all primes (including p and q) prior to this one. */
+ BIGNUM *r;
+ /* method_mod is managed by the |RSA_METHOD|. */
+ BN_MONT_CTX *method_mod;
+} RSA_additional_prime;
+
+void RSA_additional_prime_free(RSA_additional_prime *ap);
-typedef struct rsa_oaep_params_st {
- X509_ALGOR *hashFunc;
- X509_ALGOR *maskGenFunc;
- X509_ALGOR *pSourceFunc;
-} RSA_OAEP_PARAMS;
#if defined(__cplusplus)
} /* extern C */
diff --git a/src/crypto/rsa/padding.c b/src/crypto/rsa/padding.c
index 0a725f1..5a42e24 100644
--- a/src/crypto/rsa/padding.c
+++ b/src/crypto/rsa/padding.c
@@ -74,14 +74,12 @@ int RSA_padding_add_PKCS1_type_1(uint8_t *to, unsigned tlen,
uint8_t *p;
if (tlen < RSA_PKCS1_PADDING_SIZE) {
- OPENSSL_PUT_ERROR(RSA, RSA_padding_add_PKCS1_type_1,
- RSA_R_KEY_SIZE_TOO_SMALL);
+ OPENSSL_PUT_ERROR(RSA, RSA_R_KEY_SIZE_TOO_SMALL);
return 0;
}
if (flen > tlen - RSA_PKCS1_PADDING_SIZE) {
- OPENSSL_PUT_ERROR(RSA, RSA_padding_add_PKCS1_type_1,
- RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE);
+ OPENSSL_PUT_ERROR(RSA, RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE);
return 0;
}
@@ -105,15 +103,13 @@ int RSA_padding_check_PKCS1_type_1(uint8_t *to, unsigned tlen,
const uint8_t *p;
if (flen < 2) {
- OPENSSL_PUT_ERROR(RSA, RSA_padding_check_PKCS1_type_1,
- RSA_R_DATA_TOO_SMALL);
+ OPENSSL_PUT_ERROR(RSA, RSA_R_DATA_TOO_SMALL);
return -1;
}
p = from;
if ((*(p++) != 0) || (*(p++) != 1)) {
- OPENSSL_PUT_ERROR(RSA, RSA_padding_check_PKCS1_type_1,
- RSA_R_BLOCK_TYPE_IS_NOT_01);
+ OPENSSL_PUT_ERROR(RSA, RSA_R_BLOCK_TYPE_IS_NOT_01);
return -1;
}
@@ -126,8 +122,7 @@ int RSA_padding_check_PKCS1_type_1(uint8_t *to, unsigned tlen,
p++;
break;
} else {
- OPENSSL_PUT_ERROR(RSA, RSA_padding_check_PKCS1_type_1,
- RSA_R_BAD_FIXED_HEADER_DECRYPT);
+ OPENSSL_PUT_ERROR(RSA, RSA_R_BAD_FIXED_HEADER_DECRYPT);
return -1;
}
}
@@ -135,21 +130,18 @@ int RSA_padding_check_PKCS1_type_1(uint8_t *to, unsigned tlen,
}
if (i == j) {
- OPENSSL_PUT_ERROR(RSA, RSA_padding_check_PKCS1_type_1,
- RSA_R_NULL_BEFORE_BLOCK_MISSING);
+ OPENSSL_PUT_ERROR(RSA, RSA_R_NULL_BEFORE_BLOCK_MISSING);
return -1;
}
if (i < 8) {
- OPENSSL_PUT_ERROR(RSA, RSA_padding_check_PKCS1_type_1,
- RSA_R_BAD_PAD_BYTE_COUNT);
+ OPENSSL_PUT_ERROR(RSA, RSA_R_BAD_PAD_BYTE_COUNT);
return -1;
}
i++; /* Skip over the '\0' */
j -= i;
if (j > tlen) {
- OPENSSL_PUT_ERROR(RSA, RSA_padding_check_PKCS1_type_1,
- RSA_R_DATA_TOO_LARGE);
+ OPENSSL_PUT_ERROR(RSA, RSA_R_DATA_TOO_LARGE);
return -1;
}
memcpy(to, p, j);
@@ -163,14 +155,12 @@ int RSA_padding_add_PKCS1_type_2(uint8_t *to, unsigned tlen,
uint8_t *p;
if (tlen < RSA_PKCS1_PADDING_SIZE) {
- OPENSSL_PUT_ERROR(RSA, RSA_padding_add_PKCS1_type_2,
- RSA_R_KEY_SIZE_TOO_SMALL);
+ OPENSSL_PUT_ERROR(RSA, RSA_R_KEY_SIZE_TOO_SMALL);
return 0;
}
if (flen > tlen - RSA_PKCS1_PADDING_SIZE) {
- OPENSSL_PUT_ERROR(RSA, RSA_padding_add_PKCS1_type_2,
- RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE);
+ OPENSSL_PUT_ERROR(RSA, RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE);
return 0;
}
@@ -271,8 +261,7 @@ int RSA_padding_check_PKCS1_type_2(uint8_t *to, unsigned tlen,
size_t msg_index, msg_len;
if (flen == 0) {
- OPENSSL_PUT_ERROR(RSA, RSA_padding_check_PKCS1_type_2,
- RSA_R_EMPTY_PUBLIC_KEY);
+ OPENSSL_PUT_ERROR(RSA, RSA_R_EMPTY_PUBLIC_KEY);
return -1;
}
@@ -281,8 +270,7 @@ int RSA_padding_check_PKCS1_type_2(uint8_t *to, unsigned tlen,
* |RSA_PKCS1_PADDING| make it impossible to completely avoid Bleichenbacher's
* attack. */
if (!RSA_message_index_PKCS1_type_2(from, flen, &msg_index)) {
- OPENSSL_PUT_ERROR(RSA, RSA_padding_check_PKCS1_type_2,
- RSA_R_PKCS_DECODING_ERROR);
+ OPENSSL_PUT_ERROR(RSA, RSA_R_PKCS_DECODING_ERROR);
return -1;
}
@@ -290,8 +278,7 @@ int RSA_padding_check_PKCS1_type_2(uint8_t *to, unsigned tlen,
if (msg_len > tlen) {
/* This shouldn't happen because this function is always called with |tlen|
* the key size and |flen| is bounded by the key size. */
- OPENSSL_PUT_ERROR(RSA, RSA_padding_check_PKCS1_type_2,
- RSA_R_PKCS_DECODING_ERROR);
+ OPENSSL_PUT_ERROR(RSA, RSA_R_PKCS_DECODING_ERROR);
return -1;
}
memcpy(to, &from[msg_index], msg_len);
@@ -300,14 +287,12 @@ int RSA_padding_check_PKCS1_type_2(uint8_t *to, unsigned tlen,
int RSA_padding_add_none(uint8_t *to, unsigned tlen, const uint8_t *from, unsigned flen) {
if (flen > tlen) {
- OPENSSL_PUT_ERROR(RSA, RSA_padding_add_none,
- RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE);
+ OPENSSL_PUT_ERROR(RSA, RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE);
return 0;
}
if (flen < tlen) {
- OPENSSL_PUT_ERROR(RSA, RSA_padding_add_none,
- RSA_R_DATA_TOO_SMALL_FOR_KEY_SIZE);
+ OPENSSL_PUT_ERROR(RSA, RSA_R_DATA_TOO_SMALL_FOR_KEY_SIZE);
return 0;
}
@@ -315,17 +300,6 @@ int RSA_padding_add_none(uint8_t *to, unsigned tlen, const uint8_t *from, unsign
return 1;
}
-int RSA_padding_check_none(uint8_t *to, unsigned tlen, const uint8_t *from,
- unsigned flen) {
- if (flen > tlen) {
- OPENSSL_PUT_ERROR(RSA, RSA_padding_check_none, RSA_R_DATA_TOO_LARGE);
- return -1;
- }
-
- memcpy(to, from, flen);
- return flen;
-}
-
int PKCS1_MGF1(uint8_t *mask, unsigned len, const uint8_t *seed,
unsigned seedlen, const EVP_MD *dgst) {
unsigned outlen = 0;
@@ -388,21 +362,18 @@ int RSA_padding_add_PKCS1_OAEP_mgf1(uint8_t *to, unsigned tlen,
mdlen = EVP_MD_size(md);
if (tlen < 2 * mdlen + 2) {
- OPENSSL_PUT_ERROR(RSA, RSA_padding_add_PKCS1_OAEP_mgf1,
- RSA_R_KEY_SIZE_TOO_SMALL);
+ OPENSSL_PUT_ERROR(RSA, RSA_R_KEY_SIZE_TOO_SMALL);
return 0;
}
emlen = tlen - 1;
if (flen > emlen - 2 * mdlen - 1) {
- OPENSSL_PUT_ERROR(RSA, RSA_padding_add_PKCS1_OAEP_mgf1,
- RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE);
+ OPENSSL_PUT_ERROR(RSA, RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE);
return 0;
}
if (emlen < 2 * mdlen + 1) {
- OPENSSL_PUT_ERROR(RSA, RSA_padding_add_PKCS1_OAEP_mgf1,
- RSA_R_KEY_SIZE_TOO_SMALL);
+ OPENSSL_PUT_ERROR(RSA, RSA_R_KEY_SIZE_TOO_SMALL);
return 0;
}
@@ -422,8 +393,7 @@ int RSA_padding_add_PKCS1_OAEP_mgf1(uint8_t *to, unsigned tlen,
dbmask = OPENSSL_malloc(emlen - mdlen);
if (dbmask == NULL) {
- OPENSSL_PUT_ERROR(RSA, RSA_padding_add_PKCS1_OAEP_mgf1,
- ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE);
return 0;
}
@@ -477,8 +447,7 @@ int RSA_padding_check_PKCS1_OAEP_mgf1(uint8_t *to, unsigned tlen,
dblen = flen - mdlen - 1;
db = OPENSSL_malloc(dblen);
if (db == NULL) {
- OPENSSL_PUT_ERROR(RSA, RSA_padding_check_PKCS1_OAEP_mgf1,
- ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE);
goto err;
}
@@ -526,8 +495,7 @@ int RSA_padding_check_PKCS1_OAEP_mgf1(uint8_t *to, unsigned tlen,
one_index++;
mlen = dblen - one_index;
if (tlen < mlen) {
- OPENSSL_PUT_ERROR(RSA, RSA_padding_check_PKCS1_OAEP_mgf1,
- RSA_R_DATA_TOO_LARGE);
+ OPENSSL_PUT_ERROR(RSA, RSA_R_DATA_TOO_LARGE);
mlen = -1;
} else {
memcpy(to, db + one_index, mlen);
@@ -539,8 +507,7 @@ int RSA_padding_check_PKCS1_OAEP_mgf1(uint8_t *to, unsigned tlen,
decoding_err:
/* to avoid chosen ciphertext attacks, the error message should not reveal
* which kind of decoding error happened */
- OPENSSL_PUT_ERROR(RSA, RSA_padding_check_PKCS1_OAEP_mgf1,
- RSA_R_OAEP_DECODING_ERROR);
+ OPENSSL_PUT_ERROR(RSA, RSA_R_OAEP_DECODING_ERROR);
err:
OPENSSL_free(db);
return -1;
@@ -576,15 +543,14 @@ int RSA_verify_PKCS1_PSS_mgf1(RSA *rsa, const uint8_t *mHash,
} else if (sLen == -2) {
sLen = -2;
} else if (sLen < -2) {
- OPENSSL_PUT_ERROR(RSA, RSA_verify_PKCS1_PSS_mgf1, RSA_R_SLEN_CHECK_FAILED);
+ OPENSSL_PUT_ERROR(RSA, RSA_R_SLEN_CHECK_FAILED);
goto err;
}
MSBits = (BN_num_bits(rsa->n) - 1) & 0x7;
emLen = RSA_size(rsa);
if (EM[0] & (0xFF << MSBits)) {
- OPENSSL_PUT_ERROR(RSA, RSA_verify_PKCS1_PSS_mgf1,
- RSA_R_FIRST_OCTET_INVALID);
+ OPENSSL_PUT_ERROR(RSA, RSA_R_FIRST_OCTET_INVALID);
goto err;
}
if (MSBits == 0) {
@@ -593,18 +559,18 @@ int RSA_verify_PKCS1_PSS_mgf1(RSA *rsa, const uint8_t *mHash,
}
if (emLen < ((int)hLen + sLen + 2)) {
/* sLen can be small negative */
- OPENSSL_PUT_ERROR(RSA, RSA_verify_PKCS1_PSS_mgf1, RSA_R_DATA_TOO_LARGE);
+ OPENSSL_PUT_ERROR(RSA, RSA_R_DATA_TOO_LARGE);
goto err;
}
if (EM[emLen - 1] != 0xbc) {
- OPENSSL_PUT_ERROR(RSA, RSA_verify_PKCS1_PSS_mgf1, RSA_R_LAST_OCTET_INVALID);
+ OPENSSL_PUT_ERROR(RSA, RSA_R_LAST_OCTET_INVALID);
goto err;
}
maskedDBLen = emLen - hLen - 1;
H = EM + maskedDBLen;
DB = OPENSSL_malloc(maskedDBLen);
if (!DB) {
- OPENSSL_PUT_ERROR(RSA, RSA_verify_PKCS1_PSS_mgf1, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE);
goto err;
}
if (PKCS1_MGF1(DB, maskedDBLen, H, hLen, mgf1Hash) < 0) {
@@ -620,12 +586,11 @@ int RSA_verify_PKCS1_PSS_mgf1(RSA *rsa, const uint8_t *mHash,
;
}
if (DB[i++] != 0x1) {
- OPENSSL_PUT_ERROR(RSA, RSA_verify_PKCS1_PSS_mgf1,
- RSA_R_SLEN_RECOVERY_FAILED);
+ OPENSSL_PUT_ERROR(RSA, RSA_R_SLEN_RECOVERY_FAILED);
goto err;
}
if (sLen >= 0 && (maskedDBLen - i) != sLen) {
- OPENSSL_PUT_ERROR(RSA, RSA_verify_PKCS1_PSS_mgf1, RSA_R_SLEN_CHECK_FAILED);
+ OPENSSL_PUT_ERROR(RSA, RSA_R_SLEN_CHECK_FAILED);
goto err;
}
if (!EVP_DigestInit_ex(&ctx, Hash, NULL) ||
@@ -642,7 +607,7 @@ int RSA_verify_PKCS1_PSS_mgf1(RSA *rsa, const uint8_t *mHash,
goto err;
}
if (memcmp(H_, H, hLen)) {
- OPENSSL_PUT_ERROR(RSA, RSA_verify_PKCS1_PSS_mgf1, RSA_R_BAD_SIGNATURE);
+ OPENSSL_PUT_ERROR(RSA, RSA_R_BAD_SIGNATURE);
ret = 0;
} else {
ret = 1;
@@ -681,14 +646,12 @@ int RSA_padding_add_PKCS1_PSS_mgf1(RSA *rsa, unsigned char *EM,
} else if (sLen == -2) {
sLen = -2;
} else if (sLen < -2) {
- OPENSSL_PUT_ERROR(RSA, RSA_padding_add_PKCS1_PSS_mgf1,
- RSA_R_SLEN_CHECK_FAILED);
+ OPENSSL_PUT_ERROR(RSA, RSA_R_SLEN_CHECK_FAILED);
goto err;
}
if (BN_is_zero(rsa->n)) {
- OPENSSL_PUT_ERROR(RSA, RSA_padding_add_PKCS1_PSS_mgf1,
- RSA_R_EMPTY_PUBLIC_KEY);
+ OPENSSL_PUT_ERROR(RSA, RSA_R_EMPTY_PUBLIC_KEY);
goto err;
}
@@ -701,21 +664,18 @@ int RSA_padding_add_PKCS1_PSS_mgf1(RSA *rsa, unsigned char *EM,
}
if (sLen == -2) {
if (emLen < hLen + 2) {
- OPENSSL_PUT_ERROR(RSA, RSA_padding_add_PKCS1_PSS_mgf1,
- RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE);
+ OPENSSL_PUT_ERROR(RSA, RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE);
goto err;
}
sLen = emLen - hLen - 2;
} else if (emLen < hLen + sLen + 2) {
- OPENSSL_PUT_ERROR(RSA, RSA_padding_add_PKCS1_PSS_mgf1,
- RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE);
+ OPENSSL_PUT_ERROR(RSA, RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE);
goto err;
}
if (sLen > 0) {
salt = OPENSSL_malloc(sLen);
if (!salt) {
- OPENSSL_PUT_ERROR(RSA, RSA_padding_add_PKCS1_PSS_mgf1,
- ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE);
goto err;
}
if (!RAND_bytes(salt, sLen)) {
diff --git a/src/crypto/rsa/rsa.c b/src/crypto/rsa/rsa.c
index 17059b0..2f23165 100644
--- a/src/crypto/rsa/rsa.c
+++ b/src/crypto/rsa/rsa.c
@@ -79,7 +79,7 @@ RSA *RSA_new(void) { return RSA_new_method(NULL); }
RSA *RSA_new_method(const ENGINE *engine) {
RSA *rsa = (RSA *)OPENSSL_malloc(sizeof(RSA));
if (rsa == NULL) {
- OPENSSL_PUT_ERROR(RSA, RSA_new_method, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE);
return NULL;
}
@@ -114,6 +114,18 @@ RSA *RSA_new_method(const ENGINE *engine) {
return rsa;
}
+void RSA_additional_prime_free(RSA_additional_prime *ap) {
+ if (ap == NULL) {
+ return;
+ }
+
+ BN_clear_free(ap->prime);
+ BN_clear_free(ap->exp);
+ BN_clear_free(ap->coeff);
+ BN_clear_free(ap->r);
+ OPENSSL_free(ap);
+}
+
void RSA_free(RSA *rsa) {
unsigned u;
@@ -145,6 +157,10 @@ void RSA_free(RSA *rsa) {
}
OPENSSL_free(rsa->blindings);
OPENSSL_free(rsa->blindings_inuse);
+ if (rsa->additional_primes != NULL) {
+ sk_RSA_additional_prime_pop_free(rsa->additional_primes,
+ RSA_additional_prime_free);
+ }
CRYPTO_MUTEX_cleanup(&rsa->lock);
OPENSSL_free(rsa);
}
@@ -162,6 +178,16 @@ int RSA_generate_key_ex(RSA *rsa, int bits, BIGNUM *e_value, BN_GENCB *cb) {
return RSA_default_method.keygen(rsa, bits, e_value, cb);
}
+int RSA_generate_multi_prime_key(RSA *rsa, int bits, int num_primes,
+ BIGNUM *e_value, BN_GENCB *cb) {
+ if (rsa->meth->multi_prime_keygen) {
+ return rsa->meth->multi_prime_keygen(rsa, bits, num_primes, e_value, cb);
+ }
+
+ return RSA_default_method.multi_prime_keygen(rsa, bits, num_primes, e_value,
+ cb);
+}
+
int RSA_encrypt(RSA *rsa, size_t *out_len, uint8_t *out, size_t max_out,
const uint8_t *in, size_t in_len, int padding) {
if (rsa->meth->encrypt) {
@@ -342,20 +368,15 @@ static const struct pkcs1_sig_prefix kPKCS1SigPrefixes[] = {
},
};
-/* TODO(fork): mostly new code, needs careful review. */
-
-/* pkcs1_prefixed_msg builds a PKCS#1, prefixed version of |msg| for the given
- * hash function and sets |out_msg| to point to it. On successful return,
- * |*out_msg| may be allocated memory and, if so, |*is_alloced| will be 1. */
-static int pkcs1_prefixed_msg(uint8_t **out_msg, size_t *out_msg_len,
- int *is_alloced, int hash_nid, const uint8_t *msg,
- size_t msg_len) {
+int RSA_add_pkcs1_prefix(uint8_t **out_msg, size_t *out_msg_len,
+ int *is_alloced, int hash_nid, const uint8_t *msg,
+ size_t msg_len) {
unsigned i;
if (hash_nid == NID_md5_sha1) {
/* Special case: SSL signature, just check the length. */
if (msg_len != SSL_SIG_LENGTH) {
- OPENSSL_PUT_ERROR(RSA, pkcs1_prefixed_msg, RSA_R_INVALID_MESSAGE_LENGTH);
+ OPENSSL_PUT_ERROR(RSA, RSA_R_INVALID_MESSAGE_LENGTH);
return 0;
}
@@ -378,13 +399,13 @@ static int pkcs1_prefixed_msg(uint8_t **out_msg, size_t *out_msg_len,
signed_msg_len = prefix_len + msg_len;
if (signed_msg_len < prefix_len) {
- OPENSSL_PUT_ERROR(RSA, pkcs1_prefixed_msg, RSA_R_TOO_LONG);
+ OPENSSL_PUT_ERROR(RSA, RSA_R_TOO_LONG);
return 0;
}
signed_msg = OPENSSL_malloc(signed_msg_len);
if (!signed_msg) {
- OPENSSL_PUT_ERROR(RSA, pkcs1_prefixed_msg, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE);
return 0;
}
@@ -398,7 +419,7 @@ static int pkcs1_prefixed_msg(uint8_t **out_msg, size_t *out_msg_len,
return 1;
}
- OPENSSL_PUT_ERROR(RSA, pkcs1_prefixed_msg, RSA_R_UNKNOWN_ALGORITHM_TYPE);
+ OPENSSL_PUT_ERROR(RSA, RSA_R_UNKNOWN_ALGORITHM_TYPE);
return 0;
}
@@ -415,14 +436,14 @@ int RSA_sign(int hash_nid, const uint8_t *in, unsigned in_len, uint8_t *out,
return rsa->meth->sign(hash_nid, in, in_len, out, out_len, rsa);
}
- if (!pkcs1_prefixed_msg(&signed_msg, &signed_msg_len, &signed_msg_is_alloced,
- hash_nid, in, in_len)) {
+ if (!RSA_add_pkcs1_prefix(&signed_msg, &signed_msg_len,
+ &signed_msg_is_alloced, hash_nid, in, in_len)) {
return 0;
}
if (rsa_size < RSA_PKCS1_PADDING_SIZE ||
signed_msg_len > rsa_size - RSA_PKCS1_PADDING_SIZE) {
- OPENSSL_PUT_ERROR(RSA, RSA_sign, RSA_R_DIGEST_TOO_BIG_FOR_RSA_KEY);
+ OPENSSL_PUT_ERROR(RSA, RSA_R_DIGEST_TOO_BIG_FOR_RSA_KEY);
goto finish;
}
@@ -453,18 +474,18 @@ int RSA_verify(int hash_nid, const uint8_t *msg, size_t msg_len,
}
if (sig_len != rsa_size) {
- OPENSSL_PUT_ERROR(RSA, RSA_verify, RSA_R_WRONG_SIGNATURE_LENGTH);
+ OPENSSL_PUT_ERROR(RSA, RSA_R_WRONG_SIGNATURE_LENGTH);
return 0;
}
if (hash_nid == NID_md5_sha1 && msg_len != SSL_SIG_LENGTH) {
- OPENSSL_PUT_ERROR(RSA, RSA_verify, RSA_R_INVALID_MESSAGE_LENGTH);
+ OPENSSL_PUT_ERROR(RSA, RSA_R_INVALID_MESSAGE_LENGTH);
return 0;
}
buf = OPENSSL_malloc(rsa_size);
if (!buf) {
- OPENSSL_PUT_ERROR(RSA, RSA_verify, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE);
return 0;
}
@@ -473,13 +494,13 @@ int RSA_verify(int hash_nid, const uint8_t *msg, size_t msg_len,
goto out;
}
- if (!pkcs1_prefixed_msg(&signed_msg, &signed_msg_len, &signed_msg_is_alloced,
- hash_nid, msg, msg_len)) {
+ if (!RSA_add_pkcs1_prefix(&signed_msg, &signed_msg_len,
+ &signed_msg_is_alloced, hash_nid, msg, msg_len)) {
goto out;
}
if (len != signed_msg_len || CRYPTO_memcmp(buf, signed_msg, len) != 0) {
- OPENSSL_PUT_ERROR(RSA, RSA_verify, RSA_R_BAD_SIGNATURE);
+ OPENSSL_PUT_ERROR(RSA, RSA_R_BAD_SIGNATURE);
goto out;
}
@@ -509,12 +530,12 @@ int RSA_check_key(const RSA *key) {
}
if ((key->p != NULL) != (key->q != NULL)) {
- OPENSSL_PUT_ERROR(RSA, RSA_check_key, RSA_R_ONLY_ONE_OF_P_Q_GIVEN);
+ OPENSSL_PUT_ERROR(RSA, RSA_R_ONLY_ONE_OF_P_Q_GIVEN);
return 0;
}
if (!key->n || !key->e) {
- OPENSSL_PUT_ERROR(RSA, RSA_check_key, RSA_R_VALUE_MISSING);
+ OPENSSL_PUT_ERROR(RSA, RSA_R_VALUE_MISSING);
return 0;
}
@@ -526,7 +547,7 @@ int RSA_check_key(const RSA *key) {
ctx = BN_CTX_new();
if (ctx == NULL) {
- OPENSSL_PUT_ERROR(RSA, RSA_check_key, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE);
return 0;
}
@@ -540,52 +561,74 @@ int RSA_check_key(const RSA *key) {
BN_init(&dmq1);
BN_init(&iqmp);
- if (/* n = pq */
- !BN_mul(&n, key->p, key->q, ctx) ||
- /* lcm = lcm(p-1, q-1) */
+ if (!BN_mul(&n, key->p, key->q, ctx) ||
+ /* lcm = lcm(prime-1, for all primes) */
!BN_sub(&pm1, key->p, BN_value_one()) ||
!BN_sub(&qm1, key->q, BN_value_one()) ||
!BN_mul(&lcm, &pm1, &qm1, ctx) ||
+ !BN_gcd(&gcd, &pm1, &qm1, ctx)) {
+ OPENSSL_PUT_ERROR(RSA, ERR_LIB_BN);
+ goto out;
+ }
+
+ size_t num_additional_primes = 0;
+ if (key->additional_primes != NULL) {
+ num_additional_primes = sk_RSA_additional_prime_num(key->additional_primes);
+ }
+
+ size_t i;
+ for (i = 0; i < num_additional_primes; i++) {
+ const RSA_additional_prime *ap =
+ sk_RSA_additional_prime_value(key->additional_primes, i);
+ if (!BN_mul(&n, &n, ap->prime, ctx) ||
+ !BN_sub(&pm1, ap->prime, BN_value_one()) ||
+ !BN_mul(&lcm, &lcm, &pm1, ctx) ||
+ !BN_gcd(&gcd, &gcd, &pm1, ctx)) {
+ OPENSSL_PUT_ERROR(RSA, ERR_LIB_BN);
+ goto out;
+ }
+ }
+
+ if (!BN_div(&lcm, NULL, &lcm, &gcd, ctx) ||
!BN_gcd(&gcd, &pm1, &qm1, ctx) ||
- !BN_div(&lcm, NULL, &lcm, &gcd, ctx) ||
- /* de = d*e mod lcm(p-1, q-1) */
+ /* de = d*e mod lcm(prime-1, for all primes). */
!BN_mod_mul(&de, key->d, key->e, &lcm, ctx)) {
- OPENSSL_PUT_ERROR(RSA, RSA_check_key, ERR_LIB_BN);
+ OPENSSL_PUT_ERROR(RSA, ERR_LIB_BN);
goto out;
}
if (BN_cmp(&n, key->n) != 0) {
- OPENSSL_PUT_ERROR(RSA, RSA_check_key, RSA_R_N_NOT_EQUAL_P_Q);
+ OPENSSL_PUT_ERROR(RSA, RSA_R_N_NOT_EQUAL_P_Q);
goto out;
}
if (!BN_is_one(&de)) {
- OPENSSL_PUT_ERROR(RSA, RSA_check_key, RSA_R_D_E_NOT_CONGRUENT_TO_1);
+ OPENSSL_PUT_ERROR(RSA, RSA_R_D_E_NOT_CONGRUENT_TO_1);
goto out;
}
has_crt_values = key->dmp1 != NULL;
if (has_crt_values != (key->dmq1 != NULL) ||
has_crt_values != (key->iqmp != NULL)) {
- OPENSSL_PUT_ERROR(RSA, RSA_check_key, RSA_R_INCONSISTENT_SET_OF_CRT_VALUES);
+ OPENSSL_PUT_ERROR(RSA, RSA_R_INCONSISTENT_SET_OF_CRT_VALUES);
goto out;
}
- if (has_crt_values) {
+ if (has_crt_values && num_additional_primes == 0) {
if (/* dmp1 = d mod (p-1) */
!BN_mod(&dmp1, key->d, &pm1, ctx) ||
/* dmq1 = d mod (q-1) */
!BN_mod(&dmq1, key->d, &qm1, ctx) ||
/* iqmp = q^-1 mod p */
!BN_mod_inverse(&iqmp, key->q, key->p, ctx)) {
- OPENSSL_PUT_ERROR(RSA, RSA_check_key, ERR_LIB_BN);
+ OPENSSL_PUT_ERROR(RSA, ERR_LIB_BN);
goto out;
}
if (BN_cmp(&dmp1, key->dmp1) != 0 ||
BN_cmp(&dmq1, key->dmq1) != 0 ||
BN_cmp(&iqmp, key->iqmp) != 0) {
- OPENSSL_PUT_ERROR(RSA, RSA_check_key, RSA_R_CRT_VALUES_INCORRECT);
+ OPENSSL_PUT_ERROR(RSA, RSA_R_CRT_VALUES_INCORRECT);
goto out;
}
}
@@ -613,13 +656,17 @@ int RSA_recover_crt_params(RSA *rsa) {
int ok = 0;
if (rsa->n == NULL || rsa->e == NULL || rsa->d == NULL) {
- OPENSSL_PUT_ERROR(RSA, RSA_recover_crt_params, RSA_R_EMPTY_PUBLIC_KEY);
+ OPENSSL_PUT_ERROR(RSA, RSA_R_EMPTY_PUBLIC_KEY);
return 0;
}
if (rsa->p || rsa->q || rsa->dmp1 || rsa->dmq1 || rsa->iqmp) {
- OPENSSL_PUT_ERROR(RSA, RSA_recover_crt_params,
- RSA_R_CRT_PARAMS_ALREADY_GIVEN);
+ OPENSSL_PUT_ERROR(RSA, RSA_R_CRT_PARAMS_ALREADY_GIVEN);
+ return 0;
+ }
+
+ if (rsa->additional_primes != NULL) {
+ OPENSSL_PUT_ERROR(RSA, RSA_R_CANNOT_RECOVER_MULTI_PRIME_KEY);
return 0;
}
@@ -628,7 +675,7 @@ int RSA_recover_crt_params(RSA *rsa) {
ctx = BN_CTX_new();
if (ctx == NULL) {
- OPENSSL_PUT_ERROR(RSA, RSA_recover_crt_params, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE);
return 0;
}
@@ -641,7 +688,7 @@ int RSA_recover_crt_params(RSA *rsa) {
if (totient == NULL || rem == NULL || multiple == NULL || p_plus_q == NULL ||
p_minus_q == NULL) {
- OPENSSL_PUT_ERROR(RSA, RSA_recover_crt_params, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE);
goto err;
}
@@ -669,12 +716,12 @@ int RSA_recover_crt_params(RSA *rsa) {
!BN_div(multiple, NULL, totient, rsa->n, ctx) ||
!BN_add_word(multiple, 1) ||
!BN_div(totient, rem, totient, multiple, ctx)) {
- OPENSSL_PUT_ERROR(RSA, RSA_recover_crt_params, ERR_R_BN_LIB);
+ OPENSSL_PUT_ERROR(RSA, ERR_R_BN_LIB);
goto err;
}
if (!BN_is_zero(rem)) {
- OPENSSL_PUT_ERROR(RSA, RSA_recover_crt_params, RSA_R_BAD_RSA_PARAMETERS);
+ OPENSSL_PUT_ERROR(RSA, RSA_R_BAD_RSA_PARAMETERS);
goto err;
}
@@ -685,7 +732,7 @@ int RSA_recover_crt_params(RSA *rsa) {
rsa->iqmp = BN_new();
if (rsa->p == NULL || rsa->q == NULL || rsa->dmp1 == NULL || rsa->dmq1 ==
NULL || rsa->iqmp == NULL) {
- OPENSSL_PUT_ERROR(RSA, RSA_recover_crt_params, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE);
goto err;
}
@@ -703,12 +750,12 @@ int RSA_recover_crt_params(RSA *rsa) {
!BN_rshift1(rsa->q, rsa->q) ||
!BN_div(rsa->p, NULL, rsa->n, rsa->q, ctx) ||
!BN_mul(multiple, rsa->p, rsa->q, ctx)) {
- OPENSSL_PUT_ERROR(RSA, RSA_recover_crt_params, ERR_R_BN_LIB);
+ OPENSSL_PUT_ERROR(RSA, ERR_R_BN_LIB);
goto err;
}
if (BN_cmp(multiple, rsa->n) != 0) {
- OPENSSL_PUT_ERROR(RSA, RSA_recover_crt_params, RSA_R_INTERNAL_ERROR);
+ OPENSSL_PUT_ERROR(RSA, RSA_R_INTERNAL_ERROR);
goto err;
}
@@ -717,7 +764,7 @@ int RSA_recover_crt_params(RSA *rsa) {
!BN_sub(rem, rsa->q, BN_value_one()) ||
!BN_mod(rsa->dmq1, rsa->d, rem, ctx) ||
!BN_mod_inverse(rsa->iqmp, rsa->q, rsa->p, ctx)) {
- OPENSSL_PUT_ERROR(RSA, RSA_recover_crt_params, ERR_R_BN_LIB);
+ OPENSSL_PUT_ERROR(RSA, ERR_R_BN_LIB);
goto err;
}
diff --git a/src/crypto/rsa/rsa_asn1.c b/src/crypto/rsa/rsa_asn1.c
index 924cb8a..e3756ba 100644
--- a/src/crypto/rsa/rsa_asn1.c
+++ b/src/crypto/rsa/rsa_asn1.c
@@ -55,45 +55,384 @@
#include <openssl/rsa.h>
+#include <assert.h>
+#include <limits.h>
+#include <string.h>
+
#include <openssl/asn1.h>
#include <openssl/asn1t.h>
+#include <openssl/bn.h>
+#include <openssl/bytestring.h>
+#include <openssl/err.h>
+#include <openssl/mem.h>
#include "internal.h"
-/* Override the default free and new methods */
-static int rsa_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
- void *exarg) {
- if (operation == ASN1_OP_NEW_PRE) {
- *pval = (ASN1_VALUE *)RSA_new();
- if (*pval) {
- return 2;
+static int parse_integer_buggy(CBS *cbs, BIGNUM **out, int buggy) {
+ assert(*out == NULL);
+ *out = BN_new();
+ if (*out == NULL) {
+ return 0;
+ }
+ if (buggy) {
+ return BN_cbs2unsigned_buggy(cbs, *out);
+ }
+ return BN_cbs2unsigned(cbs, *out);
+}
+
+static int parse_integer(CBS *cbs, BIGNUM **out) {
+ return parse_integer_buggy(cbs, out, 0 /* not buggy */);
+}
+
+static int marshal_integer(CBB *cbb, BIGNUM *bn) {
+ if (bn == NULL) {
+ /* An RSA object may be missing some components. */
+ OPENSSL_PUT_ERROR(RSA, RSA_R_VALUE_MISSING);
+ return 0;
+ }
+ return BN_bn2cbb(cbb, bn);
+}
+
+static RSA *parse_public_key(CBS *cbs, int buggy) {
+ RSA *ret = RSA_new();
+ if (ret == NULL) {
+ return NULL;
+ }
+ CBS child;
+ if (!CBS_get_asn1(cbs, &child, CBS_ASN1_SEQUENCE) ||
+ !parse_integer_buggy(&child, &ret->n, buggy) ||
+ !parse_integer(&child, &ret->e) ||
+ CBS_len(&child) != 0) {
+ OPENSSL_PUT_ERROR(RSA, RSA_R_BAD_ENCODING);
+ RSA_free(ret);
+ return NULL;
+ }
+ return ret;
+}
+
+RSA *RSA_parse_public_key(CBS *cbs) {
+ return parse_public_key(cbs, 0 /* not buggy */);
+}
+
+RSA *RSA_parse_public_key_buggy(CBS *cbs) {
+ /* Estonian IDs issued between September 2014 to September 2015 are
+ * broken. See https://crbug.com/532048 and https://crbug.com/534766.
+ *
+ * TODO(davidben): Remove this code and callers in March 2016. */
+ return parse_public_key(cbs, 1 /* buggy */);
+}
+
+RSA *RSA_public_key_from_bytes(const uint8_t *in, size_t in_len) {
+ CBS cbs;
+ CBS_init(&cbs, in, in_len);
+ RSA *ret = RSA_parse_public_key(&cbs);
+ if (ret == NULL || CBS_len(&cbs) != 0) {
+ OPENSSL_PUT_ERROR(RSA, RSA_R_BAD_ENCODING);
+ RSA_free(ret);
+ return NULL;
+ }
+ return ret;
+}
+
+int RSA_marshal_public_key(CBB *cbb, const RSA *rsa) {
+ CBB child;
+ if (!CBB_add_asn1(cbb, &child, CBS_ASN1_SEQUENCE) ||
+ !marshal_integer(&child, rsa->n) ||
+ !marshal_integer(&child, rsa->e) ||
+ !CBB_flush(cbb)) {
+ OPENSSL_PUT_ERROR(RSA, RSA_R_ENCODE_ERROR);
+ return 0;
+ }
+ return 1;
+}
+
+int RSA_public_key_to_bytes(uint8_t **out_bytes, size_t *out_len,
+ const RSA *rsa) {
+ CBB cbb;
+ CBB_zero(&cbb);
+ if (!CBB_init(&cbb, 0) ||
+ !RSA_marshal_public_key(&cbb, rsa) ||
+ !CBB_finish(&cbb, out_bytes, out_len)) {
+ OPENSSL_PUT_ERROR(RSA, RSA_R_ENCODE_ERROR);
+ CBB_cleanup(&cbb);
+ return 0;
+ }
+ return 1;
+}
+
+/* kVersionTwoPrime and kVersionMulti are the supported values of the version
+ * field of an RSAPrivateKey structure (RFC 3447). */
+static const uint64_t kVersionTwoPrime = 0;
+static const uint64_t kVersionMulti = 1;
+
+/* rsa_parse_additional_prime parses a DER-encoded OtherPrimeInfo from |cbs| and
+ * advances |cbs|. It returns a newly-allocated |RSA_additional_prime| on
+ * success or NULL on error. The |r| and |method_mod| fields of the result are
+ * set to NULL. */
+static RSA_additional_prime *rsa_parse_additional_prime(CBS *cbs) {
+ RSA_additional_prime *ret = OPENSSL_malloc(sizeof(RSA_additional_prime));
+ if (ret == NULL) {
+ OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE);
+ return 0;
+ }
+ memset(ret, 0, sizeof(RSA_additional_prime));
+
+ CBS child;
+ if (!CBS_get_asn1(cbs, &child, CBS_ASN1_SEQUENCE) ||
+ !parse_integer(&child, &ret->prime) ||
+ !parse_integer(&child, &ret->exp) ||
+ !parse_integer(&child, &ret->coeff) ||
+ CBS_len(&child) != 0) {
+ OPENSSL_PUT_ERROR(RSA, RSA_R_BAD_ENCODING);
+ RSA_additional_prime_free(ret);
+ return NULL;
+ }
+
+ return ret;
+}
+
+RSA *RSA_parse_private_key(CBS *cbs) {
+ BN_CTX *ctx = NULL;
+ BIGNUM *product_of_primes_so_far = NULL;
+ RSA *ret = RSA_new();
+ if (ret == NULL) {
+ return NULL;
+ }
+
+ CBS child;
+ uint64_t version;
+ if (!CBS_get_asn1(cbs, &child, CBS_ASN1_SEQUENCE) ||
+ !CBS_get_asn1_uint64(&child, &version) ||
+ (version != kVersionTwoPrime && version != kVersionMulti) ||
+ !parse_integer(&child, &ret->n) ||
+ !parse_integer(&child, &ret->e) ||
+ !parse_integer(&child, &ret->d) ||
+ !parse_integer(&child, &ret->p) ||
+ !parse_integer(&child, &ret->q) ||
+ !parse_integer(&child, &ret->dmp1) ||
+ !parse_integer(&child, &ret->dmq1) ||
+ !parse_integer(&child, &ret->iqmp)) {
+ OPENSSL_PUT_ERROR(RSA, RSA_R_BAD_VERSION);
+ goto err;
+ }
+
+ /* Multi-prime RSA requires a newer version. */
+ if (version == kVersionMulti &&
+ CBS_peek_asn1_tag(&child, CBS_ASN1_SEQUENCE)) {
+ CBS other_prime_infos;
+ if (!CBS_get_asn1(&child, &other_prime_infos, CBS_ASN1_SEQUENCE) ||
+ CBS_len(&other_prime_infos) == 0) {
+ OPENSSL_PUT_ERROR(RSA, RSA_R_BAD_ENCODING);
+ goto err;
+ }
+ ret->additional_primes = sk_RSA_additional_prime_new_null();
+ if (ret->additional_primes == NULL) {
+ OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+
+ ctx = BN_CTX_new();
+ product_of_primes_so_far = BN_new();
+ if (ctx == NULL ||
+ product_of_primes_so_far == NULL ||
+ !BN_mul(product_of_primes_so_far, ret->p, ret->q, ctx)) {
+ goto err;
+ }
+
+ while (CBS_len(&other_prime_infos) > 0) {
+ RSA_additional_prime *ap = rsa_parse_additional_prime(&other_prime_infos);
+ if (ap == NULL) {
+ goto err;
+ }
+ if (!sk_RSA_additional_prime_push(ret->additional_primes, ap)) {
+ OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE);
+ RSA_additional_prime_free(ap);
+ goto err;
+ }
+ ap->r = BN_dup(product_of_primes_so_far);
+ if (ap->r == NULL ||
+ !BN_mul(product_of_primes_so_far, product_of_primes_so_far,
+ ap->prime, ctx)) {
+ goto err;
+ }
}
+ }
+
+ if (CBS_len(&child) != 0) {
+ OPENSSL_PUT_ERROR(RSA, RSA_R_BAD_ENCODING);
+ goto err;
+ }
+
+ BN_CTX_free(ctx);
+ BN_free(product_of_primes_so_far);
+ return ret;
+
+err:
+ BN_CTX_free(ctx);
+ BN_free(product_of_primes_so_far);
+ RSA_free(ret);
+ return NULL;
+}
+
+RSA *RSA_private_key_from_bytes(const uint8_t *in, size_t in_len) {
+ CBS cbs;
+ CBS_init(&cbs, in, in_len);
+ RSA *ret = RSA_parse_private_key(&cbs);
+ if (ret == NULL || CBS_len(&cbs) != 0) {
+ OPENSSL_PUT_ERROR(RSA, RSA_R_BAD_ENCODING);
+ RSA_free(ret);
+ return NULL;
+ }
+ return ret;
+}
+
+int RSA_marshal_private_key(CBB *cbb, const RSA *rsa) {
+ const int is_multiprime =
+ sk_RSA_additional_prime_num(rsa->additional_primes) > 0;
+
+ CBB child;
+ if (!CBB_add_asn1(cbb, &child, CBS_ASN1_SEQUENCE) ||
+ !CBB_add_asn1_uint64(&child,
+ is_multiprime ? kVersionMulti : kVersionTwoPrime) ||
+ !marshal_integer(&child, rsa->n) ||
+ !marshal_integer(&child, rsa->e) ||
+ !marshal_integer(&child, rsa->d) ||
+ !marshal_integer(&child, rsa->p) ||
+ !marshal_integer(&child, rsa->q) ||
+ !marshal_integer(&child, rsa->dmp1) ||
+ !marshal_integer(&child, rsa->dmq1) ||
+ !marshal_integer(&child, rsa->iqmp)) {
+ OPENSSL_PUT_ERROR(RSA, RSA_R_ENCODE_ERROR);
+ return 0;
+ }
+
+ if (is_multiprime) {
+ CBB other_prime_infos;
+ if (!CBB_add_asn1(&child, &other_prime_infos, CBS_ASN1_SEQUENCE)) {
+ OPENSSL_PUT_ERROR(RSA, RSA_R_ENCODE_ERROR);
+ return 0;
+ }
+ size_t i;
+ for (i = 0; i < sk_RSA_additional_prime_num(rsa->additional_primes); i++) {
+ RSA_additional_prime *ap =
+ sk_RSA_additional_prime_value(rsa->additional_primes, i);
+ CBB other_prime_info;
+ if (!CBB_add_asn1(&other_prime_infos, &other_prime_info,
+ CBS_ASN1_SEQUENCE) ||
+ !marshal_integer(&other_prime_info, ap->prime) ||
+ !marshal_integer(&other_prime_info, ap->exp) ||
+ !marshal_integer(&other_prime_info, ap->coeff)) {
+ OPENSSL_PUT_ERROR(RSA, RSA_R_ENCODE_ERROR);
+ return 0;
+ }
+ }
+ }
+
+ if (!CBB_flush(cbb)) {
+ OPENSSL_PUT_ERROR(RSA, RSA_R_ENCODE_ERROR);
return 0;
- } else if (operation == ASN1_OP_FREE_PRE) {
- RSA_free((RSA *)*pval);
- *pval = NULL;
- return 2;
}
return 1;
}
-ASN1_SEQUENCE_cb(RSAPrivateKey, rsa_cb) = {
- ASN1_SIMPLE(RSA, version, LONG),
- ASN1_SIMPLE(RSA, n, BIGNUM),
- ASN1_SIMPLE(RSA, e, BIGNUM),
- ASN1_SIMPLE(RSA, d, BIGNUM),
- ASN1_SIMPLE(RSA, p, BIGNUM),
- ASN1_SIMPLE(RSA, q, BIGNUM),
- ASN1_SIMPLE(RSA, dmp1, BIGNUM),
- ASN1_SIMPLE(RSA, dmq1, BIGNUM),
- ASN1_SIMPLE(RSA, iqmp, BIGNUM),
-} ASN1_SEQUENCE_END_cb(RSA, RSAPrivateKey);
+int RSA_private_key_to_bytes(uint8_t **out_bytes, size_t *out_len,
+ const RSA *rsa) {
+ CBB cbb;
+ CBB_zero(&cbb);
+ if (!CBB_init(&cbb, 0) ||
+ !RSA_marshal_private_key(&cbb, rsa) ||
+ !CBB_finish(&cbb, out_bytes, out_len)) {
+ OPENSSL_PUT_ERROR(RSA, RSA_R_ENCODE_ERROR);
+ CBB_cleanup(&cbb);
+ return 0;
+ }
+ return 1;
+}
-ASN1_SEQUENCE_cb(RSAPublicKey, rsa_cb) = {
- ASN1_SIMPLE(RSA, n, BIGNUM),
- ASN1_SIMPLE(RSA, e, BIGNUM),
-} ASN1_SEQUENCE_END_cb(RSA, RSAPublicKey);
+RSA *d2i_RSAPublicKey(RSA **out, const uint8_t **inp, long len) {
+ if (len < 0) {
+ return NULL;
+ }
+ CBS cbs;
+ CBS_init(&cbs, *inp, (size_t)len);
+ RSA *ret = RSA_parse_public_key(&cbs);
+ if (ret == NULL) {
+ return NULL;
+ }
+ if (out != NULL) {
+ RSA_free(*out);
+ *out = ret;
+ }
+ *inp += (size_t)len - CBS_len(&cbs);
+ return ret;
+}
+
+int i2d_RSAPublicKey(const RSA *in, uint8_t **outp) {
+ uint8_t *der;
+ size_t der_len;
+ if (!RSA_public_key_to_bytes(&der, &der_len, in)) {
+ return -1;
+ }
+ if (der_len > INT_MAX) {
+ OPENSSL_PUT_ERROR(RSA, ERR_R_OVERFLOW);
+ OPENSSL_free(der);
+ return -1;
+ }
+ if (outp != NULL) {
+ if (*outp == NULL) {
+ *outp = der;
+ der = NULL;
+ } else {
+ memcpy(*outp, der, der_len);
+ *outp += der_len;
+ }
+ }
+ OPENSSL_free(der);
+ return (int)der_len;
+}
+
+RSA *d2i_RSAPrivateKey(RSA **out, const uint8_t **inp, long len) {
+ if (len < 0) {
+ return NULL;
+ }
+ CBS cbs;
+ CBS_init(&cbs, *inp, (size_t)len);
+ RSA *ret = RSA_parse_private_key(&cbs);
+ if (ret == NULL) {
+ return NULL;
+ }
+ if (out != NULL) {
+ RSA_free(*out);
+ *out = ret;
+ }
+ *inp += (size_t)len - CBS_len(&cbs);
+ return ret;
+}
+
+int i2d_RSAPrivateKey(const RSA *in, uint8_t **outp) {
+ uint8_t *der;
+ size_t der_len;
+ if (!RSA_private_key_to_bytes(&der, &der_len, in)) {
+ return -1;
+ }
+ if (der_len > INT_MAX) {
+ OPENSSL_PUT_ERROR(RSA, ERR_R_OVERFLOW);
+ OPENSSL_free(der);
+ return -1;
+ }
+ if (outp != NULL) {
+ if (*outp == NULL) {
+ *outp = der;
+ der = NULL;
+ } else {
+ memcpy(*outp, der, der_len);
+ *outp += der_len;
+ }
+ }
+ OPENSSL_free(der);
+ return (int)der_len;
+}
ASN1_SEQUENCE(RSA_PSS_PARAMS) = {
ASN1_EXP_OPT(RSA_PSS_PARAMS, hashAlgorithm, X509_ALGOR,0),
@@ -104,22 +443,24 @@ ASN1_SEQUENCE(RSA_PSS_PARAMS) = {
IMPLEMENT_ASN1_FUNCTIONS(RSA_PSS_PARAMS);
-ASN1_SEQUENCE(RSA_OAEP_PARAMS) = {
- ASN1_EXP_OPT(RSA_OAEP_PARAMS, hashFunc, X509_ALGOR, 0),
- ASN1_EXP_OPT(RSA_OAEP_PARAMS, maskGenFunc, X509_ALGOR, 1),
- ASN1_EXP_OPT(RSA_OAEP_PARAMS, pSourceFunc, X509_ALGOR, 2),
-} ASN1_SEQUENCE_END(RSA_OAEP_PARAMS);
-
-IMPLEMENT_ASN1_FUNCTIONS(RSA_OAEP_PARAMS);
-
-IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(RSA, RSAPrivateKey, RSAPrivateKey);
-
-IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(RSA, RSAPublicKey, RSAPublicKey);
-
RSA *RSAPublicKey_dup(const RSA *rsa) {
- return ASN1_item_dup(ASN1_ITEM_rptr(RSAPublicKey), (RSA *) rsa);
+ uint8_t *der;
+ size_t der_len;
+ if (!RSA_public_key_to_bytes(&der, &der_len, rsa)) {
+ return NULL;
+ }
+ RSA *ret = RSA_public_key_from_bytes(der, der_len);
+ OPENSSL_free(der);
+ return ret;
}
RSA *RSAPrivateKey_dup(const RSA *rsa) {
- return ASN1_item_dup(ASN1_ITEM_rptr(RSAPrivateKey), (RSA *) rsa);
+ uint8_t *der;
+ size_t der_len;
+ if (!RSA_private_key_to_bytes(&der, &der_len, rsa)) {
+ return NULL;
+ }
+ RSA *ret = RSA_private_key_from_bytes(der, der_len);
+ OPENSSL_free(der);
+ return ret;
}
diff --git a/src/crypto/rsa/rsa_impl.c b/src/crypto/rsa/rsa_impl.c
index e14f0f5..eb4a36f 100644
--- a/src/crypto/rsa/rsa_impl.c
+++ b/src/crypto/rsa/rsa_impl.c
@@ -78,6 +78,15 @@ static int finish(RSA *rsa) {
BN_MONT_CTX_free(rsa->_method_mod_p);
BN_MONT_CTX_free(rsa->_method_mod_q);
+ if (rsa->additional_primes != NULL) {
+ size_t i;
+ for (i = 0; i < sk_RSA_additional_prime_num(rsa->additional_primes); i++) {
+ RSA_additional_prime *ap =
+ sk_RSA_additional_prime_value(rsa->additional_primes, i);
+ BN_MONT_CTX_free(ap->method_mod);
+ }
+ }
+
return 1;
}
@@ -94,24 +103,24 @@ static int encrypt(RSA *rsa, size_t *out_len, uint8_t *out, size_t max_out,
int i, ret = 0;
if (rsa_size > OPENSSL_RSA_MAX_MODULUS_BITS) {
- OPENSSL_PUT_ERROR(RSA, encrypt, RSA_R_MODULUS_TOO_LARGE);
+ OPENSSL_PUT_ERROR(RSA, RSA_R_MODULUS_TOO_LARGE);
return 0;
}
if (max_out < rsa_size) {
- OPENSSL_PUT_ERROR(RSA, encrypt, RSA_R_OUTPUT_BUFFER_TOO_SMALL);
+ OPENSSL_PUT_ERROR(RSA, RSA_R_OUTPUT_BUFFER_TOO_SMALL);
return 0;
}
if (BN_ucmp(rsa->n, rsa->e) <= 0) {
- OPENSSL_PUT_ERROR(RSA, encrypt, RSA_R_BAD_E_VALUE);
+ OPENSSL_PUT_ERROR(RSA, RSA_R_BAD_E_VALUE);
return 0;
}
/* for large moduli, enforce exponent limit */
if (BN_num_bits(rsa->n) > OPENSSL_RSA_SMALL_MODULUS_BITS &&
BN_num_bits(rsa->e) > OPENSSL_RSA_MAX_PUBEXP_BITS) {
- OPENSSL_PUT_ERROR(RSA, encrypt, RSA_R_BAD_E_VALUE);
+ OPENSSL_PUT_ERROR(RSA, RSA_R_BAD_E_VALUE);
return 0;
}
@@ -125,7 +134,7 @@ static int encrypt(RSA *rsa, size_t *out_len, uint8_t *out, size_t max_out,
result = BN_CTX_get(ctx);
buf = OPENSSL_malloc(rsa_size);
if (!f || !result || !buf) {
- OPENSSL_PUT_ERROR(RSA, encrypt, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE);
goto err;
}
@@ -142,7 +151,7 @@ static int encrypt(RSA *rsa, size_t *out_len, uint8_t *out, size_t max_out,
i = RSA_padding_add_none(buf, rsa_size, in, in_len);
break;
default:
- OPENSSL_PUT_ERROR(RSA, encrypt, RSA_R_UNKNOWN_PADDING_TYPE);
+ OPENSSL_PUT_ERROR(RSA, RSA_R_UNKNOWN_PADDING_TYPE);
goto err;
}
@@ -156,7 +165,7 @@ static int encrypt(RSA *rsa, size_t *out_len, uint8_t *out, size_t max_out,
if (BN_ucmp(f, rsa->n) >= 0) {
/* usually the padding functions would catch this */
- OPENSSL_PUT_ERROR(RSA, encrypt, RSA_R_DATA_TOO_LARGE_FOR_MODULUS);
+ OPENSSL_PUT_ERROR(RSA, RSA_R_DATA_TOO_LARGE_FOR_MODULUS);
goto err;
}
@@ -175,7 +184,7 @@ static int encrypt(RSA *rsa, size_t *out_len, uint8_t *out, size_t max_out,
/* put in leading 0 bytes if the number is less than the length of the
* modulus */
if (!BN_bn2bin_padded(out, rsa_size, result)) {
- OPENSSL_PUT_ERROR(RSA, encrypt, ERR_R_INTERNAL_ERROR);
+ OPENSSL_PUT_ERROR(RSA, ERR_R_INTERNAL_ERROR);
goto err;
}
@@ -309,13 +318,13 @@ static int sign_raw(RSA *rsa, size_t *out_len, uint8_t *out, size_t max_out,
int i, ret = 0;
if (max_out < rsa_size) {
- OPENSSL_PUT_ERROR(RSA, sign_raw, RSA_R_OUTPUT_BUFFER_TOO_SMALL);
+ OPENSSL_PUT_ERROR(RSA, RSA_R_OUTPUT_BUFFER_TOO_SMALL);
return 0;
}
buf = OPENSSL_malloc(rsa_size);
if (buf == NULL) {
- OPENSSL_PUT_ERROR(RSA, sign_raw, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE);
goto err;
}
@@ -327,7 +336,7 @@ static int sign_raw(RSA *rsa, size_t *out_len, uint8_t *out, size_t max_out,
i = RSA_padding_add_none(buf, rsa_size, in, in_len);
break;
default:
- OPENSSL_PUT_ERROR(RSA, sign_raw, RSA_R_UNKNOWN_PADDING_TYPE);
+ OPENSSL_PUT_ERROR(RSA, RSA_R_UNKNOWN_PADDING_TYPE);
goto err;
}
@@ -359,18 +368,23 @@ static int decrypt(RSA *rsa, size_t *out_len, uint8_t *out, size_t max_out,
int ret = 0;
if (max_out < rsa_size) {
- OPENSSL_PUT_ERROR(RSA, decrypt, RSA_R_OUTPUT_BUFFER_TOO_SMALL);
+ OPENSSL_PUT_ERROR(RSA, RSA_R_OUTPUT_BUFFER_TOO_SMALL);
return 0;
}
- buf = OPENSSL_malloc(rsa_size);
- if (buf == NULL) {
- OPENSSL_PUT_ERROR(RSA, decrypt, ERR_R_MALLOC_FAILURE);
- goto err;
+ if (padding == RSA_NO_PADDING) {
+ buf = out;
+ } else {
+ /* Allocate a temporary buffer to hold the padded plaintext. */
+ buf = OPENSSL_malloc(rsa_size);
+ if (buf == NULL) {
+ OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
}
if (in_len != rsa_size) {
- OPENSSL_PUT_ERROR(RSA, decrypt, RSA_R_DATA_LEN_NOT_EQUAL_TO_MOD_LEN);
+ OPENSSL_PUT_ERROR(RSA, RSA_R_DATA_LEN_NOT_EQUAL_TO_MOD_LEN);
goto err;
}
@@ -388,22 +402,22 @@ static int decrypt(RSA *rsa, size_t *out_len, uint8_t *out, size_t max_out,
NULL, 0, NULL, NULL);
break;
case RSA_NO_PADDING:
- r = RSA_padding_check_none(out, rsa_size, buf, rsa_size);
+ r = rsa_size;
break;
default:
- OPENSSL_PUT_ERROR(RSA, decrypt, RSA_R_UNKNOWN_PADDING_TYPE);
+ OPENSSL_PUT_ERROR(RSA, RSA_R_UNKNOWN_PADDING_TYPE);
goto err;
}
if (r < 0) {
- OPENSSL_PUT_ERROR(RSA, decrypt, RSA_R_PADDING_CHECK_FAILED);
+ OPENSSL_PUT_ERROR(RSA, RSA_R_PADDING_CHECK_FAILED);
} else {
*out_len = r;
ret = 1;
}
err:
- if (buf != NULL) {
+ if (padding != RSA_NO_PADDING && buf != NULL) {
OPENSSL_cleanse(buf, rsa_size);
OPENSSL_free(buf);
}
@@ -421,24 +435,24 @@ static int verify_raw(RSA *rsa, size_t *out_len, uint8_t *out, size_t max_out,
BN_CTX *ctx = NULL;
if (BN_num_bits(rsa->n) > OPENSSL_RSA_MAX_MODULUS_BITS) {
- OPENSSL_PUT_ERROR(RSA, verify_raw, RSA_R_MODULUS_TOO_LARGE);
+ OPENSSL_PUT_ERROR(RSA, RSA_R_MODULUS_TOO_LARGE);
return 0;
}
if (BN_ucmp(rsa->n, rsa->e) <= 0) {
- OPENSSL_PUT_ERROR(RSA, verify_raw, RSA_R_BAD_E_VALUE);
+ OPENSSL_PUT_ERROR(RSA, RSA_R_BAD_E_VALUE);
return 0;
}
if (max_out < rsa_size) {
- OPENSSL_PUT_ERROR(RSA, verify_raw, RSA_R_OUTPUT_BUFFER_TOO_SMALL);
+ OPENSSL_PUT_ERROR(RSA, RSA_R_OUTPUT_BUFFER_TOO_SMALL);
return 0;
}
/* for large moduli, enforce exponent limit */
if (BN_num_bits(rsa->n) > OPENSSL_RSA_SMALL_MODULUS_BITS &&
BN_num_bits(rsa->e) > OPENSSL_RSA_MAX_PUBEXP_BITS) {
- OPENSSL_PUT_ERROR(RSA, verify_raw, RSA_R_BAD_E_VALUE);
+ OPENSSL_PUT_ERROR(RSA, RSA_R_BAD_E_VALUE);
return 0;
}
@@ -450,14 +464,23 @@ static int verify_raw(RSA *rsa, size_t *out_len, uint8_t *out, size_t max_out,
BN_CTX_start(ctx);
f = BN_CTX_get(ctx);
result = BN_CTX_get(ctx);
- buf = OPENSSL_malloc(rsa_size);
- if (!f || !result || !buf) {
- OPENSSL_PUT_ERROR(RSA, verify_raw, ERR_R_MALLOC_FAILURE);
+ if (padding == RSA_NO_PADDING) {
+ buf = out;
+ } else {
+ /* Allocate a temporary buffer to hold the padded plaintext. */
+ buf = OPENSSL_malloc(rsa_size);
+ if (buf == NULL) {
+ OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+ }
+ if (!f || !result) {
+ OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE);
goto err;
}
if (in_len != rsa_size) {
- OPENSSL_PUT_ERROR(RSA, verify_raw, RSA_R_DATA_LEN_NOT_EQUAL_TO_MOD_LEN);
+ OPENSSL_PUT_ERROR(RSA, RSA_R_DATA_LEN_NOT_EQUAL_TO_MOD_LEN);
goto err;
}
@@ -466,7 +489,7 @@ static int verify_raw(RSA *rsa, size_t *out_len, uint8_t *out, size_t max_out,
}
if (BN_ucmp(f, rsa->n) >= 0) {
- OPENSSL_PUT_ERROR(RSA, verify_raw, RSA_R_DATA_TOO_LARGE_FOR_MODULUS);
+ OPENSSL_PUT_ERROR(RSA, RSA_R_DATA_TOO_LARGE_FOR_MODULUS);
goto err;
}
@@ -483,7 +506,7 @@ static int verify_raw(RSA *rsa, size_t *out_len, uint8_t *out, size_t max_out,
}
if (!BN_bn2bin_padded(buf, rsa_size, result)) {
- OPENSSL_PUT_ERROR(RSA, verify_raw, ERR_R_INTERNAL_ERROR);
+ OPENSSL_PUT_ERROR(RSA, ERR_R_INTERNAL_ERROR);
goto err;
}
@@ -492,15 +515,15 @@ static int verify_raw(RSA *rsa, size_t *out_len, uint8_t *out, size_t max_out,
r = RSA_padding_check_PKCS1_type_1(out, rsa_size, buf, rsa_size);
break;
case RSA_NO_PADDING:
- r = RSA_padding_check_none(out, rsa_size, buf, rsa_size);
+ r = rsa_size;
break;
default:
- OPENSSL_PUT_ERROR(RSA, verify_raw, RSA_R_UNKNOWN_PADDING_TYPE);
+ OPENSSL_PUT_ERROR(RSA, RSA_R_UNKNOWN_PADDING_TYPE);
goto err;
}
if (r < 0) {
- OPENSSL_PUT_ERROR(RSA, verify_raw, RSA_R_PADDING_CHECK_FAILED);
+ OPENSSL_PUT_ERROR(RSA, RSA_R_PADDING_CHECK_FAILED);
} else {
*out_len = r;
ret = 1;
@@ -511,7 +534,7 @@ err:
BN_CTX_end(ctx);
BN_CTX_free(ctx);
}
- if (buf != NULL) {
+ if (padding != RSA_NO_PADDING && buf != NULL) {
OPENSSL_cleanse(buf, rsa_size);
OPENSSL_free(buf);
}
@@ -535,7 +558,7 @@ static int private_transform(RSA *rsa, uint8_t *out, const uint8_t *in,
result = BN_CTX_get(ctx);
if (f == NULL || result == NULL) {
- OPENSSL_PUT_ERROR(RSA, private_transform, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE);
goto err;
}
@@ -545,14 +568,14 @@ static int private_transform(RSA *rsa, uint8_t *out, const uint8_t *in,
if (BN_ucmp(f, rsa->n) >= 0) {
/* Usually the padding functions would catch this. */
- OPENSSL_PUT_ERROR(RSA, private_transform, RSA_R_DATA_TOO_LARGE_FOR_MODULUS);
+ OPENSSL_PUT_ERROR(RSA, RSA_R_DATA_TOO_LARGE_FOR_MODULUS);
goto err;
}
if (!(rsa->flags & RSA_FLAG_NO_BLINDING)) {
blinding = rsa_blinding_get(rsa, &blinding_index, ctx);
if (blinding == NULL) {
- OPENSSL_PUT_ERROR(RSA, private_transform, ERR_R_INTERNAL_ERROR);
+ OPENSSL_PUT_ERROR(RSA, ERR_R_INTERNAL_ERROR);
goto err;
}
if (!BN_BLINDING_convert_ex(f, NULL, blinding, ctx)) {
@@ -593,7 +616,7 @@ static int private_transform(RSA *rsa, uint8_t *out, const uint8_t *in,
}
if (!BN_bn2bin_padded(out, len, result)) {
- OPENSSL_PUT_ERROR(RSA, private_transform, ERR_R_INTERNAL_ERROR);
+ OPENSSL_PUT_ERROR(RSA, ERR_R_INTERNAL_ERROR);
goto err;
}
@@ -616,6 +639,11 @@ static int mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx) {
BIGNUM local_dmp1, local_dmq1, local_c, local_r1;
BIGNUM *dmp1, *dmq1, *c, *pr1;
int ret = 0;
+ size_t i, num_additional_primes = 0;
+
+ if (rsa->additional_primes != NULL) {
+ num_additional_primes = sk_RSA_additional_prime_num(rsa->additional_primes);
+ }
BN_CTX_start(ctx);
r1 = BN_CTX_get(ctx);
@@ -724,6 +752,42 @@ static int mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx) {
goto err;
}
+ for (i = 0; i < num_additional_primes; i++) {
+ /* multi-prime RSA. */
+ BIGNUM local_exp, local_prime;
+ BIGNUM *exp = &local_exp, *prime = &local_prime;
+ RSA_additional_prime *ap =
+ sk_RSA_additional_prime_value(rsa->additional_primes, i);
+
+ BN_with_flags(exp, ap->exp, BN_FLG_CONSTTIME);
+ BN_with_flags(prime, ap->prime, BN_FLG_CONSTTIME);
+
+ /* c will already point to a BIGNUM with the correct flags. */
+ if (!BN_mod(r1, c, prime, ctx)) {
+ goto err;
+ }
+
+ if ((rsa->flags & RSA_FLAG_CACHE_PRIVATE) &&
+ !BN_MONT_CTX_set_locked(&ap->method_mod, &rsa->lock, prime, ctx)) {
+ goto err;
+ }
+
+ if (!rsa->meth->bn_mod_exp(m1, r1, exp, prime, ctx, ap->method_mod)) {
+ goto err;
+ }
+
+ BN_set_flags(m1, BN_FLG_CONSTTIME);
+
+ if (!BN_sub(m1, m1, r0) ||
+ !BN_mul(m1, m1, ap->coeff, ctx) ||
+ !BN_mod(m1, m1, prime, ctx) ||
+ (BN_is_negative(m1) && !BN_add(m1, m1, prime)) ||
+ !BN_mul(m1, m1, ap->r, ctx) ||
+ !BN_add(r0, r0, m1)) {
+ goto err;
+ }
+ }
+
if (rsa->e && rsa->n) {
if (!rsa->meth->bn_mod_exp(vrfy, r0, rsa->e, rsa->n, ctx,
rsa->_method_mod_n)) {
@@ -766,12 +830,20 @@ err:
return ret;
}
-static int keygen(RSA *rsa, int bits, BIGNUM *e_value, BN_GENCB *cb) {
+static int keygen_multiprime(RSA *rsa, int bits, int num_primes,
+ BIGNUM *e_value, BN_GENCB *cb) {
BIGNUM *r0 = NULL, *r1 = NULL, *r2 = NULL, *r3 = NULL, *tmp;
BIGNUM local_r0, local_d, local_p;
BIGNUM *pr0, *d, *p;
- int bitsp, bitsq, ok = -1, n = 0;
+ int prime_bits, ok = -1, n = 0, i, j;
BN_CTX *ctx = NULL;
+ STACK_OF(RSA_additional_prime) *additional_primes = NULL;
+
+ if (num_primes < 2) {
+ ok = 0; /* we set our own err */
+ OPENSSL_PUT_ERROR(RSA, RSA_R_MUST_HAVE_AT_LEAST_TWO_PRIMES);
+ goto err;
+ }
ctx = BN_CTX_new();
if (ctx == NULL) {
@@ -782,12 +854,36 @@ static int keygen(RSA *rsa, int bits, BIGNUM *e_value, BN_GENCB *cb) {
r1 = BN_CTX_get(ctx);
r2 = BN_CTX_get(ctx);
r3 = BN_CTX_get(ctx);
- if (r3 == NULL) {
+ if (r0 == NULL || r1 == NULL || r2 == NULL || r3 == NULL) {
goto err;
}
- bitsp = (bits + 1) / 2;
- bitsq = bits - bitsp;
+ if (num_primes > 2) {
+ additional_primes = sk_RSA_additional_prime_new_null();
+ if (additional_primes == NULL) {
+ goto err;
+ }
+ }
+
+ for (i = 2; i < num_primes; i++) {
+ RSA_additional_prime *ap = OPENSSL_malloc(sizeof(RSA_additional_prime));
+ if (ap == NULL) {
+ goto err;
+ }
+ memset(ap, 0, sizeof(RSA_additional_prime));
+ ap->prime = BN_new();
+ ap->exp = BN_new();
+ ap->coeff = BN_new();
+ ap->r = BN_new();
+ if (ap->prime == NULL ||
+ ap->exp == NULL ||
+ ap->coeff == NULL ||
+ ap->r == NULL ||
+ !sk_RSA_additional_prime_push(additional_primes, ap)) {
+ RSA_additional_prime_free(ap);
+ goto err;
+ }
+ }
/* We need the RSA components non-NULL */
if (!rsa->n && ((rsa->n = BN_new()) == NULL)) {
@@ -815,11 +911,14 @@ static int keygen(RSA *rsa, int bits, BIGNUM *e_value, BN_GENCB *cb) {
goto err;
}
- BN_copy(rsa->e, e_value);
+ if (!BN_copy(rsa->e, e_value)) {
+ goto err;
+ }
/* generate p and q */
+ prime_bits = (bits + (num_primes - 1)) / num_primes;
for (;;) {
- if (!BN_generate_prime_ex(rsa->p, bitsp, 0, NULL, NULL, cb) ||
+ if (!BN_generate_prime_ex(rsa->p, prime_bits, 0, NULL, NULL, cb) ||
!BN_sub(r2, rsa->p, BN_value_one()) ||
!BN_gcd(r1, r2, rsa->e, ctx)) {
goto err;
@@ -834,19 +933,20 @@ static int keygen(RSA *rsa, int bits, BIGNUM *e_value, BN_GENCB *cb) {
if (!BN_GENCB_call(cb, 3, 0)) {
goto err;
}
+ prime_bits = ((bits - prime_bits) + (num_primes - 2)) / (num_primes - 1);
for (;;) {
/* When generating ridiculously small keys, we can get stuck
* continually regenerating the same prime values. Check for
* this and bail if it happens 3 times. */
unsigned int degenerate = 0;
do {
- if (!BN_generate_prime_ex(rsa->q, bitsq, 0, NULL, NULL, cb)) {
+ if (!BN_generate_prime_ex(rsa->q, prime_bits, 0, NULL, NULL, cb)) {
goto err;
}
} while ((BN_cmp(rsa->p, rsa->q) == 0) && (++degenerate < 3));
if (degenerate == 3) {
ok = 0; /* we set our own err */
- OPENSSL_PUT_ERROR(RSA, keygen, RSA_R_KEY_SIZE_TOO_SMALL);
+ OPENSSL_PUT_ERROR(RSA, RSA_R_KEY_SIZE_TOO_SMALL);
goto err;
}
if (!BN_sub(r2, rsa->q, BN_value_one()) ||
@@ -860,20 +960,91 @@ static int keygen(RSA *rsa, int bits, BIGNUM *e_value, BN_GENCB *cb) {
goto err;
}
}
- if (!BN_GENCB_call(cb, 3, 1)) {
+
+ if (!BN_GENCB_call(cb, 3, 1) ||
+ !BN_mul(rsa->n, rsa->p, rsa->q, ctx)) {
goto err;
}
+
+ for (i = 2; i < num_primes; i++) {
+ RSA_additional_prime *ap =
+ sk_RSA_additional_prime_value(additional_primes, i - 2);
+ prime_bits = ((bits - BN_num_bits(rsa->n)) + (num_primes - (i + 1))) /
+ (num_primes - i);
+
+ for (;;) {
+ if (!BN_generate_prime_ex(ap->prime, prime_bits, 0, NULL, NULL, cb)) {
+ goto err;
+ }
+ if (BN_cmp(rsa->p, ap->prime) == 0 ||
+ BN_cmp(rsa->q, ap->prime) == 0) {
+ continue;
+ }
+
+ for (j = 0; j < i - 2; j++) {
+ if (BN_cmp(sk_RSA_additional_prime_value(additional_primes, j)->prime,
+ ap->prime) == 0) {
+ break;
+ }
+ }
+ if (j != i - 2) {
+ continue;
+ }
+
+ if (!BN_sub(r2, ap->prime, BN_value_one()) ||
+ !BN_gcd(r1, r2, rsa->e, ctx)) {
+ goto err;
+ }
+
+ if (!BN_is_one(r1)) {
+ continue;
+ }
+ if (i != num_primes - 1) {
+ break;
+ }
+
+ /* For the last prime we'll check that it makes n large enough. In the
+ * two prime case this isn't a problem because we generate primes with
+ * the top two bits set and so the product is always of the expected
+ * size. In the multi prime case, this doesn't follow. */
+ if (!BN_mul(r1, rsa->n, ap->prime, ctx)) {
+ goto err;
+ }
+ if (BN_num_bits(r1) == bits) {
+ break;
+ }
+
+ if (!BN_GENCB_call(cb, 2, n++)) {
+ goto err;
+ }
+ }
+
+ /* ap->r is is the product of all the primes prior to the current one
+ * (including p and q). */
+ if (!BN_copy(ap->r, rsa->n)) {
+ goto err;
+ }
+ if (i == num_primes - 1) {
+ /* In the case of the last prime, we calculated n as |r1| in the loop
+ * above. */
+ if (!BN_copy(rsa->n, r1)) {
+ goto err;
+ }
+ } else if (!BN_mul(rsa->n, rsa->n, ap->prime, ctx)) {
+ goto err;
+ }
+
+ if (!BN_GENCB_call(cb, 3, 1)) {
+ goto err;
+ }
+ }
+
if (BN_cmp(rsa->p, rsa->q) < 0) {
tmp = rsa->p;
rsa->p = rsa->q;
rsa->q = tmp;
}
- /* calculate n */
- if (!BN_mul(rsa->n, rsa->p, rsa->q, ctx)) {
- goto err;
- }
-
/* calculate d */
if (!BN_sub(r1, rsa->p, BN_value_one())) {
goto err; /* p-1 */
@@ -884,6 +1055,14 @@ static int keygen(RSA *rsa, int bits, BIGNUM *e_value, BN_GENCB *cb) {
if (!BN_mul(r0, r1, r2, ctx)) {
goto err; /* (p-1)(q-1) */
}
+ for (i = 2; i < num_primes; i++) {
+ RSA_additional_prime *ap =
+ sk_RSA_additional_prime_value(additional_primes, i - 2);
+ if (!BN_sub(r3, ap->prime, BN_value_one()) ||
+ !BN_mul(r0, r0, r3, ctx)) {
+ goto err;
+ }
+ }
pr0 = &local_r0;
BN_with_flags(pr0, r0, BN_FLG_CONSTTIME);
if (!BN_mod_inverse(rsa->d, rsa->e, pr0, ctx)) {
@@ -912,21 +1091,38 @@ static int keygen(RSA *rsa, int bits, BIGNUM *e_value, BN_GENCB *cb) {
goto err;
}
+ for (i = 2; i < num_primes; i++) {
+ RSA_additional_prime *ap =
+ sk_RSA_additional_prime_value(additional_primes, i - 2);
+ if (!BN_sub(ap->exp, ap->prime, BN_value_one()) ||
+ !BN_mod(ap->exp, rsa->d, ap->exp, ctx) ||
+ !BN_mod_inverse(ap->coeff, ap->r, ap->prime, ctx)) {
+ goto err;
+ }
+ }
+
ok = 1;
+ rsa->additional_primes = additional_primes;
+ additional_primes = NULL;
err:
if (ok == -1) {
- OPENSSL_PUT_ERROR(RSA, keygen, ERR_LIB_BN);
+ OPENSSL_PUT_ERROR(RSA, ERR_LIB_BN);
ok = 0;
}
if (ctx != NULL) {
BN_CTX_end(ctx);
BN_CTX_free(ctx);
}
-
+ sk_RSA_additional_prime_pop_free(additional_primes,
+ RSA_additional_prime_free);
return ok;
}
+static int keygen(RSA *rsa, int bits, BIGNUM *e_value, BN_GENCB *cb) {
+ return keygen_multiprime(rsa, bits, 2 /* num primes */, e_value, cb);
+}
+
const struct rsa_meth_st RSA_default_method = {
{
0 /* references */,
@@ -955,4 +1151,7 @@ const struct rsa_meth_st RSA_default_method = {
RSA_FLAG_CACHE_PUBLIC | RSA_FLAG_CACHE_PRIVATE,
keygen,
+ keygen_multiprime,
+
+ NULL /* supports_digest */,
};
diff --git a/src/crypto/rsa/rsa_test.c b/src/crypto/rsa/rsa_test.c
deleted file mode 100644
index 318cf3f..0000000
--- a/src/crypto/rsa/rsa_test.c
+++ /dev/null
@@ -1,511 +0,0 @@
-/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
- * All rights reserved.
- *
- * This package is an SSL implementation written
- * by Eric Young (eay@cryptsoft.com).
- * The implementation was written so as to conform with Netscapes SSL.
- *
- * This library is free for commercial and non-commercial use as long as
- * the following conditions are aheared to. The following conditions
- * apply to all code found in this distribution, be it the RC4, RSA,
- * lhash, DES, etc., code; not just the SSL code. The SSL documentation
- * included with this distribution is covered by the same copyright terms
- * except that the holder is Tim Hudson (tjh@cryptsoft.com).
- *
- * Copyright remains Eric Young's, and as such any Copyright notices in
- * the code are not to be removed.
- * If this package is used in a product, Eric Young should be given attribution
- * as the author of the parts of the library used.
- * This can be in the form of a textual message at program startup or
- * in documentation (online or textual) provided with the package.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * "This product includes cryptographic software written by
- * Eric Young (eay@cryptsoft.com)"
- * The word 'cryptographic' can be left out if the rouines from the library
- * being used are not cryptographic related :-).
- * 4. If you include any Windows specific code (or a derivative thereof) from
- * the apps directory (application code) you must include an acknowledgement:
- * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
- *
- * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * The licence and distribution terms for any publically available version or
- * derivative of this code cannot be changed. i.e. this code cannot simply be
- * copied and put under another distribution licence
- * [including the GNU Public Licence.] */
-
-#include <openssl/rsa.h>
-
-#include <stdlib.h>
-#include <string.h>
-
-#include <openssl/bn.h>
-#include <openssl/crypto.h>
-#include <openssl/err.h>
-#include <openssl/obj.h>
-
-
-#define SetKey \
- key->n = BN_bin2bn(n, sizeof(n) - 1, key->n); \
- key->e = BN_bin2bn(e, sizeof(e) - 1, key->e); \
- key->d = BN_bin2bn(d, sizeof(d) - 1, key->d); \
- key->p = BN_bin2bn(p, sizeof(p) - 1, key->p); \
- key->q = BN_bin2bn(q, sizeof(q) - 1, key->q); \
- key->dmp1 = BN_bin2bn(dmp1, sizeof(dmp1) - 1, key->dmp1); \
- key->dmq1 = BN_bin2bn(dmq1, sizeof(dmq1) - 1, key->dmq1); \
- key->iqmp = BN_bin2bn(iqmp, sizeof(iqmp) - 1, key->iqmp); \
- memcpy(c, ctext_ex, sizeof(ctext_ex) - 1); \
- return (sizeof(ctext_ex) - 1);
-
-static int key1(RSA *key, unsigned char *c) {
- static unsigned char n[] =
- "\x00\xAA\x36\xAB\xCE\x88\xAC\xFD\xFF\x55\x52\x3C\x7F\xC4\x52\x3F"
- "\x90\xEF\xA0\x0D\xF3\x77\x4A\x25\x9F\x2E\x62\xB4\xC5\xD9\x9C\xB5"
- "\xAD\xB3\x00\xA0\x28\x5E\x53\x01\x93\x0E\x0C\x70\xFB\x68\x76\x93"
- "\x9C\xE6\x16\xCE\x62\x4A\x11\xE0\x08\x6D\x34\x1E\xBC\xAC\xA0\xA1"
- "\xF5";
-
- static unsigned char e[] = "\x11";
-
- static unsigned char d[] =
- "\x0A\x03\x37\x48\x62\x64\x87\x69\x5F\x5F\x30\xBC\x38\xB9\x8B\x44"
- "\xC2\xCD\x2D\xFF\x43\x40\x98\xCD\x20\xD8\xA1\x38\xD0\x90\xBF\x64"
- "\x79\x7C\x3F\xA7\xA2\xCD\xCB\x3C\xD1\xE0\xBD\xBA\x26\x54\xB4\xF9"
- "\xDF\x8E\x8A\xE5\x9D\x73\x3D\x9F\x33\xB3\x01\x62\x4A\xFD\x1D\x51";
-
- static unsigned char p[] =
- "\x00\xD8\x40\xB4\x16\x66\xB4\x2E\x92\xEA\x0D\xA3\xB4\x32\x04\xB5"
- "\xCF\xCE\x33\x52\x52\x4D\x04\x16\xA5\xA4\x41\xE7\x00\xAF\x46\x12"
- "\x0D";
-
- static unsigned char q[] =
- "\x00\xC9\x7F\xB1\xF0\x27\xF4\x53\xF6\x34\x12\x33\xEA\xAA\xD1\xD9"
- "\x35\x3F\x6C\x42\xD0\x88\x66\xB1\xD0\x5A\x0F\x20\x35\x02\x8B\x9D"
- "\x89";
-
- static unsigned char dmp1[] =
- "\x59\x0B\x95\x72\xA2\xC2\xA9\xC4\x06\x05\x9D\xC2\xAB\x2F\x1D\xAF"
- "\xEB\x7E\x8B\x4F\x10\xA7\x54\x9E\x8E\xED\xF5\xB4\xFC\xE0\x9E\x05";
-
- static unsigned char dmq1[] =
- "\x00\x8E\x3C\x05\x21\xFE\x15\xE0\xEA\x06\xA3\x6F\xF0\xF1\x0C\x99"
- "\x52\xC3\x5B\x7A\x75\x14\xFD\x32\x38\xB8\x0A\xAD\x52\x98\x62\x8D"
- "\x51";
-
- static unsigned char iqmp[] =
- "\x36\x3F\xF7\x18\x9D\xA8\xE9\x0B\x1D\x34\x1F\x71\xD0\x9B\x76\xA8"
- "\xA9\x43\xE1\x1D\x10\xB2\x4D\x24\x9F\x2D\xEA\xFE\xF8\x0C\x18\x26";
-
- static unsigned char ctext_ex[] =
- "\x1b\x8f\x05\xf9\xca\x1a\x79\x52\x6e\x53\xf3\xcc\x51\x4f\xdb\x89"
- "\x2b\xfb\x91\x93\x23\x1e\x78\xb9\x92\xe6\x8d\x50\xa4\x80\xcb\x52"
- "\x33\x89\x5c\x74\x95\x8d\x5d\x02\xab\x8c\x0f\xd0\x40\xeb\x58\x44"
- "\xb0\x05\xc3\x9e\xd8\x27\x4a\x9d\xbf\xa8\x06\x71\x40\x94\x39\xd2";
-
- SetKey;
-}
-
-static int key2(RSA *key, unsigned char *c) {
- static unsigned char n[] =
- "\x00\xA3\x07\x9A\x90\xDF\x0D\xFD\x72\xAC\x09\x0C\xCC\x2A\x78\xB8"
- "\x74\x13\x13\x3E\x40\x75\x9C\x98\xFA\xF8\x20\x4F\x35\x8A\x0B\x26"
- "\x3C\x67\x70\xE7\x83\xA9\x3B\x69\x71\xB7\x37\x79\xD2\x71\x7B\xE8"
- "\x34\x77\xCF";
-
- static unsigned char e[] = "\x3";
-
- static unsigned char d[] =
- "\x6C\xAF\xBC\x60\x94\xB3\xFE\x4C\x72\xB0\xB3\x32\xC6\xFB\x25\xA2"
- "\xB7\x62\x29\x80\x4E\x68\x65\xFC\xA4\x5A\x74\xDF\x0F\x8F\xB8\x41"
- "\x3B\x52\xC0\xD0\xE5\x3D\x9B\x59\x0F\xF1\x9B\xE7\x9F\x49\xDD\x21"
- "\xE5\xEB";
-
- static unsigned char p[] =
- "\x00\xCF\x20\x35\x02\x8B\x9D\x86\x98\x40\xB4\x16\x66\xB4\x2E\x92"
- "\xEA\x0D\xA3\xB4\x32\x04\xB5\xCF\xCE\x91";
-
- static unsigned char q[] =
- "\x00\xC9\x7F\xB1\xF0\x27\xF4\x53\xF6\x34\x12\x33\xEA\xAA\xD1\xD9"
- "\x35\x3F\x6C\x42\xD0\x88\x66\xB1\xD0\x5F";
-
- static unsigned char dmp1[] =
- "\x00\x8A\x15\x78\xAC\x5D\x13\xAF\x10\x2B\x22\xB9\x99\xCD\x74\x61"
- "\xF1\x5E\x6D\x22\xCC\x03\x23\xDF\xDF\x0B";
-
- static unsigned char dmq1[] =
- "\x00\x86\x55\x21\x4A\xC5\x4D\x8D\x4E\xCD\x61\x77\xF1\xC7\x36\x90"
- "\xCE\x2A\x48\x2C\x8B\x05\x99\xCB\xE0\x3F";
-
- static unsigned char iqmp[] =
- "\x00\x83\xEF\xEF\xB8\xA9\xA4\x0D\x1D\xB6\xED\x98\xAD\x84\xED\x13"
- "\x35\xDC\xC1\x08\xF3\x22\xD0\x57\xCF\x8D";
-
- static unsigned char ctext_ex[] =
- "\x14\xbd\xdd\x28\xc9\x83\x35\x19\x23\x80\xe8\xe5\x49\xb1\x58\x2a"
- "\x8b\x40\xb4\x48\x6d\x03\xa6\xa5\x31\x1f\x1f\xd5\xf0\xa1\x80\xe4"
- "\x17\x53\x03\x29\xa9\x34\x90\x74\xb1\x52\x13\x54\x29\x08\x24\x52"
- "\x62\x51";
-
- SetKey;
-}
-
-static int key3(RSA *key, unsigned char *c) {
- static unsigned char n[] =
- "\x00\xBB\xF8\x2F\x09\x06\x82\xCE\x9C\x23\x38\xAC\x2B\x9D\xA8\x71"
- "\xF7\x36\x8D\x07\xEE\xD4\x10\x43\xA4\x40\xD6\xB6\xF0\x74\x54\xF5"
- "\x1F\xB8\xDF\xBA\xAF\x03\x5C\x02\xAB\x61\xEA\x48\xCE\xEB\x6F\xCD"
- "\x48\x76\xED\x52\x0D\x60\xE1\xEC\x46\x19\x71\x9D\x8A\x5B\x8B\x80"
- "\x7F\xAF\xB8\xE0\xA3\xDF\xC7\x37\x72\x3E\xE6\xB4\xB7\xD9\x3A\x25"
- "\x84\xEE\x6A\x64\x9D\x06\x09\x53\x74\x88\x34\xB2\x45\x45\x98\x39"
- "\x4E\xE0\xAA\xB1\x2D\x7B\x61\xA5\x1F\x52\x7A\x9A\x41\xF6\xC1\x68"
- "\x7F\xE2\x53\x72\x98\xCA\x2A\x8F\x59\x46\xF8\xE5\xFD\x09\x1D\xBD"
- "\xCB";
-
- static unsigned char e[] = "\x11";
-
- static unsigned char d[] =
- "\x00\xA5\xDA\xFC\x53\x41\xFA\xF2\x89\xC4\xB9\x88\xDB\x30\xC1\xCD"
- "\xF8\x3F\x31\x25\x1E\x06\x68\xB4\x27\x84\x81\x38\x01\x57\x96\x41"
- "\xB2\x94\x10\xB3\xC7\x99\x8D\x6B\xC4\x65\x74\x5E\x5C\x39\x26\x69"
- "\xD6\x87\x0D\xA2\xC0\x82\xA9\x39\xE3\x7F\xDC\xB8\x2E\xC9\x3E\xDA"
- "\xC9\x7F\xF3\xAD\x59\x50\xAC\xCF\xBC\x11\x1C\x76\xF1\xA9\x52\x94"
- "\x44\xE5\x6A\xAF\x68\xC5\x6C\x09\x2C\xD3\x8D\xC3\xBE\xF5\xD2\x0A"
- "\x93\x99\x26\xED\x4F\x74\xA1\x3E\xDD\xFB\xE1\xA1\xCE\xCC\x48\x94"
- "\xAF\x94\x28\xC2\xB7\xB8\x88\x3F\xE4\x46\x3A\x4B\xC8\x5B\x1C\xB3"
- "\xC1";
-
- static unsigned char p[] =
- "\x00\xEE\xCF\xAE\x81\xB1\xB9\xB3\xC9\x08\x81\x0B\x10\xA1\xB5\x60"
- "\x01\x99\xEB\x9F\x44\xAE\xF4\xFD\xA4\x93\xB8\x1A\x9E\x3D\x84\xF6"
- "\x32\x12\x4E\xF0\x23\x6E\x5D\x1E\x3B\x7E\x28\xFA\xE7\xAA\x04\x0A"
- "\x2D\x5B\x25\x21\x76\x45\x9D\x1F\x39\x75\x41\xBA\x2A\x58\xFB\x65"
- "\x99";
-
- static unsigned char q[] =
- "\x00\xC9\x7F\xB1\xF0\x27\xF4\x53\xF6\x34\x12\x33\xEA\xAA\xD1\xD9"
- "\x35\x3F\x6C\x42\xD0\x88\x66\xB1\xD0\x5A\x0F\x20\x35\x02\x8B\x9D"
- "\x86\x98\x40\xB4\x16\x66\xB4\x2E\x92\xEA\x0D\xA3\xB4\x32\x04\xB5"
- "\xCF\xCE\x33\x52\x52\x4D\x04\x16\xA5\xA4\x41\xE7\x00\xAF\x46\x15"
- "\x03";
-
- static unsigned char dmp1[] =
- "\x54\x49\x4C\xA6\x3E\xBA\x03\x37\xE4\xE2\x40\x23\xFC\xD6\x9A\x5A"
- "\xEB\x07\xDD\xDC\x01\x83\xA4\xD0\xAC\x9B\x54\xB0\x51\xF2\xB1\x3E"
- "\xD9\x49\x09\x75\xEA\xB7\x74\x14\xFF\x59\xC1\xF7\x69\x2E\x9A\x2E"
- "\x20\x2B\x38\xFC\x91\x0A\x47\x41\x74\xAD\xC9\x3C\x1F\x67\xC9\x81";
-
- static unsigned char dmq1[] =
- "\x47\x1E\x02\x90\xFF\x0A\xF0\x75\x03\x51\xB7\xF8\x78\x86\x4C\xA9"
- "\x61\xAD\xBD\x3A\x8A\x7E\x99\x1C\x5C\x05\x56\xA9\x4C\x31\x46\xA7"
- "\xF9\x80\x3F\x8F\x6F\x8A\xE3\x42\xE9\x31\xFD\x8A\xE4\x7A\x22\x0D"
- "\x1B\x99\xA4\x95\x84\x98\x07\xFE\x39\xF9\x24\x5A\x98\x36\xDA\x3D";
-
- static unsigned char iqmp[] =
- "\x00\xB0\x6C\x4F\xDA\xBB\x63\x01\x19\x8D\x26\x5B\xDB\xAE\x94\x23"
- "\xB3\x80\xF2\x71\xF7\x34\x53\x88\x50\x93\x07\x7F\xCD\x39\xE2\x11"
- "\x9F\xC9\x86\x32\x15\x4F\x58\x83\xB1\x67\xA9\x67\xBF\x40\x2B\x4E"
- "\x9E\x2E\x0F\x96\x56\xE6\x98\xEA\x36\x66\xED\xFB\x25\x79\x80\x39"
- "\xF7";
-
- static unsigned char ctext_ex[] =
- "\xb8\x24\x6b\x56\xa6\xed\x58\x81\xae\xb5\x85\xd9\xa2\x5b\x2a\xd7"
- "\x90\xc4\x17\xe0\x80\x68\x1b\xf1\xac\x2b\xc3\xde\xb6\x9d\x8b\xce"
- "\xf0\xc4\x36\x6f\xec\x40\x0a\xf0\x52\xa7\x2e\x9b\x0e\xff\xb5\xb3"
- "\xf2\xf1\x92\xdb\xea\xca\x03\xc1\x27\x40\x05\x71\x13\xbf\x1f\x06"
- "\x69\xac\x22\xe9\xf3\xa7\x85\x2e\x3c\x15\xd9\x13\xca\xb0\xb8\x86"
- "\x3a\x95\xc9\x92\x94\xce\x86\x74\x21\x49\x54\x61\x03\x46\xf4\xd4"
- "\x74\xb2\x6f\x7c\x48\xb4\x2e\xe6\x8e\x1f\x57\x2a\x1f\xc4\x02\x6a"
- "\xc4\x56\xb4\xf5\x9f\x7b\x62\x1e\xa1\xb9\xd8\x8f\x64\x20\x2f\xb1";
-
- SetKey;
-}
-
-static int test_bad_key(void) {
- RSA *key = RSA_new();
- BIGNUM e;
-
- BN_init(&e);
- BN_set_word(&e, RSA_F4);
-
- if (!RSA_generate_key_ex(key, 512, &e, NULL)) {
- fprintf(stderr, "RSA_generate_key_ex failed.\n");
- ERR_print_errors_fp(stderr);
- return 0;
- }
-
- if (!BN_add(key->p, key->p, BN_value_one())) {
- fprintf(stderr, "BN error.\n");
- ERR_print_errors_fp(stderr);
- return 0;
- }
-
- if (RSA_check_key(key)) {
- fprintf(stderr, "RSA_check_key passed with invalid key!\n");
- return 0;
- }
-
- ERR_clear_error();
- BN_free(&e);
- RSA_free(key);
- return 1;
-}
-
-static int test_only_d_given(void) {
- RSA *key = RSA_new();
- uint8_t buf[64];
- unsigned buf_len = sizeof(buf);
- const uint8_t kDummyHash[16] = {0};
- int ret = 0;
-
- if (!BN_hex2bn(&key->n,
- "00e77bbf3889d4ef36a9a25d4d69f3f632eb4362214c74517da6d6aeaa9bd"
- "09ac42b26621cd88f3a6eb013772fc3bf9f83914b6467231c630202c35b3e"
- "5808c659") ||
- !BN_hex2bn(&key->e, "010001") ||
- !BN_hex2bn(&key->d,
- "0365db9eb6d73b53b015c40cd8db4de7dd7035c68b5ac1bf786d7a4ee2cea"
- "316eaeca21a73ac365e58713195f2ae9849348525ca855386b6d028e437a9"
- "495a01") ||
- RSA_size(key) > sizeof(buf)) {
- goto err;
- }
-
- if (!RSA_check_key(key)) {
- fprintf(stderr, "RSA_check_key failed with only d given.\n");
- ERR_print_errors_fp(stderr);
- goto err;
- }
-
- if (!RSA_sign(NID_sha256, kDummyHash, sizeof(kDummyHash), buf, &buf_len,
- key)) {
- fprintf(stderr, "RSA_sign failed with only d given.\n");
- ERR_print_errors_fp(stderr);
- goto err;
- }
-
- if (!RSA_verify(NID_sha256, kDummyHash, sizeof(kDummyHash), buf, buf_len,
- key)) {
- fprintf(stderr, "RSA_verify failed with only d given.\n");
- ERR_print_errors_fp(stderr);
- goto err;
- }
-
- ret = 1;
-
-err:
- RSA_free(key);
- return ret;
-}
-
-static int test_recover_crt_params(void) {
- RSA *key1, *key2;
- BIGNUM *e = BN_new();
- uint8_t buf[128];
- unsigned buf_len = sizeof(buf);
- const uint8_t kDummyHash[16] = {0};
- unsigned i;
-
- BN_set_word(e, RSA_F4);
-
- ERR_clear_error();
-
- for (i = 0; i < 1; i++) {
- key1 = RSA_new();
- if (!RSA_generate_key_ex(key1, 512, e, NULL)) {
- fprintf(stderr, "RSA_generate_key_ex failed.\n");
- ERR_print_errors_fp(stderr);
- return 0;
- }
-
- if (!RSA_check_key(key1)) {
- fprintf(stderr, "RSA_check_key failed with original key.\n");
- ERR_print_errors_fp(stderr);
- return 0;
- }
-
- key2 = RSA_new();
- key2->n = BN_dup(key1->n);
- key2->e = BN_dup(key1->e);
- key2->d = BN_dup(key1->d);
- RSA_free(key1);
-
- if (!RSA_recover_crt_params(key2)) {
- fprintf(stderr, "RSA_recover_crt_params failed.\n");
- ERR_print_errors_fp(stderr);
- return 0;
- }
-
- if (RSA_size(key2) > buf_len) {
- return 0;
- }
-
- if (!RSA_check_key(key2)) {
- fprintf(stderr, "RSA_check_key failed with recovered key.\n");
- ERR_print_errors_fp(stderr);
- return 0;
- }
-
- if (!RSA_sign(NID_sha256, kDummyHash, sizeof(kDummyHash), buf, &buf_len,
- key2)) {
- fprintf(stderr, "RSA_sign failed with recovered key.\n");
- ERR_print_errors_fp(stderr);
- return 0;
- }
-
- if (!RSA_verify(NID_sha256, kDummyHash, sizeof(kDummyHash), buf, buf_len,
- key2)) {
- fprintf(stderr, "RSA_verify failed with recovered key.\n");
- ERR_print_errors_fp(stderr);
- return 0;
- }
-
- RSA_free(key2);
- }
-
- BN_free(e);
- return 1;
-}
-
-int main(int argc, char *argv[]) {
- int err = 0;
- int v;
- RSA *key;
- unsigned char ptext[256];
- unsigned char ctext[256];
- static unsigned char ptext_ex[] = "\x54\x85\x9b\x34\x2c\x49\xea\x2a";
- unsigned char ctext_ex[256];
- int plen;
- int clen = 0;
- int num;
- int n;
-
- CRYPTO_library_init();
-
- plen = sizeof(ptext_ex) - 1;
-
- for (v = 0; v < 3; v++) {
- key = RSA_new();
- switch (v) {
- case 0:
- clen = key1(key, ctext_ex);
- break;
- case 1:
- clen = key2(key, ctext_ex);
- break;
- case 2:
- clen = key3(key, ctext_ex);
- break;
- default:
- abort();
- }
-
- if (!RSA_check_key(key)) {
- printf("%d: RSA_check_key failed\n", v);
- err = 1;
- goto oaep;
- }
-
- num = RSA_public_encrypt(plen, ptext_ex, ctext, key, RSA_PKCS1_PADDING);
- if (num != clen) {
- printf("PKCS#1 v1.5 encryption failed!\n");
- err = 1;
- goto oaep;
- }
-
- num = RSA_private_decrypt(num, ctext, ptext, key, RSA_PKCS1_PADDING);
- if (num != plen || memcmp(ptext, ptext_ex, num) != 0) {
- printf("PKCS#1 v1.5 decryption failed!\n");
- err = 1;
- } else {
- printf("PKCS #1 v1.5 encryption/decryption ok\n");
- }
-
- oaep:
- ERR_clear_error();
- num =
- RSA_public_encrypt(plen, ptext_ex, ctext, key, RSA_PKCS1_OAEP_PADDING);
- if (num == -1) {
- printf("No OAEP support\n");
- goto next;
- }
- if (num != clen) {
- printf("OAEP encryption failed!\n");
- err = 1;
- goto next;
- }
-
- num = RSA_private_decrypt(num, ctext, ptext, key, RSA_PKCS1_OAEP_PADDING);
- if (num != plen || memcmp(ptext, ptext_ex, num) != 0) {
- printf("OAEP decryption (encrypted data) failed!\n");
- err = 1;
- } else if (memcmp(ctext, ctext_ex, num) == 0) {
- printf("OAEP test vector %d passed!\n", v);
- }
-
- /* Different ciphertexts (rsa_oaep.c without -DPKCS_TESTVECT).
- Try decrypting ctext_ex */
-
- num =
- RSA_private_decrypt(clen, ctext_ex, ptext, key, RSA_PKCS1_OAEP_PADDING);
-
- if (num != plen || memcmp(ptext, ptext_ex, num) != 0) {
- printf("OAEP decryption (test vector data) failed!\n");
- err = 1;
- } else {
- printf("OAEP encryption/decryption ok\n");
- }
-
- /* Try decrypting corrupted ciphertexts */
- for (n = 0; n < clen; ++n) {
- int b;
- unsigned char saved = ctext[n];
- for (b = 0; b < 256; ++b) {
- if (b == saved) {
- continue;
- }
- ctext[n] = b;
- num =
- RSA_private_decrypt(num, ctext, ptext, key, RSA_PKCS1_OAEP_PADDING);
- if (num > 0) {
- printf("Corrupt data decrypted!\n");
- err = 1;
- }
- }
- }
-
- next:
- RSA_free(key);
- }
-
- if (err != 0 ||
- !test_only_d_given() ||
- !test_recover_crt_params() ||
- !test_bad_key()) {
- err = 1;
- }
-
- if (err == 0) {
- printf("PASS\n");
- }
- return err;
-}
diff --git a/src/crypto/rsa/rsa_test.cc b/src/crypto/rsa/rsa_test.cc
new file mode 100644
index 0000000..d52b78b
--- /dev/null
+++ b/src/crypto/rsa/rsa_test.cc
@@ -0,0 +1,869 @@
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.] */
+
+#include <openssl/rsa.h>
+
+#include <stdlib.h>
+#include <string.h>
+
+#include <openssl/bn.h>
+#include <openssl/bytestring.h>
+#include <openssl/crypto.h>
+#include <openssl/err.h>
+#include <openssl/obj.h>
+
+#include "../test/scoped_types.h"
+
+
+// kPlaintext is a sample plaintext.
+static const uint8_t kPlaintext[] = "\x54\x85\x9b\x34\x2c\x49\xea\x2a";
+static const size_t kPlaintextLen = sizeof(kPlaintext) - 1;
+
+// kKey1 is a DER-encoded RSAPrivateKey.
+static const uint8_t kKey1[] =
+ "\x30\x82\x01\x38\x02\x01\x00\x02\x41\x00\xaa\x36\xab\xce\x88\xac\xfd\xff"
+ "\x55\x52\x3c\x7f\xc4\x52\x3f\x90\xef\xa0\x0d\xf3\x77\x4a\x25\x9f\x2e\x62"
+ "\xb4\xc5\xd9\x9c\xb5\xad\xb3\x00\xa0\x28\x5e\x53\x01\x93\x0e\x0c\x70\xfb"
+ "\x68\x76\x93\x9c\xe6\x16\xce\x62\x4a\x11\xe0\x08\x6d\x34\x1e\xbc\xac\xa0"
+ "\xa1\xf5\x02\x01\x11\x02\x40\x0a\x03\x37\x48\x62\x64\x87\x69\x5f\x5f\x30"
+ "\xbc\x38\xb9\x8b\x44\xc2\xcd\x2d\xff\x43\x40\x98\xcd\x20\xd8\xa1\x38\xd0"
+ "\x90\xbf\x64\x79\x7c\x3f\xa7\xa2\xcd\xcb\x3c\xd1\xe0\xbd\xba\x26\x54\xb4"
+ "\xf9\xdf\x8e\x8a\xe5\x9d\x73\x3d\x9f\x33\xb3\x01\x62\x4a\xfd\x1d\x51\x02"
+ "\x21\x00\xd8\x40\xb4\x16\x66\xb4\x2e\x92\xea\x0d\xa3\xb4\x32\x04\xb5\xcf"
+ "\xce\x33\x52\x52\x4d\x04\x16\xa5\xa4\x41\xe7\x00\xaf\x46\x12\x0d\x02\x21"
+ "\x00\xc9\x7f\xb1\xf0\x27\xf4\x53\xf6\x34\x12\x33\xea\xaa\xd1\xd9\x35\x3f"
+ "\x6c\x42\xd0\x88\x66\xb1\xd0\x5a\x0f\x20\x35\x02\x8b\x9d\x89\x02\x20\x59"
+ "\x0b\x95\x72\xa2\xc2\xa9\xc4\x06\x05\x9d\xc2\xab\x2f\x1d\xaf\xeb\x7e\x8b"
+ "\x4f\x10\xa7\x54\x9e\x8e\xed\xf5\xb4\xfc\xe0\x9e\x05\x02\x21\x00\x8e\x3c"
+ "\x05\x21\xfe\x15\xe0\xea\x06\xa3\x6f\xf0\xf1\x0c\x99\x52\xc3\x5b\x7a\x75"
+ "\x14\xfd\x32\x38\xb8\x0a\xad\x52\x98\x62\x8d\x51\x02\x20\x36\x3f\xf7\x18"
+ "\x9d\xa8\xe9\x0b\x1d\x34\x1f\x71\xd0\x9b\x76\xa8\xa9\x43\xe1\x1d\x10\xb2"
+ "\x4d\x24\x9f\x2d\xea\xfe\xf8\x0c\x18\x26";
+
+// kOAEPCiphertext1 is a sample encryption of |kPlaintext| with |kKey1| using
+// RSA OAEP.
+static const uint8_t kOAEPCiphertext1[] =
+ "\x1b\x8f\x05\xf9\xca\x1a\x79\x52\x6e\x53\xf3\xcc\x51\x4f\xdb\x89\x2b\xfb"
+ "\x91\x93\x23\x1e\x78\xb9\x92\xe6\x8d\x50\xa4\x80\xcb\x52\x33\x89\x5c\x74"
+ "\x95\x8d\x5d\x02\xab\x8c\x0f\xd0\x40\xeb\x58\x44\xb0\x05\xc3\x9e\xd8\x27"
+ "\x4a\x9d\xbf\xa8\x06\x71\x40\x94\x39\xd2";
+
+// kKey2 is a DER-encoded RSAPrivateKey.
+static const uint8_t kKey2[] =
+ "\x30\x81\xfb\x02\x01\x00\x02\x33\x00\xa3\x07\x9a\x90\xdf\x0d\xfd\x72\xac"
+ "\x09\x0c\xcc\x2a\x78\xb8\x74\x13\x13\x3e\x40\x75\x9c\x98\xfa\xf8\x20\x4f"
+ "\x35\x8a\x0b\x26\x3c\x67\x70\xe7\x83\xa9\x3b\x69\x71\xb7\x37\x79\xd2\x71"
+ "\x7b\xe8\x34\x77\xcf\x02\x01\x03\x02\x32\x6c\xaf\xbc\x60\x94\xb3\xfe\x4c"
+ "\x72\xb0\xb3\x32\xc6\xfb\x25\xa2\xb7\x62\x29\x80\x4e\x68\x65\xfc\xa4\x5a"
+ "\x74\xdf\x0f\x8f\xb8\x41\x3b\x52\xc0\xd0\xe5\x3d\x9b\x59\x0f\xf1\x9b\xe7"
+ "\x9f\x49\xdd\x21\xe5\xeb\x02\x1a\x00\xcf\x20\x35\x02\x8b\x9d\x86\x98\x40"
+ "\xb4\x16\x66\xb4\x2e\x92\xea\x0d\xa3\xb4\x32\x04\xb5\xcf\xce\x91\x02\x1a"
+ "\x00\xc9\x7f\xb1\xf0\x27\xf4\x53\xf6\x34\x12\x33\xea\xaa\xd1\xd9\x35\x3f"
+ "\x6c\x42\xd0\x88\x66\xb1\xd0\x5f\x02\x1a\x00\x8a\x15\x78\xac\x5d\x13\xaf"
+ "\x10\x2b\x22\xb9\x99\xcd\x74\x61\xf1\x5e\x6d\x22\xcc\x03\x23\xdf\xdf\x0b"
+ "\x02\x1a\x00\x86\x55\x21\x4a\xc5\x4d\x8d\x4e\xcd\x61\x77\xf1\xc7\x36\x90"
+ "\xce\x2a\x48\x2c\x8b\x05\x99\xcb\xe0\x3f\x02\x1a\x00\x83\xef\xef\xb8\xa9"
+ "\xa4\x0d\x1d\xb6\xed\x98\xad\x84\xed\x13\x35\xdc\xc1\x08\xf3\x22\xd0\x57"
+ "\xcf\x8d";
+
+// kOAEPCiphertext2 is a sample encryption of |kPlaintext| with |kKey2| using
+// RSA OAEP.
+static const uint8_t kOAEPCiphertext2[] =
+ "\x14\xbd\xdd\x28\xc9\x83\x35\x19\x23\x80\xe8\xe5\x49\xb1\x58\x2a\x8b\x40"
+ "\xb4\x48\x6d\x03\xa6\xa5\x31\x1f\x1f\xd5\xf0\xa1\x80\xe4\x17\x53\x03\x29"
+ "\xa9\x34\x90\x74\xb1\x52\x13\x54\x29\x08\x24\x52\x62\x51";
+
+// kKey3 is a DER-encoded RSAPrivateKey.
+static const uint8_t kKey3[] =
+ "\x30\x82\x02\x5b\x02\x01\x00\x02\x81\x81\x00\xbb\xf8\x2f\x09\x06\x82\xce"
+ "\x9c\x23\x38\xac\x2b\x9d\xa8\x71\xf7\x36\x8d\x07\xee\xd4\x10\x43\xa4\x40"
+ "\xd6\xb6\xf0\x74\x54\xf5\x1f\xb8\xdf\xba\xaf\x03\x5c\x02\xab\x61\xea\x48"
+ "\xce\xeb\x6f\xcd\x48\x76\xed\x52\x0d\x60\xe1\xec\x46\x19\x71\x9d\x8a\x5b"
+ "\x8b\x80\x7f\xaf\xb8\xe0\xa3\xdf\xc7\x37\x72\x3e\xe6\xb4\xb7\xd9\x3a\x25"
+ "\x84\xee\x6a\x64\x9d\x06\x09\x53\x74\x88\x34\xb2\x45\x45\x98\x39\x4e\xe0"
+ "\xaa\xb1\x2d\x7b\x61\xa5\x1f\x52\x7a\x9a\x41\xf6\xc1\x68\x7f\xe2\x53\x72"
+ "\x98\xca\x2a\x8f\x59\x46\xf8\xe5\xfd\x09\x1d\xbd\xcb\x02\x01\x11\x02\x81"
+ "\x81\x00\xa5\xda\xfc\x53\x41\xfa\xf2\x89\xc4\xb9\x88\xdb\x30\xc1\xcd\xf8"
+ "\x3f\x31\x25\x1e\x06\x68\xb4\x27\x84\x81\x38\x01\x57\x96\x41\xb2\x94\x10"
+ "\xb3\xc7\x99\x8d\x6b\xc4\x65\x74\x5e\x5c\x39\x26\x69\xd6\x87\x0d\xa2\xc0"
+ "\x82\xa9\x39\xe3\x7f\xdc\xb8\x2e\xc9\x3e\xda\xc9\x7f\xf3\xad\x59\x50\xac"
+ "\xcf\xbc\x11\x1c\x76\xf1\xa9\x52\x94\x44\xe5\x6a\xaf\x68\xc5\x6c\x09\x2c"
+ "\xd3\x8d\xc3\xbe\xf5\xd2\x0a\x93\x99\x26\xed\x4f\x74\xa1\x3e\xdd\xfb\xe1"
+ "\xa1\xce\xcc\x48\x94\xaf\x94\x28\xc2\xb7\xb8\x88\x3f\xe4\x46\x3a\x4b\xc8"
+ "\x5b\x1c\xb3\xc1\x02\x41\x00\xee\xcf\xae\x81\xb1\xb9\xb3\xc9\x08\x81\x0b"
+ "\x10\xa1\xb5\x60\x01\x99\xeb\x9f\x44\xae\xf4\xfd\xa4\x93\xb8\x1a\x9e\x3d"
+ "\x84\xf6\x32\x12\x4e\xf0\x23\x6e\x5d\x1e\x3b\x7e\x28\xfa\xe7\xaa\x04\x0a"
+ "\x2d\x5b\x25\x21\x76\x45\x9d\x1f\x39\x75\x41\xba\x2a\x58\xfb\x65\x99\x02"
+ "\x41\x00\xc9\x7f\xb1\xf0\x27\xf4\x53\xf6\x34\x12\x33\xea\xaa\xd1\xd9\x35"
+ "\x3f\x6c\x42\xd0\x88\x66\xb1\xd0\x5a\x0f\x20\x35\x02\x8b\x9d\x86\x98\x40"
+ "\xb4\x16\x66\xb4\x2e\x92\xea\x0d\xa3\xb4\x32\x04\xb5\xcf\xce\x33\x52\x52"
+ "\x4d\x04\x16\xa5\xa4\x41\xe7\x00\xaf\x46\x15\x03\x02\x40\x54\x49\x4c\xa6"
+ "\x3e\xba\x03\x37\xe4\xe2\x40\x23\xfc\xd6\x9a\x5a\xeb\x07\xdd\xdc\x01\x83"
+ "\xa4\xd0\xac\x9b\x54\xb0\x51\xf2\xb1\x3e\xd9\x49\x09\x75\xea\xb7\x74\x14"
+ "\xff\x59\xc1\xf7\x69\x2e\x9a\x2e\x20\x2b\x38\xfc\x91\x0a\x47\x41\x74\xad"
+ "\xc9\x3c\x1f\x67\xc9\x81\x02\x40\x47\x1e\x02\x90\xff\x0a\xf0\x75\x03\x51"
+ "\xb7\xf8\x78\x86\x4c\xa9\x61\xad\xbd\x3a\x8a\x7e\x99\x1c\x5c\x05\x56\xa9"
+ "\x4c\x31\x46\xa7\xf9\x80\x3f\x8f\x6f\x8a\xe3\x42\xe9\x31\xfd\x8a\xe4\x7a"
+ "\x22\x0d\x1b\x99\xa4\x95\x84\x98\x07\xfe\x39\xf9\x24\x5a\x98\x36\xda\x3d"
+ "\x02\x41\x00\xb0\x6c\x4f\xda\xbb\x63\x01\x19\x8d\x26\x5b\xdb\xae\x94\x23"
+ "\xb3\x80\xf2\x71\xf7\x34\x53\x88\x50\x93\x07\x7f\xcd\x39\xe2\x11\x9f\xc9"
+ "\x86\x32\x15\x4f\x58\x83\xb1\x67\xa9\x67\xbf\x40\x2b\x4e\x9e\x2e\x0f\x96"
+ "\x56\xe6\x98\xea\x36\x66\xed\xfb\x25\x79\x80\x39\xf7";
+
+// kOAEPCiphertext3 is a sample encryption of |kPlaintext| with |kKey3| using
+// RSA OAEP.
+static const uint8_t kOAEPCiphertext3[] =
+ "\xb8\x24\x6b\x56\xa6\xed\x58\x81\xae\xb5\x85\xd9\xa2\x5b\x2a\xd7\x90\xc4"
+ "\x17\xe0\x80\x68\x1b\xf1\xac\x2b\xc3\xde\xb6\x9d\x8b\xce\xf0\xc4\x36\x6f"
+ "\xec\x40\x0a\xf0\x52\xa7\x2e\x9b\x0e\xff\xb5\xb3\xf2\xf1\x92\xdb\xea\xca"
+ "\x03\xc1\x27\x40\x05\x71\x13\xbf\x1f\x06\x69\xac\x22\xe9\xf3\xa7\x85\x2e"
+ "\x3c\x15\xd9\x13\xca\xb0\xb8\x86\x3a\x95\xc9\x92\x94\xce\x86\x74\x21\x49"
+ "\x54\x61\x03\x46\xf4\xd4\x74\xb2\x6f\x7c\x48\xb4\x2e\xe6\x8e\x1f\x57\x2a"
+ "\x1f\xc4\x02\x6a\xc4\x56\xb4\xf5\x9f\x7b\x62\x1e\xa1\xb9\xd8\x8f\x64\x20"
+ "\x2f\xb1";
+
+static const uint8_t kTwoPrimeKey[] =
+ "\x30\x82\x04\xa1\x02\x01\x00\x02\x82\x01\x01\x00\x93\x3a\x4f\xc9\x6a\x0a"
+ "\x6b\x28\x04\xfa\xb7\x05\x56\xdf\xa0\xaa\x4f\xaa\xab\x94\xa0\xa9\x25\xef"
+ "\xc5\x96\xd2\xd4\x66\x16\x62\x2c\x13\x7b\x91\xd0\x36\x0a\x10\x11\x6d\x7a"
+ "\x91\xb6\xe4\x74\x57\xc1\x3d\x7a\xbe\x24\x05\x3a\x04\x0b\x73\x91\x53\xb1"
+ "\x74\x10\xe1\x87\xdc\x91\x28\x9c\x1e\xe5\xf2\xb9\xfc\xa2\x48\x34\xb6\x78"
+ "\xed\x6d\x95\xfb\xf2\xc0\x4e\x1c\xa4\x15\x00\x3c\x8a\x68\x2b\xd6\xce\xd5"
+ "\xb3\x9f\x66\x02\xa7\x0d\x08\xa3\x23\x9b\xe5\x36\x96\x13\x22\xf9\x69\xa6"
+ "\x87\x88\x9b\x85\x3f\x83\x9c\xab\x1a\x1b\x6d\x8d\x16\xf4\x5e\xbd\xee\x4b"
+ "\x59\x56\xf8\x9d\x58\xcd\xd2\x83\x85\x59\x43\x84\x63\x4f\xe6\x1a\x86\x66"
+ "\x0d\xb5\xa0\x87\x89\xb6\x13\x82\x43\xda\x34\x92\x3b\x68\xc4\x95\x71\x2f"
+ "\x15\xc2\xe0\x43\x67\x3c\x08\x00\x36\x10\xc3\xb4\x46\x4c\x4e\x6e\xf5\x44"
+ "\xa9\x04\x44\x9d\xce\xc7\x05\x79\xee\x11\xcf\xaf\x2c\xd7\x9a\x32\xd3\xa5"
+ "\x30\xd4\x3a\x78\x43\x37\x74\x22\x90\x24\x04\x11\xd7\x95\x08\x52\xa4\x71"
+ "\x41\x68\x94\xb0\xa0\xc3\xec\x4e\xd2\xc4\x30\x71\x98\x64\x9c\xe3\x7c\x76"
+ "\xef\x33\xa3\x2b\xb1\x87\x63\xd2\x5c\x09\xfc\x90\x2d\x92\xf4\x57\x02\x01"
+ "\x03\x02\x82\x01\x00\x62\x26\xdf\xdb\x9c\x06\xf2\x1a\xad\xfc\x7a\x03\x8f"
+ "\x3f\xc0\x71\x8a\x71\xc7\xb8\x6b\x1b\x6e\x9f\xd9\x0f\x37\x38\x44\x0e\xec"
+ "\x1d\x62\x52\x61\x35\x79\x5c\x0a\xb6\x48\xfc\x61\x24\x98\x4d\x8f\xd6\x28"
+ "\xfc\x7e\xc2\xae\x26\xad\x5c\xf7\xb6\x37\xcb\xa2\xb5\xeb\xaf\xe8\x60\xc5"
+ "\xbd\x69\xee\xa1\xd1\x53\x16\xda\xcd\xce\xfb\x48\xf3\xb9\x52\xa1\xd5\x89"
+ "\x68\x6d\x63\x55\x7d\xb1\x9a\xc7\xe4\x89\xe3\xcd\x14\xee\xac\x6f\x5e\x05"
+ "\xc2\x17\xbd\x43\x79\xb9\x62\x17\x50\xf1\x19\xaf\xb0\x67\xae\x2a\x57\xbd"
+ "\xc7\x66\xbc\xf3\xb3\x64\xa1\xe3\x16\x74\x9e\xea\x02\x5c\xab\x94\xd8\x97"
+ "\x02\x42\x0c\x2c\xba\x54\xb9\xaf\xe0\x45\x93\xad\x7f\xb3\x10\x6a\x96\x50"
+ "\x4b\xaf\xcf\xc8\x27\x62\x2d\x83\xe9\x26\xc6\x94\xc1\xef\x5c\x8e\x06\x42"
+ "\x53\xe5\x56\xaf\xc2\x99\x01\xaa\x9a\x71\xbc\xe8\x21\x33\x2a\x2d\xa3\x36"
+ "\xac\x1b\x86\x19\xf8\xcd\x1f\x80\xa4\x26\x98\xb8\x9f\x62\x62\xd5\x1a\x7f"
+ "\xee\xdb\xdf\x81\xd3\x21\xdb\x33\x92\xee\xff\xe2\x2f\x32\x77\x73\x6a\x58"
+ "\xab\x21\xf3\xe3\xe1\xbc\x4f\x12\x72\xa6\xb5\xc2\xfb\x27\x9e\xc8\xca\xab"
+ "\x64\xa0\x87\x07\x9d\xef\xca\x0f\xdb\x02\x81\x81\x00\xe6\xd3\x4d\xc0\xa1"
+ "\x91\x0e\x62\xfd\xb0\xdd\xc6\x30\xb8\x8c\xcb\x14\xc1\x4b\x69\x30\xdd\xcd"
+ "\x86\x67\xcb\x37\x14\xc5\x03\xd2\xb4\x69\xab\x3d\xe5\x16\x81\x0f\xe5\x50"
+ "\xf4\x18\xb1\xec\xbc\x71\xe9\x80\x99\x06\xe4\xa3\xfe\x44\x84\x4a\x2d\x1e"
+ "\x07\x7f\x22\x70\x6d\x4f\xd4\x93\x0b\x8b\x99\xce\x1e\xab\xcd\x4c\xd2\xd3"
+ "\x10\x47\x5c\x09\x9f\x6d\x82\xc0\x08\x75\xe3\x3d\x83\xc2\x19\x50\x29\xec"
+ "\x1f\x84\x29\xcc\xf1\x56\xee\xbd\x54\x5d\xe6\x19\xdf\x0d\x1c\xa4\xbb\x0a"
+ "\xfe\x84\x44\x29\x1d\xf9\x5c\x80\x96\x5b\x24\xb4\xf7\x02\x1b\x02\x81\x81"
+ "\x00\xa3\x48\xf1\x9c\x58\xc2\x5f\x38\xfb\xd8\x12\x39\xf1\x8e\x73\xa1\xcf"
+ "\x78\x12\xe0\xed\x2a\xbb\xef\xac\x23\xb2\xbf\xd6\x0c\xe9\x6e\x1e\xab\xea"
+ "\x3f\x68\x36\xa7\x1f\xe5\xab\xe0\x86\xa5\x76\x32\x98\xdd\x75\xb5\x2b\xbc"
+ "\xcb\x8a\x03\x00\x7c\x2e\xca\xf8\xbc\x19\xe4\xe3\xa3\x31\xbd\x1d\x20\x2b"
+ "\x09\xad\x6f\x4c\xed\x48\xd4\xdf\x87\xf9\xf0\x46\xb9\x86\x4c\x4b\x71\xe7"
+ "\x48\x78\xdc\xed\xc7\x82\x02\x44\xd3\xa6\xb3\x10\x5f\x62\x81\xfc\xb8\xe4"
+ "\x0e\xf4\x1a\xdd\xab\x3f\xbc\x63\x79\x5b\x39\x69\x5e\xea\xa9\x15\xfe\x90"
+ "\xec\xda\x75\x02\x81\x81\x00\x99\xe2\x33\xd5\xc1\x0b\x5e\xec\xa9\x20\x93"
+ "\xd9\x75\xd0\x5d\xdc\xb8\x80\xdc\xf0\xcb\x3e\x89\x04\x45\x32\x24\xb8\x83"
+ "\x57\xe1\xcd\x9b\xc7\x7e\x98\xb9\xab\x5f\xee\x35\xf8\x10\x76\x9d\xd2\xf6"
+ "\x9b\xab\x10\xaf\x43\x17\xfe\xd8\x58\x31\x73\x69\x5a\x54\xc1\xa0\x48\xdf"
+ "\xe3\x0c\xb2\x5d\x11\x34\x14\x72\x88\xdd\xe1\xe2\x0a\xda\x3d\x5b\xbf\x9e"
+ "\x57\x2a\xb0\x4e\x97\x7e\x57\xd6\xbb\x8a\xc6\x9d\x6a\x58\x1b\xdd\xf6\x39"
+ "\xf4\x7e\x38\x3e\x99\x66\x94\xb3\x68\x6d\xd2\x07\x54\x58\x2d\x70\xbe\xa6"
+ "\x3d\xab\x0e\xe7\x6d\xcd\xfa\x01\x67\x02\x81\x80\x6c\xdb\x4b\xbd\x90\x81"
+ "\x94\xd0\xa7\xe5\x61\x7b\xf6\x5e\xf7\xc1\x34\xfa\xb7\x40\x9e\x1c\x7d\x4a"
+ "\x72\xc2\x77\x2a\x8e\xb3\x46\x49\x69\xc7\xf1\x7f\x9a\xcf\x1a\x15\x43\xc7"
+ "\xeb\x04\x6e\x4e\xcc\x65\xe8\xf9\x23\x72\x7d\xdd\x06\xac\xaa\xfd\x74\x87"
+ "\x50\x7d\x66\x98\x97\xc2\x21\x28\xbe\x15\x72\x06\x73\x9f\x88\x9e\x30\x8d"
+ "\xea\x5a\xa6\xa0\x2f\x26\x59\x88\x32\x4b\xef\x85\xa5\xe8\x9e\x85\x01\x56"
+ "\xd8\x8d\x19\xcc\xb5\x94\xec\x56\xa8\x7b\x42\xb4\xa2\xbc\x93\xc7\x7f\xd2"
+ "\xec\xfb\x92\x26\x46\x3f\x47\x1b\x63\xff\x0b\x48\x91\xa3\x02\x81\x80\x2c"
+ "\x4a\xb9\xa4\x46\x7b\xff\x50\x7e\xbf\x60\x47\x3b\x2b\x66\x82\xdc\x0e\x53"
+ "\x65\x71\xe9\xda\x2a\xb8\x32\x93\x42\xb7\xff\xea\x67\x66\xf1\xbc\x87\x28"
+ "\x65\x29\x79\xca\xab\x93\x56\xda\x95\xc1\x26\x44\x3d\x27\xc1\x91\xc6\x9b"
+ "\xd9\xec\x9d\xb7\x49\xe7\x16\xee\x99\x87\x50\x95\x81\xd4\x5c\x5b\x5a\x5d"
+ "\x0a\x43\xa5\xa7\x8f\x5a\x80\x49\xa0\xb7\x10\x85\xc7\xf4\x42\x34\x86\xb6"
+ "\x5f\x3f\x88\x9e\xc7\xf5\x59\x29\x39\x68\x48\xf2\xd7\x08\x5b\x92\x8e\x6b"
+ "\xea\xa5\x63\x5f\xc0\xfb\xe4\xe1\xb2\x7d\xb7\x40\xe9\x55\x06\xbf\x58\x25"
+ "\x6f";
+
+static const uint8_t kTwoPrimeEncryptedMessage[] = {
+ 0x63, 0x0a, 0x30, 0x45, 0x43, 0x11, 0x45, 0xb7, 0x99, 0x67, 0x90, 0x35,
+ 0x37, 0x27, 0xff, 0xbc, 0xe0, 0xbf, 0xa6, 0xd1, 0x47, 0x50, 0xbb, 0x6c,
+ 0x1c, 0xaa, 0x66, 0xf2, 0xff, 0x9d, 0x9a, 0xa6, 0xb4, 0x16, 0x63, 0xb0,
+ 0xa1, 0x7c, 0x7c, 0x0c, 0xef, 0xb3, 0x66, 0x52, 0x42, 0xd7, 0x5e, 0xf3,
+ 0xa4, 0x15, 0x33, 0x40, 0x43, 0xe8, 0xb1, 0xfc, 0xe0, 0x42, 0x83, 0x46,
+ 0x28, 0xce, 0xde, 0x7b, 0x01, 0xeb, 0x28, 0x92, 0x70, 0xdf, 0x8d, 0x54,
+ 0x9e, 0xed, 0x23, 0xb4, 0x78, 0xc3, 0xca, 0x85, 0x53, 0x48, 0xd6, 0x8a,
+ 0x87, 0xf7, 0x69, 0xcd, 0x82, 0x8c, 0x4f, 0x5c, 0x05, 0x55, 0xa6, 0x78,
+ 0x89, 0xab, 0x4c, 0xd8, 0xa9, 0xd6, 0xa5, 0xf4, 0x29, 0x4c, 0x23, 0xc8,
+ 0xcf, 0xf0, 0x4c, 0x64, 0x6b, 0x4e, 0x02, 0x17, 0x69, 0xd6, 0x47, 0x83,
+ 0x30, 0x43, 0x02, 0x29, 0xda, 0xda, 0x75, 0x3b, 0xd7, 0xa7, 0x2b, 0x31,
+ 0xb3, 0xe9, 0x71, 0xa4, 0x41, 0xf7, 0x26, 0x9b, 0xcd, 0x23, 0xfa, 0x45,
+ 0x3c, 0x9b, 0x7d, 0x28, 0xf7, 0xf9, 0x67, 0x04, 0xba, 0xfc, 0x46, 0x75,
+ 0x11, 0x3c, 0xd5, 0x27, 0x43, 0x53, 0xb1, 0xb6, 0x9e, 0x18, 0xeb, 0x11,
+ 0xb4, 0x25, 0x20, 0x30, 0x0b, 0xe0, 0x1c, 0x17, 0x36, 0x22, 0x10, 0x0f,
+ 0x99, 0xb5, 0x50, 0x14, 0x73, 0x07, 0xf0, 0x2f, 0x5d, 0x4c, 0xe3, 0xf2,
+ 0x86, 0xc2, 0x05, 0xc8, 0x38, 0xed, 0xeb, 0x2a, 0x4a, 0xab, 0x76, 0xe3,
+ 0x1a, 0x75, 0x44, 0xf7, 0x6e, 0x94, 0xdc, 0x25, 0x62, 0x7e, 0x31, 0xca,
+ 0xc2, 0x73, 0x51, 0xb5, 0x03, 0xfb, 0xf9, 0xf6, 0xb5, 0x8d, 0x4e, 0x6c,
+ 0x21, 0x0e, 0xf9, 0x97, 0x26, 0x57, 0xf3, 0x52, 0x72, 0x07, 0xf8, 0xb4,
+ 0xcd, 0xb4, 0x39, 0xcf, 0xbf, 0x78, 0xcc, 0xb6, 0x87, 0xf9, 0xb7, 0x8b,
+ 0x6a, 0xce, 0x9f, 0xc8,
+};
+
+static const uint8_t kThreePrimeKey[] =
+ "\x30\x82\x04\xd7\x02\x01\x01\x02\x82\x01\x00\x62\x91\xe9\xea\xb3\x5d\x6c"
+ "\x29\xae\x21\x83\xbb\xb5\x82\xb1\x9e\xea\xe0\x64\x5b\x1e\x2f\x5e\x2c\x0a"
+ "\x80\x3d\x29\xd4\xfa\x9a\xe7\x44\xe6\x21\xbd\x98\xc0\x3d\xe0\x53\x59\xae"
+ "\xd3\x3e\xfe\xc4\xc2\xc4\x5a\x5a\x89\x07\xf4\x4f\xdc\xb0\x6a\xd4\x3e\x99"
+ "\x7d\x7a\x97\x26\x4e\xe1\x93\xca\x6e\xed\x07\xfc\xb4\xfa\x95\x1e\x73\x7b"
+ "\x86\x08\x6a\xb9\xd4\x29\xb0\x7e\x59\xb7\x9d\x7b\xeb\x67\x6e\xf0\xbb\x5e"
+ "\xcf\xb9\xcd\x58\x93\xf0\xe7\x88\x17\x6c\x0d\x76\x1e\xb9\x27\x9a\x4d\x02"
+ "\x16\xb6\x49\x6d\xa7\x83\x23\x4d\x02\x48\x0c\x0c\x1f\x0e\x85\x21\xe3\x06"
+ "\x76\x0a\x73\xe6\xc1\x21\xfa\x30\x18\x78\x29\x5c\x31\xd0\x29\xae\x6f\x7d"
+ "\x87\xd8\x2f\x16\xfa\xbc\x67\x8a\x94\x71\x59\x9b\xec\x22\x40\x55\x9f\xc2"
+ "\x94\xb5\xbd\x78\x01\xc9\xef\x18\xc8\x6d\x0d\xdc\x53\x42\xb2\x5c\xab\x65"
+ "\x05\xbd\x35\x08\x85\x1b\xf8\xe9\x47\xbc\xfe\xc5\xae\x47\x29\x63\x44\x8e"
+ "\x4d\xb7\x47\xab\x0d\xd8\x76\x68\x4f\xc7\x07\x02\xe4\x86\xb0\xcf\xd8\x19"
+ "\xad\xf4\x85\x76\x8b\x3b\x4e\x40\x8d\x29\x7a\x8a\x07\x36\xf3\x78\xae\x17"
+ "\xa6\x8f\x53\x58\x65\x4c\x86\x9e\xd7\x8b\xec\x38\x4f\x99\xc7\x02\x01\x03"
+ "\x02\x82\x01\x00\x41\xb6\x9b\xf1\xcc\xe8\xf2\xc6\x74\x16\x57\xd2\x79\x01"
+ "\xcb\xbf\x47\x40\x42\xe7\x69\x74\xe9\x72\xb1\xaa\xd3\x71\x38\xa7\x11\xef"
+ "\x83\x44\x16\x7e\x65\xd5\x7e\x95\x8c\xe6\x74\x8c\xd4\xa9\xd8\x81\xd8\x3c"
+ "\x3c\x5b\x5a\xa2\xdf\xe8\x75\x9c\x8d\x7f\x10\xfe\x51\xba\x19\x89\xeb\xb7"
+ "\xdc\x49\xf3\x5a\xa8\x78\xa7\x0e\x14\x4c\xfd\x04\x05\x9c\x7b\xe2\xc5\xa3"
+ "\x04\xee\xd9\x4c\xfd\x7d\x47\xb0\x0d\x9b\x3d\x70\x91\x81\x2c\xab\x2b\x87"
+ "\xad\x11\x68\x24\xfc\x2b\xd4\xee\x5e\x28\xeb\x6d\xab\xde\x0f\x77\x15\x58"
+ "\x76\x39\xc9\x59\x3a\x7f\x19\x9d\xc6\x7e\x86\xe4\xd5\x38\x70\x9e\xae\xb9"
+ "\xfb\x33\x33\xd1\x0c\x2d\xab\x01\x20\xe1\x8b\x29\x99\xd3\xeb\x87\x05\x72"
+ "\xaa\x43\x58\x64\x8e\x9e\x31\xdb\x45\x9b\x2b\xac\x58\x80\x5d\x33\xa2\x43"
+ "\x05\x96\xcc\xca\x2d\x04\x5f\xd6\xb7\x3d\x8b\x8f\x2d\xa3\xa5\xf8\x73\xf5"
+ "\xd7\xc0\x19\xff\x10\xe6\xee\x3a\x26\x2f\xe1\x64\x3d\x11\xcd\x2d\xe4\x0a"
+ "\x84\x27\xe3\xcb\x16\x62\x19\xe7\xe3\x0d\x13\xe8\x09\x5a\x53\xd0\x20\x56"
+ "\x15\xf5\xb3\x67\xac\xa1\xb5\x94\x6b\xab\xdc\x71\xc7\xbf\x0a\xde\x76\xf5"
+ "\x03\xa0\x30\xd8\x27\x9d\x00\x2b\x02\x57\x00\xf1\x4f\xc2\x86\x13\x06\x17"
+ "\xf7\x69\x7e\x37\xdf\x67\xc5\x32\xa0\x74\x1c\x32\x69\x0f\x9f\x08\x88\x24"
+ "\xb1\x51\xbc\xbc\x92\xba\x73\x1f\x9c\x75\xc2\x14\x6d\x4f\xc4\x5a\xcf\xda"
+ "\x44\x35\x00\x6b\x42\x3b\x9f\x14\xf1\x05\xb3\x51\x22\xb6\xbe\x9c\xe0\xc1"
+ "\x5c\x48\x61\xdf\x4e\x4c\x72\xb8\x05\x35\x7c\xac\xf1\xbb\xa0\x3b\x2a\xea"
+ "\xf7\x86\xe9\xd2\xff\x1e\x1d\x02\x56\x00\xca\xb1\x39\xf6\xa2\xc6\x3b\x65"
+ "\x45\x2f\x39\x00\xcd\x6e\xd6\x55\xf7\x71\x37\x89\xc2\xe7\x7a\xc0\x1a\xa6"
+ "\x2f\xea\x17\x7c\xaa\x2a\x91\x8f\xd4\xc7\x50\x8b\xab\x8e\x99\x3b\x33\x91"
+ "\xbc\x02\x10\x58\x4b\x58\x40\x9b\xc4\x8f\x48\x2b\xa7\x44\xfd\x07\x04\xf0"
+ "\x98\x67\x56\xea\x25\x92\x8b\x2e\x4b\x4a\xa1\xd3\xc2\xa4\xb4\x9b\x59\x70"
+ "\x32\xa6\xd8\x8b\xd9\x02\x57\x00\xa0\xdf\xd7\x04\x0c\xae\xba\xa4\xf0\xfe"
+ "\xcf\xea\x45\x2e\x21\xc0\x4d\x68\x21\x9b\x5f\xbf\x5b\x05\x6d\xcb\x8b\xd3"
+ "\x28\x61\xd1\xa2\x15\x12\xf9\x2c\x0d\x9e\x35\x2d\x91\xdf\xe6\xd8\x23\x55"
+ "\x9c\xd6\xd2\x6a\x0d\xf6\x03\xcc\xe0\xc1\xcf\x29\xbd\xeb\x2b\x92\xda\xeb"
+ "\xea\x34\x32\xf7\x25\x58\xce\x53\x1d\xf6\x7d\x15\x7c\xc7\x47\x4f\xaf\x46"
+ "\x8c\xaa\x14\x13\x02\x56\x00\x87\x20\xd1\x4f\x17\x2e\xd2\x43\x83\x74\xd0"
+ "\xab\x33\x9f\x39\x8e\xa4\xf6\x25\x06\x81\xef\xa7\x2a\xbc\x6e\xca\x9c\x0f"
+ "\xa8\x71\x71\xb6\x5f\xe3\x2f\x8b\x07\xc7\xb4\x66\x27\x77\xb6\x7d\x56\xb5"
+ "\x90\x32\x3a\xd5\xbd\x2d\xb4\xda\xc7\xc4\xd8\xa8\xaf\x58\xa0\x65\x9a\x39"
+ "\xf1\x6e\x61\xb2\x1e\xdc\xdc\x6b\xe2\x81\xc3\x23\x12\x3b\xa0\x21\xc4\x90"
+ "\x5d\x3b\x02\x57\x00\xe6\x8a\xaa\xb8\x6d\x2c\x81\x43\xb5\xd6\xa0\x2b\x42"
+ "\x49\xa9\x0a\x51\xfa\x18\xc8\x32\xea\x54\x18\xf3\x60\xc2\xb5\x4a\x43\x05"
+ "\x93\x9c\x01\xd9\x28\xed\x73\xfa\x82\xbc\x12\x64\xcb\xc4\x24\xa9\x3e\xae"
+ "\x7c\x4b\x8f\x94\x57\x7b\x14\x10\x41\xdc\x62\x12\x8c\xb2\x4a\x7c\xf6\x53"
+ "\xd4\xc6\xe4\xda\xd1\xa2\x00\x0e\x3d\x30\xf7\x05\x4f\x1d\x82\xbc\x52\xd9"
+ "\xb1\x30\x82\x01\x0a\x30\x82\x01\x06\x02\x56\x00\x84\x12\x4f\xf7\x3b\x65"
+ "\x53\x34\x6c\x6c\x4d\x77\xdf\xfd\x1f\xb6\x16\xe2\x25\x15\xca\xc9\xc1\x41"
+ "\x9a\x50\xda\xeb\x88\x4f\x3d\xb3\x01\x00\x44\xc4\xac\xe7\x14\x62\xa6\x56"
+ "\xde\xc5\xb7\xc3\x1d\x07\xbd\x7d\x64\xc5\x7e\x45\x25\x56\xed\x7a\xd2\x14"
+ "\xdb\x4e\x27\xd4\x1f\xf8\x94\xa7\xef\x07\xce\xdb\x24\xb7\xdd\x71\x5c\x63"
+ "\xc9\x33\xfe\xde\x40\x52\xeb\x02\x55\x58\x0c\x35\x4f\x7c\xee\x37\x78\x48"
+ "\x48\x33\xa5\x3f\xfe\x15\x24\x0f\x41\x6e\x0e\x87\x31\x2b\x81\x11\x8b\x3c"
+ "\x9d\x05\x8a\x29\x22\x00\xaa\xd8\x83\x1d\xef\x62\xec\x6e\xe4\x94\x83\xcf"
+ "\xd7\x68\xaf\xd3\xa8\xed\xd8\xfe\xd8\xc3\x8f\x48\xfc\x8c\x0d\xe7\x89\x6f"
+ "\xe2\xbf\xfb\x0d\xc5\x4a\x05\x34\x92\x18\x7a\x93\xa0\xe8\x42\x86\x22\xa9"
+ "\xe9\x80\x37\x47\x02\x55\x60\x76\xab\xde\x2b\xf5\xa2\x2c\xaa\x0c\x99\x81"
+ "\xee\x72\x2c\x7d\x22\x59\x2a\x35\xea\x50\x4e\x47\x6b\x92\x2d\x30\xa1\x01"
+ "\xa5\x9e\x26\x6e\x27\xca\xf5\xf2\x87\x5d\x31\xaf\xe9\x32\xcd\x10\xfd\x4d"
+ "\xdb\xf9\x86\x05\x12\x1b\x01\x84\x55\x97\x5f\xe2\x78\x27\xd9\xe4\x26\x7d"
+ "\xab\x0e\xe0\x1b\x6f\xcb\x4b\x14\xdd\xdc\xdc\x8b\xe8\x9f\xd0\x62\x96\xca"
+ "\xcf";
+
+static const uint8_t kThreePrimeEncryptedMessage[] = {
+ 0x58, 0xd9, 0xea, 0x8a, 0xf6, 0x3d, 0xb4, 0xd9, 0xf7, 0xbb, 0x02, 0xc5,
+ 0x58, 0xd2, 0xa9, 0x46, 0x80, 0x70, 0x70, 0x16, 0x07, 0x64, 0x32, 0x4c,
+ 0x4e, 0x92, 0x61, 0xb7, 0xff, 0x92, 0xdc, 0xfc, 0xf8, 0xf0, 0x2c, 0x84,
+ 0x56, 0xbc, 0xe5, 0x93, 0x76, 0xe5, 0xa3, 0x72, 0x98, 0xf2, 0xdf, 0xef,
+ 0x99, 0x53, 0xf6, 0xd8, 0x4b, 0x09, 0xac, 0xa9, 0xa3, 0xdb, 0x63, 0xa1,
+ 0xb5, 0x09, 0x8e, 0x40, 0x84, 0x8f, 0x4d, 0xd5, 0x1d, 0xac, 0x6c, 0xaa,
+ 0x6b, 0x15, 0xe7, 0xb1, 0x0c, 0x67, 0xd2, 0xb2, 0x81, 0x58, 0x30, 0x0e,
+ 0x18, 0x27, 0xa1, 0x9b, 0x96, 0xad, 0xae, 0x76, 0x1a, 0x32, 0xf7, 0x10,
+ 0x0b, 0x53, 0x85, 0x31, 0xd6, 0x2a, 0xf6, 0x1c, 0x9f, 0xc2, 0xc7, 0xb1,
+ 0x05, 0x63, 0x0b, 0xa5, 0x07, 0x1f, 0x1c, 0x01, 0xf0, 0xe0, 0x06, 0xea,
+ 0x20, 0x69, 0x41, 0x19, 0x57, 0x92, 0x17, 0xf7, 0x0c, 0x5c, 0x66, 0x75,
+ 0x0e, 0xe5, 0xb3, 0xf1, 0x67, 0x3b, 0x27, 0x47, 0xb2, 0x8e, 0x1c, 0xb6,
+ 0x3f, 0xdd, 0x76, 0x42, 0x31, 0x13, 0x68, 0x96, 0xdf, 0x3b, 0xd4, 0x87,
+ 0xd9, 0x16, 0x44, 0x71, 0x52, 0x2e, 0x54, 0x3e, 0x09, 0xcd, 0x71, 0xc1,
+ 0x1e, 0x5e, 0x96, 0x13, 0xc9, 0x1e, 0xa4, 0xe6, 0xe6, 0x97, 0x2c, 0x6b,
+ 0xf2, 0xa9, 0x5c, 0xc6, 0x60, 0x2a, 0xbc, 0x82, 0xf8, 0xcb, 0xd4, 0xd7,
+ 0xea, 0x8a, 0xa1, 0x8a, 0xd9, 0xa5, 0x14, 0x8b, 0x9e, 0xf9, 0x25, 0x02,
+ 0xd2, 0xab, 0x0c, 0x42, 0xca, 0x2d, 0x45, 0xa3, 0x56, 0x5e, 0xa2, 0x2a,
+ 0xc8, 0x60, 0xa5, 0x87, 0x5d, 0x85, 0x5c, 0xde, 0xc7, 0xa2, 0x47, 0xc3,
+ 0x99, 0x29, 0x23, 0x79, 0x36, 0x88, 0xad, 0x40, 0x3e, 0x27, 0x7d, 0xf0,
+ 0xb6, 0xfa, 0x95, 0x20, 0x3c, 0xec, 0xfc, 0x56, 0x3b, 0x20, 0x91, 0xee,
+ 0x98, 0x10, 0x2c, 0x82,
+};
+
+static const uint8_t kSixPrimeKey[] =
+ "\x30\x82\x05\x20\x02\x01\x01\x02\x82\x01\x00\x1c\x04\x39\x44\xb9\xb8\x71"
+ "\x1c\x1c\xf7\xdc\x11\x1b\x85\x3b\x2b\xe8\xa6\xeb\xeb\xe9\xb6\x86\x97\x73"
+ "\x5d\x75\x46\xd1\x35\x25\xf8\x30\x9a\xc3\x57\x44\x89\xa6\x44\x59\xe3\x3a"
+ "\x60\xb5\x33\x84\x72\xa4\x03\xc5\x1a\x20\x98\x70\xbd\xe8\x3b\xc1\x9b\x8a"
+ "\x3a\x24\x45\xb6\x6a\x73\xb4\xd0\x6c\x18\xc6\xa7\x94\xd3\x24\x70\xf0\x2d"
+ "\x0c\xa5\xb2\x3b\xc5\x33\x90\x9d\x56\x8d\x33\xf6\x93\x7d\xa7\x95\x88\x05"
+ "\xdf\xf5\x65\x58\xb9\x5b\xd3\x07\x9c\x16\x8e\x74\xfc\xb8\x76\xaf\x62\x99"
+ "\x6c\xd4\xc5\xb3\x69\xe5\x64\xdf\x38\x00\x25\x24\xe9\xb1\x4a\x85\xa6\xf4"
+ "\xb6\x23\x68\x67\x4a\x2c\xbd\x9d\x01\x3b\x04\x8c\x70\x94\x82\x76\x45\x0c"
+ "\x8b\x95\x8a\x07\x1c\x32\xe7\x09\x97\x3a\xfd\xca\x57\xe9\x57\x0c\xae\x2b"
+ "\xa3\x25\xd1\xf2\x0d\x34\xa1\xe6\x2f\x7b\x1b\x36\x53\x83\x95\xb9\x26\x6e"
+ "\x4f\x36\x26\xf8\x47\xae\xdf\xe8\x4d\xf6\xb2\xff\x03\x23\x74\xfa\xa5\x6d"
+ "\xcb\xcb\x80\x12\xc3\x77\xf0\x19\xb7\xf2\x6b\x19\x5c\xde\x0a\xd7\xee\x8c"
+ "\x48\x2f\x50\x24\xa5\x2e\xcc\x2a\xed\xc2\x35\xe0\x3d\x29\x31\x17\xd6\x8f"
+ "\x44\xaa\x5b\x33\xbd\xb4\x88\x87\xd9\x29\x3f\x94\xe7\x75\xe3\x02\x01\x03"
+ "\x02\x82\x01\x00\x12\xad\x7b\x83\x26\x7a\xf6\x12\xbd\xfa\x92\xb6\x12\x58"
+ "\xd2\x1d\x45\xc4\x9d\x47\xf1\x24\x59\xba\x4c\xe8\xf8\xd9\xe0\xce\x19\x50"
+ "\x20\x67\x2c\xe4\xd8\x5b\xc4\x2d\x91\x41\xeb\x05\x4f\xf4\xb4\x20\xc7\xbc"
+ "\xd6\xe2\x5c\xa0\x27\xcf\xb8\xb3\x3b\x5c\xeb\x5e\x96\xb7\x99\x4b\x8a\xc3"
+ "\x70\xaf\x7f\xd8\x5f\xeb\xcb\x1a\x79\x44\x68\x97\x84\xd8\x29\x87\x64\xba"
+ "\x18\x2e\x95\x66\x1a\x7d\xd9\x35\x3a\x5c\x92\x7a\x81\x1b\x6c\xa9\xf8\xfa"
+ "\x05\x23\x18\x5b\xb2\xf8\x77\x1c\xc5\x1b\x7d\x26\x5f\x48\x69\x1b\xc4\x34"
+ "\xef\x6e\xa1\x15\xd2\xb2\xac\xb8\xa8\xed\x1e\xee\xdc\xb5\xb9\x5c\x79\x25"
+ "\x48\xbb\xe5\x9d\xd8\xe5\xe2\x94\xdf\xd5\x32\x22\x84\xbf\xc2\xaa\xa4\x54"
+ "\xbb\x29\xdb\x13\x4a\x28\x3d\x83\x3a\xff\xa3\xae\x38\x08\xfc\x36\x84\x91"
+ "\x30\xd1\xfd\x82\x64\xf1\x0f\xae\xba\xd7\x9a\x43\x58\x03\x5e\x5f\x01\xcb"
+ "\x8b\x90\x8d\x77\x34\x6f\x37\x40\xb6\x6d\x22\x23\x90\xb2\xfd\x32\xb5\x96"
+ "\x45\xbf\xae\x8c\xc4\x62\x03\x6c\x68\x90\x59\x31\x1a\xcb\xfb\xa4\x0b\x94"
+ "\x15\x13\xda\x1a\x8d\xa7\x0b\x34\x62\x93\xea\xbe\x6e\x71\xc2\x1d\xc8\x9d"
+ "\xac\x66\xcc\x31\x87\xff\x99\xab\x02\x2c\x00\xa5\x57\x41\x66\x87\x68\x02"
+ "\x6a\xdf\x97\xb0\xfe\x6b\x34\xc4\x33\x88\x2b\xce\x82\xaf\x2d\x33\x5a\xad"
+ "\x75\x2d\xac\xa5\xd6\x3a\x2d\x65\x43\x68\xfb\x44\x9e\xb8\x25\x05\xed\x97"
+ "\x02\x2c\x00\xd2\x77\x34\x24\xac\x60\x9a\xc4\x68\x34\xe5\x6a\xa3\xdc\xe2"
+ "\xb0\x58\x5c\x35\x83\x5a\xc7\xa7\xc1\x0b\x7e\x9e\xa5\x85\x32\x47\x93\x22"
+ "\xee\xb6\x59\xe9\xe3\x61\x94\xd0\x0e\xcb\x02\x2b\x6e\x3a\x2b\x99\xaf\x9a"
+ "\xac\x47\x3f\xba\x75\xfe\xf2\x23\x2d\x77\xb0\x1d\x34\x57\x1f\x73\x77\x91"
+ "\xc8\xf8\xc9\x1d\xc3\xe4\x26\xc8\xee\x2c\xf0\xa7\x83\x14\x7a\xc3\x59\x49"
+ "\x0f\x02\x2c\x00\x8c\x4f\x78\x18\x72\xeb\x11\xd8\x45\x78\x98\xf1\xc2\x93"
+ "\x41\xca\xe5\x92\xce\x57\x91\xda\x6f\xd6\x07\xa9\xbf\x19\x03\x76\xda\x62"
+ "\x17\x49\xce\xe6\x9b\xec\xeb\xb8\x8a\xb4\x87\x02\x2c\x00\xa3\xc2\x29\xa6"
+ "\xa7\xe1\x3c\xe9\xcf\x0f\x50\x51\x1c\xcc\xc8\x5b\x08\x9c\x97\x24\x3a\x86"
+ "\x23\xa8\x0b\xbb\x54\xa6\xb9\x70\x3d\x1d\xd0\x1b\xa3\xac\xd9\xb2\x03\x80"
+ "\xd7\x67\xec\x30\x82\x02\x29\x30\x81\x88\x02\x2c\x00\x97\x5d\x3b\xf2\xcc"
+ "\xba\xd9\x77\x67\xaa\xd2\x22\xa7\xa3\x49\x08\xc7\xb8\x27\xa1\x59\x4b\xa7"
+ "\xa5\xd2\x74\x05\xe7\x5a\x35\xd7\x25\x79\x18\x20\x8a\x25\xec\x3b\x52\xaf"
+ "\xcb\xdb\x02\x2b\x64\xe8\xd2\xa1\xdd\xd1\xe6\x4f\x9a\x71\xe1\x6c\x6f\xc2"
+ "\x30\xb0\x85\x25\x6f\xc0\xe6\x32\x6f\xc3\xe1\xa2\xae\x9a\x3c\x23\xe4\xc3"
+ "\xa6\x10\x15\xb1\x6e\x9d\x7c\xe1\xca\x87\xe7\x02\x2b\x5e\xef\x25\x29\xed"
+ "\xf6\x52\x15\xd3\x60\xb6\x88\xcf\x0f\xe2\x24\xa4\x04\x97\x9c\x9d\x58\x13"
+ "\xbb\x00\x6d\x39\xf6\xad\x21\x7e\x56\x2c\x2e\x06\x06\xc4\x6d\x44\xac\x79"
+ "\x1f\xe5\x30\x81\x89\x02\x2c\x00\xdb\xf1\x78\xf9\xa4\x94\xea\x39\x8a\x3f"
+ "\x23\x48\x2a\x23\x8f\xd2\x18\x97\xd2\xdf\x0f\xb8\x2b\x33\xa0\xe8\x8f\xbc"
+ "\x4e\x42\xfd\x54\xc7\x0f\xde\xba\x6d\xba\x96\xa7\xce\x67\x3d\x02\x2c\x00"
+ "\x92\xa0\xfb\x51\x18\x63\x46\xd1\x06\xd4\xc2\x30\x1c\x17\xb5\x36\xbb\x0f"
+ "\xe1\xea\x0a\x7a\xc7\x77\xc0\x9b\x0a\x7d\x89\x81\xfe\x38\x84\xb5\x3f\x26"
+ "\xf3\xd1\xb9\xc5\x34\x44\xd3\x02\x2b\x4c\xbd\x1d\x44\xc8\x19\x23\xd8\xb3"
+ "\x96\x66\x4b\x62\xcb\x3e\xe6\x6c\x11\xdf\xb2\x92\xd3\xc8\x34\xb9\xa6\x5a"
+ "\x2f\x19\xf4\x0b\xb2\xe6\x8e\xa6\xaf\xa3\xae\xa4\xb3\x92\xc4\x79\x30\x81"
+ "\x85\x02\x2b\x00\x89\xab\x30\xfc\x7b\x37\x94\x11\x9f\x4d\x31\x3b\xac\x09"
+ "\x57\xe6\x64\xec\xa0\xc8\xf8\x04\x1a\xf9\x2a\xa4\x4b\x36\x18\xbb\x5f\xdc"
+ "\xcd\xf0\xc8\xcb\x97\xd1\xdf\x13\x12\x3f\x02\x2a\x5b\xc7\x75\xfd\xa7\x7a"
+ "\x62\xb6\x6a\x33\x76\x27\xc8\x06\x3a\x99\x98\x9d\xc0\x85\xfa\xad\x67\x50"
+ "\xc7\x18\x32\x24\x10\x7c\xea\x93\x33\xf5\xdb\x32\x65\x36\x94\xb7\x61\x7f"
+ "\x02\x2a\x16\x6c\x96\xa1\x50\x6f\x3a\x92\xc0\x75\x43\xb5\x6b\x9c\x17\x09"
+ "\xd3\xf0\x67\x69\x45\x92\xfb\x7b\x50\xa8\x42\x9b\x33\x92\xab\xd5\xe6\x49"
+ "\xb3\x26\x99\x55\x16\x3a\x39\x63\x30\x81\x87\x02\x2b\x00\xc1\x25\x19\x1d"
+ "\x6e\x18\xcb\x2d\x64\xe2\xe6\xb6\x1c\xe4\xaa\x9c\xb9\xee\x18\xd4\xf7\x5f"
+ "\x66\x40\xf0\xe1\x31\x38\xf2\x53\x00\x8b\xcc\xe4\x0d\xb7\x81\xb4\xe6\x1c"
+ "\x19\xaf\x02\x2b\x00\x80\xc3\x66\x13\x9e\xbb\x32\x1e\x43\x41\xef\x24\x13"
+ "\x43\x1c\x68\x7b\xf4\x10\x8d\xfa\x3f\x99\x80\xa0\x96\x20\xd0\xa1\x8c\xab"
+ "\x07\xdd\xed\x5e\x7a\x56\x78\x99\x68\x11\x1f\x02\x2b\x00\xb0\x59\xea\x67"
+ "\x93\x42\xbf\x07\x54\x38\x41\xcb\x73\xa4\x0e\xc2\xae\x56\x19\x41\xc9\x8a"
+ "\xb2\x2f\xa8\x0a\xb1\x4e\x12\x39\x2e\xc0\x94\x9a\xc6\xa3\xe4\xaf\x8a\x16"
+ "\x06\xb8";
+
+static const uint8_t kSixPrimeEncryptedMessage[] = {
+ 0x0a, 0xcb, 0x6c, 0x02, 0x9d, 0x1a, 0x7c, 0xf3, 0x4e, 0xff, 0x16, 0x88,
+ 0xee, 0x22, 0x1d, 0x8d, 0xd2, 0xfd, 0xde, 0x83, 0xb3, 0xd9, 0x35, 0x2c,
+ 0x82, 0xe0, 0xff, 0xe6, 0x79, 0x6d, 0x06, 0x21, 0x74, 0xa8, 0x04, 0x0c,
+ 0xe2, 0xd3, 0x98, 0x3f, 0xbf, 0xd0, 0xe9, 0x88, 0x24, 0xe2, 0x05, 0xa4,
+ 0x45, 0x51, 0x87, 0x6b, 0x1c, 0xef, 0x5f, 0x2d, 0x61, 0xb6, 0xf1, 0x4c,
+ 0x1f, 0x3d, 0xbf, 0x4b, 0xf2, 0xda, 0x09, 0x97, 0x81, 0xde, 0x91, 0xb7,
+ 0x0d, 0xb4, 0xc2, 0xab, 0x41, 0x64, 0x9d, 0xd9, 0x39, 0x46, 0x79, 0x66,
+ 0x43, 0xf1, 0x34, 0x21, 0x56, 0x2f, 0xc6, 0x68, 0x40, 0x4a, 0x2d, 0x73,
+ 0x96, 0x50, 0xe1, 0xb0, 0xaf, 0x49, 0x39, 0xb4, 0xf0, 0x3a, 0x78, 0x38,
+ 0x70, 0xa9, 0x91, 0x5d, 0x5e, 0x07, 0xf4, 0xec, 0xbb, 0xc4, 0xe5, 0x8a,
+ 0xb8, 0x06, 0xba, 0xdf, 0xc6, 0x48, 0x78, 0x4b, 0xca, 0x2a, 0x8a, 0x92,
+ 0x64, 0xe3, 0xa6, 0xae, 0x87, 0x97, 0x12, 0x16, 0x46, 0x67, 0x59, 0xdf,
+ 0xf2, 0xf3, 0x89, 0x6f, 0xe8, 0xa9, 0x13, 0x57, 0x63, 0x4e, 0x07, 0x98,
+ 0xcc, 0x73, 0xa0, 0x84, 0x9d, 0xe8, 0xb3, 0x50, 0x59, 0xb5, 0x51, 0xb3,
+ 0x41, 0x7d, 0x55, 0xfe, 0xd9, 0xf0, 0xc6, 0xff, 0x6e, 0x96, 0x4f, 0x22,
+ 0xb2, 0x0d, 0x6b, 0xc9, 0x83, 0x2d, 0x98, 0x98, 0xb2, 0xd1, 0xb7, 0xe4,
+ 0x50, 0x83, 0x1a, 0xa9, 0x02, 0x9f, 0xaf, 0x54, 0x74, 0x2a, 0x2c, 0x63,
+ 0x10, 0x79, 0x45, 0x5c, 0x95, 0x0d, 0xa1, 0x9b, 0x55, 0xf3, 0x1e, 0xb7,
+ 0x56, 0x59, 0xf1, 0x59, 0x8d, 0xd6, 0x15, 0x89, 0xf6, 0xfe, 0xc0, 0x00,
+ 0xdd, 0x1f, 0x2b, 0xf0, 0xf7, 0x5d, 0x64, 0x84, 0x76, 0xd3, 0xc2, 0x92,
+ 0x35, 0xac, 0xb5, 0xf9, 0xf6, 0xa8, 0x05, 0x89, 0x4c, 0x95, 0x41, 0x4e,
+ 0x34, 0x25, 0x11, 0x14,
+};
+
+// kEstonianRSAKey is an RSAPublicKey encoded with a negative modulus. See
+// https://crbug.com/532048.
+static const uint8_t kEstonianRSAKey[] = {
+ 0x30, 0x82, 0x01, 0x09, 0x02, 0x82, 0x01, 0x00, 0x96, 0xa6, 0x2e, 0x9c,
+ 0x4e, 0x6a, 0xc3, 0xcc, 0xcd, 0x8f, 0x70, 0xc3, 0x55, 0xbf, 0x5e, 0x9c,
+ 0xd4, 0xf3, 0x17, 0xc3, 0x97, 0x70, 0xae, 0xdf, 0x12, 0x5c, 0x15, 0x80,
+ 0x03, 0xef, 0x2b, 0x18, 0x9d, 0x6a, 0xcb, 0x52, 0x22, 0xc1, 0x81, 0xb8,
+ 0x7e, 0x61, 0xe8, 0x0f, 0x79, 0x24, 0x0f, 0x82, 0x70, 0x24, 0x4e, 0x29,
+ 0x20, 0x05, 0x54, 0xeb, 0xd4, 0xa9, 0x65, 0x59, 0xb6, 0x3c, 0x75, 0x95,
+ 0x2f, 0x4c, 0xf6, 0x9d, 0xd1, 0xaf, 0x5f, 0x14, 0x14, 0xe7, 0x25, 0xea,
+ 0xa5, 0x47, 0x5d, 0xc6, 0x3e, 0x28, 0x8d, 0xdc, 0x54, 0x87, 0x2a, 0x7c,
+ 0x10, 0xe9, 0xc6, 0x76, 0x2d, 0xe7, 0x79, 0xd8, 0x0e, 0xbb, 0xa9, 0xac,
+ 0xb5, 0x18, 0x98, 0xd6, 0x47, 0x6e, 0x06, 0x70, 0xbf, 0x9e, 0x82, 0x25,
+ 0x95, 0x4e, 0xfd, 0x70, 0xd7, 0x73, 0x45, 0x2e, 0xc1, 0x1f, 0x7a, 0x9a,
+ 0x9d, 0x60, 0xc0, 0x1f, 0x67, 0x06, 0x2a, 0x4e, 0x87, 0x3f, 0x19, 0x88,
+ 0x69, 0x64, 0x4d, 0x9f, 0x75, 0xf5, 0xd3, 0x1a, 0x41, 0x3d, 0x35, 0x17,
+ 0xb6, 0xd1, 0x44, 0x0d, 0x25, 0x8b, 0xe7, 0x94, 0x39, 0xb0, 0x7c, 0xaf,
+ 0x3e, 0x6a, 0xfa, 0x8d, 0x90, 0x21, 0x0f, 0x8a, 0x43, 0x94, 0x37, 0x7c,
+ 0x2a, 0x15, 0x4c, 0xa0, 0xfa, 0xa9, 0x2f, 0x21, 0xa6, 0x6f, 0x8e, 0x2f,
+ 0x89, 0xbc, 0xbb, 0x33, 0xf8, 0x31, 0xfc, 0xdf, 0xcd, 0x68, 0x9a, 0xbc,
+ 0x75, 0x06, 0x95, 0xf1, 0x3d, 0xef, 0xca, 0x76, 0x27, 0xd2, 0xba, 0x8e,
+ 0x0e, 0x1c, 0x43, 0xd7, 0x70, 0xb9, 0xc6, 0x15, 0xca, 0xd5, 0x4d, 0x87,
+ 0xb9, 0xd1, 0xae, 0xde, 0x69, 0x73, 0x00, 0x2a, 0x97, 0x51, 0x4b, 0x30,
+ 0x01, 0xc2, 0x85, 0xd0, 0x05, 0xcc, 0x2e, 0xe8, 0xc7, 0x42, 0xe7, 0x94,
+ 0x51, 0xe3, 0xf5, 0x19, 0x35, 0xdc, 0x57, 0x96, 0xe7, 0xd9, 0xb4, 0x49,
+ 0x02, 0x03, 0x01, 0x00, 0x01,
+};
+
+static bool TestRSA(const uint8_t *der, size_t der_len,
+ const uint8_t *oaep_ciphertext,
+ size_t oaep_ciphertext_len) {
+ ScopedRSA key(d2i_RSAPrivateKey(nullptr, &der, der_len));
+ if (!key) {
+ return false;
+ }
+
+ if (!RSA_check_key(key.get())) {
+ fprintf(stderr, "RSA_check_key failed\n");
+ return false;
+ }
+
+ uint8_t ciphertext[256];
+
+ int num = RSA_public_encrypt(kPlaintextLen, kPlaintext, ciphertext, key.get(),
+ RSA_PKCS1_PADDING);
+ if (num < 0 || (size_t)num != RSA_size(key.get())) {
+ fprintf(stderr, "PKCS#1 v1.5 encryption failed!\n");
+ return false;
+ }
+
+ uint8_t plaintext[256];
+ num = RSA_private_decrypt(num, ciphertext, plaintext, key.get(),
+ RSA_PKCS1_PADDING);
+ if (num < 0 ||
+ (size_t)num != kPlaintextLen || memcmp(plaintext, kPlaintext, num) != 0) {
+ fprintf(stderr, "PKCS#1 v1.5 decryption failed!\n");
+ return false;
+ }
+
+ num = RSA_public_encrypt(kPlaintextLen, kPlaintext, ciphertext, key.get(),
+ RSA_PKCS1_OAEP_PADDING);
+ if (num < 0 || (size_t)num != RSA_size(key.get())) {
+ fprintf(stderr, "OAEP encryption failed!\n");
+ return false;
+ }
+
+ num = RSA_private_decrypt(num, ciphertext, plaintext, key.get(),
+ RSA_PKCS1_OAEP_PADDING);
+ if (num < 0 ||
+ (size_t)num != kPlaintextLen || memcmp(plaintext, kPlaintext, num) != 0) {
+ fprintf(stderr, "OAEP decryption (encrypted data) failed!\n");
+ return false;
+ }
+
+ // |oaep_ciphertext| should decrypt to |kPlaintext|.
+ num = RSA_private_decrypt(oaep_ciphertext_len, oaep_ciphertext, plaintext,
+ key.get(), RSA_PKCS1_OAEP_PADDING);
+
+ if (num < 0 ||
+ (size_t)num != kPlaintextLen || memcmp(plaintext, kPlaintext, num) != 0) {
+ fprintf(stderr, "OAEP decryption (test vector data) failed!\n");
+ return false;
+ }
+
+ // Try decrypting corrupted ciphertexts.
+ memcpy(ciphertext, oaep_ciphertext, oaep_ciphertext_len);
+ for (size_t i = 0; i < oaep_ciphertext_len; i++) {
+ uint8_t saved = ciphertext[i];
+ for (unsigned b = 0; b < 256; b++) {
+ if (b == saved) {
+ continue;
+ }
+ ciphertext[i] = b;
+ num = RSA_private_decrypt(num, ciphertext, plaintext, key.get(),
+ RSA_PKCS1_OAEP_PADDING);
+ if (num > 0) {
+ fprintf(stderr, "Corrupt data decrypted!\n");
+ return false;
+ }
+ }
+ ciphertext[i] = saved;
+ }
+
+ return true;
+}
+
+static bool TestMultiPrimeKey(int nprimes, const uint8_t *der, size_t der_size,
+ const uint8_t *enc, size_t enc_size) {
+ ScopedRSA rsa(d2i_RSAPrivateKey(nullptr, &der, der_size));
+ if (!rsa) {
+ fprintf(stderr, "%d-prime key failed to parse.\n", nprimes);
+ ERR_print_errors_fp(stderr);
+ return false;
+ }
+
+ if (!RSA_check_key(rsa.get())) {
+ fprintf(stderr, "RSA_check_key failed for %d-prime key.\n", nprimes);
+ ERR_print_errors_fp(stderr);
+ return false;
+ }
+
+ uint8_t out[256];
+ size_t out_len;
+ if (!RSA_decrypt(rsa.get(), &out_len, out, sizeof(out), enc, enc_size,
+ RSA_PKCS1_PADDING) ||
+ out_len != 11 ||
+ memcmp(out, "hello world", 11) != 0) {
+ fprintf(stderr, "%d-prime key failed to decrypt.\n", nprimes);
+ ERR_print_errors_fp(stderr);
+ return false;
+ }
+
+ return true;
+}
+
+static bool TestMultiPrimeKeygen() {
+ static const char kMessage[] = "Hello world.";
+ static const size_t kBits = 1024;
+ uint8_t encrypted[kBits / 8], decrypted[kBits / 8];
+ size_t encrypted_len, decrypted_len;
+
+ ScopedRSA rsa(RSA_new());
+ ScopedBIGNUM e(BN_new());
+ if (!rsa || !e ||
+ !BN_set_word(e.get(), RSA_F4) ||
+ !RSA_generate_multi_prime_key(rsa.get(), kBits, 3, e.get(), nullptr) ||
+ !RSA_check_key(rsa.get()) ||
+ !RSA_encrypt(rsa.get(), &encrypted_len, encrypted, sizeof(encrypted),
+ (const uint8_t *)kMessage, sizeof(kMessage),
+ RSA_PKCS1_PADDING) ||
+ !RSA_decrypt(rsa.get(), &decrypted_len, decrypted, sizeof(decrypted),
+ encrypted, encrypted_len, RSA_PKCS1_PADDING) ||
+ decrypted_len != sizeof(kMessage) ||
+ memcmp(decrypted, kMessage, sizeof(kMessage)) != 0) {
+ ERR_print_errors_fp(stderr);
+ return false;
+ }
+
+ return true;
+}
+
+static bool TestBadKey() {
+ ScopedRSA key(RSA_new());
+ ScopedBIGNUM e(BN_new());
+
+ if (!key || !e || !BN_set_word(e.get(), RSA_F4)) {
+ return false;
+ }
+
+ if (!RSA_generate_key_ex(key.get(), 512, e.get(), nullptr)) {
+ fprintf(stderr, "RSA_generate_key_ex failed.\n");
+ ERR_print_errors_fp(stderr);
+ return false;
+ }
+
+ if (!BN_add(key->p, key->p, BN_value_one())) {
+ fprintf(stderr, "BN error.\n");
+ ERR_print_errors_fp(stderr);
+ return false;
+ }
+
+ if (RSA_check_key(key.get())) {
+ fprintf(stderr, "RSA_check_key passed with invalid key!\n");
+ return false;
+ }
+
+ ERR_clear_error();
+ return true;
+}
+
+static bool TestOnlyDGiven() {
+ uint8_t buf[64];
+ unsigned buf_len = sizeof(buf);
+ ScopedRSA key(RSA_new());
+ if (!key ||
+ !BN_hex2bn(&key->n,
+ "00e77bbf3889d4ef36a9a25d4d69f3f632eb4362214c74517da6d6aeaa9bd"
+ "09ac42b26621cd88f3a6eb013772fc3bf9f83914b6467231c630202c35b3e"
+ "5808c659") ||
+ !BN_hex2bn(&key->e, "010001") ||
+ !BN_hex2bn(&key->d,
+ "0365db9eb6d73b53b015c40cd8db4de7dd7035c68b5ac1bf786d7a4ee2cea"
+ "316eaeca21a73ac365e58713195f2ae9849348525ca855386b6d028e437a9"
+ "495a01") ||
+ RSA_size(key.get()) > sizeof(buf)) {
+ return false;
+ }
+
+ if (!RSA_check_key(key.get())) {
+ fprintf(stderr, "RSA_check_key failed with only d given.\n");
+ ERR_print_errors_fp(stderr);
+ return false;
+ }
+
+ const uint8_t kDummyHash[16] = {0};
+
+ if (!RSA_sign(NID_sha256, kDummyHash, sizeof(kDummyHash), buf, &buf_len,
+ key.get())) {
+ fprintf(stderr, "RSA_sign failed with only d given.\n");
+ ERR_print_errors_fp(stderr);
+ return false;
+ }
+
+ if (!RSA_verify(NID_sha256, kDummyHash, sizeof(kDummyHash), buf, buf_len,
+ key.get())) {
+ fprintf(stderr, "RSA_verify failed with only d given.\n");
+ ERR_print_errors_fp(stderr);
+ return false;
+ }
+
+ return true;
+}
+
+static bool TestRecoverCRTParams() {
+ ScopedBIGNUM e(BN_new());
+ if (!e || !BN_set_word(e.get(), RSA_F4)) {
+ return false;
+ }
+
+ ERR_clear_error();
+
+ for (unsigned i = 0; i < 1; i++) {
+ ScopedRSA key1(RSA_new());
+ if (!key1 ||
+ !RSA_generate_key_ex(key1.get(), 512, e.get(), nullptr)) {
+ fprintf(stderr, "RSA_generate_key_ex failed.\n");
+ ERR_print_errors_fp(stderr);
+ return false;
+ }
+
+ if (!RSA_check_key(key1.get())) {
+ fprintf(stderr, "RSA_check_key failed with original key.\n");
+ ERR_print_errors_fp(stderr);
+ return false;
+ }
+
+ ScopedRSA key2(RSA_new());
+ if (!key2) {
+ return false;
+ }
+ key2->n = BN_dup(key1->n);
+ key2->e = BN_dup(key1->e);
+ key2->d = BN_dup(key1->d);
+ if (key2->n == nullptr || key2->e == nullptr || key2->d == nullptr) {
+ return false;
+ }
+
+ if (!RSA_recover_crt_params(key2.get())) {
+ fprintf(stderr, "RSA_recover_crt_params failed.\n");
+ ERR_print_errors_fp(stderr);
+ return false;
+ }
+
+ uint8_t buf[128];
+ unsigned buf_len = sizeof(buf);
+ if (RSA_size(key2.get()) > buf_len) {
+ return false;
+ }
+
+ if (!RSA_check_key(key2.get())) {
+ fprintf(stderr, "RSA_check_key failed with recovered key.\n");
+ ERR_print_errors_fp(stderr);
+ return false;
+ }
+
+ const uint8_t kDummyHash[16] = {0};
+ if (!RSA_sign(NID_sha256, kDummyHash, sizeof(kDummyHash), buf, &buf_len,
+ key2.get())) {
+ fprintf(stderr, "RSA_sign failed with recovered key.\n");
+ ERR_print_errors_fp(stderr);
+ return false;
+ }
+
+ if (!RSA_verify(NID_sha256, kDummyHash, sizeof(kDummyHash), buf, buf_len,
+ key2.get())) {
+ fprintf(stderr, "RSA_verify failed with recovered key.\n");
+ ERR_print_errors_fp(stderr);
+ return false;
+ }
+ }
+
+ return true;
+}
+
+static bool TestASN1() {
+ // Test that private keys may be decoded.
+ ScopedRSA rsa(RSA_private_key_from_bytes(kKey1, sizeof(kKey1) - 1));
+ if (!rsa) {
+ return false;
+ }
+
+ // Test that the serialization round-trips.
+ uint8_t *der;
+ size_t der_len;
+ if (!RSA_private_key_to_bytes(&der, &der_len, rsa.get())) {
+ return false;
+ }
+ ScopedOpenSSLBytes delete_der(der);
+ if (der_len != sizeof(kKey1) - 1 || memcmp(der, kKey1, der_len) != 0) {
+ return false;
+ }
+
+ // Test that serializing public keys works.
+ if (!RSA_public_key_to_bytes(&der, &der_len, rsa.get())) {
+ return false;
+ }
+ delete_der.reset(der);
+
+ // Public keys may be parsed back out.
+ rsa.reset(RSA_public_key_from_bytes(der, der_len));
+ if (!rsa || rsa->p != NULL || rsa->q != NULL) {
+ return false;
+ }
+
+ // Serializing the result round-trips.
+ uint8_t *der2;
+ size_t der2_len;
+ if (!RSA_public_key_to_bytes(&der2, &der2_len, rsa.get())) {
+ return false;
+ }
+ ScopedOpenSSLBytes delete_der2(der2);
+ if (der_len != der2_len || memcmp(der, der2, der_len) != 0) {
+ return false;
+ }
+
+ // Public keys cannot be serialized as private keys.
+ if (RSA_private_key_to_bytes(&der, &der_len, rsa.get())) {
+ OPENSSL_free(der);
+ return false;
+ }
+ ERR_clear_error();
+
+ // Public keys with negative moduli are invalid.
+ rsa.reset(RSA_public_key_from_bytes(kEstonianRSAKey,
+ sizeof(kEstonianRSAKey)));
+ if (rsa) {
+ return false;
+ }
+ ERR_clear_error();
+
+ // But |RSA_parse_public_key_buggy| will accept it.
+ CBS cbs;
+ CBS_init(&cbs, kEstonianRSAKey, sizeof(kEstonianRSAKey));
+ rsa.reset(RSA_parse_public_key_buggy(&cbs));
+ if (!rsa || CBS_len(&cbs) != 0) {
+ return false;
+ }
+
+ return true;
+}
+
+int main(int argc, char *argv[]) {
+ CRYPTO_library_init();
+
+ if (!TestRSA(kKey1, sizeof(kKey1) - 1, kOAEPCiphertext1,
+ sizeof(kOAEPCiphertext1) - 1) ||
+ !TestRSA(kKey2, sizeof(kKey2) - 1, kOAEPCiphertext2,
+ sizeof(kOAEPCiphertext2) - 1) ||
+ !TestRSA(kKey3, sizeof(kKey3) - 1, kOAEPCiphertext3,
+ sizeof(kOAEPCiphertext3) - 1) ||
+ !TestOnlyDGiven() ||
+ !TestRecoverCRTParams() ||
+ !TestBadKey() ||
+ !TestMultiPrimeKey(2, kTwoPrimeKey, sizeof(kTwoPrimeKey) - 1,
+ kTwoPrimeEncryptedMessage,
+ sizeof(kTwoPrimeEncryptedMessage)) ||
+ !TestMultiPrimeKey(3, kThreePrimeKey, sizeof(kThreePrimeKey) - 1,
+ kThreePrimeEncryptedMessage,
+ sizeof(kThreePrimeEncryptedMessage)) ||
+ !TestMultiPrimeKey(6, kSixPrimeKey, sizeof(kSixPrimeKey) - 1,
+ kSixPrimeEncryptedMessage,
+ sizeof(kSixPrimeEncryptedMessage)) ||
+ !TestMultiPrimeKeygen() ||
+ !TestASN1()) {
+ return 1;
+ }
+
+ printf("PASS\n");
+ return 0;
+}
diff --git a/src/crypto/sha/CMakeLists.txt b/src/crypto/sha/CMakeLists.txt
index 5a10c85..ecff09b 100644
--- a/src/crypto/sha/CMakeLists.txt
+++ b/src/crypto/sha/CMakeLists.txt
@@ -1,4 +1,4 @@
-include_directories(. .. ../../include)
+include_directories(../../include)
if (${ARCH} STREQUAL "x86_64")
set(
diff --git a/src/crypto/sha/asm/sha1-586.pl b/src/crypto/sha/asm/sha1-586.pl
index 4895eb3..e0b5d83 100644
--- a/src/crypto/sha/asm/sha1-586.pl
+++ b/src/crypto/sha/asm/sha1-586.pl
@@ -66,9 +66,9 @@
# switch to AVX alone improves performance by as little as 4% in
# comparison to SSSE3 code path. But below result doesn't look like
# 4% improvement... Trouble is that Sandy Bridge decodes 'ro[rl]' as
-# pair of µ-ops, and it's the additional µ-ops, two per round, that
+# pair of µ-ops, and it's the additional µ-ops, two per round, that
# make it run slower than Core2 and Westmere. But 'sh[rl]d' is decoded
-# as single µ-op by Sandy Bridge and it's replacing 'ro[rl]' with
+# as single µ-op by Sandy Bridge and it's replacing 'ro[rl]' with
# equivalent 'sh[rl]d' that is responsible for the impressive 5.1
# cycles per processed byte. But 'sh[rl]d' is not something that used
# to be fast, nor does it appear to be fast in upcoming Bulldozer
diff --git a/src/crypto/sha/asm/sha1-armv4-large.pl b/src/crypto/sha/asm/sha1-armv4-large.pl
index a20d336..64e2ed6 100644
--- a/src/crypto/sha/asm/sha1-armv4-large.pl
+++ b/src/crypto/sha/asm/sha1-armv4-large.pl
@@ -178,7 +178,7 @@ ___
}
$code=<<___;
-#include "arm_arch.h"
+#include <openssl/arm_arch.h>
.text
.code 32
diff --git a/src/crypto/sha/asm/sha1-armv8.pl b/src/crypto/sha/asm/sha1-armv8.pl
index a8c08c2..1c4fe4a 100644
--- a/src/crypto/sha/asm/sha1-armv8.pl
+++ b/src/crypto/sha/asm/sha1-armv8.pl
@@ -162,7 +162,7 @@ ___
}
$code.=<<___;
-#include "arm_arch.h"
+#include <openssl/arm_arch.h>
.text
diff --git a/src/crypto/sha/asm/sha256-586.pl b/src/crypto/sha/asm/sha256-586.pl
index 6462e45..e907714 100644
--- a/src/crypto/sha/asm/sha256-586.pl
+++ b/src/crypto/sha/asm/sha256-586.pl
@@ -10,7 +10,7 @@
# SHA256 block transform for x86. September 2007.
#
# Performance improvement over compiler generated code varies from
-# 10% to 40% [see below]. Not very impressive on some µ-archs, but
+# 10% to 40% [see below]. Not very impressive on some µ-archs, but
# it's 5 times smaller and optimizies amount of writes.
#
# May 2012.
diff --git a/src/crypto/sha/asm/sha256-armv4.pl b/src/crypto/sha/asm/sha256-armv4.pl
index df71676..7e07147 100644
--- a/src/crypto/sha/asm/sha256-armv4.pl
+++ b/src/crypto/sha/asm/sha256-armv4.pl
@@ -168,7 +168,7 @@ ___
$code=<<___;
#ifndef __KERNEL__
-# include "arm_arch.h"
+# include <openssl/arm_arch.h>
#else
# define __ARM_ARCH__ __LINUX_ARM_ARCH__
# define __ARM_MAX_ARCH__ 7
diff --git a/src/crypto/sha/asm/sha512-586.pl b/src/crypto/sha/asm/sha512-586.pl
index e96ec00..2f6a202 100644
--- a/src/crypto/sha/asm/sha512-586.pl
+++ b/src/crypto/sha/asm/sha512-586.pl
@@ -37,7 +37,7 @@
#
# IALU code-path is optimized for elder Pentiums. On vanilla Pentium
# performance improvement over compiler generated code reaches ~60%,
-# while on PIII - ~35%. On newer µ-archs improvement varies from 15%
+# while on PIII - ~35%. On newer µ-archs improvement varies from 15%
# to 50%, but it's less important as they are expected to execute SSE2
# code-path, which is commonly ~2-3x faster [than compiler generated
# code]. SSE2 code-path is as fast as original sha512-sse2.pl, even
diff --git a/src/crypto/sha/asm/sha512-armv4.pl b/src/crypto/sha/asm/sha512-armv4.pl
index 2964a39..cd3662a 100644
--- a/src/crypto/sha/asm/sha512-armv4.pl
+++ b/src/crypto/sha/asm/sha512-armv4.pl
@@ -191,7 +191,7 @@ ___
}
$code=<<___;
#ifndef __KERNEL__
-# include "arm_arch.h"
+# include <openssl/arm_arch.h>
# define VFP_ABI_PUSH vstmdb sp!,{d8-d15}
# define VFP_ABI_POP vldmia sp!,{d8-d15}
#else
diff --git a/src/crypto/sha/asm/sha512-armv8.pl b/src/crypto/sha/asm/sha512-armv8.pl
index 43e7293..40eb17a 100644
--- a/src/crypto/sha/asm/sha512-armv8.pl
+++ b/src/crypto/sha/asm/sha512-armv8.pl
@@ -164,7 +164,7 @@ ___
}
$code.=<<___;
-#include "arm_arch.h"
+#include <openssl/arm_arch.h>
.text
diff --git a/src/crypto/stack/CMakeLists.txt b/src/crypto/stack/CMakeLists.txt
index bdb0599..dcd8ef4 100644
--- a/src/crypto/stack/CMakeLists.txt
+++ b/src/crypto/stack/CMakeLists.txt
@@ -1,4 +1,4 @@
-include_directories(. .. ../../include)
+include_directories(../../include)
add_library(
stack
diff --git a/src/crypto/test/CMakeLists.txt b/src/crypto/test/CMakeLists.txt
index 84a6174..8c75314 100644
--- a/src/crypto/test/CMakeLists.txt
+++ b/src/crypto/test/CMakeLists.txt
@@ -5,4 +5,5 @@ add_library(
file_test.cc
malloc.cc
+ test_util.cc
)
diff --git a/src/crypto/test/file_test.cc b/src/crypto/test/file_test.cc
index 8df6f9a..6723350 100644
--- a/src/crypto/test/file_test.cc
+++ b/src/crypto/test/file_test.cc
@@ -128,6 +128,7 @@ FileTest::ReadResult FileTest::ReadNext() {
const char *delimiter = FindDelimiter(buf);
if (delimiter == nullptr) {
fprintf(stderr, "Line %u: Could not parse attribute.\n", line_);
+ return kReadError;
}
std::string key = StripSpace(buf, delimiter - buf);
std::string value = StripSpace(delimiter + 1,
diff --git a/src/crypto/test/file_test.h b/src/crypto/test/file_test.h
index 7303d8a..24651ab 100644
--- a/src/crypto/test/file_test.h
+++ b/src/crypto/test/file_test.h
@@ -18,11 +18,19 @@
#include <stdint.h>
#include <stdio.h>
+#if defined(_MSC_VER)
+#pragma warning(push)
+#pragma warning(disable: 4702)
+#endif
+
#include <string>
#include <map>
#include <set>
#include <vector>
+#if defined(_MSC_VER)
+#pragma warning(pop)
+#endif
// File-based test framework.
//
diff --git a/src/crypto/test/malloc.cc b/src/crypto/test/malloc.cc
index 9ffdf01..898f2a7 100644
--- a/src/crypto/test/malloc.cc
+++ b/src/crypto/test/malloc.cc
@@ -34,6 +34,8 @@
#if defined(__linux__) && defined(OPENSSL_GLIBC) && !defined(OPENSSL_ARM) && \
!defined(OPENSSL_AARCH64) && !defined(OPENSSL_ASAN)
+#include <errno.h>
+#include <signal.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
@@ -45,14 +47,14 @@
/* This file defines overrides for the standard allocation functions that allow
* a given allocation to be made to fail for testing. If the program is run
* with MALLOC_NUMBER_TO_FAIL set to a base-10 number then that allocation will
- * return NULL. If MALLOC_ABORT_ON_FAIL is also defined then the allocation
- * will abort() rather than return NULL.
+ * return NULL. If MALLOC_BREAK_ON_FAIL is also defined then the allocation
+ * will signal SIGTRAP rather than return NULL.
*
* This code is not thread safe. */
static uint64_t current_malloc_count = 0;
static uint64_t malloc_number_to_fail = 0;
-static char failure_enabled = 0, abort_on_fail = 0;
+static char failure_enabled = 0, break_on_fail = 0;
static int in_call = 0;
extern "C" {
@@ -95,7 +97,7 @@ static int should_fail_allocation() {
std::set_new_handler(cpp_new_handler);
}
}
- abort_on_fail = (NULL != getenv("MALLOC_ABORT_ON_FAIL"));
+ break_on_fail = (NULL != getenv("MALLOC_BREAK_ON_FAIL"));
init = 1;
}
@@ -108,8 +110,8 @@ static int should_fail_allocation() {
should_fail = (current_malloc_count == malloc_number_to_fail);
current_malloc_count++;
- if (should_fail && abort_on_fail) {
- abort();
+ if (should_fail && break_on_fail) {
+ raise(SIGTRAP);
}
return should_fail;
}
@@ -118,6 +120,7 @@ extern "C" {
void *malloc(size_t size) {
if (should_fail_allocation()) {
+ errno = ENOMEM;
return NULL;
}
@@ -126,6 +129,7 @@ void *malloc(size_t size) {
void *calloc(size_t num_elems, size_t size) {
if (should_fail_allocation()) {
+ errno = ENOMEM;
return NULL;
}
@@ -134,6 +138,7 @@ void *calloc(size_t num_elems, size_t size) {
void *realloc(void *ptr, size_t size) {
if (should_fail_allocation()) {
+ errno = ENOMEM;
return NULL;
}
diff --git a/src/crypto/test/scoped_types.h b/src/crypto/test/scoped_types.h
index c5c8cfe..e44c6ed 100644
--- a/src/crypto/test/scoped_types.h
+++ b/src/crypto/test/scoped_types.h
@@ -18,6 +18,7 @@
#include <stdint.h>
#include <stdio.h>
+#include <openssl/aead.h>
#include <openssl/bio.h>
#include <openssl/bn.h>
#include <openssl/cmac.h>
@@ -112,9 +113,13 @@ using ScopedPKCS12 = ScopedOpenSSLType<PKCS12, PKCS12_free>;
using ScopedRSA = ScopedOpenSSLType<RSA, RSA_free>;
using ScopedX509 = ScopedOpenSSLType<X509, X509_free>;
using ScopedX509_ALGOR = ScopedOpenSSLType<X509_ALGOR, X509_ALGOR_free>;
+using ScopedX509_SIG = ScopedOpenSSLType<X509_SIG, X509_SIG_free>;
using ScopedX509Stack = ScopedOpenSSLStack<STACK_OF(X509), X509, X509_free>;
+using ScopedEVP_AEAD_CTX = ScopedOpenSSLContext<EVP_AEAD_CTX, void,
+ EVP_AEAD_CTX_zero,
+ EVP_AEAD_CTX_cleanup>;
using ScopedEVP_CIPHER_CTX = ScopedOpenSSLContext<EVP_CIPHER_CTX, int,
EVP_CIPHER_CTX_init,
EVP_CIPHER_CTX_cleanup>;
diff --git a/src/crypto/test/test_util.cc b/src/crypto/test/test_util.cc
new file mode 100644
index 0000000..8021aaa
--- /dev/null
+++ b/src/crypto/test/test_util.cc
@@ -0,0 +1,30 @@
+/* Copyright (c) 2015, Google Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
+
+#include <stdint.h>
+#include <stdio.h>
+
+#include "test_util.h"
+
+
+void hexdump(FILE *fp, const char *msg, const void *in, size_t len) {
+ const uint8_t *data = reinterpret_cast<const uint8_t*>(in);
+ size_t i;
+
+ fputs(msg, fp);
+ for (i = 0; i < len; i++) {
+ fprintf(fp, "%02x", data[i]);
+ }
+ fputs("\n", fp);
+}
diff --git a/src/crypto/test/test_util.h b/src/crypto/test/test_util.h
new file mode 100644
index 0000000..972e206
--- /dev/null
+++ b/src/crypto/test/test_util.h
@@ -0,0 +1,35 @@
+/* Copyright (c) 2015, Google Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
+
+#ifndef OPENSSL_HEADER_CRYPTO_TEST_TEST_UTIL_H
+#define OPENSSL_HEADER_CRYPTO_TEST_TEST_UTIL_H
+
+#include <stddef.h>
+#include <stdio.h>
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+
+/* hexdump writes |msg| to |fp| followed by the hex encoding of |len| bytes
+ * from |in|. */
+void hexdump(FILE *fp, const char *msg, const void *in, size_t len);
+
+
+#if defined(__cplusplus)
+}
+#endif
+
+#endif /* OPENSSL_HEADER_CRYPTO_TEST_TEST_UTIL_H */
diff --git a/src/crypto/x509/CMakeLists.txt b/src/crypto/x509/CMakeLists.txt
index 3bb5704..258c263 100644
--- a/src/crypto/x509/CMakeLists.txt
+++ b/src/crypto/x509/CMakeLists.txt
@@ -1,4 +1,4 @@
-include_directories(. .. ../../include)
+include_directories(../../include)
add_library(
x509
@@ -15,6 +15,7 @@ add_library(
i2d_pr.c
pkcs7.c
t_crl.c
+ t_req.c
t_x509.c
t_x509a.c
x509.c
diff --git a/src/crypto/x509/a_digest.c b/src/crypto/x509/a_digest.c
index 6060bbd..430e2e6 100644
--- a/src/crypto/x509/a_digest.c
+++ b/src/crypto/x509/a_digest.c
@@ -71,7 +71,7 @@ int ASN1_digest(i2d_of_void *i2d, const EVP_MD *type, char *data,
i=i2d(data,NULL);
if ((str=(unsigned char *)OPENSSL_malloc(i)) == NULL)
{
- OPENSSL_PUT_ERROR(X509, ASN1_digest, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
return(0);
}
p=str;
diff --git a/src/crypto/x509/a_sign.c b/src/crypto/x509/a_sign.c
index f219c23..4e9be8a 100644
--- a/src/crypto/x509/a_sign.c
+++ b/src/crypto/x509/a_sign.c
@@ -106,7 +106,7 @@ int ASN1_item_sign_ctx(const ASN1_ITEM *it,
if ((buf_in == NULL) || (buf_out == NULL))
{
outl=0;
- OPENSSL_PUT_ERROR(X509, ASN1_item_sign_ctx, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
goto err;
}
@@ -114,7 +114,7 @@ int ASN1_item_sign_ctx(const ASN1_ITEM *it,
|| !EVP_DigestSignFinal(ctx, buf_out, &outl))
{
outl=0;
- OPENSSL_PUT_ERROR(X509, ASN1_item_sign_ctx, ERR_R_EVP_LIB);
+ OPENSSL_PUT_ERROR(X509, ERR_R_EVP_LIB);
goto err;
}
if (signature->data != NULL) OPENSSL_free(signature->data);
diff --git a/src/crypto/x509/a_verify.c b/src/crypto/x509/a_verify.c
index 72e0a62..572a139 100644
--- a/src/crypto/x509/a_verify.c
+++ b/src/crypto/x509/a_verify.c
@@ -80,13 +80,13 @@ int ASN1_item_verify(const ASN1_ITEM *it, X509_ALGOR *a,
if (!pkey)
{
- OPENSSL_PUT_ERROR(X509, ASN1_item_verify, ERR_R_PASSED_NULL_PARAMETER);
+ OPENSSL_PUT_ERROR(X509, ERR_R_PASSED_NULL_PARAMETER);
return 0;
}
if (signature->type == V_ASN1_BIT_STRING && signature->flags & 0x7)
{
- OPENSSL_PUT_ERROR(X509, ASN1_item_verify, X509_R_INVALID_BIT_STRING_BITS_LEFT);
+ OPENSSL_PUT_ERROR(X509, X509_R_INVALID_BIT_STRING_BITS_LEFT);
return 0;
}
@@ -101,7 +101,7 @@ int ASN1_item_verify(const ASN1_ITEM *it, X509_ALGOR *a,
if (buf_in == NULL)
{
- OPENSSL_PUT_ERROR(X509, ASN1_item_verify, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
goto err;
}
@@ -109,7 +109,7 @@ int ASN1_item_verify(const ASN1_ITEM *it, X509_ALGOR *a,
{
OPENSSL_cleanse(buf_in,(unsigned int)inl);
OPENSSL_free(buf_in);
- OPENSSL_PUT_ERROR(X509, ASN1_item_verify, ERR_R_EVP_LIB);
+ OPENSSL_PUT_ERROR(X509, ERR_R_EVP_LIB);
goto err;
}
@@ -119,7 +119,7 @@ int ASN1_item_verify(const ASN1_ITEM *it, X509_ALGOR *a,
if (EVP_DigestVerifyFinal(&ctx,signature->data,
(size_t)signature->length) <= 0)
{
- OPENSSL_PUT_ERROR(X509, ASN1_item_verify, ERR_R_EVP_LIB);
+ OPENSSL_PUT_ERROR(X509, ERR_R_EVP_LIB);
goto err;
}
/* we don't need to zero the 'ctx' because we just checked
diff --git a/src/crypto/x509/asn1_gen.c b/src/crypto/x509/asn1_gen.c
index d4d1ee6..850a816 100644
--- a/src/crypto/x509/asn1_gen.c
+++ b/src/crypto/x509/asn1_gen.c
@@ -171,7 +171,7 @@ ASN1_TYPE *ASN1_generate_v3(char *str, X509V3_CTX *cnf)
{
if (!cnf)
{
- OPENSSL_PUT_ERROR(ASN1, ASN1_generate_v3, ASN1_R_SEQUENCE_OR_SET_NEEDS_CONFIG);
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_SEQUENCE_OR_SET_NEEDS_CONFIG);
return NULL;
}
ret = asn1_multi(asn1_tags.utype, asn1_tags.str, cnf);
@@ -314,7 +314,7 @@ static int asn1_cb(const char *elem, int len, void *bitstr)
if (utype == -1)
{
- OPENSSL_PUT_ERROR(ASN1, asn1_cb, ASN1_R_UNKNOWN_TAG);
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_UNKNOWN_TAG);
ERR_add_error_data(2, "tag=", elem);
return -1;
}
@@ -327,7 +327,7 @@ static int asn1_cb(const char *elem, int len, void *bitstr)
/* If no value and not end of string, error */
if (!vstart && elem[len])
{
- OPENSSL_PUT_ERROR(ASN1, asn1_cb, ASN1_R_MISSING_VALUE);
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_MISSING_VALUE);
return -1;
}
return 0;
@@ -340,7 +340,7 @@ static int asn1_cb(const char *elem, int len, void *bitstr)
/* Check for illegal multiple IMPLICIT tagging */
if (arg->imp_tag != -1)
{
- OPENSSL_PUT_ERROR(ASN1, asn1_cb, ASN1_R_ILLEGAL_NESTED_TAGGING);
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_ILLEGAL_NESTED_TAGGING);
return -1;
}
if (!parse_tagging(vstart, vlen, &arg->imp_tag, &arg->imp_class))
@@ -378,7 +378,7 @@ static int asn1_cb(const char *elem, int len, void *bitstr)
case ASN1_GEN_FLAG_FORMAT:
if (!vstart)
{
- OPENSSL_PUT_ERROR(ASN1, asn1_cb, ASN1_R_UNKNOWN_FORMAT);
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_UNKNOWN_FORMAT);
return -1;
}
if (!strncmp(vstart, "ASCII", 5))
@@ -391,7 +391,7 @@ static int asn1_cb(const char *elem, int len, void *bitstr)
arg->format = ASN1_GEN_FORMAT_BITLIST;
else
{
- OPENSSL_PUT_ERROR(ASN1, asn1_cb, ASN1_R_UNKNOWN_FORMAT);
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_UNKNOWN_FORMAT);
return -1;
}
break;
@@ -415,7 +415,7 @@ static int parse_tagging(const char *vstart, int vlen, int *ptag, int *pclass)
return 0;
if (tag_num < 0)
{
- OPENSSL_PUT_ERROR(ASN1, parse_tagging, ASN1_R_INVALID_NUMBER);
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_INVALID_NUMBER);
return 0;
}
*ptag = tag_num;
@@ -448,7 +448,7 @@ static int parse_tagging(const char *vstart, int vlen, int *ptag, int *pclass)
default:
erch[0] = *eptr;
erch[1] = 0;
- OPENSSL_PUT_ERROR(ASN1, parse_tagging, ASN1_R_INVALID_MODIFIER);
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_INVALID_MODIFIER);
ERR_add_error_data(2, "Char=", erch);
return 0;
break;
@@ -534,13 +534,13 @@ static int append_exp(tag_exp_arg *arg, int exp_tag, int exp_class, int exp_cons
/* Can only have IMPLICIT if permitted */
if ((arg->imp_tag != -1) && !imp_ok)
{
- OPENSSL_PUT_ERROR(ASN1, append_exp, ASN1_R_ILLEGAL_IMPLICIT_TAG);
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_ILLEGAL_IMPLICIT_TAG);
return 0;
}
if (arg->exp_count == ASN1_FLAG_EXP_MAX)
{
- OPENSSL_PUT_ERROR(ASN1, append_exp, ASN1_R_DEPTH_EXCEEDED);
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_DEPTH_EXCEEDED);
return 0;
}
@@ -658,7 +658,7 @@ static ASN1_TYPE *asn1_str2type(const char *str, int format, int utype)
if (!(atmp = ASN1_TYPE_new()))
{
- OPENSSL_PUT_ERROR(ASN1, asn1_str2type, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
return NULL;
}
@@ -671,7 +671,7 @@ static ASN1_TYPE *asn1_str2type(const char *str, int format, int utype)
case V_ASN1_NULL:
if (str && *str)
{
- OPENSSL_PUT_ERROR(ASN1, asn1_str2type, ASN1_R_ILLEGAL_NULL_VALUE);
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_ILLEGAL_NULL_VALUE);
goto bad_form;
}
break;
@@ -679,7 +679,7 @@ static ASN1_TYPE *asn1_str2type(const char *str, int format, int utype)
case V_ASN1_BOOLEAN:
if (format != ASN1_GEN_FORMAT_ASCII)
{
- OPENSSL_PUT_ERROR(ASN1, asn1_str2type, ASN1_R_NOT_ASCII_FORMAT);
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_NOT_ASCII_FORMAT);
goto bad_form;
}
vtmp.name = NULL;
@@ -687,7 +687,7 @@ static ASN1_TYPE *asn1_str2type(const char *str, int format, int utype)
vtmp.value = (char *)str;
if (!X509V3_get_value_bool(&vtmp, &atmp->value.boolean))
{
- OPENSSL_PUT_ERROR(ASN1, asn1_str2type, ASN1_R_ILLEGAL_BOOLEAN);
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_ILLEGAL_BOOLEAN);
goto bad_str;
}
break;
@@ -696,12 +696,12 @@ static ASN1_TYPE *asn1_str2type(const char *str, int format, int utype)
case V_ASN1_ENUMERATED:
if (format != ASN1_GEN_FORMAT_ASCII)
{
- OPENSSL_PUT_ERROR(ASN1, asn1_str2type, ASN1_R_INTEGER_NOT_ASCII_FORMAT);
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_INTEGER_NOT_ASCII_FORMAT);
goto bad_form;
}
if (!(atmp->value.integer = s2i_ASN1_INTEGER(NULL, (char *)str)))
{
- OPENSSL_PUT_ERROR(ASN1, asn1_str2type, ASN1_R_ILLEGAL_INTEGER);
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_ILLEGAL_INTEGER);
goto bad_str;
}
break;
@@ -709,12 +709,12 @@ static ASN1_TYPE *asn1_str2type(const char *str, int format, int utype)
case V_ASN1_OBJECT:
if (format != ASN1_GEN_FORMAT_ASCII)
{
- OPENSSL_PUT_ERROR(ASN1, asn1_str2type, ASN1_R_OBJECT_NOT_ASCII_FORMAT);
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_OBJECT_NOT_ASCII_FORMAT);
goto bad_form;
}
if (!(atmp->value.object = OBJ_txt2obj(str, 0)))
{
- OPENSSL_PUT_ERROR(ASN1, asn1_str2type, ASN1_R_ILLEGAL_OBJECT);
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_ILLEGAL_OBJECT);
goto bad_str;
}
break;
@@ -723,23 +723,23 @@ static ASN1_TYPE *asn1_str2type(const char *str, int format, int utype)
case V_ASN1_GENERALIZEDTIME:
if (format != ASN1_GEN_FORMAT_ASCII)
{
- OPENSSL_PUT_ERROR(ASN1, asn1_str2type, ASN1_R_TIME_NOT_ASCII_FORMAT);
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_TIME_NOT_ASCII_FORMAT);
goto bad_form;
}
if (!(atmp->value.asn1_string = ASN1_STRING_new()))
{
- OPENSSL_PUT_ERROR(ASN1, asn1_str2type, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
goto bad_str;
}
if (!ASN1_STRING_set(atmp->value.asn1_string, str, -1))
{
- OPENSSL_PUT_ERROR(ASN1, asn1_str2type, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
goto bad_str;
}
atmp->value.asn1_string->type = utype;
if (!ASN1_TIME_check(atmp->value.asn1_string))
{
- OPENSSL_PUT_ERROR(ASN1, asn1_str2type, ASN1_R_ILLEGAL_TIME_VALUE);
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_ILLEGAL_TIME_VALUE);
goto bad_str;
}
@@ -761,7 +761,7 @@ static ASN1_TYPE *asn1_str2type(const char *str, int format, int utype)
format = MBSTRING_UTF8;
else
{
- OPENSSL_PUT_ERROR(ASN1, asn1_str2type, ASN1_R_ILLEGAL_FORMAT);
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_ILLEGAL_FORMAT);
goto bad_form;
}
@@ -769,7 +769,7 @@ static ASN1_TYPE *asn1_str2type(const char *str, int format, int utype)
if (ASN1_mbstring_copy(&atmp->value.asn1_string, (unsigned char *)str,
-1, format, ASN1_tag2bit(utype)) <= 0)
{
- OPENSSL_PUT_ERROR(ASN1, asn1_str2type, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
goto bad_str;
}
@@ -782,7 +782,7 @@ static ASN1_TYPE *asn1_str2type(const char *str, int format, int utype)
if (!(atmp->value.asn1_string = ASN1_STRING_new()))
{
- OPENSSL_PUT_ERROR(ASN1, asn1_str2type, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
goto bad_form;
}
@@ -791,7 +791,7 @@ static ASN1_TYPE *asn1_str2type(const char *str, int format, int utype)
if (!(rdata = string_to_hex((char *)str, &rdlen)))
{
- OPENSSL_PUT_ERROR(ASN1, asn1_str2type, ASN1_R_ILLEGAL_HEX);
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_ILLEGAL_HEX);
goto bad_str;
}
@@ -806,7 +806,7 @@ static ASN1_TYPE *asn1_str2type(const char *str, int format, int utype)
{
if (!CONF_parse_list(str, ',', 1, bitstr_cb, atmp->value.bit_string))
{
- OPENSSL_PUT_ERROR(ASN1, asn1_str2type, ASN1_R_LIST_ERROR);
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_LIST_ERROR);
goto bad_str;
}
no_unused = 0;
@@ -814,7 +814,7 @@ static ASN1_TYPE *asn1_str2type(const char *str, int format, int utype)
}
else
{
- OPENSSL_PUT_ERROR(ASN1, asn1_str2type, ASN1_R_ILLEGAL_BITSTRING_FORMAT);
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_ILLEGAL_BITSTRING_FORMAT);
goto bad_form;
}
@@ -830,7 +830,7 @@ static ASN1_TYPE *asn1_str2type(const char *str, int format, int utype)
break;
default:
- OPENSSL_PUT_ERROR(ASN1, asn1_str2type, ASN1_R_UNSUPPORTED_TYPE);
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_UNSUPPORTED_TYPE);
goto bad_str;
break;
}
@@ -860,12 +860,12 @@ static int bitstr_cb(const char *elem, int len, void *bitstr)
return 0;
if (bitnum < 0)
{
- OPENSSL_PUT_ERROR(ASN1, bitstr_cb, ASN1_R_INVALID_NUMBER);
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_INVALID_NUMBER);
return 0;
}
if (!ASN1_BIT_STRING_set_bit(bitstr, bitnum, 1))
{
- OPENSSL_PUT_ERROR(ASN1, bitstr_cb, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE);
return 0;
}
return 1;
diff --git a/src/crypto/x509/by_dir.c b/src/crypto/x509/by_dir.c
index 34bb1e4..3393dfa 100644
--- a/src/crypto/x509/by_dir.c
+++ b/src/crypto/x509/by_dir.c
@@ -139,7 +139,7 @@ static int dir_ctrl(X509_LOOKUP *ctx, int cmd, const char *argp, long argl,
X509_FILETYPE_PEM);
if (!ret)
{
- OPENSSL_PUT_ERROR(X509, dir_ctrl, X509_R_LOADING_CERT_DIR);
+ OPENSSL_PUT_ERROR(X509, X509_R_LOADING_CERT_DIR);
}
}
else
@@ -208,7 +208,7 @@ static int add_cert_dir(BY_DIR *ctx, const char *dir, int type)
if (dir == NULL || !*dir)
{
- OPENSSL_PUT_ERROR(X509, add_cert_dir, X509_R_INVALID_DIRECTORY);
+ OPENSSL_PUT_ERROR(X509, X509_R_INVALID_DIRECTORY);
return 0;
}
@@ -237,7 +237,7 @@ static int add_cert_dir(BY_DIR *ctx, const char *dir, int type)
ctx->dirs = sk_BY_DIR_ENTRY_new_null();
if (!ctx->dirs)
{
- OPENSSL_PUT_ERROR(X509, add_cert_dir, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
return 0;
}
}
@@ -311,13 +311,13 @@ static int get_cert_by_subject(X509_LOOKUP *xl, int type, X509_NAME *name,
}
else
{
- OPENSSL_PUT_ERROR(X509, get_cert_by_subject, X509_R_WRONG_LOOKUP_TYPE);
+ OPENSSL_PUT_ERROR(X509, X509_R_WRONG_LOOKUP_TYPE);
goto finish;
}
if ((b=BUF_MEM_new()) == NULL)
{
- OPENSSL_PUT_ERROR(X509, get_cert_by_subject, ERR_R_BUF_LIB);
+ OPENSSL_PUT_ERROR(X509, ERR_R_BUF_LIB);
goto finish;
}
@@ -337,7 +337,7 @@ static int get_cert_by_subject(X509_LOOKUP *xl, int type, X509_NAME *name,
j=strlen(ent->dir)+1+8+6+1+1;
if (!BUF_MEM_grow(b,j))
{
- OPENSSL_PUT_ERROR(X509, get_cert_by_subject, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
goto finish;
}
if (type == X509_LU_CRL && ent->hashes)
diff --git a/src/crypto/x509/by_file.c b/src/crypto/x509/by_file.c
index 2fdbce4..f1d6194 100644
--- a/src/crypto/x509/by_file.c
+++ b/src/crypto/x509/by_file.c
@@ -109,7 +109,7 @@ static int by_file_ctrl(X509_LOOKUP *ctx, int cmd, const char *argp, long argl,
if (!ok)
{
- OPENSSL_PUT_ERROR(X509, by_file_ctrl, X509_R_LOADING_DEFAULTS);
+ OPENSSL_PUT_ERROR(X509, X509_R_LOADING_DEFAULTS);
}
}
else
@@ -137,7 +137,7 @@ int X509_load_cert_file(X509_LOOKUP *ctx, const char *file, int type)
if ((in == NULL) || (BIO_read_filename(in,file) <= 0))
{
- OPENSSL_PUT_ERROR(X509, X509_load_cert_file, ERR_R_SYS_LIB);
+ OPENSSL_PUT_ERROR(X509, ERR_R_SYS_LIB);
goto err;
}
@@ -156,7 +156,7 @@ int X509_load_cert_file(X509_LOOKUP *ctx, const char *file, int type)
}
else
{
- OPENSSL_PUT_ERROR(X509, X509_load_cert_file, ERR_R_PEM_LIB);
+ OPENSSL_PUT_ERROR(X509, ERR_R_PEM_LIB);
goto err;
}
}
@@ -173,7 +173,7 @@ int X509_load_cert_file(X509_LOOKUP *ctx, const char *file, int type)
x=d2i_X509_bio(in,NULL);
if (x == NULL)
{
- OPENSSL_PUT_ERROR(X509, X509_load_cert_file, ERR_R_ASN1_LIB);
+ OPENSSL_PUT_ERROR(X509, ERR_R_ASN1_LIB);
goto err;
}
i=X509_STORE_add_cert(ctx->store_ctx,x);
@@ -182,7 +182,7 @@ int X509_load_cert_file(X509_LOOKUP *ctx, const char *file, int type)
}
else
{
- OPENSSL_PUT_ERROR(X509, X509_load_cert_file, X509_R_BAD_X509_FILETYPE);
+ OPENSSL_PUT_ERROR(X509, X509_R_BAD_X509_FILETYPE);
goto err;
}
err:
@@ -203,7 +203,7 @@ int X509_load_crl_file(X509_LOOKUP *ctx, const char *file, int type)
if ((in == NULL) || (BIO_read_filename(in,file) <= 0))
{
- OPENSSL_PUT_ERROR(X509, X509_load_crl_file, ERR_R_SYS_LIB);
+ OPENSSL_PUT_ERROR(X509, ERR_R_SYS_LIB);
goto err;
}
@@ -222,7 +222,7 @@ int X509_load_crl_file(X509_LOOKUP *ctx, const char *file, int type)
}
else
{
- OPENSSL_PUT_ERROR(X509, X509_load_crl_file, ERR_R_PEM_LIB);
+ OPENSSL_PUT_ERROR(X509, ERR_R_PEM_LIB);
goto err;
}
}
@@ -239,7 +239,7 @@ int X509_load_crl_file(X509_LOOKUP *ctx, const char *file, int type)
x=d2i_X509_CRL_bio(in,NULL);
if (x == NULL)
{
- OPENSSL_PUT_ERROR(X509, X509_load_crl_file, ERR_R_ASN1_LIB);
+ OPENSSL_PUT_ERROR(X509, ERR_R_ASN1_LIB);
goto err;
}
i=X509_STORE_add_crl(ctx->store_ctx,x);
@@ -248,7 +248,7 @@ int X509_load_crl_file(X509_LOOKUP *ctx, const char *file, int type)
}
else
{
- OPENSSL_PUT_ERROR(X509, X509_load_crl_file, X509_R_BAD_X509_FILETYPE);
+ OPENSSL_PUT_ERROR(X509, X509_R_BAD_X509_FILETYPE);
goto err;
}
err:
@@ -268,13 +268,13 @@ int X509_load_cert_crl_file(X509_LOOKUP *ctx, const char *file, int type)
return X509_load_cert_file(ctx, file, type);
in = BIO_new_file(file, "r");
if(!in) {
- OPENSSL_PUT_ERROR(X509, X509_load_cert_crl_file, ERR_R_SYS_LIB);
+ OPENSSL_PUT_ERROR(X509, ERR_R_SYS_LIB);
return 0;
}
inf = PEM_X509_INFO_read_bio(in, NULL, NULL, NULL);
BIO_free(in);
if(!inf) {
- OPENSSL_PUT_ERROR(X509, X509_load_cert_crl_file, ERR_R_PEM_LIB);
+ OPENSSL_PUT_ERROR(X509, ERR_R_PEM_LIB);
return 0;
}
for(i = 0; i < sk_X509_INFO_num(inf); i++) {
diff --git a/src/crypto/x509/i2d_pr.c b/src/crypto/x509/i2d_pr.c
index 443ca53..e7f4269 100644
--- a/src/crypto/x509/i2d_pr.c
+++ b/src/crypto/x509/i2d_pr.c
@@ -78,7 +78,7 @@ int i2d_PrivateKey(const EVP_PKEY *a, unsigned char **pp)
}
/* Although this file is in crypto/x509 for layering reasons, it emits
* an error code from ASN1 for OpenSSL compatibility. */
- OPENSSL_PUT_ERROR(ASN1, i2d_PrivateKey, ASN1_R_UNSUPPORTED_PUBLIC_KEY_TYPE);
+ OPENSSL_PUT_ERROR(ASN1, ASN1_R_UNSUPPORTED_PUBLIC_KEY_TYPE);
return -1;
}
diff --git a/src/crypto/x509/pkcs7.c b/src/crypto/x509/pkcs7.c
index 99ee3da..2087f94 100644
--- a/src/crypto/x509/pkcs7.c
+++ b/src/crypto/x509/pkcs7.c
@@ -57,8 +57,7 @@ static int pkcs7_parse_header(uint8_t **der_bytes, CBS *out, CBS *cbs) {
}
if (OBJ_cbs2nid(&content_type) != NID_pkcs7_signed) {
- OPENSSL_PUT_ERROR(X509, pkcs7_parse_header,
- X509_R_NOT_PKCS7_SIGNED_DATA);
+ OPENSSL_PUT_ERROR(X509, X509_R_NOT_PKCS7_SIGNED_DATA);
goto err;
}
@@ -73,8 +72,7 @@ static int pkcs7_parse_header(uint8_t **der_bytes, CBS *out, CBS *cbs) {
}
if (version < 1) {
- OPENSSL_PUT_ERROR(X509, pkcs7_parse_header,
- X509_R_BAD_PKCS7_VERSION);
+ OPENSSL_PUT_ERROR(X509, X509_R_BAD_PKCS7_VERSION);
goto err;
}
@@ -103,8 +101,7 @@ int PKCS7_get_certificates(STACK_OF(X509) *out_certs, CBS *cbs) {
/* See https://tools.ietf.org/html/rfc2315#section-9.1 */
if (!CBS_get_asn1(&signed_data, &certificates,
CBS_ASN1_CONTEXT_SPECIFIC | CBS_ASN1_CONSTRUCTED | 0)) {
- OPENSSL_PUT_ERROR(X509, PKCS7_get_certificates,
- X509_R_NO_CERTIFICATES_INCLUDED);
+ OPENSSL_PUT_ERROR(X509, X509_R_NO_CERTIFICATES_INCLUDED);
goto err;
}
@@ -171,8 +168,7 @@ int PKCS7_get_CRLs(STACK_OF(X509_CRL) *out_crls, CBS *cbs) {
if (!CBS_get_asn1(&signed_data, &crls,
CBS_ASN1_CONTEXT_SPECIFIC | CBS_ASN1_CONSTRUCTED | 1)) {
- OPENSSL_PUT_ERROR(X509, PKCS7_get_CRLs,
- X509_R_NO_CRLS_INCLUDED);
+ OPENSSL_PUT_ERROR(X509, X509_R_NO_CRLS_INCLUDED);
goto err;
}
diff --git a/src/crypto/x509/t_crl.c b/src/crypto/x509/t_crl.c
index 93a7afb..a2d8bc7 100644
--- a/src/crypto/x509/t_crl.c
+++ b/src/crypto/x509/t_crl.c
@@ -70,7 +70,7 @@ int X509_CRL_print_fp(FILE *fp, X509_CRL *x)
if ((b=BIO_new(BIO_s_file())) == NULL)
{
- OPENSSL_PUT_ERROR(X509, X509_CRL_print_fp, ERR_R_BUF_LIB);
+ OPENSSL_PUT_ERROR(X509, ERR_R_BUF_LIB);
return(0);
}
BIO_set_fp(b,fp,BIO_NOCLOSE);
diff --git a/src/crypto/x509/t_req.c b/src/crypto/x509/t_req.c
new file mode 100644
index 0000000..39c836c
--- /dev/null
+++ b/src/crypto/x509/t_req.c
@@ -0,0 +1,246 @@
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.] */
+
+#include <stdio.h>
+
+#include <openssl/bn.h>
+#include <openssl/buffer.h>
+#include <openssl/err.h>
+#include <openssl/objects.h>
+#include <openssl/x509.h>
+#include <openssl/x509v3.h>
+
+
+int X509_REQ_print_fp(FILE *fp, X509_REQ *x) {
+ BIO *bio = BIO_new(BIO_s_file());
+ if (bio == NULL) {
+ OPENSSL_PUT_ERROR(X509, ERR_R_BUF_LIB);
+ return 0;
+ }
+
+ BIO_set_fp(bio, fp, BIO_NOCLOSE);
+ int ret = X509_REQ_print(bio, x);
+ BIO_free(bio);
+ return ret;
+}
+
+int X509_REQ_print_ex(BIO *bio, X509_REQ *x, unsigned long nmflags,
+ unsigned long cflag) {
+ long l;
+ EVP_PKEY *pkey;
+ STACK_OF(X509_ATTRIBUTE) * sk;
+ char mlch = ' ';
+
+ int nmindent = 0;
+
+ if ((nmflags & XN_FLAG_SEP_MASK) == XN_FLAG_SEP_MULTILINE) {
+ mlch = '\n';
+ nmindent = 12;
+ }
+
+ if (nmflags == X509_FLAG_COMPAT) {
+ nmindent = 16;
+ }
+
+ X509_REQ_INFO *ri = x->req_info;
+ if (!(cflag & X509_FLAG_NO_HEADER)) {
+ if (BIO_write(bio, "Certificate Request:\n", 21) <= 0 ||
+ BIO_write(bio, " Data:\n", 10) <= 0) {
+ goto err;
+ }
+ }
+ if (!(cflag & X509_FLAG_NO_VERSION)) {
+ l = X509_REQ_get_version(x);
+ if (BIO_printf(bio, "%8sVersion: %ld (0x%lx)\n", "", l + 1, l) <= 0) {
+ goto err;
+ }
+ }
+ if (!(cflag & X509_FLAG_NO_SUBJECT)) {
+ if (BIO_printf(bio, " Subject:%c", mlch) <= 0 ||
+ X509_NAME_print_ex(bio, ri->subject, nmindent, nmflags) < 0 ||
+ BIO_write(bio, "\n", 1) <= 0) {
+ goto err;
+ }
+ }
+ if (!(cflag & X509_FLAG_NO_PUBKEY)) {
+ if (BIO_write(bio, " Subject Public Key Info:\n", 33) <= 0 ||
+ BIO_printf(bio, "%12sPublic Key Algorithm: ", "") <= 0 ||
+ i2a_ASN1_OBJECT(bio, ri->pubkey->algor->algorithm) <= 0 ||
+ BIO_puts(bio, "\n") <= 0) {
+ goto err;
+ }
+
+ pkey = X509_REQ_get_pubkey(x);
+ if (pkey == NULL) {
+ BIO_printf(bio, "%12sUnable to load Public Key\n", "");
+ ERR_print_errors(bio);
+ } else {
+ EVP_PKEY_print_public(bio, pkey, 16, NULL);
+ EVP_PKEY_free(pkey);
+ }
+ }
+
+ if (!(cflag & X509_FLAG_NO_ATTRIBUTES)) {
+ if (BIO_printf(bio, "%8sAttributes:\n", "") <= 0) {
+ goto err;
+ }
+
+ sk = x->req_info->attributes;
+ if (sk_X509_ATTRIBUTE_num(sk) == 0) {
+ if (BIO_printf(bio, "%12sa0:00\n", "") <= 0) {
+ goto err;
+ }
+ } else {
+ size_t i;
+ for (i = 0; i < sk_X509_ATTRIBUTE_num(sk); i++) {
+ X509_ATTRIBUTE *a = sk_X509_ATTRIBUTE_value(sk, i);
+ ASN1_OBJECT *aobj = X509_ATTRIBUTE_get0_object(a);
+
+ if (X509_REQ_extension_nid(OBJ_obj2nid(aobj))) {
+ continue;
+ }
+
+ if (BIO_printf(bio, "%12s", "") <= 0) {
+ goto err;
+ }
+
+ const int num_attrs = X509_ATTRIBUTE_count(a);
+ const int obj_str_len = i2a_ASN1_OBJECT(bio, aobj);
+ if (obj_str_len <= 0) {
+ if (BIO_puts(bio, "(Unable to print attribute ID.)\n") < 0) {
+ goto err;
+ } else {
+ continue;
+ }
+ }
+
+ int j;
+ for (j = 0; j < num_attrs; j++) {
+ const ASN1_TYPE *at = X509_ATTRIBUTE_get0_type(a, j);
+ const int type = at->type;
+ ASN1_BIT_STRING *bs = at->value.asn1_string;
+
+ int k;
+ for (k = 25 - obj_str_len; k > 0; k--) {
+ if (BIO_write(bio, " ", 1) != 1) {
+ goto err;
+ }
+ }
+
+ if (BIO_puts(bio, ":") <= 0) {
+ goto err;
+ }
+
+ if (type == V_ASN1_PRINTABLESTRING ||
+ type == V_ASN1_UTF8STRING ||
+ type == V_ASN1_IA5STRING ||
+ type == V_ASN1_T61STRING) {
+ if (BIO_write(bio, (char *)bs->data, bs->length) != bs->length) {
+ goto err;
+ }
+ BIO_puts(bio, "\n");
+ } else {
+ BIO_puts(bio, "unable to print attribute\n");
+ }
+ }
+ }
+ }
+ }
+
+ if (!(cflag & X509_FLAG_NO_EXTENSIONS)) {
+ STACK_OF(X509_EXTENSION) *exts = X509_REQ_get_extensions(x);
+ if (exts) {
+ BIO_printf(bio, "%8sRequested Extensions:\n", "");
+
+ size_t i;
+ for (i = 0; i < sk_X509_EXTENSION_num(exts); i++) {
+ X509_EXTENSION *ex = sk_X509_EXTENSION_value(exts, i);
+ if (BIO_printf(bio, "%12s", "") <= 0) {
+ goto err;
+ }
+ ASN1_OBJECT *obj = X509_EXTENSION_get_object(ex);
+ i2a_ASN1_OBJECT(bio, obj);
+ const int is_critical = X509_EXTENSION_get_critical(ex);
+ if (BIO_printf(bio, ": %s\n", is_critical ? "critical" : "") <= 0) {
+ goto err;
+ }
+ if (!X509V3_EXT_print(bio, ex, cflag, 16)) {
+ BIO_printf(bio, "%16s", "");
+ ASN1_STRING_print(bio, X509_EXTENSION_get_data(ex));
+ }
+ if (BIO_write(bio, "\n", 1) <= 0) {
+ goto err;
+ }
+ }
+ sk_X509_EXTENSION_pop_free(exts, X509_EXTENSION_free);
+ }
+ }
+
+ if (!(cflag & X509_FLAG_NO_SIGDUMP) &&
+ !X509_signature_print(bio, x->sig_alg, x->signature)) {
+ goto err;
+ }
+
+ return 1;
+
+err:
+ OPENSSL_PUT_ERROR(X509, ERR_R_BUF_LIB);
+ return 0;
+}
+
+int X509_REQ_print(BIO *bio, X509_REQ *req) {
+ return X509_REQ_print_ex(bio, req, XN_FLAG_COMPAT, X509_FLAG_COMPAT);
+}
diff --git a/src/crypto/x509/t_x509.c b/src/crypto/x509/t_x509.c
index 2b9a421..7785ebf 100644
--- a/src/crypto/x509/t_x509.c
+++ b/src/crypto/x509/t_x509.c
@@ -74,7 +74,7 @@ int X509_print_ex_fp(FILE *fp, X509 *x, unsigned long nmflag, unsigned long cfla
if ((b=BIO_new(BIO_s_file())) == NULL)
{
- OPENSSL_PUT_ERROR(X509, X509_print_ex_fp, ERR_R_BUF_LIB);
+ OPENSSL_PUT_ERROR(X509, ERR_R_BUF_LIB);
return(0);
}
BIO_set_fp(b,fp,BIO_NOCLOSE);
@@ -493,7 +493,7 @@ int X509_NAME_print(BIO *bp, X509_NAME *name, int obase)
if (0)
{
err:
- OPENSSL_PUT_ERROR(X509, X509_NAME_print, ERR_R_BUF_LIB);
+ OPENSSL_PUT_ERROR(X509, ERR_R_BUF_LIB);
}
OPENSSL_free(b);
return(ret);
diff --git a/src/crypto/x509/x509_att.c b/src/crypto/x509/x509_att.c
index 90e7810..1491484 100644
--- a/src/crypto/x509/x509_att.c
+++ b/src/crypto/x509/x509_att.c
@@ -124,7 +124,7 @@ STACK_OF(X509_ATTRIBUTE) *X509at_add1_attr(STACK_OF(X509_ATTRIBUTE) **x,
if (x == NULL)
{
- OPENSSL_PUT_ERROR(X509, X509at_add1_attr, ERR_R_PASSED_NULL_PARAMETER);
+ OPENSSL_PUT_ERROR(X509, ERR_R_PASSED_NULL_PARAMETER);
goto err2;
}
@@ -144,7 +144,7 @@ STACK_OF(X509_ATTRIBUTE) *X509at_add1_attr(STACK_OF(X509_ATTRIBUTE) **x,
*x=sk;
return(sk);
err:
- OPENSSL_PUT_ERROR(X509, X509at_add1_attr, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
err2:
if (new_attr != NULL) X509_ATTRIBUTE_free(new_attr);
if (sk != NULL) sk_X509_ATTRIBUTE_free(sk);
@@ -214,7 +214,7 @@ X509_ATTRIBUTE *X509_ATTRIBUTE_create_by_NID(X509_ATTRIBUTE **attr, int nid,
obj=OBJ_nid2obj(nid);
if (obj == NULL)
{
- OPENSSL_PUT_ERROR(X509, X509_ATTRIBUTE_create_by_NID, X509_R_UNKNOWN_NID);
+ OPENSSL_PUT_ERROR(X509, X509_R_UNKNOWN_NID);
return(NULL);
}
return X509_ATTRIBUTE_create_by_OBJ(attr,obj,atrtype,data,len);
@@ -229,7 +229,7 @@ X509_ATTRIBUTE *X509_ATTRIBUTE_create_by_OBJ(X509_ATTRIBUTE **attr,
{
if ((ret=X509_ATTRIBUTE_new()) == NULL)
{
- OPENSSL_PUT_ERROR(X509, X509_ATTRIBUTE_create_by_OBJ, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
return(NULL);
}
}
@@ -258,7 +258,7 @@ X509_ATTRIBUTE *X509_ATTRIBUTE_create_by_txt(X509_ATTRIBUTE **attr,
obj=OBJ_txt2obj(atrname, 0);
if (obj == NULL)
{
- OPENSSL_PUT_ERROR(X509, X509_ATTRIBUTE_create_by_txt, X509_R_INVALID_FIELD_NAME);
+ OPENSSL_PUT_ERROR(X509, X509_R_INVALID_FIELD_NAME);
ERR_add_error_data(2, "name=", atrname);
return(NULL);
}
@@ -286,7 +286,7 @@ int X509_ATTRIBUTE_set1_data(X509_ATTRIBUTE *attr, int attrtype, const void *dat
stmp = ASN1_STRING_set_by_NID(NULL, data, len, attrtype,
OBJ_obj2nid(attr->object));
if(!stmp) {
- OPENSSL_PUT_ERROR(X509, X509_ATTRIBUTE_set1_data, ERR_R_ASN1_LIB);
+ OPENSSL_PUT_ERROR(X509, ERR_R_ASN1_LIB);
return 0;
}
atype = stmp->type;
@@ -314,7 +314,7 @@ int X509_ATTRIBUTE_set1_data(X509_ATTRIBUTE *attr, int attrtype, const void *dat
if(!sk_ASN1_TYPE_push(attr->value.set, ttmp)) goto err;
return 1;
err:
- OPENSSL_PUT_ERROR(X509, X509_ATTRIBUTE_set1_data, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
return 0;
}
@@ -338,7 +338,7 @@ void *X509_ATTRIBUTE_get0_data(X509_ATTRIBUTE *attr, int idx,
ttmp = X509_ATTRIBUTE_get0_type(attr, idx);
if(!ttmp) return NULL;
if(atrtype != ASN1_TYPE_get(ttmp)){
- OPENSSL_PUT_ERROR(X509, X509_ATTRIBUTE_get0_data, X509_R_WRONG_TYPE);
+ OPENSSL_PUT_ERROR(X509, X509_R_WRONG_TYPE);
return NULL;
}
return ttmp->value.ptr;
diff --git a/src/crypto/x509/x509_cmp.c b/src/crypto/x509/x509_cmp.c
index 712e36b..0e35f3e 100644
--- a/src/crypto/x509/x509_cmp.c
+++ b/src/crypto/x509/x509_cmp.c
@@ -333,13 +333,13 @@ int X509_check_private_key(X509 *x, EVP_PKEY *k)
case 1:
break;
case 0:
- OPENSSL_PUT_ERROR(X509, X509_check_private_key, X509_R_KEY_VALUES_MISMATCH);
+ OPENSSL_PUT_ERROR(X509, X509_R_KEY_VALUES_MISMATCH);
break;
case -1:
- OPENSSL_PUT_ERROR(X509, X509_check_private_key, X509_R_KEY_TYPE_MISMATCH);
+ OPENSSL_PUT_ERROR(X509, X509_R_KEY_TYPE_MISMATCH);
break;
case -2:
- OPENSSL_PUT_ERROR(X509, X509_check_private_key, X509_R_UNKNOWN_KEY_TYPE);
+ OPENSSL_PUT_ERROR(X509, X509_R_UNKNOWN_KEY_TYPE);
}
if (xk)
EVP_PKEY_free(xk);
diff --git a/src/crypto/x509/x509_lu.c b/src/crypto/x509/x509_lu.c
index a662305..6d7bc26 100644
--- a/src/crypto/x509/x509_lu.c
+++ b/src/crypto/x509/x509_lu.c
@@ -345,7 +345,7 @@ int X509_STORE_add_cert(X509_STORE *ctx, X509 *x)
obj=(X509_OBJECT *)OPENSSL_malloc(sizeof(X509_OBJECT));
if (obj == NULL)
{
- OPENSSL_PUT_ERROR(X509, X509_STORE_add_cert, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
return 0;
}
obj->type=X509_LU_X509;
@@ -359,7 +359,7 @@ int X509_STORE_add_cert(X509_STORE *ctx, X509 *x)
{
X509_OBJECT_free_contents(obj);
OPENSSL_free(obj);
- OPENSSL_PUT_ERROR(X509, X509_STORE_add_cert, X509_R_CERT_ALREADY_IN_HASH_TABLE);
+ OPENSSL_PUT_ERROR(X509, X509_R_CERT_ALREADY_IN_HASH_TABLE);
ret=0;
}
else sk_X509_OBJECT_push(ctx->objs, obj);
@@ -378,7 +378,7 @@ int X509_STORE_add_crl(X509_STORE *ctx, X509_CRL *x)
obj=(X509_OBJECT *)OPENSSL_malloc(sizeof(X509_OBJECT));
if (obj == NULL)
{
- OPENSSL_PUT_ERROR(X509, X509_STORE_add_crl, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
return 0;
}
obj->type=X509_LU_CRL;
@@ -392,7 +392,7 @@ int X509_STORE_add_crl(X509_STORE *ctx, X509_CRL *x)
{
X509_OBJECT_free_contents(obj);
OPENSSL_free(obj);
- OPENSSL_PUT_ERROR(X509, X509_STORE_add_crl, X509_R_CERT_ALREADY_IN_HASH_TABLE);
+ OPENSSL_PUT_ERROR(X509, X509_R_CERT_ALREADY_IN_HASH_TABLE);
ret=0;
}
else sk_X509_OBJECT_push(ctx->objs, obj);
@@ -410,7 +410,7 @@ void X509_OBJECT_up_ref_count(X509_OBJECT *a)
X509_up_ref(a->data.x509);
break;
case X509_LU_CRL:
- CRYPTO_refcount_inc(&a->data.crl->references);
+ X509_CRL_up_ref(a->data.crl);
break;
}
}
@@ -572,7 +572,7 @@ STACK_OF(X509_CRL)* X509_STORE_get1_crls(X509_STORE_CTX *ctx, X509_NAME *nm)
{
obj = sk_X509_OBJECT_value(ctx->ctx->objs, idx);
x = obj->data.crl;
- CRYPTO_refcount_inc(&x->references);
+ X509_CRL_up_ref(x);
if (!sk_X509_CRL_push(sk, x))
{
CRYPTO_MUTEX_unlock(&ctx->ctx->objs_lock);
@@ -641,7 +641,7 @@ int X509_STORE_CTX_get1_issuer(X509 **issuer, X509_STORE_CTX *ctx, X509 *x)
if (ok == X509_LU_RETRY)
{
X509_OBJECT_free_contents(&obj);
- OPENSSL_PUT_ERROR(X509, X509_STORE_CTX_get1_issuer, X509_R_SHOULD_RETRY);
+ OPENSSL_PUT_ERROR(X509, X509_R_SHOULD_RETRY);
return -1;
}
else if (ok != X509_LU_FAIL)
diff --git a/src/crypto/x509/x509_obj.c b/src/crypto/x509/x509_obj.c
index 914e0de..b6f0816 100644
--- a/src/crypto/x509/x509_obj.c
+++ b/src/crypto/x509/x509_obj.c
@@ -184,7 +184,7 @@ char *X509_NAME_oneline(X509_NAME *a, char *buf, int len)
*p = '\0';
return(p);
err:
- OPENSSL_PUT_ERROR(X509, X509_NAME_oneline, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
if (b != NULL) BUF_MEM_free(b);
return(NULL);
}
diff --git a/src/crypto/x509/x509_r2x.c b/src/crypto/x509/x509_r2x.c
index 3c8e9c0..85979ac 100644
--- a/src/crypto/x509/x509_r2x.c
+++ b/src/crypto/x509/x509_r2x.c
@@ -72,7 +72,7 @@ X509 *X509_REQ_to_X509(X509_REQ *r, int days, EVP_PKEY *pkey)
if ((ret=X509_new()) == NULL)
{
- OPENSSL_PUT_ERROR(X509, X509_REQ_to_X509, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
goto err;
}
diff --git a/src/crypto/x509/x509_req.c b/src/crypto/x509/x509_req.c
index 2732d6e..01c5113 100644
--- a/src/crypto/x509/x509_req.c
+++ b/src/crypto/x509/x509_req.c
@@ -77,7 +77,7 @@ X509_REQ *X509_to_X509_REQ(X509 *x, EVP_PKEY *pkey, const EVP_MD *md)
ret=X509_REQ_new();
if (ret == NULL)
{
- OPENSSL_PUT_ERROR(X509, X509_to_X509_REQ, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
goto err;
}
@@ -128,24 +128,24 @@ int X509_REQ_check_private_key(X509_REQ *x, EVP_PKEY *k)
ok=1;
break;
case 0:
- OPENSSL_PUT_ERROR(X509, X509_REQ_check_private_key, X509_R_KEY_VALUES_MISMATCH);
+ OPENSSL_PUT_ERROR(X509, X509_R_KEY_VALUES_MISMATCH);
break;
case -1:
- OPENSSL_PUT_ERROR(X509, X509_REQ_check_private_key, X509_R_KEY_TYPE_MISMATCH);
+ OPENSSL_PUT_ERROR(X509, X509_R_KEY_TYPE_MISMATCH);
break;
case -2:
if (k->type == EVP_PKEY_EC)
{
- OPENSSL_PUT_ERROR(X509, X509_REQ_check_private_key, ERR_R_EC_LIB);
+ OPENSSL_PUT_ERROR(X509, ERR_R_EC_LIB);
break;
}
if (k->type == EVP_PKEY_DH)
{
/* No idea */
- OPENSSL_PUT_ERROR(X509, X509_REQ_check_private_key, X509_R_CANT_CHECK_DH_KEY);
+ OPENSSL_PUT_ERROR(X509, X509_R_CANT_CHECK_DH_KEY);
break;
}
- OPENSSL_PUT_ERROR(X509, X509_REQ_check_private_key, X509_R_UNKNOWN_KEY_TYPE);
+ OPENSSL_PUT_ERROR(X509, X509_R_UNKNOWN_KEY_TYPE);
}
EVP_PKEY_free(xk);
diff --git a/src/crypto/x509/x509_trs.c b/src/crypto/x509/x509_trs.c
index 9b7cc9c..820e605 100644
--- a/src/crypto/x509/x509_trs.c
+++ b/src/crypto/x509/x509_trs.c
@@ -156,7 +156,7 @@ int X509_TRUST_get_by_id(int id)
int X509_TRUST_set(int *t, int trust)
{
if(X509_TRUST_get_by_id(trust) == -1) {
- OPENSSL_PUT_ERROR(X509, X509_TRUST_set, X509_R_INVALID_TRUST);
+ OPENSSL_PUT_ERROR(X509, X509_R_INVALID_TRUST);
return 0;
}
*t = trust;
@@ -179,7 +179,7 @@ int X509_TRUST_add(int id, int flags, int (*ck)(X509_TRUST *, X509 *, int),
/* Need a new entry */
if(idx == -1) {
if(!(trtmp = OPENSSL_malloc(sizeof(X509_TRUST)))) {
- OPENSSL_PUT_ERROR(X509, X509_TRUST_add, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
return 0;
}
trtmp->flags = X509_TRUST_DYNAMIC;
@@ -188,7 +188,7 @@ int X509_TRUST_add(int id, int flags, int (*ck)(X509_TRUST *, X509 *, int),
/* Duplicate the supplied name. */
name_dup = BUF_strdup(name);
if (name_dup == NULL) {
- OPENSSL_PUT_ERROR(X509, X509_TRUST_add, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
if (idx == -1)
OPENSSL_free(trtmp);
return 0;
@@ -210,12 +210,12 @@ int X509_TRUST_add(int id, int flags, int (*ck)(X509_TRUST *, X509 *, int),
/* If its a new entry manage the dynamic table */
if(idx == -1) {
if(!trtable && !(trtable = sk_X509_TRUST_new(tr_cmp))) {
- OPENSSL_PUT_ERROR(X509, X509_TRUST_add, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
trtable_free(trtmp);
return 0;
}
if (!sk_X509_TRUST_push(trtable, trtmp)) {
- OPENSSL_PUT_ERROR(X509, X509_TRUST_add, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
trtable_free(trtmp);
return 0;
}
diff --git a/src/crypto/x509/x509_v3.c b/src/crypto/x509/x509_v3.c
index 0fc9a9a..b042985 100644
--- a/src/crypto/x509/x509_v3.c
+++ b/src/crypto/x509/x509_v3.c
@@ -147,7 +147,7 @@ STACK_OF(X509_EXTENSION) *X509v3_add_ext(STACK_OF(X509_EXTENSION) **x,
if (x == NULL)
{
- OPENSSL_PUT_ERROR(X509, X509v3_add_ext, ERR_R_PASSED_NULL_PARAMETER);
+ OPENSSL_PUT_ERROR(X509, ERR_R_PASSED_NULL_PARAMETER);
goto err2;
}
@@ -171,7 +171,7 @@ STACK_OF(X509_EXTENSION) *X509v3_add_ext(STACK_OF(X509_EXTENSION) **x,
*x=sk;
return(sk);
err:
- OPENSSL_PUT_ERROR(X509, X509v3_add_ext, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
err2:
if (new_ex != NULL) X509_EXTENSION_free(new_ex);
if (sk != NULL) sk_X509_EXTENSION_free(sk);
@@ -187,7 +187,7 @@ X509_EXTENSION *X509_EXTENSION_create_by_NID(X509_EXTENSION **ex, int nid,
obj=OBJ_nid2obj(nid);
if (obj == NULL)
{
- OPENSSL_PUT_ERROR(X509, X509_EXTENSION_create_by_NID, X509_R_UNKNOWN_NID);
+ OPENSSL_PUT_ERROR(X509, X509_R_UNKNOWN_NID);
return(NULL);
}
ret=X509_EXTENSION_create_by_OBJ(ex,obj,crit,data);
@@ -203,7 +203,7 @@ X509_EXTENSION *X509_EXTENSION_create_by_OBJ(X509_EXTENSION **ex,
{
if ((ret=X509_EXTENSION_new()) == NULL)
{
- OPENSSL_PUT_ERROR(X509, X509_EXTENSION_create_by_OBJ, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
return(NULL);
}
}
diff --git a/src/crypto/x509/x509_vfy.c b/src/crypto/x509/x509_vfy.c
index f53f279..5d856f0 100644
--- a/src/crypto/x509/x509_vfy.c
+++ b/src/crypto/x509/x509_vfy.c
@@ -72,7 +72,8 @@
#include "../internal.h"
-static CRYPTO_EX_DATA_CLASS g_ex_data_class = CRYPTO_EX_DATA_CLASS_INIT;
+static CRYPTO_EX_DATA_CLASS g_ex_data_class =
+ CRYPTO_EX_DATA_CLASS_INIT_WITH_APP_DATA;
/* CRL score values */
@@ -201,7 +202,7 @@ int X509_verify_cert(X509_STORE_CTX *ctx)
STACK_OF(X509) *sktmp=NULL;
if (ctx->cert == NULL)
{
- OPENSSL_PUT_ERROR(X509, X509_verify_cert, X509_R_NO_CERT_SET_FOR_US_TO_VERIFY);
+ OPENSSL_PUT_ERROR(X509, X509_R_NO_CERT_SET_FOR_US_TO_VERIFY);
return -1;
}
@@ -214,7 +215,7 @@ int X509_verify_cert(X509_STORE_CTX *ctx)
if ( ((ctx->chain=sk_X509_new_null()) == NULL) ||
(!sk_X509_push(ctx->chain,ctx->cert)))
{
- OPENSSL_PUT_ERROR(X509, X509_verify_cert, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
goto end;
}
X509_up_ref(ctx->cert);
@@ -225,7 +226,7 @@ int X509_verify_cert(X509_STORE_CTX *ctx)
if (ctx->untrusted != NULL
&& (sktmp=sk_X509_dup(ctx->untrusted)) == NULL)
{
- OPENSSL_PUT_ERROR(X509, X509_verify_cert, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
goto end;
}
@@ -251,7 +252,7 @@ int X509_verify_cert(X509_STORE_CTX *ctx)
{
ok = ctx->get_issuer(&xtmp, ctx, x);
if (ok < 0)
- return ok;
+ goto end;
/* If successful for now free up cert so it
* will be picked up again later.
*/
@@ -270,10 +271,10 @@ int X509_verify_cert(X509_STORE_CTX *ctx)
{
if (!sk_X509_push(ctx->chain,xtmp))
{
- OPENSSL_PUT_ERROR(X509, X509_verify_cert, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
goto end;
}
- CRYPTO_refcount_inc(&xtmp->references);
+ X509_up_ref(xtmp);
(void)sk_X509_delete_ptr(sktmp,xtmp);
ctx->last_untrusted++;
x=xtmp;
@@ -349,15 +350,16 @@ int X509_verify_cert(X509_STORE_CTX *ctx)
ok = ctx->get_issuer(&xtmp, ctx, x);
- if (ok < 0) return ok;
+ if (ok < 0) goto end;
if (ok == 0) break;
x = xtmp;
if (!sk_X509_push(ctx->chain,x))
{
X509_free(xtmp);
- OPENSSL_PUT_ERROR(X509, X509_verify_cert, ERR_R_MALLOC_FAILURE);
- return 0;
+ OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
+ ok = 0;
+ goto end;
}
num++;
}
@@ -990,7 +992,7 @@ static int get_crl_sk(X509_STORE_CTX *ctx, X509_CRL **pcrl, X509_CRL **pdcrl,
*pissuer = best_crl_issuer;
*pscore = best_score;
*preasons = best_reasons;
- CRYPTO_refcount_inc(&best_crl->references);
+ X509_CRL_up_ref(best_crl);
if (*pdcrl)
{
X509_CRL_free(*pdcrl);
@@ -1097,7 +1099,7 @@ static void get_delta_sk(X509_STORE_CTX *ctx, X509_CRL **dcrl, int *pscore,
{
if (check_crl_time(ctx, delta, 0))
*pscore |= CRL_SCORE_TIME_DELTA;
- CRYPTO_refcount_inc(&delta->references);
+ X509_CRL_up_ref(delta);
*dcrl = delta;
return;
}
@@ -1634,7 +1636,7 @@ static int check_policy(X509_STORE_CTX *ctx)
ctx->param->policies, ctx->param->flags);
if (ret == 0)
{
- OPENSSL_PUT_ERROR(X509, check_policy, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
return 0;
}
/* Invalid or inconsistent extensions */
@@ -1983,44 +1985,44 @@ X509_CRL *X509_CRL_diff(X509_CRL *base, X509_CRL *newer,
/* CRLs can't be delta already */
if (base->base_crl_number || newer->base_crl_number)
{
- OPENSSL_PUT_ERROR(X509, X509_CRL_diff, X509_R_CRL_ALREADY_DELTA);
+ OPENSSL_PUT_ERROR(X509, X509_R_CRL_ALREADY_DELTA);
return NULL;
}
/* Base and new CRL must have a CRL number */
if (!base->crl_number || !newer->crl_number)
{
- OPENSSL_PUT_ERROR(X509, X509_CRL_diff, X509_R_NO_CRL_NUMBER);
+ OPENSSL_PUT_ERROR(X509, X509_R_NO_CRL_NUMBER);
return NULL;
}
/* Issuer names must match */
if (X509_NAME_cmp(X509_CRL_get_issuer(base),
X509_CRL_get_issuer(newer)))
{
- OPENSSL_PUT_ERROR(X509, X509_CRL_diff, X509_R_ISSUER_MISMATCH);
+ OPENSSL_PUT_ERROR(X509, X509_R_ISSUER_MISMATCH);
return NULL;
}
/* AKID and IDP must match */
if (!crl_extension_match(base, newer, NID_authority_key_identifier))
{
- OPENSSL_PUT_ERROR(X509, X509_CRL_diff, X509_R_AKID_MISMATCH);
+ OPENSSL_PUT_ERROR(X509, X509_R_AKID_MISMATCH);
return NULL;
}
if (!crl_extension_match(base, newer, NID_issuing_distribution_point))
{
- OPENSSL_PUT_ERROR(X509, X509_CRL_diff, X509_R_IDP_MISMATCH);
+ OPENSSL_PUT_ERROR(X509, X509_R_IDP_MISMATCH);
return NULL;
}
/* Newer CRL number must exceed full CRL number */
if (ASN1_INTEGER_cmp(newer->crl_number, base->crl_number) <= 0)
{
- OPENSSL_PUT_ERROR(X509, X509_CRL_diff, X509_R_NEWER_CRL_NOT_NEWER);
+ OPENSSL_PUT_ERROR(X509, X509_R_NEWER_CRL_NOT_NEWER);
return NULL;
}
/* CRLs must verify */
if (skey && (X509_CRL_verify(base, skey) <= 0 ||
X509_CRL_verify(newer, skey) <= 0))
{
- OPENSSL_PUT_ERROR(X509, X509_CRL_diff, X509_R_CRL_VERIFY_FAILURE);
+ OPENSSL_PUT_ERROR(X509, X509_R_CRL_VERIFY_FAILURE);
return NULL;
}
/* Create new CRL */
@@ -2085,7 +2087,7 @@ X509_CRL *X509_CRL_diff(X509_CRL *base, X509_CRL *newer,
return crl;
memerr:
- OPENSSL_PUT_ERROR(X509, X509_CRL_diff, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
if (crl)
X509_CRL_free(crl);
return NULL;
@@ -2210,7 +2212,7 @@ int X509_STORE_CTX_purpose_inherit(X509_STORE_CTX *ctx, int def_purpose,
idx = X509_PURPOSE_get_by_id(purpose);
if (idx == -1)
{
- OPENSSL_PUT_ERROR(X509, X509_STORE_CTX_purpose_inherit, X509_R_UNKNOWN_PURPOSE_ID);
+ OPENSSL_PUT_ERROR(X509, X509_R_UNKNOWN_PURPOSE_ID);
return 0;
}
ptmp = X509_PURPOSE_get0(idx);
@@ -2219,7 +2221,7 @@ int X509_STORE_CTX_purpose_inherit(X509_STORE_CTX *ctx, int def_purpose,
idx = X509_PURPOSE_get_by_id(def_purpose);
if (idx == -1)
{
- OPENSSL_PUT_ERROR(X509, X509_STORE_CTX_purpose_inherit, X509_R_UNKNOWN_PURPOSE_ID);
+ OPENSSL_PUT_ERROR(X509, X509_R_UNKNOWN_PURPOSE_ID);
return 0;
}
ptmp = X509_PURPOSE_get0(idx);
@@ -2232,7 +2234,7 @@ int X509_STORE_CTX_purpose_inherit(X509_STORE_CTX *ctx, int def_purpose,
idx = X509_TRUST_get_by_id(trust);
if (idx == -1)
{
- OPENSSL_PUT_ERROR(X509, X509_STORE_CTX_purpose_inherit, X509_R_UNKNOWN_TRUST_ID);
+ OPENSSL_PUT_ERROR(X509, X509_R_UNKNOWN_TRUST_ID);
return 0;
}
}
@@ -2248,7 +2250,7 @@ X509_STORE_CTX *X509_STORE_CTX_new(void)
ctx = (X509_STORE_CTX *)OPENSSL_malloc(sizeof(X509_STORE_CTX));
if (!ctx)
{
- OPENSSL_PUT_ERROR(X509, X509_STORE_CTX_new, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
return NULL;
}
memset(ctx, 0, sizeof(X509_STORE_CTX));
@@ -2371,7 +2373,7 @@ err:
}
memset(ctx, 0, sizeof(X509_STORE_CTX));
- OPENSSL_PUT_ERROR(X509, X509_STORE_CTX_init, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
return 0;
}
diff --git a/src/crypto/x509/x509cset.c b/src/crypto/x509/x509cset.c
index b526c69..82d61d0 100644
--- a/src/crypto/x509/x509cset.c
+++ b/src/crypto/x509/x509cset.c
@@ -57,6 +57,8 @@
#include <openssl/obj.h>
#include <openssl/x509.h>
+#include "../internal.h"
+
int X509_CRL_set_version(X509_CRL *x, long version)
{
@@ -128,6 +130,11 @@ int X509_CRL_sort(X509_CRL *c)
return 1;
}
+void X509_CRL_up_ref(X509_CRL *crl)
+ {
+ CRYPTO_refcount_inc(&crl->references);
+ }
+
int X509_REVOKED_set_revocationDate(X509_REVOKED *x, ASN1_TIME *tm)
{
ASN1_TIME *in;
diff --git a/src/crypto/x509/x509name.c b/src/crypto/x509/x509name.c
index 042d18b..7bb3aa1 100644
--- a/src/crypto/x509/x509name.c
+++ b/src/crypto/x509/x509name.c
@@ -254,7 +254,7 @@ int X509_NAME_add_entry(X509_NAME *name, X509_NAME_ENTRY *ne, int loc,
new_name->set=set;
if (!sk_X509_NAME_ENTRY_insert(sk,new_name,loc))
{
- OPENSSL_PUT_ERROR(X509, X509_NAME_add_entry, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
goto err;
}
if (inc)
@@ -279,7 +279,7 @@ X509_NAME_ENTRY *X509_NAME_ENTRY_create_by_txt(X509_NAME_ENTRY **ne,
obj=OBJ_txt2obj(field, 0);
if (obj == NULL)
{
- OPENSSL_PUT_ERROR(X509, X509_NAME_ENTRY_create_by_txt, X509_R_INVALID_FIELD_NAME);
+ OPENSSL_PUT_ERROR(X509, X509_R_INVALID_FIELD_NAME);
ERR_add_error_data(2, "name=", field);
return(NULL);
}
@@ -297,7 +297,7 @@ X509_NAME_ENTRY *X509_NAME_ENTRY_create_by_NID(X509_NAME_ENTRY **ne, int nid,
obj=OBJ_nid2obj(nid);
if (obj == NULL)
{
- OPENSSL_PUT_ERROR(X509, X509_NAME_ENTRY_create_by_NID, X509_R_UNKNOWN_NID);
+ OPENSSL_PUT_ERROR(X509, X509_R_UNKNOWN_NID);
return(NULL);
}
nentry = X509_NAME_ENTRY_create_by_OBJ(ne,obj,type,bytes,len);
@@ -336,7 +336,7 @@ int X509_NAME_ENTRY_set_object(X509_NAME_ENTRY *ne, const ASN1_OBJECT *obj)
{
if ((ne == NULL) || (obj == NULL))
{
- OPENSSL_PUT_ERROR(X509, X509_NAME_ENTRY_set_object, ERR_R_PASSED_NULL_PARAMETER);
+ OPENSSL_PUT_ERROR(X509, ERR_R_PASSED_NULL_PARAMETER);
return(0);
}
ASN1_OBJECT_free(ne->object);
diff --git a/src/crypto/x509/x509spki.c b/src/crypto/x509/x509spki.c
index 9bab957..ccf93e0 100644
--- a/src/crypto/x509/x509spki.c
+++ b/src/crypto/x509/x509spki.c
@@ -84,15 +84,15 @@ NETSCAPE_SPKI * NETSCAPE_SPKI_b64_decode(const char *str, int len)
if (len <= 0)
len = strlen(str);
if (!EVP_DecodedLength(&spki_len, len)) {
- OPENSSL_PUT_ERROR(X509, NETSCAPE_SPKI_b64_decode, X509_R_BASE64_DECODE_ERROR);
+ OPENSSL_PUT_ERROR(X509, X509_R_BASE64_DECODE_ERROR);
return NULL;
}
if (!(spki_der = OPENSSL_malloc(spki_len))) {
- OPENSSL_PUT_ERROR(X509, NETSCAPE_SPKI_b64_decode, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
return NULL;
}
if (!EVP_DecodeBase64(spki_der, &spki_len, spki_len, (const uint8_t *)str, len)) {
- OPENSSL_PUT_ERROR(X509, NETSCAPE_SPKI_b64_decode, X509_R_BASE64_DECODE_ERROR);
+ OPENSSL_PUT_ERROR(X509, X509_R_BASE64_DECODE_ERROR);
OPENSSL_free(spki_der);
return NULL;
}
@@ -113,18 +113,18 @@ char * NETSCAPE_SPKI_b64_encode(NETSCAPE_SPKI *spki)
der_len = i2d_NETSCAPE_SPKI(spki, NULL);
if (!EVP_EncodedLength(&b64_len, der_len))
{
- OPENSSL_PUT_ERROR(X509, NETSCAPE_SPKI_b64_encode, ERR_R_OVERFLOW);
+ OPENSSL_PUT_ERROR(X509, ERR_R_OVERFLOW);
return NULL;
}
der_spki = OPENSSL_malloc(der_len);
if (der_spki == NULL) {
- OPENSSL_PUT_ERROR(X509, NETSCAPE_SPKI_b64_encode, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
return NULL;
}
b64_str = OPENSSL_malloc(b64_len);
if (b64_str == NULL) {
OPENSSL_free(der_spki);
- OPENSSL_PUT_ERROR(X509, NETSCAPE_SPKI_b64_encode, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
return NULL;
}
p = der_spki;
diff --git a/src/crypto/x509/x_all.c b/src/crypto/x509/x_all.c
index 785fd1e..d7f2d29 100644
--- a/src/crypto/x509/x_all.c
+++ b/src/crypto/x509/x_all.c
@@ -64,9 +64,6 @@
#include <openssl/x509.h>
-extern const ASN1_ITEM RSAPrivateKey_it;
-extern const ASN1_ITEM RSAPublicKey_it;
-
int X509_verify(X509 *a, EVP_PKEY *r)
{
if (X509_ALGOR_cmp(a->sig_alg, a->cert_info->signature))
@@ -144,6 +141,12 @@ int NETSCAPE_SPKI_sign(NETSCAPE_SPKI *x, EVP_PKEY *pkey, const EVP_MD *md)
x->signature, x->spkac,pkey,md));
}
+int NETSCAPE_SPKI_verify(NETSCAPE_SPKI *x, EVP_PKEY *pkey)
+ {
+ return (ASN1_item_verify(ASN1_ITEM_rptr(NETSCAPE_SPKAC), x->sig_algor,
+ x->signature, x->spkac, pkey));
+ }
+
#ifndef OPENSSL_NO_FP_API
X509 *d2i_X509_fp(FILE *fp, X509 **x509)
{
@@ -239,17 +242,17 @@ int i2d_X509_REQ_bio(BIO *bp, X509_REQ *req)
#ifndef OPENSSL_NO_FP_API
RSA *d2i_RSAPrivateKey_fp(FILE *fp, RSA **rsa)
{
- return ASN1_item_d2i_fp(ASN1_ITEM_rptr(RSAPrivateKey), fp, rsa);
+ return ASN1_d2i_fp_of(RSA, RSA_new, d2i_RSAPrivateKey, fp, rsa);
}
int i2d_RSAPrivateKey_fp(FILE *fp, RSA *rsa)
{
- return ASN1_item_i2d_fp(ASN1_ITEM_rptr(RSAPrivateKey), fp, rsa);
+ return ASN1_i2d_fp_of_const(RSA, i2d_RSAPrivateKey, fp, rsa);
}
RSA *d2i_RSAPublicKey_fp(FILE *fp, RSA **rsa)
{
- return ASN1_item_d2i_fp(ASN1_ITEM_rptr(RSAPublicKey), fp, rsa);
+ return ASN1_d2i_fp_of(RSA, RSA_new, d2i_RSAPublicKey, fp, rsa);
}
RSA *d2i_RSA_PUBKEY_fp(FILE *fp, RSA **rsa)
@@ -261,7 +264,7 @@ RSA *d2i_RSA_PUBKEY_fp(FILE *fp, RSA **rsa)
int i2d_RSAPublicKey_fp(FILE *fp, RSA *rsa)
{
- return ASN1_item_i2d_fp(ASN1_ITEM_rptr(RSAPublicKey), fp, rsa);
+ return ASN1_i2d_fp_of_const(RSA, i2d_RSAPublicKey, fp, rsa);
}
int i2d_RSA_PUBKEY_fp(FILE *fp, RSA *rsa)
@@ -272,17 +275,17 @@ int i2d_RSA_PUBKEY_fp(FILE *fp, RSA *rsa)
RSA *d2i_RSAPrivateKey_bio(BIO *bp, RSA **rsa)
{
- return ASN1_item_d2i_bio(ASN1_ITEM_rptr(RSAPrivateKey), bp, rsa);
+ return ASN1_d2i_bio_of(RSA, RSA_new, d2i_RSAPrivateKey, bp, rsa);
}
int i2d_RSAPrivateKey_bio(BIO *bp, RSA *rsa)
{
- return ASN1_item_i2d_bio(ASN1_ITEM_rptr(RSAPrivateKey), bp, rsa);
+ return ASN1_i2d_bio_of_const(RSA, i2d_RSAPrivateKey, bp, rsa);
}
RSA *d2i_RSAPublicKey_bio(BIO *bp, RSA **rsa)
{
- return ASN1_item_d2i_bio(ASN1_ITEM_rptr(RSAPublicKey), bp, rsa);
+ return ASN1_d2i_bio_of(RSA, RSA_new, d2i_RSAPublicKey, bp, rsa);
}
@@ -293,7 +296,7 @@ RSA *d2i_RSA_PUBKEY_bio(BIO *bp, RSA **rsa)
int i2d_RSAPublicKey_bio(BIO *bp, RSA *rsa)
{
- return ASN1_item_i2d_bio(ASN1_ITEM_rptr(RSAPublicKey), bp, rsa);
+ return ASN1_i2d_bio_of_const(RSA, i2d_RSAPublicKey, bp, rsa);
}
int i2d_RSA_PUBKEY_bio(BIO *bp, RSA *rsa)
diff --git a/src/crypto/x509/x_crl.c b/src/crypto/x509/x_crl.c
index 2f41bb1..d516872 100644
--- a/src/crypto/x509/x_crl.c
+++ b/src/crypto/x509/x_crl.c
@@ -400,7 +400,7 @@ int X509_CRL_add0_revoked(X509_CRL *crl, X509_REVOKED *rev)
if(!inf->revoked)
inf->revoked = sk_X509_REVOKED_new(X509_REVOKED_cmp);
if(!inf->revoked || !sk_X509_REVOKED_push(inf->revoked, rev)) {
- OPENSSL_PUT_ERROR(X509, X509_CRL_add0_revoked, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
return 0;
}
inf->enc.modified = 1;
diff --git a/src/crypto/x509/x_info.c b/src/crypto/x509/x_info.c
index f9e9ab8..be579d7 100644
--- a/src/crypto/x509/x_info.c
+++ b/src/crypto/x509/x_info.c
@@ -69,7 +69,7 @@ X509_INFO *X509_INFO_new(void)
ret=(X509_INFO *)OPENSSL_malloc(sizeof(X509_INFO));
if (ret == NULL)
{
- OPENSSL_PUT_ERROR(X509, X509_INFO_new, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
return(NULL);
}
diff --git a/src/crypto/x509/x_name.c b/src/crypto/x509/x_name.c
index 5cfb3ae..762756b 100644
--- a/src/crypto/x509/x_name.c
+++ b/src/crypto/x509/x_name.c
@@ -150,7 +150,7 @@ static int x509_name_ex_new(ASN1_VALUE **val, const ASN1_ITEM *it)
return 1;
memerr:
- OPENSSL_PUT_ERROR(X509, x509_name_ex_new, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
if (ret)
{
if (ret->entries)
@@ -239,7 +239,7 @@ static int x509_name_ex_d2i(ASN1_VALUE **val,
err:
if (nm.x != NULL)
X509_NAME_free(nm.x);
- OPENSSL_PUT_ERROR(X509, x509_name_ex_d2i, ERR_R_ASN1_LIB);
+ OPENSSL_PUT_ERROR(X509, ERR_R_ASN1_LIB);
return 0;
}
@@ -300,7 +300,7 @@ static int x509_name_encode(X509_NAME *a)
memerr:
sk_STACK_OF_X509_NAME_ENTRY_pop_free(intname.s,
local_sk_X509_NAME_ENTRY_free);
- OPENSSL_PUT_ERROR(X509, x509_name_encode, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
return -1;
}
diff --git a/src/crypto/x509/x_pkey.c b/src/crypto/x509/x_pkey.c
index 5bc6415..f5e98b8 100644
--- a/src/crypto/x509/x_pkey.c
+++ b/src/crypto/x509/x_pkey.c
@@ -69,7 +69,7 @@ X509_PKEY *X509_PKEY_new(void)
X509_PKEY *ret = OPENSSL_malloc(sizeof(X509_PKEY));
if (ret == NULL)
{
- OPENSSL_PUT_ERROR(X509, X509_PKEY_new, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
goto err;
}
memset(ret, 0, sizeof(X509_PKEY));
diff --git a/src/crypto/x509/x_pubkey.c b/src/crypto/x509/x_pubkey.c
index c2e0863..a16edca 100644
--- a/src/crypto/x509/x_pubkey.c
+++ b/src/crypto/x509/x_pubkey.c
@@ -100,19 +100,19 @@ int X509_PUBKEY_set(X509_PUBKEY **x, EVP_PKEY *pkey)
{
if (!pkey->ameth->pub_encode(pk, pkey))
{
- OPENSSL_PUT_ERROR(X509, X509_PUBKEY_set, X509_R_PUBLIC_KEY_ENCODE_ERROR);
+ OPENSSL_PUT_ERROR(X509, X509_R_PUBLIC_KEY_ENCODE_ERROR);
goto error;
}
}
else
{
- OPENSSL_PUT_ERROR(X509, X509_PUBKEY_set, X509_R_METHOD_NOT_SUPPORTED);
+ OPENSSL_PUT_ERROR(X509, X509_R_METHOD_NOT_SUPPORTED);
goto error;
}
}
else
{
- OPENSSL_PUT_ERROR(X509, X509_PUBKEY_set, X509_R_UNSUPPORTED_ALGORITHM);
+ OPENSSL_PUT_ERROR(X509, X509_R_UNSUPPORTED_ALGORITHM);
goto error;
}
@@ -151,13 +151,13 @@ EVP_PKEY *X509_PUBKEY_get(X509_PUBKEY *key)
if ((ret = EVP_PKEY_new()) == NULL)
{
- OPENSSL_PUT_ERROR(X509, X509_PUBKEY_get, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
goto error;
}
if (!EVP_PKEY_set_type(ret, OBJ_obj2nid(key->algor->algorithm)))
{
- OPENSSL_PUT_ERROR(X509, X509_PUBKEY_get, X509_R_UNSUPPORTED_ALGORITHM);
+ OPENSSL_PUT_ERROR(X509, X509_R_UNSUPPORTED_ALGORITHM);
goto error;
}
@@ -165,13 +165,13 @@ EVP_PKEY *X509_PUBKEY_get(X509_PUBKEY *key)
{
if (!ret->ameth->pub_decode(ret, key))
{
- OPENSSL_PUT_ERROR(X509, X509_PUBKEY_get, X509_R_PUBLIC_KEY_DECODE_ERROR);
+ OPENSSL_PUT_ERROR(X509, X509_R_PUBLIC_KEY_DECODE_ERROR);
goto error;
}
}
else
{
- OPENSSL_PUT_ERROR(X509, X509_PUBKEY_get, X509_R_METHOD_NOT_SUPPORTED);
+ OPENSSL_PUT_ERROR(X509, X509_R_METHOD_NOT_SUPPORTED);
goto error;
}
@@ -262,7 +262,7 @@ int i2d_RSA_PUBKEY(const RSA *a, unsigned char **pp)
pktmp = EVP_PKEY_new();
if (!pktmp)
{
- OPENSSL_PUT_ERROR(X509, i2d_RSA_PUBKEY, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
return 0;
}
EVP_PKEY_set1_RSA(pktmp, (RSA*) a);
@@ -301,7 +301,7 @@ int i2d_DSA_PUBKEY(const DSA *a, unsigned char **pp)
pktmp = EVP_PKEY_new();
if(!pktmp)
{
- OPENSSL_PUT_ERROR(X509, i2d_DSA_PUBKEY, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
return 0;
}
EVP_PKEY_set1_DSA(pktmp, (DSA*) a);
@@ -338,7 +338,7 @@ int i2d_EC_PUBKEY(const EC_KEY *a, unsigned char **pp)
if (!a) return(0);
if ((pktmp = EVP_PKEY_new()) == NULL)
{
- OPENSSL_PUT_ERROR(X509, i2d_EC_PUBKEY, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE);
return(0);
}
EVP_PKEY_set1_EC_KEY(pktmp, (EC_KEY*) a);
diff --git a/src/crypto/x509/x_x509a.c b/src/crypto/x509/x_x509a.c
index e13204b..fb7172b 100644
--- a/src/crypto/x509/x_x509a.c
+++ b/src/crypto/x509/x_x509a.c
@@ -133,24 +133,44 @@ unsigned char *X509_keyid_get0(X509 *x, int *len)
int X509_add1_trust_object(X509 *x, ASN1_OBJECT *obj)
{
- X509_CERT_AUX *aux;
- ASN1_OBJECT *objtmp;
- if(!(objtmp = OBJ_dup(obj))) return 0;
- if(!(aux = aux_get(x))) return 0;
- if(!aux->trust
- && !(aux->trust = sk_ASN1_OBJECT_new_null())) return 0;
- return sk_ASN1_OBJECT_push(aux->trust, objtmp);
+ ASN1_OBJECT *objtmp = OBJ_dup(obj);
+ if (objtmp == NULL)
+ goto err;
+ X509_CERT_AUX *aux = aux_get(x);
+ if (aux->trust == NULL)
+ {
+ aux->trust = sk_ASN1_OBJECT_new_null();
+ if (aux->trust == NULL)
+ goto err;
+ }
+ if (!sk_ASN1_OBJECT_push(aux->trust, objtmp))
+ goto err;
+ return 1;
+
+err:
+ ASN1_OBJECT_free(objtmp);
+ return 0;
}
int X509_add1_reject_object(X509 *x, ASN1_OBJECT *obj)
{
- X509_CERT_AUX *aux;
- ASN1_OBJECT *objtmp;
- if(!(objtmp = OBJ_dup(obj))) return 0;
- if(!(aux = aux_get(x))) return 0;
- if(!aux->reject
- && !(aux->reject = sk_ASN1_OBJECT_new_null())) return 0;
- return sk_ASN1_OBJECT_push(aux->reject, objtmp);
+ ASN1_OBJECT *objtmp = OBJ_dup(obj);
+ if (objtmp == NULL)
+ goto err;
+ X509_CERT_AUX *aux = aux_get(x);
+ if (aux->reject == NULL)
+ {
+ aux->reject = sk_ASN1_OBJECT_new_null();
+ if (aux->reject == NULL)
+ goto err;
+ }
+ if (!sk_ASN1_OBJECT_push(aux->reject, objtmp))
+ goto err;
+ return 1;
+
+err:
+ ASN1_OBJECT_free(objtmp);
+ return 0;
}
void X509_trust_clear(X509 *x)
diff --git a/src/crypto/x509v3/CMakeLists.txt b/src/crypto/x509v3/CMakeLists.txt
index c7e6054..5cc1b49 100644
--- a/src/crypto/x509v3/CMakeLists.txt
+++ b/src/crypto/x509v3/CMakeLists.txt
@@ -1,4 +1,4 @@
-include_directories(. .. ../../include)
+include_directories(../../include)
add_library(
x509v3
@@ -46,7 +46,7 @@ add_library(
add_executable(
v3name_test
- v3nametest.c
+ v3name_test.c
$<TARGET_OBJECTS:test_support>
)
@@ -56,7 +56,7 @@ target_link_libraries(v3name_test crypto)
add_executable(
tab_test
- tabtest.c
+ tab_test.c
$<TARGET_OBJECTS:test_support>
)
diff --git a/src/crypto/x509v3/tabtest.c b/src/crypto/x509v3/tab_test.c
index 6b97e91..6b97e91 100644
--- a/src/crypto/x509v3/tabtest.c
+++ b/src/crypto/x509v3/tab_test.c
diff --git a/src/crypto/x509v3/v3_akey.c b/src/crypto/x509v3/v3_akey.c
index f6e6b69..9578a57 100644
--- a/src/crypto/x509v3/v3_akey.c
+++ b/src/crypto/x509v3/v3_akey.c
@@ -144,7 +144,7 @@ static AUTHORITY_KEYID *v2i_AUTHORITY_KEYID(X509V3_EXT_METHOD *method,
}
else
{
- OPENSSL_PUT_ERROR(X509V3, v2i_AUTHORITY_KEYID, X509V3_R_UNKNOWN_OPTION);
+ OPENSSL_PUT_ERROR(X509V3, X509V3_R_UNKNOWN_OPTION);
ERR_add_error_data(2, "name=", cnf->name);
return NULL;
}
@@ -154,7 +154,7 @@ static AUTHORITY_KEYID *v2i_AUTHORITY_KEYID(X509V3_EXT_METHOD *method,
{
if(ctx && (ctx->flags==CTX_TEST))
return AUTHORITY_KEYID_new();
- OPENSSL_PUT_ERROR(X509V3, v2i_AUTHORITY_KEYID, X509V3_R_NO_ISSUER_CERTIFICATE);
+ OPENSSL_PUT_ERROR(X509V3, X509V3_R_NO_ISSUER_CERTIFICATE);
return NULL;
}
@@ -167,7 +167,7 @@ static AUTHORITY_KEYID *v2i_AUTHORITY_KEYID(X509V3_EXT_METHOD *method,
ikeyid = X509V3_EXT_d2i(ext);
if(keyid==2 && !ikeyid)
{
- OPENSSL_PUT_ERROR(X509V3, v2i_AUTHORITY_KEYID, X509V3_R_UNABLE_TO_GET_ISSUER_KEYID);
+ OPENSSL_PUT_ERROR(X509V3, X509V3_R_UNABLE_TO_GET_ISSUER_KEYID);
return NULL;
}
}
@@ -178,7 +178,7 @@ static AUTHORITY_KEYID *v2i_AUTHORITY_KEYID(X509V3_EXT_METHOD *method,
serial = M_ASN1_INTEGER_dup(X509_get_serialNumber(cert));
if(!isname || !serial)
{
- OPENSSL_PUT_ERROR(X509V3, v2i_AUTHORITY_KEYID, X509V3_R_UNABLE_TO_GET_ISSUER_DETAILS);
+ OPENSSL_PUT_ERROR(X509V3, X509V3_R_UNABLE_TO_GET_ISSUER_DETAILS);
goto err;
}
}
@@ -191,7 +191,7 @@ static AUTHORITY_KEYID *v2i_AUTHORITY_KEYID(X509V3_EXT_METHOD *method,
|| !(gen = GENERAL_NAME_new())
|| !sk_GENERAL_NAME_push(gens, gen))
{
- OPENSSL_PUT_ERROR(X509V3, v2i_AUTHORITY_KEYID, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
goto err;
}
gen->type = GEN_DIRNAME;
diff --git a/src/crypto/x509v3/v3_alt.c b/src/crypto/x509v3/v3_alt.c
index f547316..e639f45 100644
--- a/src/crypto/x509v3/v3_alt.c
+++ b/src/crypto/x509v3/v3_alt.c
@@ -250,7 +250,7 @@ static GENERAL_NAMES *v2i_issuer_alt(X509V3_EXT_METHOD *method,
CONF_VALUE *cnf;
size_t i;
if(!(gens = sk_GENERAL_NAME_new_null())) {
- OPENSSL_PUT_ERROR(X509V3, v2i_issuer_alt, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
return NULL;
}
for(i = 0; i < sk_CONF_VALUE_num(nval); i++) {
@@ -282,21 +282,21 @@ static int copy_issuer(X509V3_CTX *ctx, GENERAL_NAMES *gens)
size_t j;
if(ctx && (ctx->flags == CTX_TEST)) return 1;
if(!ctx || !ctx->issuer_cert) {
- OPENSSL_PUT_ERROR(X509V3, copy_issuer, X509V3_R_NO_ISSUER_DETAILS);
+ OPENSSL_PUT_ERROR(X509V3, X509V3_R_NO_ISSUER_DETAILS);
goto err;
}
i = X509_get_ext_by_NID(ctx->issuer_cert, NID_subject_alt_name, -1);
if(i < 0) return 1;
if(!(ext = X509_get_ext(ctx->issuer_cert, i)) ||
!(ialt = X509V3_EXT_d2i(ext)) ) {
- OPENSSL_PUT_ERROR(X509V3, copy_issuer, X509V3_R_ISSUER_DECODE_ERROR);
+ OPENSSL_PUT_ERROR(X509V3, X509V3_R_ISSUER_DECODE_ERROR);
goto err;
}
for(j = 0; j < sk_GENERAL_NAME_num(ialt); j++) {
gen = sk_GENERAL_NAME_value(ialt, j);
if(!sk_GENERAL_NAME_push(gens, gen)) {
- OPENSSL_PUT_ERROR(X509V3, copy_issuer, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
goto err;
}
}
@@ -316,7 +316,7 @@ static GENERAL_NAMES *v2i_subject_alt(X509V3_EXT_METHOD *method,
CONF_VALUE *cnf;
size_t i;
if(!(gens = sk_GENERAL_NAME_new_null())) {
- OPENSSL_PUT_ERROR(X509V3, v2i_subject_alt, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
return NULL;
}
for(i = 0; i < sk_CONF_VALUE_num(nval); i++) {
@@ -354,7 +354,7 @@ static int copy_email(X509V3_CTX *ctx, GENERAL_NAMES *gens, int move_p)
if(ctx != NULL && ctx->flags == CTX_TEST)
return 1;
if(!ctx || (!ctx->subject_cert && !ctx->subject_req)) {
- OPENSSL_PUT_ERROR(X509V3, copy_email, X509V3_R_NO_SUBJECT_DETAILS);
+ OPENSSL_PUT_ERROR(X509V3, X509V3_R_NO_SUBJECT_DETAILS);
goto err;
}
/* Find the subject name */
@@ -374,14 +374,14 @@ static int copy_email(X509V3_CTX *ctx, GENERAL_NAMES *gens, int move_p)
i--;
}
if(!email || !(gen = GENERAL_NAME_new())) {
- OPENSSL_PUT_ERROR(X509V3, copy_email, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
goto err;
}
gen->d.ia5 = email;
email = NULL;
gen->type = GEN_EMAIL;
if(!sk_GENERAL_NAME_push(gens, gen)) {
- OPENSSL_PUT_ERROR(X509V3, copy_email, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
goto err;
}
gen = NULL;
@@ -405,7 +405,7 @@ GENERAL_NAMES *v2i_GENERAL_NAMES(const X509V3_EXT_METHOD *method,
CONF_VALUE *cnf;
size_t i;
if(!(gens = sk_GENERAL_NAME_new_null())) {
- OPENSSL_PUT_ERROR(X509V3, v2i_GENERAL_NAMES, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
return NULL;
}
for(i = 0; i < sk_CONF_VALUE_num(nval); i++) {
@@ -434,7 +434,7 @@ GENERAL_NAME *a2i_GENERAL_NAME(GENERAL_NAME *out,
if(!value)
{
- OPENSSL_PUT_ERROR(X509V3, a2i_GENERAL_NAME, X509V3_R_MISSING_VALUE);
+ OPENSSL_PUT_ERROR(X509V3, X509V3_R_MISSING_VALUE);
return NULL;
}
@@ -445,7 +445,7 @@ GENERAL_NAME *a2i_GENERAL_NAME(GENERAL_NAME *out,
gen = GENERAL_NAME_new();
if(gen == NULL)
{
- OPENSSL_PUT_ERROR(X509V3, a2i_GENERAL_NAME, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
return NULL;
}
}
@@ -463,7 +463,7 @@ GENERAL_NAME *a2i_GENERAL_NAME(GENERAL_NAME *out,
ASN1_OBJECT *obj;
if(!(obj = OBJ_txt2obj(value,0)))
{
- OPENSSL_PUT_ERROR(X509V3, a2i_GENERAL_NAME, X509V3_R_BAD_OBJECT);
+ OPENSSL_PUT_ERROR(X509V3, X509V3_R_BAD_OBJECT);
ERR_add_error_data(2, "value=", value);
goto err;
}
@@ -478,7 +478,7 @@ GENERAL_NAME *a2i_GENERAL_NAME(GENERAL_NAME *out,
gen->d.ip = a2i_IPADDRESS(value);
if(gen->d.ip == NULL)
{
- OPENSSL_PUT_ERROR(X509V3, a2i_GENERAL_NAME, X509V3_R_BAD_IP_ADDRESS);
+ OPENSSL_PUT_ERROR(X509V3, X509V3_R_BAD_IP_ADDRESS);
ERR_add_error_data(2, "value=", value);
goto err;
}
@@ -487,7 +487,7 @@ GENERAL_NAME *a2i_GENERAL_NAME(GENERAL_NAME *out,
case GEN_DIRNAME:
if (!do_dirname(gen, value, ctx))
{
- OPENSSL_PUT_ERROR(X509V3, a2i_GENERAL_NAME, X509V3_R_DIRNAME_ERROR);
+ OPENSSL_PUT_ERROR(X509V3, X509V3_R_DIRNAME_ERROR);
goto err;
}
break;
@@ -495,12 +495,12 @@ GENERAL_NAME *a2i_GENERAL_NAME(GENERAL_NAME *out,
case GEN_OTHERNAME:
if (!do_othername(gen, value, ctx))
{
- OPENSSL_PUT_ERROR(X509V3, a2i_GENERAL_NAME, X509V3_R_OTHERNAME_ERROR);
+ OPENSSL_PUT_ERROR(X509V3, X509V3_R_OTHERNAME_ERROR);
goto err;
}
break;
default:
- OPENSSL_PUT_ERROR(X509V3, a2i_GENERAL_NAME, X509V3_R_UNSUPPORTED_TYPE);
+ OPENSSL_PUT_ERROR(X509V3, X509V3_R_UNSUPPORTED_TYPE);
goto err;
}
@@ -510,7 +510,7 @@ GENERAL_NAME *a2i_GENERAL_NAME(GENERAL_NAME *out,
!ASN1_STRING_set(gen->d.ia5, (unsigned char*)value,
strlen(value)))
{
- OPENSSL_PUT_ERROR(X509V3, a2i_GENERAL_NAME, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
goto err;
}
}
@@ -538,7 +538,7 @@ GENERAL_NAME *v2i_GENERAL_NAME_ex(GENERAL_NAME *out,
if(!value)
{
- OPENSSL_PUT_ERROR(X509V3, v2i_GENERAL_NAME_ex, X509V3_R_MISSING_VALUE);
+ OPENSSL_PUT_ERROR(X509V3, X509V3_R_MISSING_VALUE);
return NULL;
}
@@ -558,7 +558,7 @@ GENERAL_NAME *v2i_GENERAL_NAME_ex(GENERAL_NAME *out,
type = GEN_OTHERNAME;
else
{
- OPENSSL_PUT_ERROR(X509V3, v2i_GENERAL_NAME_ex, X509V3_R_UNSUPPORTED_OPTION);
+ OPENSSL_PUT_ERROR(X509V3, X509V3_R_UNSUPPORTED_OPTION);
ERR_add_error_data(2, "name=", name);
return NULL;
}
@@ -604,7 +604,7 @@ static int do_dirname(GENERAL_NAME *gen, char *value, X509V3_CTX *ctx)
sk = X509V3_get_section(ctx, value);
if (!sk)
{
- OPENSSL_PUT_ERROR(X509V3, do_dirname, X509V3_R_SECTION_NOT_FOUND);
+ OPENSSL_PUT_ERROR(X509V3, X509V3_R_SECTION_NOT_FOUND);
ERR_add_error_data(2, "section=", value);
X509_NAME_free(nm);
return 0;
diff --git a/src/crypto/x509v3/v3_bcons.c b/src/crypto/x509v3/v3_bcons.c
index a1381b4..73ef21e 100644
--- a/src/crypto/x509v3/v3_bcons.c
+++ b/src/crypto/x509v3/v3_bcons.c
@@ -103,7 +103,7 @@ static BASIC_CONSTRAINTS *v2i_BASIC_CONSTRAINTS(X509V3_EXT_METHOD *method,
CONF_VALUE *val;
size_t i;
if(!(bcons = BASIC_CONSTRAINTS_new())) {
- OPENSSL_PUT_ERROR(X509V3, v2i_BASIC_CONSTRAINTS, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
return NULL;
}
for(i = 0; i < sk_CONF_VALUE_num(values); i++) {
@@ -113,7 +113,7 @@ static BASIC_CONSTRAINTS *v2i_BASIC_CONSTRAINTS(X509V3_EXT_METHOD *method,
} else if(!strcmp(val->name, "pathlen")) {
if(!X509V3_get_value_int(val, &bcons->pathlen)) goto err;
} else {
- OPENSSL_PUT_ERROR(X509V3, v2i_BASIC_CONSTRAINTS, X509V3_R_INVALID_NAME);
+ OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_NAME);
X509V3_conf_err(val);
goto err;
}
diff --git a/src/crypto/x509v3/v3_bitst.c b/src/crypto/x509v3/v3_bitst.c
index 15e9859..e1e2087 100644
--- a/src/crypto/x509v3/v3_bitst.c
+++ b/src/crypto/x509v3/v3_bitst.c
@@ -112,7 +112,7 @@ ASN1_BIT_STRING *v2i_ASN1_BIT_STRING(X509V3_EXT_METHOD *method,
size_t i;
const BIT_STRING_BITNAME *bnam;
if(!(bs = M_ASN1_BIT_STRING_new())) {
- OPENSSL_PUT_ERROR(X509V3, v2i_ASN1_BIT_STRING, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
return NULL;
}
for(i = 0; i < sk_CONF_VALUE_num(nval); i++) {
@@ -121,7 +121,7 @@ ASN1_BIT_STRING *v2i_ASN1_BIT_STRING(X509V3_EXT_METHOD *method,
if(!strcmp(bnam->sname, val->name) ||
!strcmp(bnam->lname, val->name) ) {
if(!ASN1_BIT_STRING_set_bit(bs, bnam->bitnum, 1)) {
- OPENSSL_PUT_ERROR(X509V3, v2i_ASN1_BIT_STRING, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
M_ASN1_BIT_STRING_free(bs);
return NULL;
}
@@ -129,7 +129,7 @@ ASN1_BIT_STRING *v2i_ASN1_BIT_STRING(X509V3_EXT_METHOD *method,
}
}
if(!bnam->lname) {
- OPENSSL_PUT_ERROR(X509V3, v2i_ASN1_BIT_STRING, X509V3_R_UNKNOWN_BIT_STRING_ARGUMENT);
+ OPENSSL_PUT_ERROR(X509V3, X509V3_R_UNKNOWN_BIT_STRING_ARGUMENT);
X509V3_conf_err(val);
M_ASN1_BIT_STRING_free(bs);
return NULL;
diff --git a/src/crypto/x509v3/v3_conf.c b/src/crypto/x509v3/v3_conf.c
index cb6569f..fe71566 100644
--- a/src/crypto/x509v3/v3_conf.c
+++ b/src/crypto/x509v3/v3_conf.c
@@ -92,7 +92,7 @@ X509_EXTENSION *X509V3_EXT_nconf(CONF *conf, X509V3_CTX *ctx, char *name,
ret = do_ext_nconf(conf, ctx, OBJ_sn2nid(name), crit, value);
if (!ret)
{
- OPENSSL_PUT_ERROR(X509V3, X509V3_EXT_nconf, X509V3_R_ERROR_IN_EXTENSION);
+ OPENSSL_PUT_ERROR(X509V3, X509V3_R_ERROR_IN_EXTENSION);
ERR_add_error_data(4,"name=", name, ", value=", value);
}
return ret;
@@ -123,12 +123,12 @@ static X509_EXTENSION *do_ext_nconf(CONF *conf, X509V3_CTX *ctx, int ext_nid,
void *ext_struc;
if (ext_nid == NID_undef)
{
- OPENSSL_PUT_ERROR(X509V3, do_ext_nconf, X509V3_R_UNKNOWN_EXTENSION_NAME);
+ OPENSSL_PUT_ERROR(X509V3, X509V3_R_UNKNOWN_EXTENSION_NAME);
return NULL;
}
if (!(method = X509V3_EXT_get_nid(ext_nid)))
{
- OPENSSL_PUT_ERROR(X509V3, do_ext_nconf, X509V3_R_UNKNOWN_EXTENSION);
+ OPENSSL_PUT_ERROR(X509V3, X509V3_R_UNKNOWN_EXTENSION);
return NULL;
}
/* Now get internal extension representation based on type */
@@ -138,7 +138,7 @@ static X509_EXTENSION *do_ext_nconf(CONF *conf, X509V3_CTX *ctx, int ext_nid,
else nval = X509V3_parse_list(value);
if(sk_CONF_VALUE_num(nval) <= 0)
{
- OPENSSL_PUT_ERROR(X509V3, do_ext_nconf, X509V3_R_INVALID_EXTENSION_STRING);
+ OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_EXTENSION_STRING);
ERR_add_error_data(4, "name=", OBJ_nid2sn(ext_nid), ",section=", value);
return NULL;
}
@@ -155,14 +155,14 @@ static X509_EXTENSION *do_ext_nconf(CONF *conf, X509V3_CTX *ctx, int ext_nid,
{
if(!ctx->db || !ctx->db_meth)
{
- OPENSSL_PUT_ERROR(X509V3, do_ext_nconf, X509V3_R_NO_CONFIG_DATABASE);
+ OPENSSL_PUT_ERROR(X509V3, X509V3_R_NO_CONFIG_DATABASE);
return NULL;
}
if(!(ext_struc = method->r2i(method, ctx, value))) return NULL;
}
else
{
- OPENSSL_PUT_ERROR(X509V3, do_ext_nconf, X509V3_R_EXTENSION_SETTING_NOT_SUPPORTED);
+ OPENSSL_PUT_ERROR(X509V3, X509V3_R_EXTENSION_SETTING_NOT_SUPPORTED);
ERR_add_error_data(2, "name=", OBJ_nid2sn(ext_nid));
return NULL;
}
@@ -207,7 +207,7 @@ static X509_EXTENSION *do_ext_i2d(const X509V3_EXT_METHOD *method, int ext_nid,
return ext;
merr:
- OPENSSL_PUT_ERROR(X509V3, do_ext_i2d, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
return NULL;
}
@@ -218,7 +218,7 @@ X509_EXTENSION *X509V3_EXT_i2d(int ext_nid, int crit, void *ext_struc)
{
const X509V3_EXT_METHOD *method;
if (!(method = X509V3_EXT_get_nid(ext_nid))) {
- OPENSSL_PUT_ERROR(X509V3, X509V3_EXT_i2d, X509V3_R_UNKNOWN_EXTENSION);
+ OPENSSL_PUT_ERROR(X509V3, X509V3_R_UNKNOWN_EXTENSION);
return NULL;
}
return do_ext_i2d(method, ext_nid, crit, ext_struc);
@@ -271,7 +271,7 @@ static X509_EXTENSION *v3_generic_extension(const char *ext, char *value,
X509_EXTENSION *extension=NULL;
if (!(obj = OBJ_txt2obj(ext, 0)))
{
- OPENSSL_PUT_ERROR(X509V3, v3_generic_extension, X509V3_R_EXTENSION_NAME_ERROR);
+ OPENSSL_PUT_ERROR(X509V3, X509V3_R_EXTENSION_NAME_ERROR);
ERR_add_error_data(2, "name=", ext);
goto err;
}
@@ -283,14 +283,14 @@ static X509_EXTENSION *v3_generic_extension(const char *ext, char *value,
if (ext_der == NULL)
{
- OPENSSL_PUT_ERROR(X509V3, v3_generic_extension, X509V3_R_EXTENSION_VALUE_ERROR);
+ OPENSSL_PUT_ERROR(X509V3, X509V3_R_EXTENSION_VALUE_ERROR);
ERR_add_error_data(2, "value=", value);
goto err;
}
if (!(oct = M_ASN1_OCTET_STRING_new()))
{
- OPENSSL_PUT_ERROR(X509V3, v3_generic_extension, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
goto err;
}
@@ -389,7 +389,7 @@ char * X509V3_get_string(X509V3_CTX *ctx, char *name, char *section)
{
if(!ctx->db || !ctx->db_meth || !ctx->db_meth->get_string)
{
- OPENSSL_PUT_ERROR(X509V3, X509V3_get_string, X509V3_R_OPERATION_NOT_DEFINED);
+ OPENSSL_PUT_ERROR(X509V3, X509V3_R_OPERATION_NOT_DEFINED);
return NULL;
}
if (ctx->db_meth->get_string)
@@ -401,7 +401,7 @@ STACK_OF(CONF_VALUE) * X509V3_get_section(X509V3_CTX *ctx, char *section)
{
if(!ctx->db || !ctx->db_meth || !ctx->db_meth->get_section)
{
- OPENSSL_PUT_ERROR(X509V3, X509V3_get_section, X509V3_R_OPERATION_NOT_DEFINED);
+ OPENSSL_PUT_ERROR(X509V3, X509V3_R_OPERATION_NOT_DEFINED);
return NULL;
}
if (ctx->db_meth->get_section)
diff --git a/src/crypto/x509v3/v3_cpols.c b/src/crypto/x509v3/v3_cpols.c
index cbe596b..0b58676 100644
--- a/src/crypto/x509v3/v3_cpols.c
+++ b/src/crypto/x509v3/v3_cpols.c
@@ -146,19 +146,19 @@ static STACK_OF(POLICYINFO) *r2i_certpol(X509V3_EXT_METHOD *method,
int ia5org;
pols = sk_POLICYINFO_new_null();
if (pols == NULL) {
- OPENSSL_PUT_ERROR(X509V3, r2i_certpol, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
return NULL;
}
vals = X509V3_parse_list(value);
if (vals == NULL) {
- OPENSSL_PUT_ERROR(X509V3, r2i_certpol, ERR_R_X509V3_LIB);
+ OPENSSL_PUT_ERROR(X509V3, ERR_R_X509V3_LIB);
goto err;
}
ia5org = 0;
for(i = 0; i < sk_CONF_VALUE_num(vals); i++) {
cnf = sk_CONF_VALUE_value(vals, i);
if(cnf->value || !cnf->name ) {
- OPENSSL_PUT_ERROR(X509V3, r2i_certpol, X509V3_R_INVALID_POLICY_IDENTIFIER);
+ OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_POLICY_IDENTIFIER);
X509V3_conf_err(cnf);
goto err;
}
@@ -170,7 +170,7 @@ static STACK_OF(POLICYINFO) *r2i_certpol(X509V3_EXT_METHOD *method,
STACK_OF(CONF_VALUE) *polsect;
polsect = X509V3_get_section(ctx, pstr + 1);
if(!polsect) {
- OPENSSL_PUT_ERROR(X509V3, r2i_certpol, X509V3_R_INVALID_SECTION);
+ OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_SECTION);
X509V3_conf_err(cnf);
goto err;
@@ -180,7 +180,7 @@ static STACK_OF(POLICYINFO) *r2i_certpol(X509V3_EXT_METHOD *method,
if(!pol) goto err;
} else {
if(!(pobj = OBJ_txt2obj(cnf->name, 0))) {
- OPENSSL_PUT_ERROR(X509V3, r2i_certpol, X509V3_R_INVALID_OBJECT_IDENTIFIER);
+ OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_OBJECT_IDENTIFIER);
X509V3_conf_err(cnf);
goto err;
}
@@ -189,7 +189,7 @@ static STACK_OF(POLICYINFO) *r2i_certpol(X509V3_EXT_METHOD *method,
}
if (!sk_POLICYINFO_push(pols, pol)){
POLICYINFO_free(pol);
- OPENSSL_PUT_ERROR(X509V3, r2i_certpol, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
goto err;
}
}
@@ -214,7 +214,7 @@ static POLICYINFO *policy_section(X509V3_CTX *ctx,
if(!strcmp(cnf->name, "policyIdentifier")) {
ASN1_OBJECT *pobj;
if(!(pobj = OBJ_txt2obj(cnf->value, 0))) {
- OPENSSL_PUT_ERROR(X509V3, policy_section, X509V3_R_INVALID_OBJECT_IDENTIFIER);
+ OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_OBJECT_IDENTIFIER);
X509V3_conf_err(cnf);
goto err;
}
@@ -229,7 +229,7 @@ static POLICYINFO *policy_section(X509V3_CTX *ctx,
/* TODO(fork): const correctness */
qual->pqualid = (ASN1_OBJECT*) OBJ_nid2obj(NID_id_qt_cps);
if (qual->pqualid == NULL) {
- OPENSSL_PUT_ERROR(X509V3, policy_section, ERR_R_INTERNAL_ERROR);
+ OPENSSL_PUT_ERROR(X509V3, ERR_R_INTERNAL_ERROR);
goto err;
}
qual->d.cpsuri = M_ASN1_IA5STRING_new();
@@ -241,13 +241,13 @@ static POLICYINFO *policy_section(X509V3_CTX *ctx,
} else if(!name_cmp(cnf->name, "userNotice")) {
STACK_OF(CONF_VALUE) *unot;
if(*cnf->value != '@') {
- OPENSSL_PUT_ERROR(X509V3, policy_section, X509V3_R_EXPECTED_A_SECTION_NAME);
+ OPENSSL_PUT_ERROR(X509V3, X509V3_R_EXPECTED_A_SECTION_NAME);
X509V3_conf_err(cnf);
goto err;
}
unot = X509V3_get_section(ctx, cnf->value + 1);
if(!unot) {
- OPENSSL_PUT_ERROR(X509V3, policy_section, X509V3_R_INVALID_SECTION);
+ OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_SECTION);
X509V3_conf_err(cnf);
goto err;
@@ -260,21 +260,21 @@ static POLICYINFO *policy_section(X509V3_CTX *ctx,
if(!sk_POLICYQUALINFO_push(pol->qualifiers, qual))
goto merr;
} else {
- OPENSSL_PUT_ERROR(X509V3, policy_section, X509V3_R_INVALID_OPTION);
+ OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_OPTION);
X509V3_conf_err(cnf);
goto err;
}
}
if(!pol->policyid) {
- OPENSSL_PUT_ERROR(X509V3, policy_section, X509V3_R_NO_POLICY_IDENTIFIER);
+ OPENSSL_PUT_ERROR(X509V3, X509V3_R_NO_POLICY_IDENTIFIER);
goto err;
}
return pol;
merr:
- OPENSSL_PUT_ERROR(X509V3, policy_section, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
err:
POLICYINFO_free(pol);
@@ -296,7 +296,7 @@ static POLICYQUALINFO *notice_section(X509V3_CTX *ctx,
qual->pqualid = (ASN1_OBJECT *) OBJ_nid2obj(NID_id_qt_unotice);
if (qual->pqualid == NULL)
{
- OPENSSL_PUT_ERROR(X509V3, notice_section, ERR_R_INTERNAL_ERROR);
+ OPENSSL_PUT_ERROR(X509V3, ERR_R_INTERNAL_ERROR);
goto err;
}
if(!(not = USERNOTICE_new())) goto merr;
@@ -328,7 +328,7 @@ static POLICYQUALINFO *notice_section(X509V3_CTX *ctx,
} else nref = not->noticeref;
nos = X509V3_parse_list(cnf->value);
if(!nos || !sk_CONF_VALUE_num(nos)) {
- OPENSSL_PUT_ERROR(X509V3, notice_section, X509V3_R_INVALID_NUMBERS);
+ OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_NUMBERS);
X509V3_conf_err(cnf);
goto err;
}
@@ -337,7 +337,7 @@ static POLICYQUALINFO *notice_section(X509V3_CTX *ctx,
if (!ret)
goto err;
} else {
- OPENSSL_PUT_ERROR(X509V3, notice_section, X509V3_R_INVALID_OPTION);
+ OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_OPTION);
X509V3_conf_err(cnf);
goto err;
}
@@ -345,14 +345,14 @@ static POLICYQUALINFO *notice_section(X509V3_CTX *ctx,
if(not->noticeref &&
(!not->noticeref->noticenos || !not->noticeref->organization)) {
- OPENSSL_PUT_ERROR(X509V3, notice_section, X509V3_R_NEED_ORGANIZATION_AND_NUMBERS);
+ OPENSSL_PUT_ERROR(X509V3, X509V3_R_NEED_ORGANIZATION_AND_NUMBERS);
goto err;
}
return qual;
merr:
- OPENSSL_PUT_ERROR(X509V3, notice_section, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
err:
POLICYQUALINFO_free(qual);
@@ -369,7 +369,7 @@ static int nref_nos(STACK_OF(ASN1_INTEGER) *nnums, STACK_OF(CONF_VALUE) *nos)
for(i = 0; i < sk_CONF_VALUE_num(nos); i++) {
cnf = sk_CONF_VALUE_value(nos, i);
if(!(aint = s2i_ASN1_INTEGER(NULL, cnf->name))) {
- OPENSSL_PUT_ERROR(X509V3, nref_nos, X509V3_R_INVALID_NUMBER);
+ OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_NUMBER);
goto err;
}
if(!sk_ASN1_INTEGER_push(nnums, aint)) goto merr;
@@ -377,7 +377,7 @@ static int nref_nos(STACK_OF(ASN1_INTEGER) *nnums, STACK_OF(CONF_VALUE) *nos)
return 1;
merr:
- OPENSSL_PUT_ERROR(X509V3, nref_nos, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
err:
sk_ASN1_INTEGER_pop_free(nnums, ASN1_STRING_free);
diff --git a/src/crypto/x509v3/v3_crld.c b/src/crypto/x509v3/v3_crld.c
index e41dd65..3984c31 100644
--- a/src/crypto/x509v3/v3_crld.c
+++ b/src/crypto/x509v3/v3_crld.c
@@ -103,7 +103,7 @@ static STACK_OF(GENERAL_NAME) *gnames_from_sectname(X509V3_CTX *ctx, char *sect)
gnsect = X509V3_parse_list(sect);
if (!gnsect)
{
- OPENSSL_PUT_ERROR(X509V3, gnames_from_sectname, X509V3_R_SECTION_NOT_FOUND);
+ OPENSSL_PUT_ERROR(X509V3, X509V3_R_SECTION_NOT_FOUND);
return NULL;
}
gens = v2i_GENERAL_NAMES(NULL, ctx, gnsect);
@@ -136,7 +136,7 @@ static int set_dist_point_name(DIST_POINT_NAME **pdp, X509V3_CTX *ctx,
dnsect = X509V3_get_section(ctx, cnf->value);
if (!dnsect)
{
- OPENSSL_PUT_ERROR(X509V3, set_dist_point_name, X509V3_R_SECTION_NOT_FOUND);
+ OPENSSL_PUT_ERROR(X509V3, X509V3_R_SECTION_NOT_FOUND);
return -1;
}
ret = X509V3_NAME_from_section(nm, dnsect, MBSTRING_ASC);
@@ -152,7 +152,7 @@ static int set_dist_point_name(DIST_POINT_NAME **pdp, X509V3_CTX *ctx,
if (sk_X509_NAME_ENTRY_value(rnm,
sk_X509_NAME_ENTRY_num(rnm) - 1)->set)
{
- OPENSSL_PUT_ERROR(X509V3, set_dist_point_name, X509V3_R_INVALID_MULTIPLE_RDNS);
+ OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_MULTIPLE_RDNS);
goto err;
}
}
@@ -161,7 +161,7 @@ static int set_dist_point_name(DIST_POINT_NAME **pdp, X509V3_CTX *ctx,
if (*pdp)
{
- OPENSSL_PUT_ERROR(X509V3, set_dist_point_name, X509V3_R_DISTPOINT_ALREADY_SET);
+ OPENSSL_PUT_ERROR(X509V3, X509V3_R_DISTPOINT_ALREADY_SET);
goto err;
}
@@ -362,7 +362,7 @@ static void *v2i_crld(const X509V3_EXT_METHOD *method,
return crld;
merr:
- OPENSSL_PUT_ERROR(X509V3, v2i_crld, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
err:
GENERAL_NAME_free(gen);
GENERAL_NAMES_free(gens);
@@ -490,7 +490,7 @@ static void *v2i_idp(const X509V3_EXT_METHOD *method, X509V3_CTX *ctx,
}
else
{
- OPENSSL_PUT_ERROR(X509V3, v2i_idp, X509V3_R_INVALID_NAME);
+ OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_NAME);
X509V3_conf_err(cnf);
goto err;
}
@@ -498,7 +498,7 @@ static void *v2i_idp(const X509V3_EXT_METHOD *method, X509V3_CTX *ctx,
return idp;
merr:
- OPENSSL_PUT_ERROR(X509V3, v2i_idp, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
err:
ISSUING_DIST_POINT_free(idp);
return NULL;
diff --git a/src/crypto/x509v3/v3_extku.c b/src/crypto/x509v3/v3_extku.c
index f4b8af8..d64eb9c 100644
--- a/src/crypto/x509v3/v3_extku.c
+++ b/src/crypto/x509v3/v3_extku.c
@@ -125,7 +125,7 @@ static void *v2i_EXTENDED_KEY_USAGE(const X509V3_EXT_METHOD *method,
size_t i;
if(!(extku = sk_ASN1_OBJECT_new_null())) {
- OPENSSL_PUT_ERROR(X509V3, v2i_EXTENDED_KEY_USAGE, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
return NULL;
}
@@ -135,7 +135,7 @@ static void *v2i_EXTENDED_KEY_USAGE(const X509V3_EXT_METHOD *method,
else extval = val->name;
if(!(objtmp = OBJ_txt2obj(extval, 0))) {
sk_ASN1_OBJECT_pop_free(extku, ASN1_OBJECT_free);
- OPENSSL_PUT_ERROR(X509V3, v2i_EXTENDED_KEY_USAGE, X509V3_R_INVALID_OBJECT_IDENTIFIER);
+ OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_OBJECT_IDENTIFIER);
X509V3_conf_err(val);
return NULL;
}
diff --git a/src/crypto/x509v3/v3_ia5.c b/src/crypto/x509v3/v3_ia5.c
index ec57e9b..5a27233 100644
--- a/src/crypto/x509v3/v3_ia5.c
+++ b/src/crypto/x509v3/v3_ia5.c
@@ -87,7 +87,7 @@ static char *i2s_ASN1_IA5STRING(X509V3_EXT_METHOD *method,
char *tmp;
if(!ia5 || !ia5->length) return NULL;
if(!(tmp = OPENSSL_malloc(ia5->length + 1))) {
- OPENSSL_PUT_ERROR(X509V3, i2s_ASN1_IA5STRING, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
return NULL;
}
memcpy(tmp, ia5->data, ia5->length);
@@ -100,7 +100,7 @@ static ASN1_IA5STRING *s2i_ASN1_IA5STRING(X509V3_EXT_METHOD *method,
{
ASN1_IA5STRING *ia5;
if(!str) {
- OPENSSL_PUT_ERROR(X509V3, s2i_ASN1_IA5STRING, X509V3_R_INVALID_NULL_ARGUMENT);
+ OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_NULL_ARGUMENT);
return NULL;
}
if(!(ia5 = M_ASN1_IA5STRING_new())) goto err;
@@ -111,7 +111,7 @@ static ASN1_IA5STRING *s2i_ASN1_IA5STRING(X509V3_EXT_METHOD *method,
}
return ia5;
err:
- OPENSSL_PUT_ERROR(X509V3, s2i_ASN1_IA5STRING, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
return NULL;
}
diff --git a/src/crypto/x509v3/v3_info.c b/src/crypto/x509v3/v3_info.c
index 7558b2d..475c56f 100644
--- a/src/crypto/x509v3/v3_info.c
+++ b/src/crypto/x509v3/v3_info.c
@@ -124,7 +124,7 @@ static STACK_OF(CONF_VALUE) *i2v_AUTHORITY_INFO_ACCESS(X509V3_EXT_METHOD *method
nlen = strlen(objtmp) + strlen(vtmp->name) + 5;
ntmp = OPENSSL_malloc(nlen);
if(!ntmp) {
- OPENSSL_PUT_ERROR(X509V3, i2v_AUTHORITY_INFO_ACCESS, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
return NULL;
}
BUF_strlcpy(ntmp, objtmp, nlen);
@@ -148,19 +148,19 @@ static AUTHORITY_INFO_ACCESS *v2i_AUTHORITY_INFO_ACCESS(X509V3_EXT_METHOD *metho
int objlen;
char *objtmp, *ptmp;
if(!(ainfo = sk_ACCESS_DESCRIPTION_new_null())) {
- OPENSSL_PUT_ERROR(X509V3, v2i_AUTHORITY_INFO_ACCESS, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
return NULL;
}
for(i = 0; i < sk_CONF_VALUE_num(nval); i++) {
cnf = sk_CONF_VALUE_value(nval, i);
if(!(acc = ACCESS_DESCRIPTION_new())
|| !sk_ACCESS_DESCRIPTION_push(ainfo, acc)) {
- OPENSSL_PUT_ERROR(X509V3, v2i_AUTHORITY_INFO_ACCESS, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
goto err;
}
ptmp = strchr(cnf->name, ';');
if(!ptmp) {
- OPENSSL_PUT_ERROR(X509V3, v2i_AUTHORITY_INFO_ACCESS, X509V3_R_INVALID_SYNTAX);
+ OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_SYNTAX);
goto err;
}
objlen = ptmp - cnf->name;
@@ -169,14 +169,14 @@ static AUTHORITY_INFO_ACCESS *v2i_AUTHORITY_INFO_ACCESS(X509V3_EXT_METHOD *metho
if(!v2i_GENERAL_NAME_ex(acc->location, method, ctx, &ctmp, 0))
goto err;
if(!(objtmp = OPENSSL_malloc(objlen + 1))) {
- OPENSSL_PUT_ERROR(X509V3, v2i_AUTHORITY_INFO_ACCESS, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
goto err;
}
strncpy(objtmp, cnf->name, objlen);
objtmp[objlen] = 0;
acc->method = OBJ_txt2obj(objtmp, 0);
if(!acc->method) {
- OPENSSL_PUT_ERROR(X509V3, v2i_AUTHORITY_INFO_ACCESS, X509V3_R_BAD_OBJECT);
+ OPENSSL_PUT_ERROR(X509V3, X509V3_R_BAD_OBJECT);
ERR_add_error_data(2, "value=", objtmp);
OPENSSL_free(objtmp);
goto err;
diff --git a/src/crypto/x509v3/v3_lib.c b/src/crypto/x509v3/v3_lib.c
index d4e4e78..f8e5531 100644
--- a/src/crypto/x509v3/v3_lib.c
+++ b/src/crypto/x509v3/v3_lib.c
@@ -78,12 +78,12 @@ static int ext_stack_cmp(const X509V3_EXT_METHOD **a, const X509V3_EXT_METHOD **
int X509V3_EXT_add(X509V3_EXT_METHOD *ext)
{
if(!ext_list && !(ext_list = sk_X509V3_EXT_METHOD_new(ext_stack_cmp))) {
- OPENSSL_PUT_ERROR(X509V3, X509V3_EXT_add, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
ext_list_free(ext);
return 0;
}
if(!sk_X509V3_EXT_METHOD_push(ext_list, ext)) {
- OPENSSL_PUT_ERROR(X509V3, X509V3_EXT_add, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
ext_list_free(ext);
return 0;
}
@@ -127,7 +127,7 @@ int X509V3_EXT_free(int nid, void *ext_data)
const X509V3_EXT_METHOD *ext_method = X509V3_EXT_get_nid(nid);
if (ext_method == NULL)
{
- OPENSSL_PUT_ERROR(X509V3, X509V3_EXT_free, X509V3_R_CANNOT_FIND_FREE_FUNCTION);
+ OPENSSL_PUT_ERROR(X509V3, X509V3_R_CANNOT_FIND_FREE_FUNCTION);
return 0;
}
@@ -137,7 +137,7 @@ int X509V3_EXT_free(int nid, void *ext_data)
ext_method->ext_free(ext_data);
else
{
- OPENSSL_PUT_ERROR(X509V3, X509V3_EXT_free, X509V3_R_CANNOT_FIND_FREE_FUNCTION);
+ OPENSSL_PUT_ERROR(X509V3, X509V3_R_CANNOT_FIND_FREE_FUNCTION);
return 0;
}
@@ -157,11 +157,11 @@ int X509V3_EXT_add_alias(int nid_to, int nid_from)
X509V3_EXT_METHOD *tmpext;
if(!(ext = X509V3_EXT_get_nid(nid_from))) {
- OPENSSL_PUT_ERROR(X509V3, X509V3_EXT_add_alias, X509V3_R_EXTENSION_NOT_FOUND);
+ OPENSSL_PUT_ERROR(X509V3, X509V3_R_EXTENSION_NOT_FOUND);
return 0;
}
if(!(tmpext = (X509V3_EXT_METHOD *)OPENSSL_malloc(sizeof(X509V3_EXT_METHOD)))) {
- OPENSSL_PUT_ERROR(X509V3, X509V3_EXT_add_alias, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
return 0;
}
*tmpext = *ext;
@@ -311,7 +311,7 @@ int X509V3_add1_i2d(STACK_OF(X509_EXTENSION) **x, int nid, void *value,
ext = X509V3_EXT_i2d(nid, crit, value);
if(!ext) {
- OPENSSL_PUT_ERROR(X509V3, X509V3_add1_i2d, X509V3_R_ERROR_CREATING_EXTENSION);
+ OPENSSL_PUT_ERROR(X509V3, X509V3_R_ERROR_CREATING_EXTENSION);
return 0;
}
@@ -330,6 +330,6 @@ int X509V3_add1_i2d(STACK_OF(X509_EXTENSION) **x, int nid, void *value,
err:
if(!(flags & X509V3_ADD_SILENT))
- OPENSSL_PUT_ERROR(X509V3, X509V3_add1_i2d, errcode);
+ OPENSSL_PUT_ERROR(X509V3, errcode);
return 0;
}
diff --git a/src/crypto/x509v3/v3_ncons.c b/src/crypto/x509v3/v3_ncons.c
index c42a665..19f5e94 100644
--- a/src/crypto/x509v3/v3_ncons.c
+++ b/src/crypto/x509v3/v3_ncons.c
@@ -135,7 +135,7 @@ static void *v2i_NAME_CONSTRAINTS(const X509V3_EXT_METHOD *method,
}
else
{
- OPENSSL_PUT_ERROR(X509V3, v2i_NAME_CONSTRAINTS, X509V3_R_INVALID_SYNTAX);
+ OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_SYNTAX);
goto err;
}
tval.value = val->value;
@@ -152,7 +152,7 @@ static void *v2i_NAME_CONSTRAINTS(const X509V3_EXT_METHOD *method,
return ncons;
memerr:
- OPENSSL_PUT_ERROR(X509V3, v2i_NAME_CONSTRAINTS, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
err:
if (ncons)
NAME_CONSTRAINTS_free(ncons);
diff --git a/src/crypto/x509v3/v3_pci.c b/src/crypto/x509v3/v3_pci.c
index aa93891..f19a37a 100644
--- a/src/crypto/x509v3/v3_pci.c
+++ b/src/crypto/x509v3/v3_pci.c
@@ -87,13 +87,13 @@ static int process_pci_value(CONF_VALUE *val,
{
if (*language)
{
- OPENSSL_PUT_ERROR(X509V3, process_pci_value, X509V3_R_POLICY_LANGUAGE_ALREADY_DEFINED);
+ OPENSSL_PUT_ERROR(X509V3, X509V3_R_POLICY_LANGUAGE_ALREADY_DEFINED);
X509V3_conf_err(val);
return 0;
}
if (!(*language = OBJ_txt2obj(val->value, 0)))
{
- OPENSSL_PUT_ERROR(X509V3, process_pci_value, X509V3_R_INVALID_OBJECT_IDENTIFIER);
+ OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_OBJECT_IDENTIFIER);
X509V3_conf_err(val);
return 0;
}
@@ -102,13 +102,13 @@ static int process_pci_value(CONF_VALUE *val,
{
if (*pathlen)
{
- OPENSSL_PUT_ERROR(X509V3, process_pci_value, X509V3_R_POLICY_PATH_LENGTH_ALREADY_DEFINED);
+ OPENSSL_PUT_ERROR(X509V3, X509V3_R_POLICY_PATH_LENGTH_ALREADY_DEFINED);
X509V3_conf_err(val);
return 0;
}
if (!X509V3_get_value_int(val, pathlen))
{
- OPENSSL_PUT_ERROR(X509V3, process_pci_value, X509V3_R_POLICY_PATH_LENGTH);
+ OPENSSL_PUT_ERROR(X509V3, X509V3_R_POLICY_PATH_LENGTH);
X509V3_conf_err(val);
return 0;
}
@@ -122,7 +122,7 @@ static int process_pci_value(CONF_VALUE *val,
*policy = ASN1_OCTET_STRING_new();
if (!*policy)
{
- OPENSSL_PUT_ERROR(X509V3, process_pci_value, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
X509V3_conf_err(val);
return 0;
}
@@ -135,7 +135,7 @@ static int process_pci_value(CONF_VALUE *val,
if (!tmp_data2)
{
- OPENSSL_PUT_ERROR(X509V3, process_pci_value, X509V3_R_ILLEGAL_HEX_DIGIT);
+ OPENSSL_PUT_ERROR(X509V3, X509V3_R_ILLEGAL_HEX_DIGIT);
X509V3_conf_err(val);
goto err;
}
@@ -156,7 +156,7 @@ static int process_pci_value(CONF_VALUE *val,
/* realloc failure implies the original data space is b0rked too! */
(*policy)->data = NULL;
(*policy)->length = 0;
- OPENSSL_PUT_ERROR(X509V3, process_pci_value, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
X509V3_conf_err(val);
goto err;
}
@@ -169,7 +169,7 @@ static int process_pci_value(CONF_VALUE *val,
BIO *b = BIO_new_file(val->value + 5, "r");
if (!b)
{
- OPENSSL_PUT_ERROR(X509V3, process_pci_value, ERR_R_BIO_LIB);
+ OPENSSL_PUT_ERROR(X509V3, ERR_R_BIO_LIB);
X509V3_conf_err(val);
goto err;
}
@@ -194,7 +194,7 @@ static int process_pci_value(CONF_VALUE *val,
if (n < 0)
{
- OPENSSL_PUT_ERROR(X509V3, process_pci_value, ERR_R_BIO_LIB);
+ OPENSSL_PUT_ERROR(X509V3, ERR_R_BIO_LIB);
X509V3_conf_err(val);
goto err;
}
@@ -217,20 +217,20 @@ static int process_pci_value(CONF_VALUE *val,
/* realloc failure implies the original data space is b0rked too! */
(*policy)->data = NULL;
(*policy)->length = 0;
- OPENSSL_PUT_ERROR(X509V3, process_pci_value, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
X509V3_conf_err(val);
goto err;
}
}
else
{
- OPENSSL_PUT_ERROR(X509V3, process_pci_value, X509V3_R_INCORRECT_POLICY_SYNTAX_TAG);
+ OPENSSL_PUT_ERROR(X509V3, X509V3_R_INCORRECT_POLICY_SYNTAX_TAG);
X509V3_conf_err(val);
goto err;
}
if (!tmp_data)
{
- OPENSSL_PUT_ERROR(X509V3, process_pci_value, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
X509V3_conf_err(val);
goto err;
}
@@ -262,7 +262,7 @@ static PROXY_CERT_INFO_EXTENSION *r2i_pci(X509V3_EXT_METHOD *method,
CONF_VALUE *cnf = sk_CONF_VALUE_value(vals, i);
if (!cnf->name || (*cnf->name != '@' && !cnf->value))
{
- OPENSSL_PUT_ERROR(X509V3, r2i_pci, X509V3_R_INVALID_PROXY_POLICY_SETTING);
+ OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_PROXY_POLICY_SETTING);
X509V3_conf_err(cnf);
goto err;
}
@@ -274,7 +274,7 @@ static PROXY_CERT_INFO_EXTENSION *r2i_pci(X509V3_EXT_METHOD *method,
sect = X509V3_get_section(ctx, cnf->name + 1);
if (!sect)
{
- OPENSSL_PUT_ERROR(X509V3, r2i_pci, X509V3_R_INVALID_SECTION);
+ OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_SECTION);
X509V3_conf_err(cnf);
goto err;
}
@@ -302,20 +302,21 @@ static PROXY_CERT_INFO_EXTENSION *r2i_pci(X509V3_EXT_METHOD *method,
/* Language is mandatory */
if (!language)
{
- OPENSSL_PUT_ERROR(X509V3, r2i_pci, X509V3_R_NO_PROXY_CERT_POLICY_LANGUAGE_DEFINED);
+ OPENSSL_PUT_ERROR(X509V3, X509V3_R_NO_PROXY_CERT_POLICY_LANGUAGE_DEFINED);
goto err;
}
nid = OBJ_obj2nid(language);
if ((nid == NID_Independent || nid == NID_id_ppl_inheritAll) && policy)
{
- OPENSSL_PUT_ERROR(X509V3, r2i_pci, X509V3_R_POLICY_WHEN_PROXY_LANGUAGE_REQUIRES_NO_POLICY);
+ OPENSSL_PUT_ERROR(X509V3,
+ X509V3_R_POLICY_WHEN_PROXY_LANGUAGE_REQUIRES_NO_POLICY);
goto err;
}
pci = PROXY_CERT_INFO_EXTENSION_new();
if (!pci)
{
- OPENSSL_PUT_ERROR(X509V3, r2i_pci, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
goto err;
}
diff --git a/src/crypto/x509v3/v3_pcons.c b/src/crypto/x509v3/v3_pcons.c
index f87c6a0..b752290 100644
--- a/src/crypto/x509v3/v3_pcons.c
+++ b/src/crypto/x509v3/v3_pcons.c
@@ -112,7 +112,7 @@ static void *v2i_POLICY_CONSTRAINTS(const X509V3_EXT_METHOD *method,
CONF_VALUE *val;
size_t i;
if(!(pcons = POLICY_CONSTRAINTS_new())) {
- OPENSSL_PUT_ERROR(X509V3, v2i_POLICY_CONSTRAINTS, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
return NULL;
}
for(i = 0; i < sk_CONF_VALUE_num(values); i++) {
@@ -124,13 +124,13 @@ static void *v2i_POLICY_CONSTRAINTS(const X509V3_EXT_METHOD *method,
if(!X509V3_get_value_int(val,
&pcons->inhibitPolicyMapping)) goto err;
} else {
- OPENSSL_PUT_ERROR(X509V3, v2i_POLICY_CONSTRAINTS, X509V3_R_INVALID_NAME);
+ OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_NAME);
X509V3_conf_err(val);
goto err;
}
}
if (!pcons->inhibitPolicyMapping && !pcons->requireExplicitPolicy) {
- OPENSSL_PUT_ERROR(X509V3, v2i_POLICY_CONSTRAINTS, X509V3_R_ILLEGAL_EMPTY_EXTENSION);
+ OPENSSL_PUT_ERROR(X509V3, X509V3_R_ILLEGAL_EMPTY_EXTENSION);
goto err;
}
diff --git a/src/crypto/x509v3/v3_pmaps.c b/src/crypto/x509v3/v3_pmaps.c
index fbc169d..5b90977 100644
--- a/src/crypto/x509v3/v3_pmaps.c
+++ b/src/crypto/x509v3/v3_pmaps.c
@@ -122,7 +122,7 @@ static void *v2i_POLICY_MAPPINGS(const X509V3_EXT_METHOD *method,
size_t i;
if(!(pmaps = sk_POLICY_MAPPING_new_null())) {
- OPENSSL_PUT_ERROR(X509V3, v2i_POLICY_MAPPINGS, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
return NULL;
}
@@ -130,7 +130,7 @@ static void *v2i_POLICY_MAPPINGS(const X509V3_EXT_METHOD *method,
val = sk_CONF_VALUE_value(nval, i);
if(!val->value || !val->name) {
sk_POLICY_MAPPING_pop_free(pmaps, POLICY_MAPPING_free);
- OPENSSL_PUT_ERROR(X509V3, v2i_POLICY_MAPPINGS, X509V3_R_INVALID_OBJECT_IDENTIFIER);
+ OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_OBJECT_IDENTIFIER);
X509V3_conf_err(val);
return NULL;
}
@@ -138,14 +138,14 @@ static void *v2i_POLICY_MAPPINGS(const X509V3_EXT_METHOD *method,
obj2 = OBJ_txt2obj(val->value, 0);
if(!obj1 || !obj2) {
sk_POLICY_MAPPING_pop_free(pmaps, POLICY_MAPPING_free);
- OPENSSL_PUT_ERROR(X509V3, v2i_POLICY_MAPPINGS, X509V3_R_INVALID_OBJECT_IDENTIFIER);
+ OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_OBJECT_IDENTIFIER);
X509V3_conf_err(val);
return NULL;
}
pmap = POLICY_MAPPING_new();
if (!pmap) {
sk_POLICY_MAPPING_pop_free(pmaps, POLICY_MAPPING_free);
- OPENSSL_PUT_ERROR(X509V3, v2i_POLICY_MAPPINGS, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
return NULL;
}
pmap->issuerDomainPolicy = obj1;
diff --git a/src/crypto/x509v3/v3_purp.c b/src/crypto/x509v3/v3_purp.c
index 8ae8a06..f53c0f1 100644
--- a/src/crypto/x509v3/v3_purp.c
+++ b/src/crypto/x509v3/v3_purp.c
@@ -128,7 +128,7 @@ int X509_check_purpose(X509 *x, int id, int ca)
int X509_PURPOSE_set(int *p, int purpose)
{
if(X509_PURPOSE_get_by_id(purpose) == -1) {
- OPENSSL_PUT_ERROR(X509V3, X509_PURPOSE_set, X509V3_R_INVALID_PURPOSE);
+ OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_PURPOSE);
return 0;
}
*p = purpose;
@@ -191,7 +191,7 @@ int X509_PURPOSE_add(int id, int trust, int flags,
/* Need a new entry */
if(idx == -1) {
if(!(ptmp = OPENSSL_malloc(sizeof(X509_PURPOSE)))) {
- OPENSSL_PUT_ERROR(X509V3, X509_PURPOSE_add, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
return 0;
}
ptmp->flags = X509_PURPOSE_DYNAMIC;
@@ -201,7 +201,7 @@ int X509_PURPOSE_add(int id, int trust, int flags,
name_dup = BUF_strdup(name);
sname_dup = BUF_strdup(sname);
if (name_dup == NULL || sname_dup == NULL) {
- OPENSSL_PUT_ERROR(X509V3, X509_PURPOSE_add, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
if (name_dup != NULL)
OPENSSL_free(name_dup);
if (sname_dup != NULL)
@@ -232,12 +232,12 @@ int X509_PURPOSE_add(int id, int trust, int flags,
/* If its a new entry manage the dynamic table */
if(idx == -1) {
if(!xptable && !(xptable = sk_X509_PURPOSE_new(xp_cmp))) {
- OPENSSL_PUT_ERROR(X509V3, X509_PURPOSE_add, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
xptable_free(ptmp);
return 0;
}
if (!sk_X509_PURPOSE_push(xptable, ptmp)) {
- OPENSSL_PUT_ERROR(X509V3, X509_PURPOSE_add, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
xptable_free(ptmp);
return 0;
}
diff --git a/src/crypto/x509v3/v3_skey.c b/src/crypto/x509v3/v3_skey.c
index 471a1ab..e396f05 100644
--- a/src/crypto/x509v3/v3_skey.c
+++ b/src/crypto/x509v3/v3_skey.c
@@ -86,7 +86,7 @@ ASN1_OCTET_STRING *s2i_ASN1_OCTET_STRING(X509V3_EXT_METHOD *method,
long length;
if(!(oct = M_ASN1_OCTET_STRING_new())) {
- OPENSSL_PUT_ERROR(X509V3, s2i_ASN1_OCTET_STRING, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
return NULL;
}
@@ -112,14 +112,14 @@ static ASN1_OCTET_STRING *s2i_skey_id(X509V3_EXT_METHOD *method,
if(strcmp(str, "hash")) return s2i_ASN1_OCTET_STRING(method, ctx, str);
if(!(oct = M_ASN1_OCTET_STRING_new())) {
- OPENSSL_PUT_ERROR(X509V3, s2i_skey_id, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
return NULL;
}
if(ctx && (ctx->flags == CTX_TEST)) return oct;
if(!ctx || (!ctx->subject_req && !ctx->subject_cert)) {
- OPENSSL_PUT_ERROR(X509V3, s2i_skey_id, X509V3_R_NO_PUBLIC_KEY);
+ OPENSSL_PUT_ERROR(X509V3, X509V3_R_NO_PUBLIC_KEY);
goto err;
}
@@ -128,7 +128,7 @@ static ASN1_OCTET_STRING *s2i_skey_id(X509V3_EXT_METHOD *method,
else pk = ctx->subject_cert->cert_info->key->public_key;
if(!pk) {
- OPENSSL_PUT_ERROR(X509V3, s2i_skey_id, X509V3_R_NO_PUBLIC_KEY);
+ OPENSSL_PUT_ERROR(X509V3, X509V3_R_NO_PUBLIC_KEY);
goto err;
}
@@ -136,7 +136,7 @@ static ASN1_OCTET_STRING *s2i_skey_id(X509V3_EXT_METHOD *method,
goto err;
if(!M_ASN1_OCTET_STRING_set(oct, pkey_dig, diglen)) {
- OPENSSL_PUT_ERROR(X509V3, s2i_skey_id, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
goto err;
}
diff --git a/src/crypto/x509v3/v3_sxnet.c b/src/crypto/x509v3/v3_sxnet.c
index bb5e214..4dd5bfc 100644
--- a/src/crypto/x509v3/v3_sxnet.c
+++ b/src/crypto/x509v3/v3_sxnet.c
@@ -159,7 +159,7 @@ int SXNET_add_id_asc(SXNET **psx, char *zone, char *user,
{
ASN1_INTEGER *izone = NULL;
if(!(izone = s2i_ASN1_INTEGER(NULL, zone))) {
- OPENSSL_PUT_ERROR(X509V3, SXNET_add_id_asc, X509V3_R_ERROR_CONVERTING_ZONE);
+ OPENSSL_PUT_ERROR(X509V3, X509V3_R_ERROR_CONVERTING_ZONE);
return 0;
}
return SXNET_add_id_INTEGER(psx, izone, user, userlen);
@@ -172,7 +172,7 @@ int SXNET_add_id_ulong(SXNET **psx, unsigned long lzone, char *user,
{
ASN1_INTEGER *izone = NULL;
if(!(izone = M_ASN1_INTEGER_new()) || !ASN1_INTEGER_set(izone, lzone)) {
- OPENSSL_PUT_ERROR(X509V3, SXNET_add_id_ulong, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
M_ASN1_INTEGER_free(izone);
return 0;
}
@@ -191,12 +191,12 @@ int SXNET_add_id_INTEGER(SXNET **psx, ASN1_INTEGER *zone, char *user,
SXNET *sx = NULL;
SXNETID *id = NULL;
if(!psx || !zone || !user) {
- OPENSSL_PUT_ERROR(X509V3, SXNET_add_id_INTEGER, X509V3_R_INVALID_NULL_ARGUMENT);
+ OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_NULL_ARGUMENT);
return 0;
}
if(userlen == -1) userlen = strlen(user);
if(userlen > 64) {
- OPENSSL_PUT_ERROR(X509V3, SXNET_add_id_INTEGER, X509V3_R_USER_TOO_LONG);
+ OPENSSL_PUT_ERROR(X509V3, X509V3_R_USER_TOO_LONG);
return 0;
}
if(!*psx) {
@@ -205,7 +205,7 @@ int SXNET_add_id_INTEGER(SXNET **psx, ASN1_INTEGER *zone, char *user,
*psx = sx;
} else sx = *psx;
if(SXNET_get_id_INTEGER(sx, zone)) {
- OPENSSL_PUT_ERROR(X509V3, SXNET_add_id_INTEGER, X509V3_R_DUPLICATE_ZONE_ID);
+ OPENSSL_PUT_ERROR(X509V3, X509V3_R_DUPLICATE_ZONE_ID);
return 0;
}
@@ -218,7 +218,7 @@ int SXNET_add_id_INTEGER(SXNET **psx, ASN1_INTEGER *zone, char *user,
return 1;
err:
- OPENSSL_PUT_ERROR(X509V3, SXNET_add_id_INTEGER, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
SXNETID_free(id);
SXNET_free(sx);
*psx = NULL;
@@ -230,7 +230,7 @@ ASN1_OCTET_STRING *SXNET_get_id_asc(SXNET *sx, char *zone)
ASN1_INTEGER *izone = NULL;
ASN1_OCTET_STRING *oct;
if(!(izone = s2i_ASN1_INTEGER(NULL, zone))) {
- OPENSSL_PUT_ERROR(X509V3, SXNET_get_id_asc, X509V3_R_ERROR_CONVERTING_ZONE);
+ OPENSSL_PUT_ERROR(X509V3, X509V3_R_ERROR_CONVERTING_ZONE);
return NULL;
}
oct = SXNET_get_id_INTEGER(sx, izone);
@@ -243,7 +243,7 @@ ASN1_OCTET_STRING *SXNET_get_id_ulong(SXNET *sx, unsigned long lzone)
ASN1_INTEGER *izone = NULL;
ASN1_OCTET_STRING *oct;
if(!(izone = M_ASN1_INTEGER_new()) || !ASN1_INTEGER_set(izone, lzone)) {
- OPENSSL_PUT_ERROR(X509V3, SXNET_get_id_ulong, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
M_ASN1_INTEGER_free(izone);
return NULL;
}
diff --git a/src/crypto/x509v3/v3_utl.c b/src/crypto/x509v3/v3_utl.c
index 77fc65c..aa65c79 100644
--- a/src/crypto/x509v3/v3_utl.c
+++ b/src/crypto/x509v3/v3_utl.c
@@ -70,6 +70,8 @@
#include <openssl/obj.h>
#include <openssl/x509v3.h>
+#include "../conf/internal.h"
+
static char *strip_spaces(char *name);
static int sk_strcmp(const OPENSSL_STRING *a, const OPENSSL_STRING *b);
@@ -91,7 +93,7 @@ int X509V3_add_value(const char *name, const char *value,
char *tname = NULL, *tvalue = NULL;
if(name && !(tname = BUF_strdup(name))) goto err;
if(value && !(tvalue = BUF_strdup(value))) goto err;
- if(!(vtmp = (CONF_VALUE *)OPENSSL_malloc(sizeof(CONF_VALUE)))) goto err;
+ if(!(vtmp = CONF_VALUE_new())) goto err;
if(!*extlist && !(*extlist = sk_CONF_VALUE_new_null())) goto err;
vtmp->section = NULL;
vtmp->name = tname;
@@ -99,7 +101,7 @@ int X509V3_add_value(const char *name, const char *value,
if(!sk_CONF_VALUE_push(*extlist, vtmp)) goto err;
return 1;
err:
- OPENSSL_PUT_ERROR(X509V3, X509V3_add_value, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
if(vtmp) OPENSSL_free(vtmp);
if(tname) OPENSSL_free(tname);
if(tvalue) OPENSSL_free(tvalue);
@@ -145,7 +147,7 @@ char *i2s_ASN1_ENUMERATED(X509V3_EXT_METHOD *method, ASN1_ENUMERATED *a)
if(!a) return NULL;
if(!(bntmp = ASN1_ENUMERATED_to_BN(a, NULL)) ||
!(strtmp = BN_bn2dec(bntmp)) )
- OPENSSL_PUT_ERROR(X509V3, i2s_ASN1_ENUMERATED, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
BN_free(bntmp);
return strtmp;
}
@@ -157,7 +159,7 @@ char *i2s_ASN1_INTEGER(X509V3_EXT_METHOD *method, ASN1_INTEGER *a)
if(!a) return NULL;
if(!(bntmp = ASN1_INTEGER_to_BN(a, NULL)) ||
!(strtmp = BN_bn2dec(bntmp)) )
- OPENSSL_PUT_ERROR(X509V3, i2s_ASN1_INTEGER, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
BN_free(bntmp);
return strtmp;
}
@@ -169,7 +171,7 @@ ASN1_INTEGER *s2i_ASN1_INTEGER(X509V3_EXT_METHOD *method, char *value)
int isneg, ishex;
int ret;
if (!value) {
- OPENSSL_PUT_ERROR(X509V3, s2i_ASN1_INTEGER, X509V3_R_INVALID_NULL_VALUE);
+ OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_NULL_VALUE);
return 0;
}
bn = BN_new();
@@ -188,7 +190,7 @@ ASN1_INTEGER *s2i_ASN1_INTEGER(X509V3_EXT_METHOD *method, char *value)
if (!ret || value[ret]) {
BN_free(bn);
- OPENSSL_PUT_ERROR(X509V3, s2i_ASN1_INTEGER, X509V3_R_BN_DEC2BN_ERROR);
+ OPENSSL_PUT_ERROR(X509V3, X509V3_R_BN_DEC2BN_ERROR);
return 0;
}
@@ -197,7 +199,7 @@ ASN1_INTEGER *s2i_ASN1_INTEGER(X509V3_EXT_METHOD *method, char *value)
aint = BN_to_ASN1_INTEGER(bn, NULL);
BN_free(bn);
if (!aint) {
- OPENSSL_PUT_ERROR(X509V3, s2i_ASN1_INTEGER, X509V3_R_BN_TO_ASN1_INTEGER_ERROR);
+ OPENSSL_PUT_ERROR(X509V3, X509V3_R_BN_TO_ASN1_INTEGER_ERROR);
return 0;
}
if (isneg) aint->type |= V_ASN1_NEG;
@@ -232,7 +234,7 @@ int X509V3_get_value_bool(CONF_VALUE *value, int *asn1_bool)
return 1;
}
err:
- OPENSSL_PUT_ERROR(X509V3, X509V3_get_value_bool, X509V3_R_INVALID_BOOLEAN_STRING);
+ OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_BOOLEAN_STRING);
X509V3_conf_err(value);
return 0;
}
@@ -264,7 +266,7 @@ STACK_OF(CONF_VALUE) *X509V3_parse_list(const char *line)
linebuf = BUF_strdup(line);
if (linebuf == NULL)
{
- OPENSSL_PUT_ERROR(X509V3, X509V3_parse_list, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
goto err;
}
state = HDR_NAME;
@@ -279,7 +281,7 @@ STACK_OF(CONF_VALUE) *X509V3_parse_list(const char *line)
*p = 0;
ntmp = strip_spaces(q);
if(!ntmp) {
- OPENSSL_PUT_ERROR(X509V3, X509V3_parse_list, X509V3_R_INVALID_NULL_NAME);
+ OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_NULL_NAME);
goto err;
}
q = p + 1;
@@ -291,7 +293,7 @@ STACK_OF(CONF_VALUE) *X509V3_parse_list(const char *line)
printf("%s\n", ntmp);
#endif
if(!ntmp) {
- OPENSSL_PUT_ERROR(X509V3, X509V3_parse_list, X509V3_R_INVALID_NULL_NAME);
+ OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_NULL_NAME);
goto err;
}
X509V3_add_value(ntmp, NULL, &values);
@@ -307,7 +309,7 @@ STACK_OF(CONF_VALUE) *X509V3_parse_list(const char *line)
printf("%s\n", ntmp);
#endif
if(!vtmp) {
- OPENSSL_PUT_ERROR(X509V3, X509V3_parse_list, X509V3_R_INVALID_NULL_VALUE);
+ OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_NULL_VALUE);
goto err;
}
X509V3_add_value(ntmp, vtmp, &values);
@@ -324,7 +326,7 @@ STACK_OF(CONF_VALUE) *X509V3_parse_list(const char *line)
printf("%s=%s\n", ntmp, vtmp);
#endif
if(!vtmp) {
- OPENSSL_PUT_ERROR(X509V3, X509V3_parse_list, X509V3_R_INVALID_NULL_VALUE);
+ OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_NULL_VALUE);
goto err;
}
X509V3_add_value(ntmp, vtmp, &values);
@@ -334,7 +336,7 @@ STACK_OF(CONF_VALUE) *X509V3_parse_list(const char *line)
printf("%s\n", ntmp);
#endif
if(!ntmp) {
- OPENSSL_PUT_ERROR(X509V3, X509V3_parse_list, X509V3_R_INVALID_NULL_NAME);
+ OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_NULL_NAME);
goto err;
}
X509V3_add_value(ntmp, NULL, &values);
@@ -379,7 +381,7 @@ char *hex_to_string(const unsigned char *buffer, long len)
static const char hexdig[] = "0123456789ABCDEF";
if(!buffer || !len) return NULL;
if(!(tmp = OPENSSL_malloc(len * 3 + 1))) {
- OPENSSL_PUT_ERROR(X509V3, hex_to_string, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
return NULL;
}
q = tmp;
@@ -402,7 +404,7 @@ unsigned char *string_to_hex(const char *str, long *len)
unsigned char *hexbuf, *q;
unsigned char ch, cl, *p;
if(!str) {
- OPENSSL_PUT_ERROR(X509V3, string_to_hex, X509V3_R_INVALID_NULL_ARGUMENT);
+ OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_NULL_ARGUMENT);
return NULL;
}
if(!(hexbuf = OPENSSL_malloc(strlen(str) >> 1))) goto err;
@@ -411,7 +413,7 @@ unsigned char *string_to_hex(const char *str, long *len)
if(ch == ':') continue;
cl = *p++;
if(!cl) {
- OPENSSL_PUT_ERROR(X509V3, string_to_hex, X509V3_R_ODD_NUMBER_OF_DIGITS);
+ OPENSSL_PUT_ERROR(X509V3, X509V3_R_ODD_NUMBER_OF_DIGITS);
OPENSSL_free(hexbuf);
return NULL;
}
@@ -435,12 +437,12 @@ unsigned char *string_to_hex(const char *str, long *len)
err:
if(hexbuf) OPENSSL_free(hexbuf);
- OPENSSL_PUT_ERROR(X509V3, string_to_hex, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE);
return NULL;
badhex:
OPENSSL_free(hexbuf);
- OPENSSL_PUT_ERROR(X509V3, string_to_hex, X509V3_R_ILLEGAL_HEX_DIGIT);
+ OPENSSL_PUT_ERROR(X509V3, X509V3_R_ILLEGAL_HEX_DIGIT);
return NULL;
}
diff --git a/src/crypto/x509v3/v3nametest.c b/src/crypto/x509v3/v3name_test.c
index a3197e6..a3197e6 100644
--- a/src/crypto/x509v3/v3nametest.c
+++ b/src/crypto/x509v3/v3name_test.c
diff --git a/src/decrepit/CMakeLists.txt b/src/decrepit/CMakeLists.txt
index b43fea7..84e5252 100644
--- a/src/decrepit/CMakeLists.txt
+++ b/src/decrepit/CMakeLists.txt
@@ -1,9 +1,17 @@
-add_subdirectory(cast)
+add_subdirectory(bio)
add_subdirectory(blowfish)
+add_subdirectory(cast)
+add_subdirectory(des)
+add_subdirectory(rsa)
+add_subdirectory(xts)
add_library(
decrepit
- $<TARGET_OBJECTS:cast>
+ $<TARGET_OBJECTS:bio_decrepit>
$<TARGET_OBJECTS:blowfish>
+ $<TARGET_OBJECTS:cast>
+ $<TARGET_OBJECTS:des_decrepit>
+ $<TARGET_OBJECTS:rsa_decrepit>
+ $<TARGET_OBJECTS:xts>
)
diff --git a/src/decrepit/bio/CMakeLists.txt b/src/decrepit/bio/CMakeLists.txt
new file mode 100644
index 0000000..95d9231
--- /dev/null
+++ b/src/decrepit/bio/CMakeLists.txt
@@ -0,0 +1,9 @@
+include_directories(../../include)
+
+add_library(
+ bio_decrepit
+
+ OBJECT
+
+ base64_bio.c
+)
diff --git a/src/decrepit/bio/base64_bio.c b/src/decrepit/bio/base64_bio.c
new file mode 100644
index 0000000..2056138
--- /dev/null
+++ b/src/decrepit/bio/base64_bio.c
@@ -0,0 +1,536 @@
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.] */
+
+#include <assert.h>
+#include <errno.h>
+#include <stdio.h>
+#include <string.h>
+
+#include <openssl/base64.h>
+#include <openssl/bio.h>
+#include <openssl/buffer.h>
+#include <openssl/evp.h>
+#include <openssl/mem.h>
+
+
+#define B64_BLOCK_SIZE 1024
+#define B64_BLOCK_SIZE2 768
+#define B64_NONE 0
+#define B64_ENCODE 1
+#define B64_DECODE 2
+#define EVP_ENCODE_LENGTH(l) (((l+2)/3*4)+(l/48+1)*2+80)
+
+typedef struct b64_struct {
+ int buf_len;
+ int buf_off;
+ int tmp_len; /* used to find the start when decoding */
+ int tmp_nl; /* If true, scan until '\n' */
+ int encode;
+ int start; /* have we started decoding yet? */
+ int cont; /* <= 0 when finished */
+ EVP_ENCODE_CTX base64;
+ char buf[EVP_ENCODE_LENGTH(B64_BLOCK_SIZE) + 10];
+ char tmp[B64_BLOCK_SIZE];
+} BIO_B64_CTX;
+
+static int b64_new(BIO *bio) {
+ BIO_B64_CTX *ctx;
+
+ ctx = OPENSSL_malloc(sizeof(*ctx));
+ if (ctx == NULL) {
+ return 0;
+ }
+
+ memset(ctx, 0, sizeof(*ctx));
+
+ ctx->cont = 1;
+ ctx->start = 1;
+
+ bio->init = 1;
+ bio->ptr = (char *)ctx;
+ return 1;
+}
+
+static int b64_free(BIO *bio) {
+ if (bio == NULL) {
+ return 0;
+ }
+ OPENSSL_free(bio->ptr);
+ bio->ptr = NULL;
+ bio->init = 0;
+ bio->flags = 0;
+ return 1;
+}
+
+static int b64_read(BIO *b, char *out, int outl) {
+ int ret = 0, i, ii, j, k, x, n, num, ret_code = 0;
+ BIO_B64_CTX *ctx;
+ uint8_t *p, *q;
+
+ if (out == NULL) {
+ return 0;
+ }
+ ctx = (BIO_B64_CTX *) b->ptr;
+
+ if (ctx == NULL || b->next_bio == NULL) {
+ return 0;
+ }
+
+ BIO_clear_retry_flags(b);
+
+ if (ctx->encode != B64_DECODE) {
+ ctx->encode = B64_DECODE;
+ ctx->buf_len = 0;
+ ctx->buf_off = 0;
+ ctx->tmp_len = 0;
+ EVP_DecodeInit(&ctx->base64);
+ }
+
+ /* First check if there are bytes decoded/encoded */
+ if (ctx->buf_len > 0) {
+ assert(ctx->buf_len >= ctx->buf_off);
+ i = ctx->buf_len - ctx->buf_off;
+ if (i > outl) {
+ i = outl;
+ }
+ assert(ctx->buf_off + i < (int)sizeof(ctx->buf));
+ memcpy(out, &ctx->buf[ctx->buf_off], i);
+ ret = i;
+ out += i;
+ outl -= i;
+ ctx->buf_off += i;
+ if (ctx->buf_len == ctx->buf_off) {
+ ctx->buf_len = 0;
+ ctx->buf_off = 0;
+ }
+ }
+
+ /* At this point, we have room of outl bytes and an empty buffer, so we
+ * should read in some more. */
+
+ ret_code = 0;
+ while (outl > 0) {
+ if (ctx->cont <= 0) {
+ break;
+ }
+
+ i = BIO_read(b->next_bio, &(ctx->tmp[ctx->tmp_len]),
+ B64_BLOCK_SIZE - ctx->tmp_len);
+
+ if (i <= 0) {
+ ret_code = i;
+
+ /* Should we continue next time we are called? */
+ if (!BIO_should_retry(b->next_bio)) {
+ ctx->cont = i;
+ /* If buffer empty break */
+ if (ctx->tmp_len == 0) {
+ break;
+ } else {
+ /* Fall through and process what we have */
+ i = 0;
+ }
+ } else {
+ /* else we retry and add more data to buffer */
+ break;
+ }
+ }
+ i += ctx->tmp_len;
+ ctx->tmp_len = i;
+
+ /* We need to scan, a line at a time until we have a valid line if we are
+ * starting. */
+ if (ctx->start && (BIO_test_flags(b, BIO_FLAGS_BASE64_NO_NL))) {
+ /* ctx->start = 1; */
+ ctx->tmp_len = 0;
+ } else if (ctx->start) {
+ q = p = (uint8_t *)ctx->tmp;
+ num = 0;
+ for (j = 0; j < i; j++) {
+ if (*(q++) != '\n') {
+ continue;
+ }
+
+ /* due to a previous very long line, we need to keep on scanning for a
+ * '\n' before we even start looking for base64 encoded stuff. */
+ if (ctx->tmp_nl) {
+ p = q;
+ ctx->tmp_nl = 0;
+ continue;
+ }
+
+ k = EVP_DecodeUpdate(&(ctx->base64), (uint8_t *)ctx->buf, &num, p,
+ q - p);
+
+ if (k <= 0 && num == 0 && ctx->start) {
+ EVP_DecodeInit(&ctx->base64);
+ } else {
+ if (p != (uint8_t *)&(ctx->tmp[0])) {
+ i -= (p - (uint8_t *)&(ctx->tmp[0]));
+ for (x = 0; x < i; x++) {
+ ctx->tmp[x] = p[x];
+ }
+ }
+ EVP_DecodeInit(&ctx->base64);
+ ctx->start = 0;
+ break;
+ }
+ p = q;
+ }
+
+ /* we fell off the end without starting */
+ if (j == i && num == 0) {
+ /* Is this is one long chunk?, if so, keep on reading until a new
+ * line. */
+ if (p == (uint8_t *)&(ctx->tmp[0])) {
+ /* Check buffer full */
+ if (i == B64_BLOCK_SIZE) {
+ ctx->tmp_nl = 1;
+ ctx->tmp_len = 0;
+ }
+ } else if (p != q) { /* finished on a '\n' */
+ n = q - p;
+ for (ii = 0; ii < n; ii++) {
+ ctx->tmp[ii] = p[ii];
+ }
+ ctx->tmp_len = n;
+ }
+ /* else finished on a '\n' */
+ continue;
+ } else {
+ ctx->tmp_len = 0;
+ }
+ } else if (i < B64_BLOCK_SIZE && ctx->cont > 0) {
+ /* If buffer isn't full and we can retry then restart to read in more
+ * data. */
+ continue;
+ }
+
+ if (BIO_test_flags(b, BIO_FLAGS_BASE64_NO_NL)) {
+ int z, jj;
+
+ jj = i & ~3; /* process per 4 */
+ z = EVP_DecodeBlock((uint8_t *)ctx->buf, (uint8_t *)ctx->tmp, jj);
+ if (jj > 2) {
+ if (ctx->tmp[jj - 1] == '=') {
+ z--;
+ if (ctx->tmp[jj - 2] == '=') {
+ z--;
+ }
+ }
+ }
+ /* z is now number of output bytes and jj is the number consumed. */
+ if (jj != i) {
+ memmove(ctx->tmp, &ctx->tmp[jj], i - jj);
+ ctx->tmp_len = i - jj;
+ }
+ ctx->buf_len = 0;
+ if (z > 0) {
+ ctx->buf_len = z;
+ }
+ i = z;
+ } else {
+ i = EVP_DecodeUpdate(&(ctx->base64), (uint8_t *)ctx->buf,
+ &ctx->buf_len, (uint8_t *)ctx->tmp, i);
+ ctx->tmp_len = 0;
+ }
+ ctx->buf_off = 0;
+ if (i < 0) {
+ ret_code = 0;
+ ctx->buf_len = 0;
+ break;
+ }
+
+ if (ctx->buf_len <= outl) {
+ i = ctx->buf_len;
+ } else {
+ i = outl;
+ }
+
+ memcpy(out, ctx->buf, i);
+ ret += i;
+ ctx->buf_off = i;
+ if (ctx->buf_off == ctx->buf_len) {
+ ctx->buf_len = 0;
+ ctx->buf_off = 0;
+ }
+ outl -= i;
+ out += i;
+ }
+
+ BIO_copy_next_retry(b);
+ return ret == 0 ? ret_code : ret;
+}
+
+static int b64_write(BIO *b, const char *in, int inl) {
+ int ret = 0, n, i;
+ BIO_B64_CTX *ctx;
+
+ ctx = (BIO_B64_CTX *)b->ptr;
+ BIO_clear_retry_flags(b);
+
+ if (ctx->encode != B64_ENCODE) {
+ ctx->encode = B64_ENCODE;
+ ctx->buf_len = 0;
+ ctx->buf_off = 0;
+ ctx->tmp_len = 0;
+ EVP_EncodeInit(&(ctx->base64));
+ }
+
+ assert(ctx->buf_off < (int)sizeof(ctx->buf));
+ assert(ctx->buf_len <= (int)sizeof(ctx->buf));
+ assert(ctx->buf_len >= ctx->buf_off);
+
+ n = ctx->buf_len - ctx->buf_off;
+ while (n > 0) {
+ i = BIO_write(b->next_bio, &(ctx->buf[ctx->buf_off]), n);
+ if (i <= 0) {
+ BIO_copy_next_retry(b);
+ return i;
+ }
+ assert(i <= n);
+ ctx->buf_off += i;
+ assert(ctx->buf_off <= (int)sizeof(ctx->buf));
+ assert(ctx->buf_len >= ctx->buf_off);
+ n -= i;
+ }
+
+ /* at this point all pending data has been written. */
+ ctx->buf_off = 0;
+ ctx->buf_len = 0;
+
+ if (in == NULL || inl <= 0) {
+ return 0;
+ }
+
+ while (inl > 0) {
+ n = (inl > B64_BLOCK_SIZE) ? B64_BLOCK_SIZE : inl;
+
+ if (BIO_test_flags(b, BIO_FLAGS_BASE64_NO_NL)) {
+ if (ctx->tmp_len > 0) {
+ assert(ctx->tmp_len <= 3);
+ n = 3 - ctx->tmp_len;
+ /* There's a theoretical possibility of this. */
+ if (n > inl) {
+ n = inl;
+ }
+ memcpy(&(ctx->tmp[ctx->tmp_len]), in, n);
+ ctx->tmp_len += n;
+ ret += n;
+ if (ctx->tmp_len < 3) {
+ break;
+ }
+ ctx->buf_len = EVP_EncodeBlock((uint8_t *)ctx->buf, (uint8_t *)ctx->tmp,
+ ctx->tmp_len);
+ assert(ctx->buf_len <= (int)sizeof(ctx->buf));
+ assert(ctx->buf_len >= ctx->buf_off);
+
+ /* Since we're now done using the temporary buffer, the length should
+ * be zeroed. */
+ ctx->tmp_len = 0;
+ } else {
+ if (n < 3) {
+ memcpy(ctx->tmp, in, n);
+ ctx->tmp_len = n;
+ ret += n;
+ break;
+ }
+ n -= n % 3;
+ ctx->buf_len =
+ EVP_EncodeBlock((uint8_t *)ctx->buf, (const uint8_t *)in, n);
+ assert(ctx->buf_len <= (int)sizeof(ctx->buf));
+ assert(ctx->buf_len >= ctx->buf_off);
+ ret += n;
+ }
+ } else {
+ EVP_EncodeUpdate(&(ctx->base64), (uint8_t *)ctx->buf, &ctx->buf_len,
+ (uint8_t *)in, n);
+ assert(ctx->buf_len <= (int)sizeof(ctx->buf));
+ assert(ctx->buf_len >= ctx->buf_off);
+ ret += n;
+ }
+ inl -= n;
+ in += n;
+
+ ctx->buf_off = 0;
+ n = ctx->buf_len;
+
+ while (n > 0) {
+ i = BIO_write(b->next_bio, &(ctx->buf[ctx->buf_off]), n);
+ if (i <= 0) {
+ BIO_copy_next_retry(b);
+ return ret == 0 ? i : ret;
+ }
+ assert(i <= n);
+ n -= i;
+ ctx->buf_off += i;
+ assert(ctx->buf_off <= (int)sizeof(ctx->buf));
+ assert(ctx->buf_len >= ctx->buf_off);
+ }
+ ctx->buf_len = 0;
+ ctx->buf_off = 0;
+ }
+ return ret;
+}
+
+static long b64_ctrl(BIO *b, int cmd, long num, void *ptr) {
+ BIO_B64_CTX *ctx;
+ long ret = 1;
+ int i;
+
+ ctx = (BIO_B64_CTX *)b->ptr;
+
+ switch (cmd) {
+ case BIO_CTRL_RESET:
+ ctx->cont = 1;
+ ctx->start = 1;
+ ctx->encode = B64_NONE;
+ ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
+ break;
+
+ case BIO_CTRL_EOF: /* More to read */
+ if (ctx->cont <= 0) {
+ ret = 1;
+ } else {
+ ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
+ }
+ break;
+
+ case BIO_CTRL_WPENDING: /* More to write in buffer */
+ assert(ctx->buf_len >= ctx->buf_off);
+ ret = ctx->buf_len - ctx->buf_off;
+ if ((ret == 0) && (ctx->encode != B64_NONE) && (ctx->base64.num != 0)) {
+ ret = 1;
+ } else if (ret <= 0) {
+ ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
+ }
+ break;
+
+ case BIO_CTRL_PENDING: /* More to read in buffer */
+ assert(ctx->buf_len >= ctx->buf_off);
+ ret = ctx->buf_len - ctx->buf_off;
+ if (ret <= 0) {
+ ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
+ }
+ break;
+
+ case BIO_CTRL_FLUSH:
+ /* do a final write */
+ again:
+ while (ctx->buf_len != ctx->buf_off) {
+ i = b64_write(b, NULL, 0);
+ if (i < 0) {
+ return i;
+ }
+ }
+ if (BIO_test_flags(b, BIO_FLAGS_BASE64_NO_NL)) {
+ if (ctx->tmp_len != 0) {
+ ctx->buf_len = EVP_EncodeBlock((uint8_t *)ctx->buf,
+ (uint8_t *)ctx->tmp, ctx->tmp_len);
+ ctx->buf_off = 0;
+ ctx->tmp_len = 0;
+ goto again;
+ }
+ } else if (ctx->encode != B64_NONE && ctx->base64.num != 0) {
+ ctx->buf_off = 0;
+ EVP_EncodeFinal(&(ctx->base64), (uint8_t *)ctx->buf, &(ctx->buf_len));
+ /* push out the bytes */
+ goto again;
+ }
+ /* Finally flush the underlying BIO */
+ ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
+ break;
+
+ case BIO_C_DO_STATE_MACHINE:
+ BIO_clear_retry_flags(b);
+ ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
+ BIO_copy_next_retry(b);
+ break;
+
+ case BIO_CTRL_INFO:
+ case BIO_CTRL_GET:
+ case BIO_CTRL_SET:
+ default:
+ ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
+ break;
+ }
+ return ret;
+}
+
+static long b64_callback_ctrl(BIO *b, int cmd, bio_info_cb fp) {
+ long ret = 1;
+
+ if (b->next_bio == NULL) {
+ return 0;
+ }
+ switch (cmd) {
+ default:
+ ret = BIO_callback_ctrl(b->next_bio, cmd, fp);
+ break;
+ }
+ return ret;
+}
+
+static int b64_puts(BIO *b, const char *str) {
+ return b64_write(b, str, strlen(str));
+}
+
+static const BIO_METHOD b64_method = {
+ BIO_TYPE_BASE64, "base64 encoding", b64_write, b64_read, b64_puts,
+ NULL /* gets */, b64_ctrl, b64_new, b64_free, b64_callback_ctrl,
+};
+
+const BIO_METHOD *BIO_f_base64(void) { return &b64_method; }
diff --git a/src/decrepit/blowfish/CMakeLists.txt b/src/decrepit/blowfish/CMakeLists.txt
index afaf641..29729c4 100644
--- a/src/decrepit/blowfish/CMakeLists.txt
+++ b/src/decrepit/blowfish/CMakeLists.txt
@@ -1,4 +1,4 @@
-include_directories(. ../../include)
+include_directories(../../include)
add_library(
blowfish
diff --git a/src/decrepit/cast/CMakeLists.txt b/src/decrepit/cast/CMakeLists.txt
index ada99e4..2830381 100644
--- a/src/decrepit/cast/CMakeLists.txt
+++ b/src/decrepit/cast/CMakeLists.txt
@@ -1,4 +1,4 @@
-include_directories(. ../../include)
+include_directories(../../include)
add_library(
cast
diff --git a/src/decrepit/des/CMakeLists.txt b/src/decrepit/des/CMakeLists.txt
new file mode 100644
index 0000000..0ee5c2e
--- /dev/null
+++ b/src/decrepit/des/CMakeLists.txt
@@ -0,0 +1,9 @@
+include_directories(../../include)
+
+add_library(
+ des_decrepit
+
+ OBJECT
+
+ cfb64ede.c
+)
diff --git a/src/decrepit/des/cfb64ede.c b/src/decrepit/des/cfb64ede.c
new file mode 100644
index 0000000..680a75a
--- /dev/null
+++ b/src/decrepit/des/cfb64ede.c
@@ -0,0 +1,242 @@
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.] */
+
+#include <string.h>
+
+#include <openssl/des.h>
+
+#include "../crypto/des/internal.h"
+
+
+/* defined in des.c */
+void DES_decrypt3(uint32_t *data, const DES_key_schedule *ks1,
+ const DES_key_schedule *ks2, const DES_key_schedule *ks3);
+void DES_encrypt3(uint32_t *data, const DES_key_schedule *ks1,
+ const DES_key_schedule *ks2, const DES_key_schedule *ks3);
+
+/* The input and output encrypted as though 64bit cfb mode is being used. The
+ * extra state information to record how much of the 64bit block we have used
+ * is contained in *num; */
+void DES_ede3_cfb64_encrypt(const uint8_t *in, uint8_t *out,
+ long length, DES_key_schedule *ks1,
+ DES_key_schedule *ks2, DES_key_schedule *ks3,
+ DES_cblock *ivec, int *num, int enc) {
+ uint32_t v0, v1;
+ long l = length;
+ int n = *num;
+ uint32_t ti[2];
+ uint8_t *iv, c, cc;
+
+ iv = ivec->bytes;
+ if (enc) {
+ while (l--) {
+ if (n == 0) {
+ c2l(iv, v0);
+ c2l(iv, v1);
+
+ ti[0] = v0;
+ ti[1] = v1;
+ DES_encrypt3(ti, ks1, ks2, ks3);
+ v0 = ti[0];
+ v1 = ti[1];
+
+ iv = ivec->bytes;
+ l2c(v0, iv);
+ l2c(v1, iv);
+ iv = ivec->bytes;
+ }
+ c = *(in++) ^ iv[n];
+ *(out++) = c;
+ iv[n] = c;
+ n = (n + 1) & 0x07;
+ }
+ } else {
+ while (l--) {
+ if (n == 0) {
+ c2l(iv, v0);
+ c2l(iv, v1);
+
+ ti[0] = v0;
+ ti[1] = v1;
+ DES_encrypt3(ti, ks1, ks2, ks3);
+ v0 = ti[0];
+ v1 = ti[1];
+
+ iv = ivec->bytes;
+ l2c(v0, iv);
+ l2c(v1, iv);
+ iv = ivec->bytes;
+ }
+ cc = *(in++);
+ c = iv[n];
+ iv[n] = cc;
+ *(out++) = c ^ cc;
+ n = (n + 1) & 0x07;
+ }
+ }
+ v0 = v1 = ti[0] = ti[1] = c = cc = 0;
+ *num = n;
+}
+
+/* This is compatible with the single key CFB-r for DES, even thought that's
+ * not what EVP needs. */
+
+void DES_ede3_cfb_encrypt(const uint8_t *in, uint8_t *out, int numbits,
+ long length, DES_key_schedule *ks1,
+ DES_key_schedule *ks2, DES_key_schedule *ks3,
+ DES_cblock *ivec, int enc) {
+ uint32_t d0, d1, v0, v1;
+ unsigned long l = length, n = ((unsigned int)numbits + 7) / 8;
+ int num = numbits, i;
+ uint32_t ti[2];
+ uint8_t *iv;
+ uint8_t ovec[16];
+
+ if (num > 64) {
+ return;
+ };
+
+ iv = ivec->bytes;
+ c2l(iv, v0);
+ c2l(iv, v1);
+
+ if (enc) {
+ while (l >= n) {
+ l -= n;
+ ti[0] = v0;
+ ti[1] = v1;
+ DES_encrypt3(ti, ks1, ks2, ks3);
+ c2ln(in, d0, d1, n);
+ in += n;
+ d0 ^= ti[0];
+ d1 ^= ti[1];
+ l2cn(d0, d1, out, n);
+ out += n;
+ /* 30-08-94 - eay - changed because l>>32 and l<<32 are bad under
+ * gcc :-( */
+ if (num == 32) {
+ v0 = v1;
+ v1 = d0;
+ } else if (num == 64) {
+ v0 = d0;
+ v1 = d1;
+ } else {
+ iv = &ovec[0];
+ l2c(v0, iv);
+ l2c(v1, iv);
+ l2c(d0, iv);
+ l2c(d1, iv);
+ /* shift ovec left most of the bits... */
+ memmove(ovec, ovec + num / 8, 8 + (num % 8 ? 1 : 0));
+ /* now the remaining bits */
+ if (num % 8 != 0) {
+ for (i = 0; i < 8; ++i) {
+ ovec[i] <<= num % 8;
+ ovec[i] |= ovec[i + 1] >> (8 - num % 8);
+ }
+ }
+ iv = &ovec[0];
+ c2l(iv, v0);
+ c2l(iv, v1);
+ }
+ }
+ } else {
+ while (l >= n) {
+ l -= n;
+ ti[0] = v0;
+ ti[1] = v1;
+ DES_encrypt3(ti, ks1, ks2, ks3);
+ c2ln(in, d0, d1, n);
+ in += n;
+ /* 30-08-94 - eay - changed because l>>32 and l<<32 are bad under
+ * gcc :-( */
+ if (num == 32) {
+ v0 = v1;
+ v1 = d0;
+ } else if (num == 64) {
+ v0 = d0;
+ v1 = d1;
+ } else {
+ iv = &ovec[0];
+ l2c(v0, iv);
+ l2c(v1, iv);
+ l2c(d0, iv);
+ l2c(d1, iv);
+ /* shift ovec left most of the bits... */
+ memmove(ovec, ovec + num / 8, 8 + (num % 8 ? 1 : 0));
+ /* now the remaining bits */
+ if (num % 8 != 0) {
+ for (i = 0; i < 8; ++i) {
+ ovec[i] <<= num % 8;
+ ovec[i] |= ovec[i + 1] >> (8 - num % 8);
+ }
+ }
+ iv = &ovec[0];
+ c2l(iv, v0);
+ c2l(iv, v1);
+ }
+ d0 ^= ti[0];
+ d1 ^= ti[1];
+ l2cn(d0, d1, out, n);
+ out += n;
+ }
+ }
+
+ iv = ivec->bytes;
+ l2c(v0, iv);
+ l2c(v1, iv);
+ v0 = v1 = d0 = d1 = ti[0] = ti[1] = 0;
+}
diff --git a/src/decrepit/rsa/CMakeLists.txt b/src/decrepit/rsa/CMakeLists.txt
new file mode 100644
index 0000000..66d836b
--- /dev/null
+++ b/src/decrepit/rsa/CMakeLists.txt
@@ -0,0 +1,9 @@
+include_directories(../../include)
+
+add_library(
+ rsa_decrepit
+
+ OBJECT
+
+ rsa_decrepit.c
+)
diff --git a/src/ssl/ssl_algs.c b/src/decrepit/rsa/rsa_decrepit.c
index fda39a5..c238f46 100644
--- a/src/ssl/ssl_algs.c
+++ b/src/decrepit/rsa/rsa_decrepit.c
@@ -54,13 +54,33 @@
* copied and put under another distribution licence
* [including the GNU Public Licence.] */
-#include "internal.h"
+#include <openssl/rsa.h>
-#include <openssl/crypto.h>
+#include <assert.h>
-int SSL_library_init(void) {
- CRYPTO_library_init();
- return 1;
-}
+#include <openssl/bn.h>
+
+
+RSA *RSA_generate_key(int bits, unsigned long e_value, void *callback,
+ void *cb_arg) {
+ assert(callback == NULL);
+ assert(cb_arg == NULL);
+
+ RSA *rsa = RSA_new();
+ BIGNUM *e = BN_new();
-void SSL_load_error_strings(void) {}
+ if (rsa == NULL ||
+ e == NULL ||
+ !BN_set_word(e, e_value) ||
+ !RSA_generate_key_ex(rsa, bits, e, NULL)) {
+ goto err;
+ }
+
+ BN_free(e);
+ return rsa;
+
+err:
+ BN_free(e);
+ RSA_free(rsa);
+ return NULL;
+}
diff --git a/src/decrepit/xts/CMakeLists.txt b/src/decrepit/xts/CMakeLists.txt
new file mode 100644
index 0000000..7dccde0
--- /dev/null
+++ b/src/decrepit/xts/CMakeLists.txt
@@ -0,0 +1,9 @@
+include_directories(../../include)
+
+add_library(
+ xts
+
+ OBJECT
+
+ xts.c
+)
diff --git a/src/decrepit/xts/xts.c b/src/decrepit/xts/xts.c
new file mode 100644
index 0000000..cf8ad39
--- /dev/null
+++ b/src/decrepit/xts/xts.c
@@ -0,0 +1,295 @@
+/* ====================================================================
+ * Copyright (c) 2011 The OpenSSL Project. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ * software must display the following acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ * endorse or promote products derived from this software without
+ * prior written permission. For written permission, please contact
+ * openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ * nor may "OpenSSL" appear in their names without prior written
+ * permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ * acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ==================================================================== */
+
+#include <openssl/evp.h>
+
+#include <string.h>
+
+#include <openssl/aes.h>
+#include <openssl/cipher.h>
+#include <openssl/modes.h>
+
+
+#if defined(OPENSSL_X86_64) || defined(OPENSSL_X86) || defined(OPENSSL_AARCH64)
+#define STRICT_ALIGNMENT 0
+#else
+#define STRICT_ALIGNMENT 1
+#endif
+
+typedef struct xts128_context {
+ void *key1, *key2;
+ block128_f block1, block2;
+} XTS128_CONTEXT;
+
+static size_t CRYPTO_xts128_encrypt(const XTS128_CONTEXT *ctx,
+ const uint8_t iv[16], const uint8_t *inp,
+ uint8_t *out, size_t len, int enc) {
+ const union {
+ long one;
+ char little;
+ } is_endian = {1};
+ union {
+ uint64_t u[2];
+ uint32_t d[4];
+ uint8_t c[16];
+ } tweak, scratch;
+ unsigned int i;
+
+ if (len < 16) return 0;
+
+ memcpy(tweak.c, iv, 16);
+
+ (*ctx->block2)(tweak.c, tweak.c, ctx->key2);
+
+ if (!enc && (len % 16)) len -= 16;
+
+ while (len >= 16) {
+#if defined(STRICT_ALIGNMENT)
+ memcpy(scratch.c, inp, 16);
+ scratch.u[0] ^= tweak.u[0];
+ scratch.u[1] ^= tweak.u[1];
+#else
+ scratch.u[0] = ((unint64_t *)inp)[0] ^ tweak.u[0];
+ scratch.u[1] = ((unint64_t *)inp)[1] ^ tweak.u[1];
+#endif
+ (*ctx->block1)(scratch.c, scratch.c, ctx->key1);
+#if defined(STRICT_ALIGNMENT)
+ scratch.u[0] ^= tweak.u[0];
+ scratch.u[1] ^= tweak.u[1];
+ memcpy(out, scratch.c, 16);
+#else
+ ((unint64_t *)out)[0] = scratch.u[0] ^= tweak.u[0];
+ ((unint64_t *)out)[1] = scratch.u[1] ^= tweak.u[1];
+#endif
+ inp += 16;
+ out += 16;
+ len -= 16;
+
+ if (len == 0) return 1;
+
+ if (is_endian.little) {
+ unsigned int carry, res;
+
+ res = 0x87 & (((int)tweak.d[3]) >> 31);
+ carry = (unsigned int)(tweak.u[0] >> 63);
+ tweak.u[0] = (tweak.u[0] << 1) ^ res;
+ tweak.u[1] = (tweak.u[1] << 1) | carry;
+ } else {
+ size_t c;
+
+ for (c = 0, i = 0; i < 16; ++i) {
+ /*
+ * + substitutes for |, because c is 1 bit
+ */
+ c += ((size_t)tweak.c[i]) << 1;
+ tweak.c[i] = (uint8_t)c;
+ c = c >> 8;
+ }
+ tweak.c[0] ^= (uint8_t)(0x87 & (0 - c));
+ }
+ }
+ if (enc) {
+ for (i = 0; i < len; ++i) {
+ uint8_t c = inp[i];
+ out[i] = scratch.c[i];
+ scratch.c[i] = c;
+ }
+ scratch.u[0] ^= tweak.u[0];
+ scratch.u[1] ^= tweak.u[1];
+ (*ctx->block1)(scratch.c, scratch.c, ctx->key1);
+ scratch.u[0] ^= tweak.u[0];
+ scratch.u[1] ^= tweak.u[1];
+ memcpy(out - 16, scratch.c, 16);
+ } else {
+ union {
+ uint64_t u[2];
+ uint8_t c[16];
+ } tweak1;
+
+ if (is_endian.little) {
+ unsigned int carry, res;
+
+ res = 0x87 & (((int)tweak.d[3]) >> 31);
+ carry = (unsigned int)(tweak.u[0] >> 63);
+ tweak1.u[0] = (tweak.u[0] << 1) ^ res;
+ tweak1.u[1] = (tweak.u[1] << 1) | carry;
+ } else {
+ size_t c;
+
+ for (c = 0, i = 0; i < 16; ++i) {
+ /*
+ * + substitutes for |, because c is 1 bit
+ */
+ c += ((size_t)tweak.c[i]) << 1;
+ tweak1.c[i] = (uint8_t)c;
+ c = c >> 8;
+ }
+ tweak1.c[0] ^= (uint8_t)(0x87 & (0 - c));
+ }
+#if defined(STRICT_ALIGNMENT)
+ memcpy(scratch.c, inp, 16);
+ scratch.u[0] ^= tweak1.u[0];
+ scratch.u[1] ^= tweak1.u[1];
+#else
+ scratch.u[0] = ((unint64_t *)inp)[0] ^ tweak1.u[0];
+ scratch.u[1] = ((unint64_t *)inp)[1] ^ tweak1.u[1];
+#endif
+ (*ctx->block1)(scratch.c, scratch.c, ctx->key1);
+ scratch.u[0] ^= tweak1.u[0];
+ scratch.u[1] ^= tweak1.u[1];
+
+ for (i = 0; i < len; ++i) {
+ uint8_t c = inp[16 + i];
+ out[16 + i] = scratch.c[i];
+ scratch.c[i] = c;
+ }
+ scratch.u[0] ^= tweak.u[0];
+ scratch.u[1] ^= tweak.u[1];
+ (*ctx->block1)(scratch.c, scratch.c, ctx->key1);
+#if defined(STRICT_ALIGNMENT)
+ scratch.u[0] ^= tweak.u[0];
+ scratch.u[1] ^= tweak.u[1];
+ memcpy(out, scratch.c, 16);
+#else
+ ((unint64_t *)out)[0] = scratch.u[0] ^ tweak.u[0];
+ ((unint64_t *)out)[1] = scratch.u[1] ^ tweak.u[1];
+#endif
+ }
+
+ return 1;
+}
+
+typedef struct {
+ union {
+ double align;
+ AES_KEY ks;
+ } ks1, ks2; /* AES key schedules to use */
+ XTS128_CONTEXT xts;
+} EVP_AES_XTS_CTX;
+
+static int aes_xts_init_key(EVP_CIPHER_CTX *ctx, const uint8_t *key,
+ const uint8_t *iv, int enc) {
+ EVP_AES_XTS_CTX *xctx = ctx->cipher_data;
+ if (!iv && !key) {
+ return 1;
+ }
+
+ if (key) {
+ /* key_len is two AES keys */
+ if (enc) {
+ AES_set_encrypt_key(key, ctx->key_len * 4, &xctx->ks1.ks);
+ xctx->xts.block1 = (block128_f) AES_encrypt;
+ } else {
+ AES_set_decrypt_key(key, ctx->key_len * 4, &xctx->ks1.ks);
+ xctx->xts.block1 = (block128_f) AES_decrypt;
+ }
+
+ AES_set_encrypt_key(key + ctx->key_len / 2,
+ ctx->key_len * 4, &xctx->ks2.ks);
+ xctx->xts.block2 = (block128_f) AES_encrypt;
+ xctx->xts.key1 = &xctx->ks1;
+ }
+
+ if (iv) {
+ xctx->xts.key2 = &xctx->ks2;
+ memcpy(ctx->iv, iv, 16);
+ }
+
+ return 1;
+}
+
+static int aes_xts_cipher(EVP_CIPHER_CTX *ctx, uint8_t *out,
+ const uint8_t *in, size_t len) {
+ EVP_AES_XTS_CTX *xctx = ctx->cipher_data;
+ if (!xctx->xts.key1 ||
+ !xctx->xts.key2 ||
+ !out ||
+ !in ||
+ len < AES_BLOCK_SIZE ||
+ !CRYPTO_xts128_encrypt(&xctx->xts, ctx->iv, in, out, len, ctx->encrypt)) {
+ return 0;
+ }
+ return 1;
+}
+
+static int aes_xts_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr) {
+ EVP_AES_XTS_CTX *xctx = c->cipher_data;
+ if (type == EVP_CTRL_COPY) {
+ EVP_CIPHER_CTX *out = ptr;
+ EVP_AES_XTS_CTX *xctx_out = out->cipher_data;
+ if (xctx->xts.key1) {
+ if (xctx->xts.key1 != &xctx->ks1) {
+ return 0;
+ }
+ xctx_out->xts.key1 = &xctx_out->ks1;
+ }
+ if (xctx->xts.key2) {
+ if (xctx->xts.key2 != &xctx->ks2) {
+ return 0;
+ }
+ xctx_out->xts.key2 = &xctx_out->ks2;
+ }
+ return 1;
+ } else if (type != EVP_CTRL_INIT) {
+ return -1;
+ }
+ /* key1 and key2 are used as an indicator both key and IV are set */
+ xctx->xts.key1 = NULL;
+ xctx->xts.key2 = NULL;
+ return 1;
+}
+
+static const EVP_CIPHER aes_256_xts = {
+ NID_aes_256_xts, 1 /* block_size */, 32 /* key_size */,
+ 16 /* iv_len */, sizeof(EVP_AES_XTS_CTX),
+ EVP_CIPH_XTS_MODE | EVP_CIPH_CUSTOM_IV | EVP_CIPH_ALWAYS_CALL_INIT |
+ EVP_CIPH_CTRL_INIT | EVP_CIPH_CUSTOM_COPY,
+ NULL /* app_data */, aes_xts_init_key, aes_xts_cipher,
+ NULL /* cleanup */, aes_xts_ctrl};
+
+const EVP_CIPHER *EVP_aes_256_xts(void) { return &aes_256_xts; }
diff --git a/src/doc/doc.css b/src/doc/doc.css
deleted file mode 120000
index d7c5102..0000000
--- a/src/doc/doc.css
+++ /dev/null
@@ -1 +0,0 @@
-../util/doc.css \ No newline at end of file
diff --git a/src/include/openssl/aead.h b/src/include/openssl/aead.h
index dc453e3..659f05f 100644
--- a/src/include/openssl/aead.h
+++ b/src/include/openssl/aead.h
@@ -153,6 +153,8 @@ OPENSSL_EXPORT const EVP_AEAD *EVP_aead_aes_256_cbc_sha384_tls(void);
OPENSSL_EXPORT const EVP_AEAD *EVP_aead_des_ede3_cbc_sha1_tls(void);
OPENSSL_EXPORT const EVP_AEAD *EVP_aead_des_ede3_cbc_sha1_tls_implicit_iv(void);
+OPENSSL_EXPORT const EVP_AEAD *EVP_aead_null_sha1_tls(void);
+
/* SSLv3-specific AEAD algorithms.
*
@@ -167,6 +169,7 @@ OPENSSL_EXPORT const EVP_AEAD *EVP_aead_rc4_sha1_ssl3(void);
OPENSSL_EXPORT const EVP_AEAD *EVP_aead_aes_128_cbc_sha1_ssl3(void);
OPENSSL_EXPORT const EVP_AEAD *EVP_aead_aes_256_cbc_sha1_ssl3(void);
OPENSSL_EXPORT const EVP_AEAD *EVP_aead_des_ede3_cbc_sha1_ssl3(void);
+OPENSSL_EXPORT const EVP_AEAD *EVP_aead_null_sha1_ssl3(void);
/* Utility functions. */
@@ -223,11 +226,17 @@ enum evp_aead_direction_t {
evp_aead_seal,
};
-/* EVP_AEAD_CTX_init initializes |ctx| for the given AEAD algorithm from |impl|.
- * The |impl| argument may be NULL to choose the default implementation.
- * Authentication tags may be truncated by passing a size as |tag_len|. A
- * |tag_len| of zero indicates the default tag length and this is defined as
- * EVP_AEAD_DEFAULT_TAG_LENGTH for readability.
+/* EVP_AEAD_CTX_zero sets an uninitialized |ctx| to the zero state. It must be
+ * initialized with |EVP_AEAD_CTX_init| before use. It is safe, but not
+ * necessary, to call |EVP_AEAD_CTX_cleanup| in this state. This may be used for
+ * more uniform cleanup of |EVP_AEAD_CTX|. */
+OPENSSL_EXPORT void EVP_AEAD_CTX_zero(EVP_AEAD_CTX *ctx);
+
+/* EVP_AEAD_CTX_init initializes |ctx| for the given AEAD algorithm. The |impl|
+ * argument is ignored and should be NULL. Authentication tags may be truncated
+ * by passing a size as |tag_len|. A |tag_len| of zero indicates the default
+ * tag length and this is defined as EVP_AEAD_DEFAULT_TAG_LENGTH for
+ * readability.
*
* Returns 1 on success. Otherwise returns 0 and pushes to the error stack. In
* the error case, you do not need to call |EVP_AEAD_CTX_cleanup|, but it's
diff --git a/src/include/openssl/aes.h b/src/include/openssl/aes.h
index 84cde41..ed060ff 100644
--- a/src/include/openssl/aes.h
+++ b/src/include/openssl/aes.h
@@ -124,7 +124,7 @@ OPENSSL_EXPORT void AES_cbc_encrypt(const uint8_t *in, uint8_t *out, size_t len,
const AES_KEY *key, uint8_t *ivec,
const int enc);
-/* AES_ofb128_encrypt encrypts (or decrypts, it's the same in CTR mode) |len|
+/* AES_ofb128_encrypt encrypts (or decrypts, it's the same in OFB mode) |len|
* bytes from |in| to |out|. The |num| parameter must be set to zero on the
* first call. */
OPENSSL_EXPORT void AES_ofb128_encrypt(const uint8_t *in, uint8_t *out,
diff --git a/src/crypto/arm_arch.h b/src/include/openssl/arm_arch.h
index 0600fbb..123a890 100644
--- a/src/crypto/arm_arch.h
+++ b/src/include/openssl/arm_arch.h
@@ -133,4 +133,4 @@ extern uint32_t OPENSSL_armcap_P;
#define ARMV8_PMULL (1 << 5)
-#endif /* OPENSSL_HEADER_THREAD_H */
+#endif /* OPENSSL_HEADER_ARM_ARCH_H */
diff --git a/src/include/openssl/asn1.h b/src/include/openssl/asn1.h
index 4baf81c..043524d 100644
--- a/src/include/openssl/asn1.h
+++ b/src/include/openssl/asn1.h
@@ -515,7 +515,6 @@ struct X509_algor_st
ASN1_OBJECT *algorithm;
ASN1_TYPE *parameter;
} /* X509_ALGOR */;
-DEFINE_STACK_OF(X509_ALGOR);
DECLARE_ASN1_FUNCTIONS(X509_ALGOR)
@@ -950,7 +949,7 @@ OPENSSL_EXPORT void *ASN1_d2i_bio(void *(*xnew)(void), d2i_of_void *d2i, BIO *in
CHECKED_PPTR_OF(type, x)))
OPENSSL_EXPORT void *ASN1_item_d2i_bio(const ASN1_ITEM *it, BIO *in, void *x);
-OPENSSL_EXPORT int ASN1_i2d_bio(i2d_of_void *i2d,BIO *out, unsigned char *x);
+OPENSSL_EXPORT int ASN1_i2d_bio(i2d_of_void *i2d,BIO *out, void *x);
#define ASN1_i2d_bio_of(type,i2d,out,x) \
(ASN1_i2d_bio(CHECKED_I2D_OF(type, i2d), \
@@ -1078,70 +1077,6 @@ OPENSSL_EXPORT int BIO_asn1_get_suffix(BIO *b, asn1_ps_func **psuffix, asn1_ps_f
}
#endif
-#define ASN1_F_ASN1_BIT_STRING_set_bit 100
-#define ASN1_F_ASN1_ENUMERATED_set 101
-#define ASN1_F_ASN1_ENUMERATED_to_BN 102
-#define ASN1_F_ASN1_GENERALIZEDTIME_adj 103
-#define ASN1_F_ASN1_INTEGER_set 104
-#define ASN1_F_ASN1_INTEGER_to_BN 105
-#define ASN1_F_ASN1_OBJECT_new 106
-#define ASN1_F_ASN1_PCTX_new 107
-#define ASN1_F_ASN1_STRING_TABLE_add 108
-#define ASN1_F_ASN1_STRING_set 109
-#define ASN1_F_ASN1_STRING_type_new 110
-#define ASN1_F_ASN1_TIME_adj 111
-#define ASN1_F_ASN1_UTCTIME_adj 112
-#define ASN1_F_ASN1_d2i_fp 113
-#define ASN1_F_ASN1_dup 114
-#define ASN1_F_ASN1_generate_v3 115
-#define ASN1_F_ASN1_get_object 116
-#define ASN1_F_ASN1_i2d_bio 117
-#define ASN1_F_ASN1_i2d_fp 118
-#define ASN1_F_ASN1_item_d2i_fp 119
-#define ASN1_F_ASN1_item_dup 120
-#define ASN1_F_ASN1_item_ex_d2i 121
-#define ASN1_F_ASN1_item_i2d_bio 122
-#define ASN1_F_ASN1_item_i2d_fp 123
-#define ASN1_F_ASN1_item_pack 124
-#define ASN1_F_ASN1_item_unpack 125
-#define ASN1_F_ASN1_mbstring_ncopy 126
-#define ASN1_F_ASN1_template_new 127
-#define ASN1_F_BIO_new_NDEF 128
-#define ASN1_F_BN_to_ASN1_ENUMERATED 129
-#define ASN1_F_BN_to_ASN1_INTEGER 130
-#define ASN1_F_a2d_ASN1_OBJECT 131
-#define ASN1_F_a2i_ASN1_ENUMERATED 132
-#define ASN1_F_a2i_ASN1_INTEGER 133
-#define ASN1_F_a2i_ASN1_STRING 134
-#define ASN1_F_append_exp 135
-#define ASN1_F_asn1_cb 136
-#define ASN1_F_asn1_check_tlen 137
-#define ASN1_F_asn1_collate_primitive 138
-#define ASN1_F_asn1_collect 139
-#define ASN1_F_asn1_d2i_ex_primitive 140
-#define ASN1_F_asn1_d2i_read_bio 141
-#define ASN1_F_asn1_do_adb 142
-#define ASN1_F_asn1_ex_c2i 143
-#define ASN1_F_asn1_find_end 144
-#define ASN1_F_asn1_item_ex_combine_new 145
-#define ASN1_F_asn1_str2type 146
-#define ASN1_F_asn1_template_ex_d2i 147
-#define ASN1_F_asn1_template_noexp_d2i 148
-#define ASN1_F_bitstr_cb 149
-#define ASN1_F_c2i_ASN1_BIT_STRING 150
-#define ASN1_F_c2i_ASN1_INTEGER 151
-#define ASN1_F_c2i_ASN1_OBJECT 152
-#define ASN1_F_collect_data 153
-#define ASN1_F_d2i_ASN1_BOOLEAN 154
-#define ASN1_F_d2i_ASN1_OBJECT 155
-#define ASN1_F_d2i_ASN1_UINTEGER 156
-#define ASN1_F_d2i_ASN1_UTCTIME 157
-#define ASN1_F_d2i_ASN1_bytes 158
-#define ASN1_F_d2i_ASN1_type_bytes 159
-#define ASN1_F_i2d_ASN1_TIME 160
-#define ASN1_F_i2d_PrivateKey 161
-#define ASN1_F_long_c2i 162
-#define ASN1_F_parse_tagging 163
#define ASN1_R_ASN1_LENGTH_MISMATCH 100
#define ASN1_R_AUX_ERROR 101
#define ASN1_R_BAD_GET_ASN1_OBJECT_CALL 102
diff --git a/src/include/openssl/base.h b/src/include/openssl/base.h
index b769ad5..661817a 100644
--- a/src/include/openssl/base.h
+++ b/src/include/openssl/base.h
@@ -79,9 +79,8 @@ extern "C" {
#elif defined(__arm) || defined(__arm__) || defined(_M_ARM)
#define OPENSSL_32_BIT
#define OPENSSL_ARM
-#elif defined(__aarch64__)
+#elif defined(__PPC64__) || defined(__powerpc64__)
#define OPENSSL_64_BIT
-#define OPENSSL_AARCH64
#elif defined(__mips__) && !defined(__LP64__)
#define OPENSSL_32_BIT
#define OPENSSL_MIPS
@@ -99,7 +98,7 @@ extern "C" {
#define OPENSSL_APPLE
#endif
-#if defined(WIN32) || defined(_WIN32)
+#if defined(_WIN32)
#define OPENSSL_WINDOWS
#endif
@@ -109,7 +108,9 @@ extern "C" {
#endif
#define OPENSSL_IS_BORINGSSL
+#define BORINGSSL_201509
#define OPENSSL_VERSION_NUMBER 0x10002000
+#define SSLEAY_VERSION_NUMBER OPENSSL_VERSION_NUMBER
#if defined(BORINGSSL_SHARED_LIBRARY)
@@ -166,13 +167,29 @@ typedef struct AUTHORITY_KEYID_st AUTHORITY_KEYID;
typedef struct DIST_POINT_st DIST_POINT;
typedef struct ISSUING_DIST_POINT_st ISSUING_DIST_POINT;
typedef struct NAME_CONSTRAINTS_st NAME_CONSTRAINTS;
+typedef struct Netscape_certificate_sequence NETSCAPE_CERT_SEQUENCE;
+typedef struct Netscape_spkac_st NETSCAPE_SPKAC;
+typedef struct Netscape_spki_st NETSCAPE_SPKI;
+typedef struct PBE2PARAM_st PBE2PARAM;
+typedef struct PBEPARAM_st PBEPARAM;
+typedef struct PBKDF2PARAM_st PBKDF2PARAM;
typedef struct X509_POLICY_CACHE_st X509_POLICY_CACHE;
typedef struct X509_POLICY_LEVEL_st X509_POLICY_LEVEL;
typedef struct X509_POLICY_NODE_st X509_POLICY_NODE;
typedef struct X509_POLICY_TREE_st X509_POLICY_TREE;
typedef struct X509_algor_st X509_ALGOR;
+typedef struct X509_crl_info_st X509_CRL_INFO;
typedef struct X509_crl_st X509_CRL;
+typedef struct X509_extension_st X509_EXTENSION;
+typedef struct X509_info_st X509_INFO;
+typedef struct X509_name_entry_st X509_NAME_ENTRY;
+typedef struct X509_name_st X509_NAME;
+typedef struct X509_objects_st X509_OBJECTS;
typedef struct X509_pubkey_st X509_PUBKEY;
+typedef struct X509_req_info_st X509_REQ_INFO;
+typedef struct X509_req_st X509_REQ;
+typedef struct X509_sig_st X509_SIG;
+typedef struct X509_val_st X509_VAL;
typedef struct bignum_ctx BN_CTX;
typedef struct bignum_st BIGNUM;
typedef struct bio_method_st BIO_METHOD;
@@ -205,8 +222,9 @@ typedef struct evp_pkey_st EVP_PKEY;
typedef struct hmac_ctx_st HMAC_CTX;
typedef struct md4_state_st MD4_CTX;
typedef struct md5_state_st MD5_CTX;
-typedef struct pkcs8_priv_key_info_st PKCS8_PRIV_KEY_INFO;
typedef struct pkcs12_st PKCS12;
+typedef struct pkcs8_priv_key_info_st PKCS8_PRIV_KEY_INFO;
+typedef struct private_key_st X509_PKEY;
typedef struct rand_meth_st RAND_METHOD;
typedef struct rc4_key_st RC4_KEY;
typedef struct rsa_meth_st RSA_METHOD;
@@ -214,15 +232,26 @@ typedef struct rsa_st RSA;
typedef struct sha256_state_st SHA256_CTX;
typedef struct sha512_state_st SHA512_CTX;
typedef struct sha_state_st SHA_CTX;
+typedef struct srtp_protection_profile_st SRTP_PROTECTION_PROFILE;
+typedef struct ssl_cipher_st SSL_CIPHER;
typedef struct ssl_ctx_st SSL_CTX;
+typedef struct ssl_custom_extension SSL_CUSTOM_EXTENSION;
+typedef struct ssl_method_st SSL_METHOD;
+typedef struct ssl_session_st SSL_SESSION;
typedef struct ssl_st SSL;
typedef struct st_ERR_FNS ERR_FNS;
typedef struct v3_ext_ctx X509V3_CTX;
+typedef struct x509_attributes_st X509_ATTRIBUTE;
+typedef struct x509_cert_aux_st X509_CERT_AUX;
+typedef struct x509_cert_pair_st X509_CERT_PAIR;
+typedef struct x509_cinf_st X509_CINF;
typedef struct x509_crl_method_st X509_CRL_METHOD;
typedef struct x509_revoked_st X509_REVOKED;
typedef struct x509_st X509;
typedef struct x509_store_ctx_st X509_STORE_CTX;
typedef struct x509_store_st X509_STORE;
+typedef struct x509_trust_st X509_TRUST;
+
typedef void *OPENSSL_BLOCK;
diff --git a/src/include/openssl/base64.h b/src/include/openssl/base64.h
index 7aee990..2d27c89 100644
--- a/src/include/openssl/base64.h
+++ b/src/include/openssl/base64.h
@@ -148,9 +148,11 @@ OPENSSL_EXPORT int EVP_DecodeUpdate(EVP_ENCODE_CTX *ctx, uint8_t *out,
OPENSSL_EXPORT int EVP_DecodeFinal(EVP_ENCODE_CTX *ctx, uint8_t *out,
int *out_len);
-/* Deprecated: EVP_DecodeBlock encodes |src_len| bytes from |src| and
- * writes the result to |dst|. It returns the number of bytes written
- * or -1 on error.
+
+/* Deprecated functions. */
+
+/* EVP_DecodeBlock encodes |src_len| bytes from |src| and writes the result to
+ * |dst|. It returns the number of bytes written or -1 on error.
*
* WARNING: EVP_DecodeBlock's return value does not take padding into
* account. It also strips leading whitespace and trailing
diff --git a/src/include/openssl/bio.h b/src/include/openssl/bio.h
index 8724657..04e3790 100644
--- a/src/include/openssl/bio.h
+++ b/src/include/openssl/bio.h
@@ -76,8 +76,6 @@ extern "C" {
/* Allocation and freeing. */
-DEFINE_STACK_OF(BIO);
-
/* BIO_new creates a new BIO with the given type and a reference count of one.
* It returns the fresh |BIO|, or NULL on error. */
OPENSSL_EXPORT BIO *BIO_new(const BIO_METHOD *type);
@@ -207,7 +205,7 @@ OPENSSL_EXPORT void BIO_clear_flags(BIO *bio, int flags);
* flags on |bio|. */
OPENSSL_EXPORT void BIO_set_retry_read(BIO *bio);
-/* BIO_set_retry_read sets the |BIO_FLAGS_WRITE| and |BIO_FLAGS_SHOULD_RETRY|
+/* BIO_set_retry_write sets the |BIO_FLAGS_WRITE| and |BIO_FLAGS_SHOULD_RETRY|
* flags on |bio|. */
OPENSSL_EXPORT void BIO_set_retry_write(BIO *bio);
@@ -656,7 +654,7 @@ OPENSSL_EXPORT int BIO_zero_copy_get_read_buf(BIO* bio,
* error stack. */
OPENSSL_EXPORT int BIO_zero_copy_get_read_buf_done(BIO* bio, size_t bytes_read);
-/* BIO_zero_copy_get_write_buf_done initiates a zero copy write operation.
+/* BIO_zero_copy_get_write_buf initiates a zero copy write operation.
* |out_write_buf| is set to to the internal write buffer, and |out_buf_offset|
* is set to the current write position of |out_write_buf|.
* The number of bytes available for write from |out_write_buf| +
@@ -667,7 +665,7 @@ OPENSSL_EXPORT int BIO_zero_copy_get_read_buf_done(BIO* bio, size_t bytes_read);
* stack.
*
* The zero copy write operation is completed by calling
- * |BIO_zero_copy_write_buf_done|. Neither |BIO_zero_copy_get_write_buf|
+ * |BIO_zero_copy_get_write_buf_done|. Neither |BIO_zero_copy_get_write_buf|
* nor any other I/O write operation may be called while a zero copy write
* operation is active. */
OPENSSL_EXPORT int BIO_zero_copy_get_write_buf(BIO* bio,
@@ -675,8 +673,8 @@ OPENSSL_EXPORT int BIO_zero_copy_get_write_buf(BIO* bio,
size_t* out_buf_offset,
size_t* out_available_bytes);
-/* BIO_zero_copy_write_buf_done must be called after writing to a BIO using
- * |BIO_zero_copy_get_write_buf_done| to finish the write operation. The
+/* BIO_zero_copy_get_write_buf_done must be called after writing to a BIO using
+ * |BIO_zero_copy_get_write_buf| to finish the write operation. The
* |bytes_written| argument gives the number of bytes written.
*
* It returns one on success. In case of error it returns zero and pushes to the
@@ -727,6 +725,18 @@ OPENSSL_EXPORT int BIO_zero_copy_get_write_buf_done(BIO* bio,
#define BIO_print_errors_fp ERR_print_errors_fp
+/* Deprecated functions. */
+
+/* Returns a filter |BIO| that base64-encodes data written into it, and decodes
+ * data read from it. |BIO_gets| is not supported. Call |BIO_flush| when done
+ * writing, to signal that no more data are to be encoded. The flag
+ * |BIO_FLAGS_BASE64_NO_NL| may be set to encode all the data on one line. */
+OPENSSL_EXPORT const BIO_METHOD *BIO_f_base64(void);
+
+/* ERR_print_errors is an alias for |BIO_print_errors|. */
+OPENSSL_EXPORT void ERR_print_errors(BIO *bio);
+
+
/* Private functions */
#define BIO_FLAGS_READ 0x01
@@ -870,25 +880,6 @@ struct bio_st {
} /* extern C */
#endif
-#define BIO_F_BIO_callback_ctrl 100
-#define BIO_F_BIO_ctrl 101
-#define BIO_F_BIO_new 102
-#define BIO_F_BIO_new_file 103
-#define BIO_F_BIO_new_mem_buf 104
-#define BIO_F_BIO_zero_copy_get_read_buf 105
-#define BIO_F_BIO_zero_copy_get_read_buf_done 106
-#define BIO_F_BIO_zero_copy_get_write_buf 107
-#define BIO_F_BIO_zero_copy_get_write_buf_done 108
-#define BIO_F_bio_io 109
-#define BIO_F_bio_make_pair 110
-#define BIO_F_bio_write 111
-#define BIO_F_buffer_ctrl 112
-#define BIO_F_conn_ctrl 113
-#define BIO_F_conn_state 114
-#define BIO_F_file_ctrl 115
-#define BIO_F_file_read 116
-#define BIO_F_mem_write 117
-#define BIO_F_BIO_printf 118
#define BIO_R_BAD_FOPEN_MODE 100
#define BIO_R_BROKEN_PIPE 101
#define BIO_R_CONNECT_ERROR 102
diff --git a/src/include/openssl/bn.h b/src/include/openssl/bn.h
index ec1c8ff..8de8cc4 100644
--- a/src/include/openssl/bn.h
+++ b/src/include/openssl/bn.h
@@ -182,7 +182,8 @@ OPENSSL_EXPORT void BN_clear_free(BIGNUM *bn);
* allocated BIGNUM on success or NULL otherwise. */
OPENSSL_EXPORT BIGNUM *BN_dup(const BIGNUM *src);
-/* BN_copy sets |dest| equal to |src| and returns |dest|. */
+/* BN_copy sets |dest| equal to |src| and returns |dest| or NULL on allocation
+ * failure. */
OPENSSL_EXPORT BIGNUM *BN_copy(BIGNUM *dest, const BIGNUM *src);
/* BN_clear sets |bn| to zero and erases the old data. */
@@ -297,6 +298,21 @@ OPENSSL_EXPORT int BN_print_fp(FILE *fp, const BIGNUM *a);
OPENSSL_EXPORT BN_ULONG BN_get_word(const BIGNUM *bn);
+/* ASN.1 functions. */
+
+/* BN_cbs2unsigned parses a non-negative DER INTEGER from |cbs| writes the
+ * result to |ret|. It returns one on success and zero on failure. */
+OPENSSL_EXPORT int BN_cbs2unsigned(CBS *cbs, BIGNUM *ret);
+
+/* BN_cbs2unsigned_buggy acts like |BN_cbs2unsigned| but tolerates some invalid
+ * encodings. Do not use this function. */
+OPENSSL_EXPORT int BN_cbs2unsigned_buggy(CBS *cbs, BIGNUM *ret);
+
+/* BN_bn2cbb marshals |bn| as a non-negative DER INTEGER and appends the result
+ * to |cbb|. It returns one on success and zero on failure. */
+OPENSSL_EXPORT int BN_bn2cbb(CBB *cbb, const BIGNUM *bn);
+
+
/* Internal functions.
*
* These functions are useful for code that is doing low-level manipulations of
@@ -310,7 +326,7 @@ OPENSSL_EXPORT void bn_correct_top(BIGNUM *bn);
/* bn_wexpand ensures that |bn| has at least |words| works of space without
* altering its value. It returns one on success or zero on allocation
* failure. */
-OPENSSL_EXPORT BIGNUM *bn_wexpand(BIGNUM *bn, unsigned words);
+OPENSSL_EXPORT BIGNUM *bn_wexpand(BIGNUM *bn, size_t words);
/* BIGNUM pools.
@@ -694,6 +710,14 @@ OPENSSL_EXPORT int BN_gcd(BIGNUM *r, const BIGNUM *a, const BIGNUM *b,
OPENSSL_EXPORT BIGNUM *BN_mod_inverse(BIGNUM *out, const BIGNUM *a,
const BIGNUM *n, BN_CTX *ctx);
+/* BN_mod_inverse_ex acts like |BN_mod_inverse| except that, when it returns
+ * zero, it will set |*out_no_inverse| to one if the failure was caused because
+ * |a| has no inverse mod |n|. Otherwise it will set |*out_no_inverse| to
+ * zero. */
+OPENSSL_EXPORT BIGNUM *BN_mod_inverse_ex(BIGNUM *out, int *out_no_inverse,
+ const BIGNUM *a, const BIGNUM *n,
+ BN_CTX *ctx);
+
/* BN_kronecker returns the Kronecker symbol of |a| and |b| (which is -1, 0 or
* 1), or -2 on error. */
OPENSSL_EXPORT int BN_kronecker(const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx);
@@ -782,6 +806,25 @@ OPENSSL_EXPORT int BN_mod_exp2_mont(BIGNUM *r, const BIGNUM *a1,
BN_CTX *ctx, BN_MONT_CTX *m_ctx);
+/* Deprecated functions */
+
+/* BN_bn2mpi serialises the value of |in| to |out|, using a format that consists
+ * of the number's length in bytes represented as a 4-byte big-endian number,
+ * and the number itself in big-endian format, where the most significant bit
+ * signals a negative number. (The representation of numbers with the MSB set is
+ * prefixed with null byte). |out| must have sufficient space available; to
+ * find the needed amount of space, call the function with |out| set to NULL. */
+OPENSSL_EXPORT size_t BN_bn2mpi(const BIGNUM *in, uint8_t *out);
+
+/* BN_bin2bn parses |len| bytes from |in| and returns the resulting value. The
+ * bytes at |in| are expected to be in the format emitted by |BN_bn2mpi|.
+ *
+ * If |out| is NULL then a fresh |BIGNUM| is allocated and returned, otherwise
+ * |out| is reused and returned. On error, NULL is returned and the error queue
+ * is updated. */
+OPENSSL_EXPORT BIGNUM *BN_mpi2bn(const uint8_t *in, size_t len, BIGNUM *out);
+
+
/* Private functions */
struct bignum_st {
@@ -827,33 +870,6 @@ OPENSSL_EXPORT BIGNUM *get_rfc3526_prime_1536(BIGNUM *bn);
} /* extern C */
#endif
-#define BN_F_BN_CTX_get 100
-#define BN_F_BN_CTX_new 101
-#define BN_F_BN_CTX_start 102
-#define BN_F_BN_bn2dec 103
-#define BN_F_BN_bn2hex 104
-#define BN_F_BN_div 105
-#define BN_F_BN_div_recp 106
-#define BN_F_BN_exp 107
-#define BN_F_BN_generate_dsa_nonce 108
-#define BN_F_BN_generate_prime_ex 109
-#define BN_F_BN_mod_exp2_mont 110
-#define BN_F_BN_mod_exp_mont 111
-#define BN_F_BN_mod_exp_mont_consttime 112
-#define BN_F_BN_mod_exp_mont_word 113
-#define BN_F_BN_mod_inverse 114
-#define BN_F_BN_mod_inverse_no_branch 115
-#define BN_F_BN_mod_lshift_quick 116
-#define BN_F_BN_mod_sqrt 117
-#define BN_F_BN_new 118
-#define BN_F_BN_rand 119
-#define BN_F_BN_rand_range 120
-#define BN_F_BN_sqrt 121
-#define BN_F_BN_usub 122
-#define BN_F_bn_wexpand 123
-#define BN_F_mod_exp_recp 124
-#define BN_F_BN_lshift 125
-#define BN_F_BN_rshift 126
#define BN_R_ARG2_LT_ARG3 100
#define BN_R_BAD_RECIPROCAL 101
#define BN_R_BIGNUM_TOO_LONG 102
@@ -871,5 +887,7 @@ OPENSSL_EXPORT BIGNUM *get_rfc3526_prime_1536(BIGNUM *bn);
#define BN_R_P_IS_NOT_PRIME 114
#define BN_R_TOO_MANY_ITERATIONS 115
#define BN_R_TOO_MANY_TEMPORARY_VARIABLES 116
+#define BN_R_BAD_ENCODING 117
+#define BN_R_ENCODE_ERROR 118
#endif /* OPENSSL_HEADER_BN_H */
diff --git a/src/include/openssl/buf.h b/src/include/openssl/buf.h
index 2b36ce4..76e3795 100644
--- a/src/include/openssl/buf.h
+++ b/src/include/openssl/buf.h
@@ -115,9 +115,4 @@ OPENSSL_EXPORT size_t BUF_strlcat(char *dst, const char *src, size_t size);
} /* extern C */
#endif
-#define BUF_F_BUF_MEM_new 100
-#define BUF_F_BUF_memdup 101
-#define BUF_F_BUF_strndup 102
-#define BUF_F_buf_mem_grow 103
-
#endif /* OPENSSL_HEADER_BUFFER_H */
diff --git a/src/include/openssl/bytestring.h b/src/include/openssl/bytestring.h
index 9963426..1b1a0a9 100644
--- a/src/include/openssl/bytestring.h
+++ b/src/include/openssl/bytestring.h
@@ -99,6 +99,10 @@ OPENSSL_EXPORT int CBS_get_u32(CBS *cbs, uint32_t *out);
* |cbs|. It returns one on success and zero on error. */
OPENSSL_EXPORT int CBS_get_bytes(CBS *cbs, CBS *out, size_t len);
+/* CBS_copy_bytes copies the next |len| bytes from |cbs| to |out| and advances
+ * |cbs|. It returns one on success and zero on error. */
+OPENSSL_EXPORT int CBS_copy_bytes(CBS *cbs, uint8_t *out, size_t len);
+
/* CBS_get_u8_length_prefixed sets |*out| to the contents of an 8-bit,
* length-prefixed value from |cbs| and advances |cbs| over it. It returns one
* on success and zero on error. */
@@ -121,10 +125,12 @@ OPENSSL_EXPORT int CBS_get_u24_length_prefixed(CBS *cbs, CBS *out);
#define CBS_ASN1_INTEGER 0x2
#define CBS_ASN1_BITSTRING 0x3
#define CBS_ASN1_OCTETSTRING 0x4
+#define CBS_ASN1_NULL 0x5
#define CBS_ASN1_OBJECT 0x6
#define CBS_ASN1_ENUMERATED 0xa
#define CBS_ASN1_SEQUENCE (0x10 | CBS_ASN1_CONSTRUCTED)
#define CBS_ASN1_SET (0x11 | CBS_ASN1_CONSTRUCTED)
+#define CBS_ASN1_GENERALIZEDTIME 0x18
#define CBS_ASN1_CONSTRUCTED 0x20
#define CBS_ASN1_CONTEXT_SPECIFIC 0x80
@@ -158,16 +164,24 @@ OPENSSL_EXPORT int CBS_get_any_asn1_element(CBS *cbs, CBS *out,
unsigned *out_tag,
size_t *out_header_len);
+/* CBS_get_any_ber_asn1_element acts the same as |CBS_get_any_asn1_element| but
+ * also allows indefinite-length elements to be returned. In that case,
+ * |*out_header_len| and |CBS_len(out)| will both be two as only the header is
+ * returned, otherwise it behaves the same as the previous function. */
+OPENSSL_EXPORT int CBS_get_any_ber_asn1_element(CBS *cbs, CBS *out,
+ unsigned *out_tag,
+ size_t *out_header_len);
+
/* CBS_get_asn1_uint64 gets an ASN.1 INTEGER from |cbs| using |CBS_get_asn1|
* and sets |*out| to its value. It returns one on success and zero on error,
* where error includes the integer being negative, or too large to represent
* in 64 bits. */
OPENSSL_EXPORT int CBS_get_asn1_uint64(CBS *cbs, uint64_t *out);
-/* CBS_get_optional_asn1 gets an optional explicitly-tagged element
- * from |cbs| tagged with |tag| and sets |*out| to its contents. If
- * present, it sets |*out_present| to one, otherwise zero. It returns
- * one on success, whether or not the element was present, and zero on
+/* CBS_get_optional_asn1 gets an optional explicitly-tagged element from |cbs|
+ * tagged with |tag| and sets |*out| to its contents. If present and if
+ * |out_present| is not NULL, it sets |*out_present| to one, otherwise zero. It
+ * returns one on success, whether or not the element was present, and zero on
* decode failure. */
OPENSSL_EXPORT int CBS_get_optional_asn1(CBS *cbs, CBS *out, int *out_present,
unsigned tag);
@@ -238,6 +252,12 @@ struct cbb_st {
char is_top_level;
};
+/* CBB_zero sets an uninitialised |cbb| to the zero state. It must be
+ * initialised with |CBB_init| or |CBB_init_fixed| before use, but it is safe to
+ * call |CBB_cleanup| without a successful |CBB_init|. This may be used for more
+ * uniform cleanup of a |CBB|. */
+OPENSSL_EXPORT void CBB_zero(CBB *cbb);
+
/* CBB_init initialises |cbb| with |initial_capacity|. Since a |CBB| grows as
* needed, the |initial_capacity| is just a hint. It returns one on success or
* zero on error. */
@@ -268,6 +288,14 @@ OPENSSL_EXPORT int CBB_finish(CBB *cbb, uint8_t **out_data, size_t *out_len);
* on error. */
OPENSSL_EXPORT int CBB_flush(CBB *cbb);
+/* CBB_len returns the number of bytes written to |cbb|'s top-level |CBB|. It
+ * may be compared before and after an operation to determine how many bytes
+ * were written.
+ *
+ * It is a fatal error to call this on a CBB with any active children. This does
+ * not flush |cbb|. */
+OPENSSL_EXPORT size_t CBB_len(const CBB *cbb);
+
/* CBB_add_u8_length_prefixed sets |*out_contents| to a new child of |cbb|. The
* data written to |*out_contents| will be prefixed in |cbb| with an 8-bit
* length. It returns one on success or zero on error. */
@@ -283,7 +311,7 @@ OPENSSL_EXPORT int CBB_add_u16_length_prefixed(CBB *cbb, CBB *out_contents);
* big-endian length. It returns one on success or zero on error. */
OPENSSL_EXPORT int CBB_add_u24_length_prefixed(CBB *cbb, CBB *out_contents);
-/* CBB_add_asn sets |*out_contents| to a |CBB| into which the contents of an
+/* CBB_add_asn1 sets |*out_contents| to a |CBB| into which the contents of an
* ASN.1 object can be written. The |tag| argument will be used as the tag for
* the object. Passing in |tag| number 31 will return in an error since only
* single octet identifiers are supported. It returns one on success or zero
@@ -304,7 +332,7 @@ OPENSSL_EXPORT int CBB_add_space(CBB *cbb, uint8_t **out_data, size_t len);
* success and zero otherwise. */
OPENSSL_EXPORT int CBB_add_u8(CBB *cbb, uint8_t value);
-/* CBB_add_u8 appends a 16-bit, big-endian number from |value| to |cbb|. It
+/* CBB_add_u16 appends a 16-bit, big-endian number from |value| to |cbb|. It
* returns one on success and zero otherwise. */
OPENSSL_EXPORT int CBB_add_u16(CBB *cbb, uint16_t value);
diff --git a/src/include/openssl/chacha.h b/src/include/openssl/chacha.h
index ce53d49..b7f5882 100644
--- a/src/include/openssl/chacha.h
+++ b/src/include/openssl/chacha.h
@@ -25,9 +25,9 @@ extern "C" {
/* CRYPTO_chacha_20 encrypts |in_len| bytes from |in| with the given key and
* nonce and writes the result to |out|, which may be equal to |in|. The
* initial block counter is specified by |counter|. */
-void CRYPTO_chacha_20(uint8_t *out, const uint8_t *in,
- size_t in_len, const uint8_t key[32],
- const uint8_t nonce[8], size_t counter);
+OPENSSL_EXPORT void CRYPTO_chacha_20(uint8_t *out, const uint8_t *in,
+ size_t in_len, const uint8_t key[32],
+ const uint8_t nonce[8], size_t counter);
#if defined(__cplusplus)
diff --git a/src/include/openssl/cipher.h b/src/include/openssl/cipher.h
index 7f5fe04..a4e79dd 100644
--- a/src/include/openssl/cipher.h
+++ b/src/include/openssl/cipher.h
@@ -75,6 +75,9 @@ extern "C" {
OPENSSL_EXPORT const EVP_CIPHER *EVP_rc4(void);
OPENSSL_EXPORT const EVP_CIPHER *EVP_des_cbc(void);
+OPENSSL_EXPORT const EVP_CIPHER *EVP_des_ecb(void);
+OPENSSL_EXPORT const EVP_CIPHER *EVP_des_ede(void);
+OPENSSL_EXPORT const EVP_CIPHER *EVP_des_ede_cbc(void);
OPENSSL_EXPORT const EVP_CIPHER *EVP_des_ede3_cbc(void);
OPENSSL_EXPORT const EVP_CIPHER *EVP_aes_128_ecb(void);
@@ -86,6 +89,7 @@ OPENSSL_EXPORT const EVP_CIPHER *EVP_aes_256_ecb(void);
OPENSSL_EXPORT const EVP_CIPHER *EVP_aes_256_cbc(void);
OPENSSL_EXPORT const EVP_CIPHER *EVP_aes_256_ctr(void);
OPENSSL_EXPORT const EVP_CIPHER *EVP_aes_256_ofb(void);
+OPENSSL_EXPORT const EVP_CIPHER *EVP_aes_256_xts(void);
/* Deprecated AES-GCM implementations that set |EVP_CIPH_FLAG_CUSTOM_CIPHER|.
* Use |EVP_aead_aes_128_gcm| and |EVP_aead_aes_256_gcm| instead. */
@@ -102,6 +106,9 @@ OPENSSL_EXPORT const EVP_CIPHER *EVP_aes_192_gcm(void);
* ciphertext. */
OPENSSL_EXPORT const EVP_CIPHER *EVP_enc_null(void);
+/* EVP_rc2_cbc returns a cipher that implements 128-bit RC2 in CBC mode. */
+OPENSSL_EXPORT const EVP_CIPHER *EVP_rc2_cbc(void);
+
/* EVP_rc2_40_cbc returns a cipher that implements 40-bit RC2 in CBC mode. This
* is obviously very, very weak and is included only in order to read PKCS#12
* files, which often encrypt the certificate chain using this cipher. It is
@@ -338,6 +345,7 @@ OPENSSL_EXPORT int EVP_BytesToKey(const EVP_CIPHER *type, const EVP_MD *md,
#define EVP_CIPH_OFB_MODE 0x4
#define EVP_CIPH_CTR_MODE 0x5
#define EVP_CIPH_GCM_MODE 0x6
+#define EVP_CIPH_XTS_MODE 0x7
/* Cipher flags (for |EVP_CIPHER_flags|). */
@@ -533,41 +541,6 @@ struct evp_cipher_st {
} /* extern C */
#endif
-#define CIPHER_F_EVP_AEAD_CTX_init 100
-#define CIPHER_F_EVP_AEAD_CTX_open 101
-#define CIPHER_F_EVP_AEAD_CTX_seal 102
-#define CIPHER_F_EVP_CIPHER_CTX_copy 103
-#define CIPHER_F_EVP_CIPHER_CTX_ctrl 104
-#define CIPHER_F_EVP_CIPHER_CTX_set_key_length 105
-#define CIPHER_F_EVP_CipherInit_ex 106
-#define CIPHER_F_EVP_DecryptFinal_ex 107
-#define CIPHER_F_EVP_EncryptFinal_ex 108
-#define CIPHER_F_aead_aes_gcm_init 109
-#define CIPHER_F_aead_aes_gcm_open 110
-#define CIPHER_F_aead_aes_gcm_seal 111
-#define CIPHER_F_aead_aes_key_wrap_init 112
-#define CIPHER_F_aead_aes_key_wrap_open 113
-#define CIPHER_F_aead_aes_key_wrap_seal 114
-#define CIPHER_F_aead_chacha20_poly1305_init 115
-#define CIPHER_F_aead_chacha20_poly1305_open 116
-#define CIPHER_F_aead_chacha20_poly1305_seal 117
-#define CIPHER_F_aead_rc4_md5_tls_init 118
-#define CIPHER_F_aead_rc4_md5_tls_open 119
-#define CIPHER_F_aead_rc4_md5_tls_seal 120
-#define CIPHER_F_aead_ssl3_ensure_cipher_init 121
-#define CIPHER_F_aead_ssl3_init 122
-#define CIPHER_F_aead_ssl3_open 123
-#define CIPHER_F_aead_ssl3_seal 124
-#define CIPHER_F_aead_tls_ensure_cipher_init 125
-#define CIPHER_F_aead_tls_init 126
-#define CIPHER_F_aead_tls_open 127
-#define CIPHER_F_aead_tls_seal 128
-#define CIPHER_F_aes_init_key 129
-#define CIPHER_F_aesni_init_key 130
-#define CIPHER_F_EVP_AEAD_CTX_init_with_direction 131
-#define CIPHER_F_aead_aes_ctr_hmac_sha256_init 132
-#define CIPHER_F_aead_aes_ctr_hmac_sha256_open 133
-#define CIPHER_F_aead_aes_ctr_hmac_sha256_seal 134
#define CIPHER_R_AES_KEY_SETUP_FAILED 100
#define CIPHER_R_BAD_DECRYPT 101
#define CIPHER_R_BAD_KEY_LENGTH 102
diff --git a/src/include/openssl/conf.h b/src/include/openssl/conf.h
index 84fc94f..a2741a8 100644
--- a/src/include/openssl/conf.h
+++ b/src/include/openssl/conf.h
@@ -135,10 +135,6 @@ int CONF_parse_list(const char *list, char sep, int remove_whitespace,
} /* extern C */
#endif
-#define CONF_F_CONF_parse_list 100
-#define CONF_F_NCONF_load 101
-#define CONF_F_def_load_bio 102
-#define CONF_F_str_copy 103
#define CONF_R_LIST_CANNOT_BE_NULL 100
#define CONF_R_MISSING_CLOSE_SQUARE_BRACKET 101
#define CONF_R_MISSING_EQUAL_SIGN 102
diff --git a/src/include/openssl/cpu.h b/src/include/openssl/cpu.h
index 83ec473..981d246 100644
--- a/src/include/openssl/cpu.h
+++ b/src/include/openssl/cpu.h
@@ -77,11 +77,16 @@ extern "C" {
*
* Index 0:
* EDX for CPUID where EAX = 1
+ * Bit 20 is always zero
+ * Bit 28 is adjusted to reflect whether the data cache is shared between
+ * multiple logical cores
* Bit 30 is used to indicate an Intel CPU
* Index 1:
* ECX for CPUID where EAX = 1
+ * Bit 11 is used to indicate AMD XOP support, not SDBG
* Index 2:
* EBX for CPUID where EAX = 7
+ * Index 3 is set to zero.
*
* Note: the CPUID bits are pre-adjusted for the OSXSAVE bit and the YMM and XMM
* bits in XCR0, so it is not necessary to check those. */
diff --git a/src/include/openssl/crypto.h b/src/include/openssl/crypto.h
index 3af1547..5207a12 100644
--- a/src/include/openssl/crypto.h
+++ b/src/include/openssl/crypto.h
@@ -21,6 +21,10 @@
* mem.h. */
#include <openssl/mem.h>
+/* Upstream OpenSSL defines |CRYPTO_LOCK|, etc., in crypto.h rather than
+ * thread.h. */
+#include <openssl/thread.h>
+
#if defined(__cplusplus)
extern "C" {
@@ -55,9 +59,4 @@ OPENSSL_EXPORT unsigned long SSLeay(void);
} /* extern C */
#endif
-#define CRYPTO_F_CRYPTO_get_ex_new_index 100
-#define CRYPTO_F_CRYPTO_set_ex_data 101
-#define CRYPTO_F_get_class 102
-#define CRYPTO_F_get_func_pointers 103
-
#endif /* OPENSSL_HEADER_CRYPTO_H */
diff --git a/src/include/openssl/des.h b/src/include/openssl/des.h
index 6e1b0cf..f9db62d 100644
--- a/src/include/openssl/des.h
+++ b/src/include/openssl/des.h
@@ -72,12 +72,7 @@ typedef struct DES_cblock_st {
} DES_cblock;
typedef struct DES_ks {
- union {
- DES_cblock cblock;
- /* make sure things are correct size on machines with
- * 8 byte longs */
- uint32_t deslong[2];
- } ks[16];
+ uint32_t subkeys[16][2];
} DES_key_schedule;
@@ -142,6 +137,26 @@ OPENSSL_EXPORT void DES_ede2_cbc_encrypt(const uint8_t *in, uint8_t *out,
DES_cblock *ivec, int enc);
+/* Deprecated functions. */
+
+/* DES_set_key_unchecked calls |DES_set_key|. */
+OPENSSL_EXPORT void DES_set_key_unchecked(const DES_cblock *key,
+ DES_key_schedule *schedule);
+
+OPENSSL_EXPORT void DES_ede3_cfb64_encrypt(const uint8_t *in, uint8_t *out,
+ long length, DES_key_schedule *ks1,
+ DES_key_schedule *ks2,
+ DES_key_schedule *ks3,
+ DES_cblock *ivec, int *num, int enc);
+
+OPENSSL_EXPORT void DES_ede3_cfb_encrypt(const uint8_t *in, uint8_t *out,
+ int numbits, long length,
+ DES_key_schedule *ks1,
+ DES_key_schedule *ks2,
+ DES_key_schedule *ks3,
+ DES_cblock *ivec, int enc);
+
+
#if defined(__cplusplus)
} /* extern C */
#endif
diff --git a/src/include/openssl/dh.h b/src/include/openssl/dh.h
index 17574d5..75df632 100644
--- a/src/include/openssl/dh.h
+++ b/src/include/openssl/dh.h
@@ -235,7 +235,7 @@ struct dh_st {
BIGNUM *p;
BIGNUM *g;
- BIGNUM *pub_key; /* g^x */
+ BIGNUM *pub_key; /* g^x mod p */
BIGNUM *priv_key; /* x */
/* priv_length contains the length, in bits, of the private value. If zero,
@@ -262,10 +262,6 @@ struct dh_st {
} /* extern C */
#endif
-#define DH_F_DH_new_method 100
-#define DH_F_compute_key 101
-#define DH_F_generate_key 102
-#define DH_F_generate_parameters 103
#define DH_R_BAD_GENERATOR 100
#define DH_R_INVALID_PUBKEY 101
#define DH_R_MODULUS_TOO_LARGE 102
diff --git a/src/include/openssl/digest.h b/src/include/openssl/digest.h
index 2ea4ec4..66be4d0 100644
--- a/src/include/openssl/digest.h
+++ b/src/include/openssl/digest.h
@@ -234,15 +234,9 @@ struct evp_md_pctx_ops;
struct env_md_ctx_st {
/* digest is the underlying digest function, or NULL if not set. */
const EVP_MD *digest;
- /* flags is the OR of a number of |EVP_MD_CTX_FLAG_*| values. */
- uint32_t flags;
/* md_data points to a block of memory that contains the hash-specific
* context. */
void *md_data;
- /* update is usually copied from |digest->update| but can differ in some
- * cases, i.e. HMAC.
- * TODO(davidben): Remove this hook once |EVP_PKEY_HMAC| is gone. */
- void (*update)(EVP_MD_CTX *ctx, const void *data, size_t count);
/* pctx is an opaque (at this layer) pointer to additional context that
* EVP_PKEY functions may store in this object. */
@@ -258,8 +252,6 @@ struct env_md_ctx_st {
} /* extern C */
#endif
-#define DIGEST_F_EVP_DigestInit_ex 100
-#define DIGEST_F_EVP_MD_CTX_copy_ex 101
#define DIGEST_R_INPUT_NOT_INITIALIZED 100
#endif /* OPENSSL_HEADER_DIGEST_H */
diff --git a/src/include/openssl/dsa.h b/src/include/openssl/dsa.h
index 7274e4c..b1e7309 100644
--- a/src/include/openssl/dsa.h
+++ b/src/include/openssl/dsa.h
@@ -366,11 +366,6 @@ struct dsa_st {
} /* extern C */
#endif
-#define DSA_F_DSA_new_method 100
-#define DSA_F_dsa_sig_cb 101
-#define DSA_F_sign 102
-#define DSA_F_sign_setup 103
-#define DSA_F_verify 104
#define DSA_R_BAD_Q_VALUE 100
#define DSA_R_MISSING_PARAMETERS 101
#define DSA_R_MODULUS_TOO_LARGE 102
diff --git a/src/include/openssl/ec.h b/src/include/openssl/ec.h
index 25b4551..f664211 100644
--- a/src/include/openssl/ec.h
+++ b/src/include/openssl/ec.h
@@ -220,7 +220,7 @@ OPENSSL_EXPORT int EC_POINT_get_affine_coordinates_GFp(const EC_GROUP *group,
BIGNUM *x, BIGNUM *y,
BN_CTX *ctx);
-/* EC_POINT_set_affine_coordinates sets the value of |p| to be (|x|, |y|). The
+/* EC_POINT_set_affine_coordinates_GFp sets the value of |p| to be (|x|, |y|). The
* |ctx| argument may be used if not NULL. */
OPENSSL_EXPORT int EC_POINT_set_affine_coordinates_GFp(const EC_GROUP *group,
EC_POINT *point,
@@ -265,7 +265,7 @@ OPENSSL_EXPORT int EC_POINT_add(const EC_GROUP *group, EC_POINT *r,
OPENSSL_EXPORT int EC_POINT_dbl(const EC_GROUP *group, EC_POINT *r,
const EC_POINT *a, BN_CTX *ctx);
-/* EC_POINT_dbl sets |a| equal to minus |a|. It returns one on success and zero
+/* EC_POINT_invert sets |a| equal to minus |a|. It returns one on success and zero
* otherwise. If |ctx| is not NULL, it may be used. */
OPENSSL_EXPORT int EC_POINT_invert(const EC_GROUP *group, EC_POINT *a,
BN_CTX *ctx);
@@ -334,73 +334,6 @@ OPENSSL_EXPORT void EC_GROUP_set_point_conversion_form(
} /* extern C */
#endif
-#define EC_F_EC_GROUP_copy 100
-#define EC_F_EC_GROUP_get_curve_GFp 101
-#define EC_F_EC_GROUP_get_degree 102
-#define EC_F_EC_GROUP_new_by_curve_name 103
-#define EC_F_EC_KEY_check_key 104
-#define EC_F_EC_KEY_copy 105
-#define EC_F_EC_KEY_generate_key 106
-#define EC_F_EC_KEY_new_method 107
-#define EC_F_EC_KEY_set_public_key_affine_coordinates 108
-#define EC_F_EC_POINT_add 109
-#define EC_F_EC_POINT_cmp 110
-#define EC_F_EC_POINT_copy 111
-#define EC_F_EC_POINT_dbl 112
-#define EC_F_EC_POINT_dup 113
-#define EC_F_EC_POINT_get_affine_coordinates_GFp 114
-#define EC_F_EC_POINT_invert 115
-#define EC_F_EC_POINT_is_at_infinity 116
-#define EC_F_EC_POINT_is_on_curve 117
-#define EC_F_EC_POINT_make_affine 118
-#define EC_F_EC_POINT_new 119
-#define EC_F_EC_POINT_oct2point 120
-#define EC_F_EC_POINT_point2oct 121
-#define EC_F_EC_POINT_set_affine_coordinates_GFp 122
-#define EC_F_EC_POINT_set_compressed_coordinates_GFp 123
-#define EC_F_EC_POINT_set_to_infinity 124
-#define EC_F_EC_POINTs_make_affine 125
-#define EC_F_compute_wNAF 126
-#define EC_F_d2i_ECPKParameters 127
-#define EC_F_d2i_ECParameters 128
-#define EC_F_d2i_ECPrivateKey 129
-#define EC_F_ec_GFp_mont_field_decode 130
-#define EC_F_ec_GFp_mont_field_encode 131
-#define EC_F_ec_GFp_mont_field_mul 132
-#define EC_F_ec_GFp_mont_field_set_to_one 133
-#define EC_F_ec_GFp_mont_field_sqr 134
-#define EC_F_ec_GFp_mont_group_set_curve 135
-#define EC_F_ec_GFp_simple_group_check_discriminant 136
-#define EC_F_ec_GFp_simple_group_set_curve 137
-#define EC_F_ec_GFp_simple_make_affine 138
-#define EC_F_ec_GFp_simple_oct2point 139
-#define EC_F_ec_GFp_simple_point2oct 140
-#define EC_F_ec_GFp_simple_point_get_affine_coordinates 141
-#define EC_F_ec_GFp_simple_point_set_affine_coordinates 142
-#define EC_F_ec_GFp_simple_points_make_affine 143
-#define EC_F_ec_GFp_simple_set_compressed_coordinates 144
-#define EC_F_ec_asn1_group2pkparameters 145
-#define EC_F_ec_asn1_pkparameters2group 146
-#define EC_F_ec_group_new 147
-#define EC_F_ec_group_new_curve_GFp 148
-#define EC_F_ec_group_new_from_data 149
-#define EC_F_ec_point_set_Jprojective_coordinates_GFp 150
-#define EC_F_ec_pre_comp_new 151
-#define EC_F_ec_wNAF_mul 152
-#define EC_F_ec_wNAF_precompute_mult 153
-#define EC_F_i2d_ECPKParameters 154
-#define EC_F_i2d_ECParameters 155
-#define EC_F_i2d_ECPrivateKey 156
-#define EC_F_i2o_ECPublicKey 157
-#define EC_F_o2i_ECPublicKey 158
-#define EC_F_BN_to_felem 159
-#define EC_F_ec_GFp_nistp256_group_set_curve 160
-#define EC_F_ec_GFp_nistp256_point_get_affine_coordinates 161
-#define EC_F_ec_GFp_nistp256_points_mul 162
-#define EC_F_ec_group_copy 163
-#define EC_F_nistp256_pre_comp_new 164
-#define EC_F_EC_KEY_new_by_curve_name 165
-#define EC_F_EC_GROUP_new_curve_GFp 166
#define EC_R_BUFFER_TOO_SMALL 100
#define EC_R_COORDINATES_OUT_OF_RANGE 101
#define EC_R_D2I_ECPKPARAMETERS_FAILURE 102
diff --git a/src/include/openssl/ec_key.h b/src/include/openssl/ec_key.h
index ee64030..1cd4e6e 100644
--- a/src/include/openssl/ec_key.h
+++ b/src/include/openssl/ec_key.h
@@ -192,7 +192,7 @@ OPENSSL_EXPORT int EC_KEY_generate_key(EC_KEY *key);
OPENSSL_EXPORT EC_KEY *d2i_ECPrivateKey(EC_KEY **out_key, const uint8_t **inp,
long len);
-/* i2d_ECParameters marshals an EC private key from |key| to an ASN.1, DER
+/* i2d_ECPrivateKey marshals an EC private key from |key| to an ASN.1, DER
* structure. If |outp| is not NULL then the result is written to |*outp| and
* |*outp| is advanced just past the output. It returns the number of bytes in
* the result, whether written or not, or a negative value on error. */
@@ -215,8 +215,8 @@ OPENSSL_EXPORT int i2d_ECParameters(const EC_KEY *key, uint8_t **outp);
/* o2i_ECPublicKey parses an EC point from |len| bytes at |*inp| into
* |*out_key|. Note that this differs from the d2i format in that |*out_key|
- * must be non-NULL. On successful exit, |*inp| is advanced past the DER
- * structure. It returns |*out_key| or NULL on error. */
+ * must be non-NULL with a group set. On successful exit, |*inp| is advanced by
+ * |len| bytes. It returns |*out_key| or NULL on error. */
OPENSSL_EXPORT EC_KEY *o2i_ECPublicKey(EC_KEY **out_key, const uint8_t **inp,
long len);
diff --git a/src/include/openssl/ecdh.h b/src/include/openssl/ecdh.h
index 27a8578..878cbeb 100644
--- a/src/include/openssl/ecdh.h
+++ b/src/include/openssl/ecdh.h
@@ -95,7 +95,6 @@ OPENSSL_EXPORT int ECDH_compute_key(void *out, size_t outlen,
} /* extern C */
#endif
-#define ECDH_F_ECDH_compute_key 100
#define ECDH_R_KDF_FAILED 100
#define ECDH_R_NO_PRIVATE_VALUE 101
#define ECDH_R_POINT_ARITHMETIC_FAILURE 102
diff --git a/src/include/openssl/ecdsa.h b/src/include/openssl/ecdsa.h
index e045463..84702c3 100644
--- a/src/include/openssl/ecdsa.h
+++ b/src/include/openssl/ecdsa.h
@@ -148,6 +148,34 @@ OPENSSL_EXPORT int ECDSA_sign_ex(int type, const uint8_t *digest,
/* ASN.1 functions. */
+/* ECDSA_SIG_parse parses a DER-encoded ECDSA-Sig-Value structure from |cbs| and
+ * advances |cbs|. It returns a newly-allocated |ECDSA_SIG| or NULL on error. */
+OPENSSL_EXPORT ECDSA_SIG *ECDSA_SIG_parse(CBS *cbs);
+
+/* ECDSA_SIG_from_bytes parses |in| as a DER-encoded ECDSA-Sig-Value structure.
+ * It returns a newly-allocated |ECDSA_SIG| structure or NULL on error. */
+OPENSSL_EXPORT ECDSA_SIG *ECDSA_SIG_from_bytes(const uint8_t *in,
+ size_t in_len);
+
+/* ECDSA_SIG_marshal marshals |sig| as a DER-encoded ECDSA-Sig-Value and appends
+ * the result to |cbb|. It returns one on success and zero on error. */
+OPENSSL_EXPORT int ECDSA_SIG_marshal(CBB *cbb, const ECDSA_SIG *sig);
+
+/* ECDSA_SIG_to_asn1 marshals |sig| as a DER-encoded ECDSA-Sig-Value and, on
+ * success, sets |*out_bytes| to a newly allocated buffer containing the result
+ * and returns one. Otherwise, it returns zero. The result should be freed with
+ * |OPENSSL_free|. */
+OPENSSL_EXPORT int ECDSA_SIG_to_bytes(uint8_t **out_bytes, size_t *out_len,
+ const ECDSA_SIG *sig);
+
+/* ECDSA_SIG_max_len returns the maximum length of a DER-encoded ECDSA-Sig-Value
+ * structure for a group whose order is represented in |order_len| bytes, or
+ * zero on overflow. */
+OPENSSL_EXPORT size_t ECDSA_SIG_max_len(size_t order_len);
+
+
+/* Deprecated functions. */
+
/* d2i_ECDSA_SIG parses an ASN.1, DER-encoded, signature from |len| bytes at
* |*inp|. If |out| is not NULL then, on exit, a pointer to the result is in
* |*out|. If |*out| is already non-NULL on entry then the result is written
@@ -168,15 +196,11 @@ OPENSSL_EXPORT int i2d_ECDSA_SIG(const ECDSA_SIG *sig, uint8_t **outp);
} /* extern C */
#endif
-#define ECDSA_F_ECDSA_do_sign_ex 100
-#define ECDSA_F_ECDSA_do_verify 101
-#define ECDSA_F_ECDSA_sign_ex 102
-#define ECDSA_F_digest_to_bn 103
-#define ECDSA_F_ecdsa_sign_setup 104
#define ECDSA_R_BAD_SIGNATURE 100
#define ECDSA_R_MISSING_PARAMETERS 101
#define ECDSA_R_NEED_NEW_SETUP_VALUES 102
#define ECDSA_R_NOT_IMPLEMENTED 103
#define ECDSA_R_RANDOM_NUMBER_GENERATION_FAILED 104
+#define ECDSA_R_ENCODE_ERROR 105
#endif /* OPENSSL_HEADER_ECDSA_H */
diff --git a/src/include/openssl/err.h b/src/include/openssl/err.h
index 30dc4af..c61e1ef 100644
--- a/src/include/openssl/err.h
+++ b/src/include/openssl/err.h
@@ -126,12 +126,11 @@ extern "C" {
*
* Each error contains:
* 1) The library (i.e. ec, pem, rsa) which created it.
- * 2) A function identifier and reason code.
- * 3) The file and line number of the call that added the error.
- * 4) A pointer to some error specific data, which may be NULL.
+ * 2) The function, file, and line number of the call that added the error.
+ * 3) A pointer to some error specific data, which may be NULL.
*
- * The library identifier, function identifier and reason code are packed in a
- * uint32_t and there exist various functions for unpacking it.
+ * The library identifier and reason code are packed in a uint32_t and there
+ * exist various functions for unpacking it.
*
* The typical behaviour is that an error will occur deep in a call queue and
* that code will push an error onto the error queue. As the error queue
@@ -184,6 +183,10 @@ OPENSSL_EXPORT uint32_t ERR_peek_error_line(const char **file, int *line);
OPENSSL_EXPORT uint32_t ERR_peek_error_line_data(const char **file, int *line,
const char **data, int *flags);
+/* ERR_peek_function returns the name of the function which added the least
+ * recent error or NULL if the queue is empty. */
+OPENSSL_EXPORT const char *ERR_peek_function(void);
+
/* The "peek last" functions act like the "peek" functions, above, except that
* they return the most recent error. */
OPENSSL_EXPORT uint32_t ERR_peek_last_error(void);
@@ -202,10 +205,10 @@ OPENSSL_EXPORT uint32_t ERR_peek_last_error_line_data(const char **file,
*
* The string will have the following format:
*
- * error:[error code]:[library name]:[function name]:[reason string]
+ * error:[error code]:[library name]:OPENSSL_internal:[reason string]
*
- * error code is an 8 digit hexadecimal number; library name, function name
- * and reason string are ASCII text.
+ * error code is an 8 digit hexadecimal number; library name and reason string
+ * are ASCII text.
*
* TODO(fork): remove in favour of |ERR_error_string_n|. */
OPENSSL_EXPORT char *ERR_error_string(uint32_t packed_error, char *buf);
@@ -222,10 +225,6 @@ OPENSSL_EXPORT void ERR_error_string_n(uint32_t packed_error, char *buf,
* generated |packed_error|. */
OPENSSL_EXPORT const char *ERR_lib_error_string(uint32_t packed_error);
-/* ERR_func_error_string returns a string representation of the function that
- * generated |packed_error|. */
-OPENSSL_EXPORT const char *ERR_func_error_string(uint32_t packed_error);
-
/* ERR_reason_error_string returns a string representation of the reason for
* |packed_error|. */
OPENSSL_EXPORT const char *ERR_reason_error_string(uint32_t packed_error);
@@ -258,11 +257,11 @@ typedef int (*ERR_print_errors_callback_t)(const char *str, size_t len,
OPENSSL_EXPORT void ERR_print_errors_cb(ERR_print_errors_callback_t callback,
void *ctx);
-
/* ERR_print_errors_fp prints the current contents of the error stack to |file|
* using human readable strings where possible. */
OPENSSL_EXPORT void ERR_print_errors_fp(FILE *file);
+
/* Clearing errors. */
/* ERR_clear_error clears the error queue for the current thread. */
@@ -287,30 +286,41 @@ OPENSSL_EXPORT int ERR_get_next_error_library(void);
/* Deprecated functions. */
-/* |ERR_remove_state| calls |ERR_clear_error|. */
+/* ERR_remove_state calls |ERR_clear_error|. */
OPENSSL_EXPORT void ERR_remove_state(unsigned long pid);
+/* ERR_func_error_string returns the string "OPENSSL_internal". */
+OPENSSL_EXPORT const char *ERR_func_error_string(uint32_t packed_error);
+
/* Private functions. */
/* ERR_clear_system_error clears the system's error value (i.e. errno). */
OPENSSL_EXPORT void ERR_clear_system_error(void);
+#if defined(OPENSSL_WINDOWS)
+/* TODO(davidben): Use |__func__| directly once the minimum MSVC version
+ * supports it. */
+#define OPENSSL_CURRENT_FUNCTION __FUNCTION__
+#else
+#define OPENSSL_CURRENT_FUNCTION __func__
+#endif
+
/* OPENSSL_PUT_ERROR is used by OpenSSL code to add an error to the error
* queue. */
-#define OPENSSL_PUT_ERROR(library, func, reason) \
- ERR_put_error(ERR_LIB_##library, library##_F_##func, reason, __FILE__, \
+#define OPENSSL_PUT_ERROR(library, reason) \
+ ERR_put_error(ERR_LIB_##library, reason, OPENSSL_CURRENT_FUNCTION, __FILE__, \
__LINE__)
/* OPENSSL_PUT_SYSTEM_ERROR is used by OpenSSL code to add an error from the
* operating system to the error queue. */
/* TODO(fork): include errno. */
#define OPENSSL_PUT_SYSTEM_ERROR(func) \
- ERR_put_error(ERR_LIB_SYS, SYS_F_##func, 0, __FILE__, __LINE__);
+ ERR_put_error(ERR_LIB_SYS, 0, #func, __FILE__, __LINE__);
/* ERR_put_error adds an error to the error queue, dropping the least recent
* error if neccessary for space reasons. */
-OPENSSL_EXPORT void ERR_put_error(int library, int func, int reason,
+OPENSSL_EXPORT void ERR_put_error(int library, int reason, const char *function,
const char *file, unsigned line);
/* ERR_add_error_data takes a variable number (|count|) of const char*
@@ -333,6 +343,8 @@ OPENSSL_EXPORT int ERR_set_mark(void);
OPENSSL_EXPORT int ERR_pop_to_mark(void);
struct err_error_st {
+ /* function contains the name of the function where the error occured. */
+ const char *function;
/* file contains the filename where the error occured. */
const char *file;
/* data contains optional data. It must be freed with |OPENSSL_free| if
@@ -418,8 +430,8 @@ enum {
ERR_LIB_HMAC,
ERR_LIB_DIGEST,
ERR_LIB_CIPHER,
- ERR_LIB_USER,
ERR_LIB_HKDF,
+ ERR_LIB_USER,
ERR_NUM_LIBS
};
@@ -469,22 +481,11 @@ enum {
#define ERR_R_INTERNAL_ERROR (4 | ERR_R_FATAL)
#define ERR_R_OVERFLOW (5 | ERR_R_FATAL)
-/* System error functions */
-#define SYS_F_fopen 100
-#define SYS_F_fclose 101
-#define SYS_F_fread 102
-#define SYS_F_fwrite 103
-#define SYS_F_socket 104
-#define SYS_F_setsockopt 105
-#define SYS_F_connect 106
-#define SYS_F_getaddrinfo 107
-
-#define ERR_PACK(lib, func, reason) \
- (((((uint32_t)lib) & 0xff) << 24) | ((((uint32_t)func) & 0xfff) << 12) | \
- ((((uint32_t)reason) & 0xfff)))
+#define ERR_PACK(lib, reason) \
+ (((((uint32_t)lib) & 0xff) << 24) | ((((uint32_t)reason) & 0xfff)))
#define ERR_GET_LIB(packed_error) ((int)(((packed_error) >> 24) & 0xff))
-#define ERR_GET_FUNC(packed_error) ((int)(((packed_error) >> 12) & 0xfff))
+#define ERR_GET_FUNC(packed_error) 0
#define ERR_GET_REASON(packed_error) ((int)((packed_error) & 0xfff))
/* OPENSSL_DECLARE_ERROR_REASON is used by util/make_errors.h (which generates
@@ -494,13 +495,6 @@ enum {
* ${lib}_R_${reason}. */
#define OPENSSL_DECLARE_ERROR_REASON(lib, reason)
-/* OPENSSL_DECLARE_ERROR_FUNCTION is used by util/make_errors.h (which
- * generates the error * defines to recognise that an additional function value
- * is needed. This is * needed when the function value is used outside of an
- * |OPENSSL_PUT_ERROR| * macro. The resulting define will be
- * ${lib}_F_${reason}. */
-#define OPENSSL_DECLARE_ERROR_FUNCTION(lib, function_name)
-
#if defined(__cplusplus)
} /* extern C */
diff --git a/src/include/openssl/evp.h b/src/include/openssl/evp.h
index 490a951..99b147e 100644
--- a/src/include/openssl/evp.h
+++ b/src/include/openssl/evp.h
@@ -66,6 +66,7 @@
*
* TODO(fork): clean up callers so that they include what they use. */
#include <openssl/aead.h>
+#include <openssl/base64.h>
#include <openssl/cipher.h>
#include <openssl/digest.h>
#include <openssl/obj.h>
@@ -136,14 +137,6 @@ OPENSSL_EXPORT int EVP_PKEY_id(const EVP_PKEY *pkey);
* |EVP_PKEY_RSA2| will be turned into |EVP_PKEY_RSA|. */
OPENSSL_EXPORT int EVP_PKEY_type(int nid);
-/* Deprecated: EVP_PKEY_new_mac_key allocates a fresh |EVP_PKEY| of the given
- * type (e.g. |EVP_PKEY_HMAC|), sets |mac_key| as the MAC key and "generates" a
- * new key, suitable for signing. It returns the fresh |EVP_PKEY|, or NULL on
- * error. Use |HMAC_CTX| directly instead. */
-OPENSSL_EXPORT EVP_PKEY *EVP_PKEY_new_mac_key(int type, ENGINE *engine,
- const uint8_t *mac_key,
- size_t mac_key_len);
-
/* Getting and setting concrete public key types.
*
@@ -177,9 +170,6 @@ OPENSSL_EXPORT struct dh_st *EVP_PKEY_get1_DH(EVP_PKEY *pkey);
#define EVP_PKEY_DHX NID_dhpublicnumber
#define EVP_PKEY_EC NID_X9_62_id_ecPublicKey
-/* Deprecated: Use |HMAC_CTX| directly instead. */
-#define EVP_PKEY_HMAC NID_hmac
-
/* EVP_PKEY_assign sets the underlying key of |pkey| to |key|, which must be of
* the given type. The |type| argument should be one of the |EVP_PKEY_*|
* values. */
@@ -220,10 +210,13 @@ OPENSSL_EXPORT EVP_PKEY *d2i_AutoPrivateKey(EVP_PKEY **out, const uint8_t **inp,
* the result, whether written or not, or a negative value on error. */
OPENSSL_EXPORT int i2d_PrivateKey(const EVP_PKEY *key, uint8_t **outp);
-/* i2d_PublicKey marshals a public key from |key| to an ASN.1, DER
- * structure. If |outp| is not NULL then the result is written to |*outp| and
+/* i2d_PublicKey marshals a public key from |key| to a type-specific format.
+ * If |outp| is not NULL then the result is written to |*outp| and
* |*outp| is advanced just past the output. It returns the number of bytes in
- * the result, whether written or not, or a negative value on error. */
+ * the result, whether written or not, or a negative value on error.
+ *
+ * RSA keys are serialized as a DER-encoded RSAPublicKey (RFC 3447) structure.
+ * EC keys are serialized as an EC point per SEC 1. */
OPENSSL_EXPORT int i2d_PublicKey(EVP_PKEY *key, uint8_t **outp);
@@ -377,12 +370,12 @@ OPENSSL_EXPORT int EVP_VerifyFinal(EVP_MD_CTX *ctx, const uint8_t *sig,
OPENSSL_EXPORT int EVP_PKEY_print_public(BIO *out, const EVP_PKEY *pkey,
int indent, ASN1_PCTX *pctx);
-/* EVP_PKEY_print_public prints a textual representation of the private key in
+/* EVP_PKEY_print_private prints a textual representation of the private key in
* |pkey| to |out|. Returns one on success or zero otherwise. */
OPENSSL_EXPORT int EVP_PKEY_print_private(BIO *out, const EVP_PKEY *pkey,
int indent, ASN1_PCTX *pctx);
-/* EVP_PKEY_print_public prints a textual representation of the parameters in
+/* EVP_PKEY_print_params prints a textual representation of the parameters in
* |pkey| to |out|. Returns one on success or zero otherwise. */
OPENSSL_EXPORT int EVP_PKEY_print_params(BIO *out, const EVP_PKEY *pkey,
int indent, ASN1_PCTX *pctx);
@@ -419,13 +412,13 @@ OPENSSL_EXPORT int PKCS5_PBKDF2_HMAC_SHA1(const char *password,
* returns the context or NULL on error. */
OPENSSL_EXPORT EVP_PKEY_CTX *EVP_PKEY_CTX_new(EVP_PKEY *pkey, ENGINE *e);
-/* EVP_PKEY_CTX_new allocates a fresh |EVP_PKEY_CTX| for a key of type |id|
+/* EVP_PKEY_CTX_new_id allocates a fresh |EVP_PKEY_CTX| for a key of type |id|
* (e.g. |EVP_PKEY_HMAC|). This can be used for key generation where
* |EVP_PKEY_CTX_new| can't be used because there isn't an |EVP_PKEY| to pass
* it. It returns the context or NULL on error. */
OPENSSL_EXPORT EVP_PKEY_CTX *EVP_PKEY_CTX_new_id(int id, ENGINE *e);
-/* EVP_KEY_CTX_free frees |ctx| and the data it owns. */
+/* EVP_PKEY_CTX_free frees |ctx| and the data it owns. */
OPENSSL_EXPORT void EVP_PKEY_CTX_free(EVP_PKEY_CTX *ctx);
/* EVP_PKEY_CTX_dup allocates a fresh |EVP_PKEY_CTX| and sets it equal to the
@@ -650,17 +643,6 @@ OPENSSL_EXPORT int EVP_PKEY_CTX_get0_rsa_oaep_label(EVP_PKEY_CTX *ctx,
/* Deprecated functions. */
-/* EVP_PKEY_dup adds one to the reference count of |pkey| and returns
- * |pkey|.
- *
- * WARNING: this is a |_dup| function that doesn't actually duplicate! Use
- * |EVP_PKEY_up_ref| if you want to increment the reference count without
- * confusion. */
-OPENSSL_EXPORT EVP_PKEY *EVP_PKEY_dup(EVP_PKEY *pkey);
-
-
-/* Private functions */
-
/* OpenSSL_add_all_algorithms does nothing. */
OPENSSL_EXPORT void OpenSSL_add_all_algorithms(void);
@@ -673,6 +655,9 @@ OPENSSL_EXPORT void OpenSSL_add_all_digests(void);
/* EVP_cleanup does nothing. */
OPENSSL_EXPORT void EVP_cleanup(void);
+
+/* Private functions */
+
/* EVP_PKEY_asn1_find returns the ASN.1 method table for the given |nid|, which
* should be one of the |EVP_PKEY_*| values. It returns NULL if |nid| is
* unknown. */
@@ -692,10 +677,10 @@ struct evp_pkey_st {
union {
char *ptr;
- struct rsa_st *rsa; /* RSA */
- struct dsa_st *dsa; /* DSA */
- struct dh_st *dh; /* DH */
- struct ec_key_st *ec; /* ECC */
+ RSA *rsa;
+ DSA *dsa;
+ DH *dh;
+ EC_KEY *ec;
} pkey;
/* ameth contains a pointer to a method table that contains many ASN.1
@@ -708,74 +693,6 @@ struct evp_pkey_st {
} /* extern C */
#endif
-#define EVP_F_EVP_PKEY_derive_init 108
-#define EVP_F_EVP_PKEY_encrypt 110
-#define EVP_F_EVP_PKEY_encrypt_init 111
-#define EVP_F_EVP_PKEY_get1_DH 112
-#define EVP_F_EVP_PKEY_get1_EC_KEY 114
-#define EVP_F_EVP_PKEY_get1_RSA 115
-#define EVP_F_EVP_PKEY_keygen 116
-#define EVP_F_EVP_PKEY_sign 120
-#define EVP_F_EVP_PKEY_sign_init 121
-#define EVP_F_EVP_PKEY_verify 122
-#define EVP_F_EVP_PKEY_verify_init 123
-#define EVP_F_d2i_AutoPrivateKey 125
-#define EVP_F_d2i_PrivateKey 126
-#define EVP_F_do_EC_KEY_print 127
-#define EVP_F_do_sigver_init 129
-#define EVP_F_eckey_param2type 130
-#define EVP_F_eckey_param_decode 131
-#define EVP_F_eckey_priv_decode 132
-#define EVP_F_eckey_priv_encode 133
-#define EVP_F_eckey_pub_decode 134
-#define EVP_F_eckey_pub_encode 135
-#define EVP_F_eckey_type2param 136
-#define EVP_F_evp_pkey_ctx_new 137
-#define EVP_F_hmac_signctx 138
-#define EVP_F_i2d_PublicKey 139
-#define EVP_F_old_ec_priv_decode 140
-#define EVP_F_old_rsa_priv_decode 141
-#define EVP_F_pkey_ec_ctrl 142
-#define EVP_F_pkey_ec_derive 143
-#define EVP_F_pkey_ec_keygen 144
-#define EVP_F_pkey_ec_paramgen 145
-#define EVP_F_pkey_ec_sign 146
-#define EVP_F_pkey_rsa_ctrl 147
-#define EVP_F_pkey_rsa_decrypt 148
-#define EVP_F_pkey_rsa_encrypt 149
-#define EVP_F_pkey_rsa_sign 150
-#define EVP_F_rsa_algor_to_md 151
-#define EVP_F_rsa_digest_verify_init_from_algorithm 152
-#define EVP_F_rsa_mgf1_to_md 153
-#define EVP_F_rsa_priv_decode 154
-#define EVP_F_rsa_priv_encode 155
-#define EVP_F_rsa_pss_to_ctx 156
-#define EVP_F_rsa_pub_decode 157
-#define EVP_F_pkey_hmac_ctrl 158
-#define EVP_F_EVP_PKEY_CTX_get0_rsa_oaep_label 159
-#define EVP_F_EVP_DigestSignAlgorithm 160
-#define EVP_F_EVP_DigestVerifyInitFromAlgorithm 161
-#define EVP_F_EVP_PKEY_CTX_ctrl 162
-#define EVP_F_EVP_PKEY_CTX_dup 163
-#define EVP_F_EVP_PKEY_copy_parameters 164
-#define EVP_F_EVP_PKEY_decrypt 165
-#define EVP_F_EVP_PKEY_decrypt_init 166
-#define EVP_F_EVP_PKEY_derive 167
-#define EVP_F_EVP_PKEY_derive_set_peer 168
-#define EVP_F_EVP_PKEY_get1_DSA 169
-#define EVP_F_EVP_PKEY_keygen_init 170
-#define EVP_F_EVP_PKEY_new 171
-#define EVP_F_EVP_PKEY_set_type 172
-#define EVP_F_check_padding_md 173
-#define EVP_F_do_dsa_print 174
-#define EVP_F_do_rsa_print 175
-#define EVP_F_dsa_param_decode 176
-#define EVP_F_dsa_priv_decode 177
-#define EVP_F_dsa_priv_encode 178
-#define EVP_F_dsa_pub_decode 179
-#define EVP_F_dsa_pub_encode 180
-#define EVP_F_dsa_sig_print 181
-#define EVP_F_old_dsa_priv_decode 182
#define EVP_R_BUFFER_TOO_SMALL 100
#define EVP_R_COMMAND_NOT_SUPPORTED 101
#define EVP_R_DIFFERENT_KEY_TYPES 104
diff --git a/src/include/openssl/ex_data.h b/src/include/openssl/ex_data.h
index 2303eb4..c0d3773 100644
--- a/src/include/openssl/ex_data.h
+++ b/src/include/openssl/ex_data.h
@@ -134,7 +134,7 @@ typedef struct crypto_ex_data_st CRYPTO_EX_DATA;
#if 0 /* Sample */
-/* |TYPE_get_ex_new_index| allocates a new index for |TYPE|. See the
+/* TYPE_get_ex_new_index allocates a new index for |TYPE|. See the
* descriptions of the callback typedefs for details of when they are
* called. Any of the callback arguments may be NULL. The |argl| and |argp|
* arguments are opaque values that are passed to the callbacks. It returns the
@@ -146,11 +146,11 @@ OPENSSL_EXPORT int TYPE_get_ex_new_index(long argl, void *argp,
CRYPTO_EX_dup *dup_func,
CRYPTO_EX_free *free_func);
-/* |TYPE_set_ex_data| sets an extra data pointer on |t|. The |index| argument
+/* TYPE_set_ex_data sets an extra data pointer on |t|. The |index| argument
* should have been returned from a previous call to |TYPE_get_ex_new_index|. */
OPENSSL_EXPORT int TYPE_set_ex_data(TYPE *t, int index, void *arg);
-/* |TYPE_get_ex_data| returns an extra data pointer for |t|, or NULL if no such
+/* TYPE_get_ex_data returns an extra data pointer for |t|, or NULL if no such
* pointer exists. The |index| argument should have been returned from a
* previous call to |TYPE_get_ex_new_index|. */
OPENSSL_EXPORT void *TYPE_get_ex_data(const TYPE *t, int index);
diff --git a/src/include/openssl/hkdf.h b/src/include/openssl/hkdf.h
index 4091b84..b7a0dc2 100644
--- a/src/include/openssl/hkdf.h
+++ b/src/include/openssl/hkdf.h
@@ -39,7 +39,6 @@ OPENSSL_EXPORT int HKDF(uint8_t *out_key, size_t out_len, const EVP_MD *digest,
} /* extern C */
#endif
-#define HKDF_F_HKDF 100
#define HKDF_R_OUTPUT_TOO_LARGE 100
#endif /* OPENSSL_HEADER_HKDF_H */
diff --git a/src/include/openssl/lhash.h b/src/include/openssl/lhash.h
index d2ee982..691b247 100644
--- a/src/include/openssl/lhash.h
+++ b/src/include/openssl/lhash.h
@@ -1,4 +1,5 @@
-/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved.
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
*
* This package is an SSL implementation written
* by Eric Young (eay@cryptsoft.com).
diff --git a/src/include/openssl/md4.h b/src/include/openssl/md4.h
index ce4fa99..1db7499 100644
--- a/src/include/openssl/md4.h
+++ b/src/include/openssl/md4.h
@@ -1,4 +1,5 @@
-/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved.
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
*
* This package is an SSL implementation written
* by Eric Young (eay@cryptsoft.com).
@@ -71,7 +72,7 @@ extern "C" {
/* MD4_DIGEST_LENGTH is the length of an MD4 digest. */
#define MD4_DIGEST_LENGTH 16
-/* MD41_Init initialises |md4| and returns one. */
+/* MD4_Init initialises |md4| and returns one. */
OPENSSL_EXPORT int MD4_Init(MD4_CTX *md4);
/* MD4_Update adds |len| bytes from |data| to |md4| and returns one. */
diff --git a/src/include/openssl/md5.h b/src/include/openssl/md5.h
index efedc98..9b13922 100644
--- a/src/include/openssl/md5.h
+++ b/src/include/openssl/md5.h
@@ -1,4 +1,5 @@
-/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved.
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
*
* This package is an SSL implementation written
* by Eric Young (eay@cryptsoft.com).
@@ -72,7 +73,7 @@ extern "C" {
/* MD5_DIGEST_LENGTH is the length of an MD5 digest. */
#define MD5_DIGEST_LENGTH 16
-/* MD51_Init initialises |md5| and returns one. */
+/* MD5_Init initialises |md5| and returns one. */
OPENSSL_EXPORT int MD5_Init(MD5_CTX *md5);
/* MD5_Update adds |len| bytes from |data| to |md5| and returns one. */
diff --git a/src/include/openssl/mem.h b/src/include/openssl/mem.h
index 42ec46a..c8e2b3e 100644
--- a/src/include/openssl/mem.h
+++ b/src/include/openssl/mem.h
@@ -1,4 +1,5 @@
-/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved.
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
*
* This package is an SSL implementation written
* by Eric Young (eay@cryptsoft.com).
diff --git a/src/include/openssl/obj.h b/src/include/openssl/obj.h
index f476617..0c7ae60 100644
--- a/src/include/openssl/obj.h
+++ b/src/include/openssl/obj.h
@@ -128,7 +128,7 @@ OPENSSL_EXPORT const char *OBJ_nid2sn(int nid);
/* OBJ_nid2sn returns the long name for |nid|, or NULL if |nid| is unknown. */
OPENSSL_EXPORT const char *OBJ_nid2ln(int nid);
-/* OBJ_nid2cbs writes |nid| as an ASN.1 OBJECT IDENTIFIER to |out|. It returns
+/* OBJ_nid2cbb writes |nid| as an ASN.1 OBJECT IDENTIFIER to |out|. It returns
* one on success or zero otherwise. */
OPENSSL_EXPORT int OBJ_nid2cbb(CBB *out, int nid);
@@ -193,10 +193,6 @@ OPENSSL_EXPORT int OBJ_find_sigid_by_algs(int *out_sign_nid, int digest_nid,
} /* extern C */
#endif
-#define OBJ_F_OBJ_create 100
-#define OBJ_F_OBJ_dup 101
-#define OBJ_F_OBJ_nid2obj 102
-#define OBJ_F_OBJ_txt2obj 103
#define OBJ_R_UNKNOWN_NID 100
#endif /* OPENSSL_HEADER_OBJECTS_H */
diff --git a/src/include/openssl/pem.h b/src/include/openssl/pem.h
index 7756e45..db763d5 100644
--- a/src/include/openssl/pem.h
+++ b/src/include/openssl/pem.h
@@ -410,7 +410,7 @@ OPENSSL_EXPORT void PEM_SignInit(EVP_MD_CTX *ctx, EVP_MD *type);
OPENSSL_EXPORT void PEM_SignUpdate(EVP_MD_CTX *ctx,unsigned char *d,unsigned int cnt);
OPENSSL_EXPORT int PEM_SignFinal(EVP_MD_CTX *ctx, unsigned char *sigret, unsigned int *siglen, EVP_PKEY *pkey);
-/* |PEM_def_callback| treats |userdata| as a string and copies it into |buf|,
+/* PEM_def_callback treats |userdata| as a string and copies it into |buf|,
* assuming its |size| is sufficient. Returns the length of the string, or 0
* if there is not enough room. If either |buf| or |userdata| is NULL, 0 is
* returned. Note that this is different from OpenSSL, which prompts for a
@@ -502,30 +502,6 @@ void ERR_load_PEM_strings(void);
}
#endif
-#define PEM_F_PEM_ASN1_read 100
-#define PEM_F_PEM_ASN1_read_bio 101
-#define PEM_F_PEM_ASN1_write 102
-#define PEM_F_PEM_ASN1_write_bio 103
-#define PEM_F_PEM_X509_INFO_read 104
-#define PEM_F_PEM_X509_INFO_read_bio 105
-#define PEM_F_PEM_X509_INFO_write_bio 106
-#define PEM_F_PEM_do_header 107
-#define PEM_F_PEM_get_EVP_CIPHER_INFO 108
-#define PEM_F_PEM_read 109
-#define PEM_F_PEM_read_DHparams 110
-#define PEM_F_PEM_read_PrivateKey 111
-#define PEM_F_PEM_read_bio 112
-#define PEM_F_PEM_read_bio_DHparams 113
-#define PEM_F_PEM_read_bio_Parameters 114
-#define PEM_F_PEM_read_bio_PrivateKey 115
-#define PEM_F_PEM_write 116
-#define PEM_F_PEM_write_PrivateKey 117
-#define PEM_F_PEM_write_bio 118
-#define PEM_F_d2i_PKCS8PrivateKey_bio 119
-#define PEM_F_d2i_PKCS8PrivateKey_fp 120
-#define PEM_F_do_pk8pkey 121
-#define PEM_F_do_pk8pkey_fp 122
-#define PEM_F_load_iv 123
#define PEM_R_BAD_BASE64_DECODE 100
#define PEM_R_BAD_DECRYPT 101
#define PEM_R_BAD_END_LINE 102
diff --git a/src/include/openssl/pkcs8.h b/src/include/openssl/pkcs8.h
index 8dc7731..bb6b03c 100644
--- a/src/include/openssl/pkcs8.h
+++ b/src/include/openssl/pkcs8.h
@@ -66,13 +66,15 @@ extern "C" {
#endif
-/* PKCS8_encrypt_pbe serializes and encrypts a PKCS8_PRIV_KEY_INFO with PBES1 as
- * defined in PKCS #5. Only pbeWithSHAAnd128BitRC4,
+/* PKCS8_encrypt_pbe serializes and encrypts a PKCS8_PRIV_KEY_INFO with PBES1 or
+ * PBES2 as defined in PKCS #5. Only pbeWithSHAAnd128BitRC4,
* pbeWithSHAAnd3-KeyTripleDES-CBC and pbeWithSHA1And40BitRC2, defined in PKCS
- * #12, are supported. The |pass_raw_len| bytes pointed to by |pass_raw| are
- * used as the password. Note that any conversions from the password as
- * supplied in a text string (such as those specified in B.1 of PKCS #12) must
- * be performed by the caller.
+ * #12, and PBES2, are supported. PBES2 is selected by setting |cipher| and
+ * passing -1 for |pbe_nid|. Otherwise, PBES1 is used and |cipher| is ignored.
+ *
+ * The |pass_raw_len| bytes pointed to by |pass_raw| are used as the password.
+ * Note that any conversions from the password as supplied in a text string
+ * (such as those specified in B.1 of PKCS #12) must be performed by the caller.
*
* If |salt| is NULL, a random salt of |salt_len| bytes is generated. If
* |salt_len| is zero, a default salt length is used instead.
@@ -83,19 +85,21 @@ extern "C" {
* TODO(davidben): Really? An X509_SIG? OpenSSL probably did that because it has
* the same structure as EncryptedPrivateKeyInfo. */
OPENSSL_EXPORT X509_SIG *PKCS8_encrypt_pbe(int pbe_nid,
+ const EVP_CIPHER *cipher,
const uint8_t *pass_raw,
size_t pass_raw_len,
uint8_t *salt, size_t salt_len,
int iterations,
PKCS8_PRIV_KEY_INFO *p8inf);
-/* PKCS8_decrypt_pbe decrypts and decodes a PKCS8_PRIV_KEY_INFO with PBES1 as
- * defined in PKCS #5. Only pbeWithSHAAnd128BitRC4,
- * pbeWithSHAAnd3-KeyTripleDES-CBC and pbeWithSHA1And40BitRC2, defined in PKCS
- * #12, are supported. The |pass_raw_len| bytes pointed to by |pass_raw| are
- * used as the password. Note that any conversions from the password as
- * supplied in a text string (such as those specified in B.1 of PKCS #12) must
- * be performed by the caller.
+/* PKCS8_decrypt_pbe decrypts and decodes a PKCS8_PRIV_KEY_INFO with PBES1 or
+ * PBES2 as defined in PKCS #5. Only pbeWithSHAAnd128BitRC4,
+ * pbeWithSHAAnd3-KeyTripleDES-CBC and pbeWithSHA1And40BitRC2, and PBES2,
+ * defined in PKCS #12, are supported.
+ *
+ * The |pass_raw_len| bytes pointed to by |pass_raw| are used as the password.
+ * Note that any conversions from the password as supplied in a text string
+ * (such as those specified in B.1 of PKCS #12) must be performed by the caller.
*
* The resulting structure must be freed by the caller. */
OPENSSL_EXPORT PKCS8_PRIV_KEY_INFO *PKCS8_decrypt_pbe(X509_SIG *pkcs8,
@@ -105,18 +109,20 @@ OPENSSL_EXPORT PKCS8_PRIV_KEY_INFO *PKCS8_decrypt_pbe(X509_SIG *pkcs8,
/* Deprecated functions. */
-/* PKCS8_encrypt calls PKCS8_encrypt_pbe after treating |pass| as an ASCII
- * string, appending U+0000, and converting to UCS-2. (So the empty password
- * encodes as two NUL bytes.) The |cipher| argument is ignored. */
+/* PKCS8_encrypt calls |PKCS8_encrypt_pbe| after (in the PKCS#12 case) treating
+ * |pass| as an ASCII string, appending U+0000, and converting to UCS-2. (So the
+ * empty password encodes as two NUL bytes.) In the PBES2 case, the password is
+ * unchanged. */
OPENSSL_EXPORT X509_SIG *PKCS8_encrypt(int pbe_nid, const EVP_CIPHER *cipher,
const char *pass, int pass_len,
uint8_t *salt, size_t salt_len,
int iterations,
PKCS8_PRIV_KEY_INFO *p8inf);
-/* PKCS8_decrypt calls PKCS8_decrypt_pbe after treating |pass| as an ASCII
- * string, appending U+0000, and converting to UCS-2. (So the empty password
- * encodes as two NUL bytes.) */
+/* PKCS8_decrypt calls PKCS8_decrypt_pbe after (in the PKCS#12 case) treating
+ * |pass| as an ASCII string, appending U+0000, and converting to UCS-2. (So the
+ * empty password encodes as two NUL bytes.) In the PBES2 case, the password is
+ * unchanged. */
OPENSSL_EXPORT PKCS8_PRIV_KEY_INFO *PKCS8_decrypt(X509_SIG *pkcs8,
const char *pass,
int pass_len);
@@ -170,24 +176,6 @@ OPENSSL_EXPORT void PKCS12_free(PKCS12 *p12);
} /* extern C */
#endif
-#define PKCS8_F_EVP_PKCS82PKEY 100
-#define PKCS8_F_EVP_PKEY2PKCS8 101
-#define PKCS8_F_PKCS12_get_key_and_certs 102
-#define PKCS8_F_PKCS12_handle_content_info 103
-#define PKCS8_F_PKCS12_handle_content_infos 104
-#define PKCS8_F_PKCS5_pbe2_set_iv 105
-#define PKCS8_F_PKCS5_pbe_set 106
-#define PKCS8_F_PKCS5_pbe_set0_algor 107
-#define PKCS8_F_PKCS5_pbkdf2_set 108
-#define PKCS8_F_PKCS8_decrypt 109
-#define PKCS8_F_PKCS8_encrypt 110
-#define PKCS8_F_PKCS8_encrypt_pbe 111
-#define PKCS8_F_pbe_cipher_init 112
-#define PKCS8_F_pbe_crypt 113
-#define PKCS8_F_pkcs12_item_decrypt_d2i 114
-#define PKCS8_F_pkcs12_item_i2d_encrypt 115
-#define PKCS8_F_pkcs12_key_gen_raw 116
-#define PKCS8_F_pkcs12_pbe_keyivgen 117
#define PKCS8_R_BAD_PKCS12_DATA 100
#define PKCS8_R_BAD_PKCS12_VERSION 101
#define PKCS8_R_CIPHER_HAS_NO_OBJECT_IDENTIFIER 102
@@ -213,5 +201,11 @@ OPENSSL_EXPORT void PKCS12_free(PKCS12 *p12);
#define PKCS8_R_UNKNOWN_DIGEST 122
#define PKCS8_R_UNKNOWN_HASH 123
#define PKCS8_R_UNSUPPORTED_PRIVATE_KEY_ALGORITHM 124
+#define PKCS8_R_UNSUPPORTED_KEYLENGTH 125
+#define PKCS8_R_UNSUPPORTED_SALT_TYPE 126
+#define PKCS8_R_UNSUPPORTED_CIPHER 127
+#define PKCS8_R_UNSUPPORTED_KEY_DERIVATION_FUNCTION 128
+#define PKCS8_R_BAD_ITERATION_COUNT 129
+#define PKCS8_R_UNSUPPORTED_PRF 130
#endif /* OPENSSL_HEADER_PKCS8_H */
diff --git a/src/include/openssl/poly1305.h b/src/include/openssl/poly1305.h
index aa90486..0da9f6e 100644
--- a/src/include/openssl/poly1305.h
+++ b/src/include/openssl/poly1305.h
@@ -22,22 +22,25 @@ extern "C" {
#endif
-typedef unsigned char poly1305_state[512];
+typedef uint8_t poly1305_state[512];
/* poly1305_init sets up |state| so that it can be used to calculate an
* authentication tag with the one-time key |key|. Note that |key| is a
* one-time key and therefore there is no `reset' method because that would
* enable several messages to be authenticated with the same key. */
-extern void CRYPTO_poly1305_init(poly1305_state* state, const uint8_t key[32]);
+OPENSSL_EXPORT void CRYPTO_poly1305_init(poly1305_state* state,
+ const uint8_t key[32]);
/* poly1305_update processes |in_len| bytes from |in|. It can be called zero or
* more times after poly1305_init. */
-extern void CRYPTO_poly1305_update(poly1305_state* state, const uint8_t* in,
- size_t in_len);
+OPENSSL_EXPORT void CRYPTO_poly1305_update(poly1305_state* state,
+ const uint8_t* in,
+ size_t in_len);
/* poly1305_finish completes the poly1305 calculation and writes a 16 byte
* authentication tag to |mac|. The |mac| address must be 16-byte aligned. */
-extern void CRYPTO_poly1305_finish(poly1305_state* state, uint8_t mac[16]);
+OPENSSL_EXPORT void CRYPTO_poly1305_finish(poly1305_state* state,
+ uint8_t mac[16]);
#if defined(__cplusplus)
diff --git a/src/include/openssl/rand.h b/src/include/openssl/rand.h
index 300bf42..de1bd8d 100644
--- a/src/include/openssl/rand.h
+++ b/src/include/openssl/rand.h
@@ -33,6 +33,36 @@ OPENSSL_EXPORT int RAND_bytes(uint8_t *buf, size_t len);
OPENSSL_EXPORT void RAND_cleanup(void);
+/* Obscure functions. */
+
+#if !defined(OPENSSL_WINDOWS)
+/* RAND_set_urandom_fd causes the module to use a copy of |fd| for system
+ * randomness rather opening /dev/urandom internally. The caller retains
+ * ownership of |fd| and is at liberty to close it at any time. This is useful
+ * if, due to a sandbox, /dev/urandom isn't available. If used, it must be
+ * called before the first call to |RAND_bytes|, and it is mutually exclusive
+ * with |RAND_enable_fork_unsafe_buffering|.
+ *
+ * |RAND_set_urandom_fd| does not buffer any entropy, so it is safe to call
+ * |fork| at any time after calling |RAND_set_urandom_fd|. */
+OPENSSL_EXPORT void RAND_set_urandom_fd(int fd);
+
+/* RAND_enable_fork_unsafe_buffering enables efficient buffered reading of
+ * /dev/urandom. It adds an overhead of a few KB of memory per thread. It must
+ * be called before the first call to |RAND_bytes| and it is mutually exclusive
+ * with calls to |RAND_set_urandom_fd|.
+ *
+ * If |fd| is non-negative then a copy of |fd| will be used rather than opening
+ * /dev/urandom internally. Like |RAND_set_urandom_fd|, the caller retains
+ * ownership of |fd|. If |fd| is negative then /dev/urandom will be opened and
+ * any error from open(2) crashes the address space.
+ *
+ * It has an unusual name because the buffer is unsafe across calls to |fork|.
+ * Hence, this function should never be called by libraries. */
+OPENSSL_EXPORT void RAND_enable_fork_unsafe_buffering(int fd);
+#endif
+
+
/* Deprecated functions */
/* RAND_pseudo_bytes is a wrapper around |RAND_bytes|. */
@@ -47,12 +77,33 @@ OPENSSL_EXPORT int RAND_load_file(const char *path, long num);
/* RAND_add does nothing. */
OPENSSL_EXPORT void RAND_add(const void *buf, int num, double entropy);
+/* RAND_egd returns 255. */
+OPENSSL_EXPORT int RAND_egd(const char *);
+
/* RAND_poll returns one. */
OPENSSL_EXPORT int RAND_poll(void);
/* RAND_status returns one. */
OPENSSL_EXPORT int RAND_status(void);
+/* rand_meth_st is typedefed to |RAND_METHOD| in base.h. It isn't used; it
+ * exists only to be the return type of |RAND_SSLeay|. It's
+ * external so that variables of this type can be initialized. */
+struct rand_meth_st {
+ void (*seed) (const void *buf, int num);
+ int (*bytes) (uint8_t *buf, size_t num);
+ void (*cleanup) (void);
+ void (*add) (const void *buf, int num, double entropy);
+ int (*pseudorand) (uint8_t *buf, size_t num);
+ int (*status) (void);
+};
+
+/* RAND_SSLeay returns a pointer to a dummy |RAND_METHOD|. */
+OPENSSL_EXPORT RAND_METHOD *RAND_SSLeay(void);
+
+/* RAND_set_rand_method does nothing. */
+OPENSSL_EXPORT void RAND_set_rand_method(const RAND_METHOD *);
+
#if defined(__cplusplus)
} /* extern C */
diff --git a/src/include/openssl/rsa.h b/src/include/openssl/rsa.h
index 9b415d7..2be50dc 100644
--- a/src/include/openssl/rsa.h
+++ b/src/include/openssl/rsa.h
@@ -59,6 +59,7 @@
#include <openssl/base.h>
+#include <openssl/asn1.h>
#include <openssl/engine.h>
#include <openssl/ex_data.h>
#include <openssl/thread.h>
@@ -100,6 +101,12 @@ OPENSSL_EXPORT int RSA_up_ref(RSA *rsa);
OPENSSL_EXPORT int RSA_generate_key_ex(RSA *rsa, int bits, BIGNUM *e,
BN_GENCB *cb);
+/* RSA_generate_multi_prime_key acts like |RSA_generate_key_ex| but can
+ * generate an RSA private key with more than two primes. */
+OPENSSL_EXPORT int RSA_generate_multi_prime_key(RSA *rsa, int bits,
+ int num_primes, BIGNUM *e,
+ BN_GENCB *cb);
+
/* Encryption / Decryption */
@@ -240,7 +247,7 @@ OPENSSL_EXPORT int RSA_verify_raw(RSA *rsa, size_t *out_len, uint8_t *out,
OPENSSL_EXPORT int RSA_private_encrypt(int flen, const uint8_t *from,
uint8_t *to, RSA *rsa, int padding);
-/* RSA_private_encrypt verifies |flen| bytes of signature from |from| using the
+/* RSA_public_decrypt verifies |flen| bytes of signature from |from| using the
* public key in |rsa| and writes the plaintext to |to|. The |to| buffer must
* have at least |RSA_size| bytes of space. It returns the number of bytes
* written, or -1 on error. The |padding| argument must be one of the
@@ -266,7 +273,7 @@ OPENSSL_EXPORT int RSA_is_opaque(const RSA *rsa);
* of type |md|. Otherwise it returns zero. */
OPENSSL_EXPORT int RSA_supports_digest(const RSA *rsa, const EVP_MD *md);
-/* RSAPublicKey_dup allocates a fresh |RSA| and copies the private key from
+/* RSAPublicKey_dup allocates a fresh |RSA| and copies the public key from
* |rsa| into it. It returns the fresh |RSA| object, or NULL on error. */
OPENSSL_EXPORT RSA *RSAPublicKey_dup(const RSA *rsa);
@@ -315,36 +322,63 @@ OPENSSL_EXPORT int RSA_padding_add_PKCS1_PSS_mgf1(RSA *rsa, uint8_t *EM,
const EVP_MD *mgf1Hash,
int sLen);
+/* RSA_add_pkcs1_prefix builds a version of |msg| prefixed with the DigestInfo
+ * header for the given hash function and sets |out_msg| to point to it. On
+ * successful return, |*out_msg| may be allocated memory and, if so,
+ * |*is_alloced| will be 1. */
+OPENSSL_EXPORT int RSA_add_pkcs1_prefix(uint8_t **out_msg, size_t *out_msg_len,
+ int *is_alloced, int hash_nid,
+ const uint8_t *msg, size_t msg_len);
-/* ASN.1 functions. */
-/* d2i_RSAPublicKey parses an ASN.1, DER-encoded, RSA public key from |len|
- * bytes at |*inp|. If |out| is not NULL then, on exit, a pointer to the result
- * is in |*out|. If |*out| is already non-NULL on entry then the result is
- * written directly into |*out|, otherwise a fresh |RSA| is allocated. On
- * successful exit, |*inp| is advanced past the DER structure. It returns the
- * result or NULL on error. */
-OPENSSL_EXPORT RSA *d2i_RSAPublicKey(RSA **out, const uint8_t **inp, long len);
-
-/* i2d_RSAPublicKey marshals |in| to an ASN.1, DER structure. If |outp| is not
- * NULL then the result is written to |*outp| and |*outp| is advanced just past
- * the output. It returns the number of bytes in the result, whether written or
- * not, or a negative value on error. */
-OPENSSL_EXPORT int i2d_RSAPublicKey(const RSA *in, uint8_t **outp);
-
-/* d2i_RSAPrivateKey parses an ASN.1, DER-encoded, RSA private key from |len|
- * bytes at |*inp|. If |out| is not NULL then, on exit, a pointer to the result
- * is in |*out|. If |*out| is already non-NULL on entry then the result is
- * written directly into |*out|, otherwise a fresh |RSA| is allocated. On
- * successful exit, |*inp| is advanced past the DER structure. It returns the
- * result or NULL on error. */
-OPENSSL_EXPORT RSA *d2i_RSAPrivateKey(RSA **out, const uint8_t **inp, long len);
+/* ASN.1 functions. */
-/* i2d_RSAPrivateKey marshals |in| to an ASN.1, DER structure. If |outp| is not
- * NULL then the result is written to |*outp| and |*outp| is advanced just past
- * the output. It returns the number of bytes in the result, whether written or
- * not, or a negative value on error. */
-OPENSSL_EXPORT int i2d_RSAPrivateKey(const RSA *in, uint8_t **outp);
+/* RSA_parse_public_key parses a DER-encoded RSAPublicKey structure (RFC 3447)
+ * from |cbs| and advances |cbs|. It returns a newly-allocated |RSA| or NULL on
+ * error. */
+OPENSSL_EXPORT RSA *RSA_parse_public_key(CBS *cbs);
+
+/* RSA_parse_public_key_buggy behaves like |RSA_parse_public_key|, but it
+ * tolerates some invalid encodings. Do not use this function. */
+OPENSSL_EXPORT RSA *RSA_parse_public_key_buggy(CBS *cbs);
+
+/* RSA_public_key_from_bytes parses |in| as a DER-encoded RSAPublicKey structure
+ * (RFC 3447). It returns a newly-allocated |RSA| or NULL on error. */
+OPENSSL_EXPORT RSA *RSA_public_key_from_bytes(const uint8_t *in, size_t in_len);
+
+/* RSA_marshal_public_key marshals |rsa| as a DER-encoded RSAPublicKey structure
+ * (RFC 3447) and appends the result to |cbb|. It returns one on success and
+ * zero on failure. */
+OPENSSL_EXPORT int RSA_marshal_public_key(CBB *cbb, const RSA *rsa);
+
+/* RSA_public_key_to_bytes marshals |rsa| as a DER-encoded RSAPublicKey
+ * structure (RFC 3447) and, on success, sets |*out_bytes| to a newly allocated
+ * buffer containing the result and returns one. Otherwise, it returns zero. The
+ * result should be freed with |OPENSSL_free|. */
+OPENSSL_EXPORT int RSA_public_key_to_bytes(uint8_t **out_bytes, size_t *out_len,
+ const RSA *rsa);
+
+/* RSA_parse_private_key parses a DER-encoded RSAPrivateKey structure (RFC 3447)
+ * from |cbs| and advances |cbs|. It returns a newly-allocated |RSA| or NULL on
+ * error. */
+OPENSSL_EXPORT RSA *RSA_parse_private_key(CBS *cbs);
+
+/* RSA_private_key_from_bytes parses |in| as a DER-encoded RSAPrivateKey
+ * structure (RFC 3447). It returns a newly-allocated |RSA| or NULL on error. */
+OPENSSL_EXPORT RSA *RSA_private_key_from_bytes(const uint8_t *in,
+ size_t in_len);
+
+/* RSA_marshal_private_key marshals |rsa| as a DER-encoded RSAPrivateKey
+ * structure (RFC 3447) and appends the result to |cbb|. It returns one on
+ * success and zero on failure. */
+OPENSSL_EXPORT int RSA_marshal_private_key(CBB *cbb, const RSA *rsa);
+
+/* RSA_private_key_to_bytes marshals |rsa| as a DER-encoded RSAPrivateKey
+ * structure (RFC 3447) and, on success, sets |*out_bytes| to a newly allocated
+ * buffer containing the result and returns one. Otherwise, it returns zero. The
+ * result should be freed with |OPENSSL_free|. */
+OPENSSL_EXPORT int RSA_private_key_to_bytes(uint8_t **out_bytes,
+ size_t *out_len, const RSA *rsa);
/* ex_data functions.
@@ -358,6 +392,9 @@ OPENSSL_EXPORT int RSA_get_ex_new_index(long argl, void *argp,
OPENSSL_EXPORT int RSA_set_ex_data(RSA *r, int idx, void *arg);
OPENSSL_EXPORT void *RSA_get_ex_data(const RSA *r, int idx);
+
+/* Flags. */
+
/* RSA_FLAG_OPAQUE specifies that this RSA_METHOD does not expose its key
* material. This may be set if, for instance, it is wrapping some other crypto
* API, like a platform key store. */
@@ -395,6 +432,50 @@ OPENSSL_EXPORT void *RSA_get_ex_data(const RSA *r, int idx);
/* RSA_blinding_on returns one. */
OPENSSL_EXPORT int RSA_blinding_on(RSA *rsa, BN_CTX *ctx);
+/* RSA_generate_key behaves like |RSA_generate_key_ex|, which is what you
+ * should use instead. It returns NULL on error, or a newly-allocated |RSA| on
+ * success. This function is provided for compatibility only. The |callback|
+ * and |cb_arg| parameters must be NULL. */
+OPENSSL_EXPORT RSA *RSA_generate_key(int bits, unsigned long e, void *callback,
+ void *cb_arg);
+
+/* d2i_RSAPublicKey parses an ASN.1, DER-encoded, RSA public key from |len|
+ * bytes at |*inp|. If |out| is not NULL then, on exit, a pointer to the result
+ * is in |*out|. If |*out| is already non-NULL on entry then the result is
+ * written directly into |*out|, otherwise a fresh |RSA| is allocated. On
+ * successful exit, |*inp| is advanced past the DER structure. It returns the
+ * result or NULL on error. */
+OPENSSL_EXPORT RSA *d2i_RSAPublicKey(RSA **out, const uint8_t **inp, long len);
+
+/* i2d_RSAPublicKey marshals |in| to an ASN.1, DER structure. If |outp| is not
+ * NULL then the result is written to |*outp| and |*outp| is advanced just past
+ * the output. It returns the number of bytes in the result, whether written or
+ * not, or a negative value on error. */
+OPENSSL_EXPORT int i2d_RSAPublicKey(const RSA *in, uint8_t **outp);
+
+/* d2i_RSAPrivateKey parses an ASN.1, DER-encoded, RSA private key from |len|
+ * bytes at |*inp|. If |out| is not NULL then, on exit, a pointer to the result
+ * is in |*out|. If |*out| is already non-NULL on entry then the result is
+ * written directly into |*out|, otherwise a fresh |RSA| is allocated. On
+ * successful exit, |*inp| is advanced past the DER structure. It returns the
+ * result or NULL on error. */
+OPENSSL_EXPORT RSA *d2i_RSAPrivateKey(RSA **out, const uint8_t **inp, long len);
+
+/* i2d_RSAPrivateKey marshals |in| to an ASN.1, DER structure. If |outp| is not
+ * NULL then the result is written to |*outp| and |*outp| is advanced just past
+ * the output. It returns the number of bytes in the result, whether written or
+ * not, or a negative value on error. */
+OPENSSL_EXPORT int i2d_RSAPrivateKey(const RSA *in, uint8_t **outp);
+
+typedef struct rsa_pss_params_st {
+ X509_ALGOR *hashAlgorithm;
+ X509_ALGOR *maskGenAlgorithm;
+ ASN1_INTEGER *saltLength;
+ ASN1_INTEGER *trailerField;
+} RSA_PSS_PARAMS;
+
+DECLARE_ASN1_FUNCTIONS(RSA_PSS_PARAMS)
+
struct rsa_meth_st {
struct openssl_method_common_st common;
@@ -450,6 +531,9 @@ struct rsa_meth_st {
int (*keygen)(RSA *rsa, int bits, BIGNUM *e, BN_GENCB *cb);
+ int (*multi_prime_keygen)(RSA *rsa, int bits, int num_primes, BIGNUM *e,
+ BN_GENCB *cb);
+
/* supports_digest returns one if |rsa| supports digests of type
* |md|. If null, it is assumed that all digests are supported. */
int (*supports_digest)(const RSA *rsa, const EVP_MD *md);
@@ -461,8 +545,6 @@ struct rsa_meth_st {
typedef struct bn_blinding_st BN_BLINDING;
struct rsa_st {
- /* version is only used during ASN.1 (de)serialisation. */
- long version;
RSA_METHOD *meth;
BIGNUM *n;
@@ -473,6 +555,9 @@ struct rsa_st {
BIGNUM *dmp1;
BIGNUM *dmq1;
BIGNUM *iqmp;
+
+ STACK_OF(RSA_additional_prime) *additional_primes;
+
/* be careful using this if the RSA structure is shared */
CRYPTO_EX_DATA ex_data;
CRYPTO_refcount_t references;
@@ -502,34 +587,6 @@ struct rsa_st {
} /* extern C */
#endif
-#define RSA_F_BN_BLINDING_convert_ex 100
-#define RSA_F_BN_BLINDING_create_param 101
-#define RSA_F_BN_BLINDING_invert_ex 102
-#define RSA_F_BN_BLINDING_new 103
-#define RSA_F_BN_BLINDING_update 104
-#define RSA_F_RSA_check_key 105
-#define RSA_F_RSA_new_method 106
-#define RSA_F_RSA_padding_add_PKCS1_OAEP_mgf1 107
-#define RSA_F_RSA_padding_add_PKCS1_PSS_mgf1 108
-#define RSA_F_RSA_padding_add_PKCS1_type_1 109
-#define RSA_F_RSA_padding_add_PKCS1_type_2 110
-#define RSA_F_RSA_padding_add_none 111
-#define RSA_F_RSA_padding_check_PKCS1_OAEP_mgf1 112
-#define RSA_F_RSA_padding_check_PKCS1_type_1 113
-#define RSA_F_RSA_padding_check_PKCS1_type_2 114
-#define RSA_F_RSA_padding_check_none 115
-#define RSA_F_RSA_recover_crt_params 116
-#define RSA_F_RSA_sign 117
-#define RSA_F_RSA_verify 118
-#define RSA_F_RSA_verify_PKCS1_PSS_mgf1 119
-#define RSA_F_decrypt 120
-#define RSA_F_encrypt 121
-#define RSA_F_keygen 122
-#define RSA_F_pkcs1_prefixed_msg 123
-#define RSA_F_private_transform 124
-#define RSA_F_rsa_setup_blinding 125
-#define RSA_F_sign_raw 126
-#define RSA_F_verify_raw 127
#define RSA_R_BAD_E_VALUE 100
#define RSA_R_BAD_FIXED_HEADER_DECRYPT 101
#define RSA_R_BAD_PAD_BYTE_COUNT 102
@@ -571,5 +628,10 @@ struct rsa_st {
#define RSA_R_UNKNOWN_PADDING_TYPE 138
#define RSA_R_VALUE_MISSING 139
#define RSA_R_WRONG_SIGNATURE_LENGTH 140
+#define RSA_R_MUST_HAVE_AT_LEAST_TWO_PRIMES 141
+#define RSA_R_CANNOT_RECOVER_MULTI_PRIME_KEY 142
+#define RSA_R_BAD_ENCODING 143
+#define RSA_R_ENCODE_ERROR 144
+#define RSA_R_BAD_VERSION 145
#endif /* OPENSSL_HEADER_RSA_H */
diff --git a/src/include/openssl/srtp.h b/src/include/openssl/srtp.h
index 3f5a53e..39f6a85 100644
--- a/src/include/openssl/srtp.h
+++ b/src/include/openssl/srtp.h
@@ -1,178 +1,18 @@
-/* ssl/tls1.h */
-/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
- * All rights reserved.
+/* Copyright (c) 2015, Google Inc.
*
- * This package is an SSL implementation written
- * by Eric Young (eay@cryptsoft.com).
- * The implementation was written so as to conform with Netscapes SSL.
- *
- * This library is free for commercial and non-commercial use as long as
- * the following conditions are aheared to. The following conditions
- * apply to all code found in this distribution, be it the RC4, RSA,
- * lhash, DES, etc., code; not just the SSL code. The SSL documentation
- * included with this distribution is covered by the same copyright terms
- * except that the holder is Tim Hudson (tjh@cryptsoft.com).
- *
- * Copyright remains Eric Young's, and as such any Copyright notices in
- * the code are not to be removed.
- * If this package is used in a product, Eric Young should be given attribution
- * as the author of the parts of the library used.
- * This can be in the form of a textual message at program startup or
- * in documentation (online or textual) provided with the package.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * "This product includes cryptographic software written by
- * Eric Young (eay@cryptsoft.com)"
- * The word 'cryptographic' can be left out if the rouines from the library
- * being used are not cryptographic related :-).
- * 4. If you include any Windows specific code (or a derivative thereof) from
- * the apps directory (application code) you must include an acknowledgement:
- * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
- *
- * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * The licence and distribution terms for any publically available version or
- * derivative of this code cannot be changed. i.e. this code cannot simply be
- * copied and put under another distribution licence
- * [including the GNU Public Licence.]
- */
-/* ====================================================================
- * Copyright (c) 1998-2006 The OpenSSL Project. All rights reserved.
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
*
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in
- * the documentation and/or other materials provided with the
- * distribution.
- *
- * 3. All advertising materials mentioning features or use of this
- * software must display the following acknowledgment:
- * "This product includes software developed by the OpenSSL Project
- * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
- *
- * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
- * endorse or promote products derived from this software without
- * prior written permission. For written permission, please contact
- * openssl-core@openssl.org.
- *
- * 5. Products derived from this software may not be called "OpenSSL"
- * nor may "OpenSSL" appear in their names without prior written
- * permission of the OpenSSL Project.
- *
- * 6. Redistributions of any form whatsoever must retain the following
- * acknowledgment:
- * "This product includes software developed by the OpenSSL Project
- * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
- *
- * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
- * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
- * OF THE POSSIBILITY OF SUCH DAMAGE.
- * ====================================================================
- *
- * This product includes cryptographic software written by Eric Young
- * (eay@cryptsoft.com). This product includes software written by Tim
- * Hudson (tjh@cryptsoft.com).
- *
- */
-/*
- DTLS code by Eric Rescorla <ekr@rtfm.com>
-
- Copyright (C) 2006, Network Resonance, Inc.
- Copyright (C) 2011, RTFM, Inc.
-*/
-
-#ifndef OPENSSL_HEADER_SRTP_H
-#define OPENSSL_HEADER_SRTP_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-
-/* Constants for SRTP profiles */
-#define SRTP_AES128_CM_SHA1_80 0x0001
-#define SRTP_AES128_CM_SHA1_32 0x0002
-#define SRTP_AES128_F8_SHA1_80 0x0003
-#define SRTP_AES128_F8_SHA1_32 0x0004
-#define SRTP_NULL_SHA1_80 0x0005
-#define SRTP_NULL_SHA1_32 0x0006
-
-/* SSL_CTX_set_srtp_profiles enables SRTP for all SSL objects created from
- * |ctx|. |profile| contains a colon-separated list of profile names. It returns
- * one on success and zero on failure. */
-OPENSSL_EXPORT int SSL_CTX_set_srtp_profiles(SSL_CTX *ctx,
- const char *profiles);
-
-/* SSL_set_srtp_profiles enables SRTP for |ssl|. |profile| contains a
- * colon-separated list of profile names. It returns one on success and zero on
- * failure. */
-OPENSSL_EXPORT int SSL_set_srtp_profiles(SSL *ctx, const char *profiles);
-
-/* SSL_get_srtp_profiles returns the SRTP profiles supported by |ssl|. */
-OPENSSL_EXPORT STACK_OF(SRTP_PROTECTION_PROFILE) *SSL_get_srtp_profiles(
- SSL *ssl);
-
-/* SSL_get_selected_srtp_profile returns the selected SRTP profile, or NULL if
- * SRTP was not negotiated. */
-OPENSSL_EXPORT const SRTP_PROTECTION_PROFILE *SSL_get_selected_srtp_profile(
- SSL *s);
-
-
-/* Deprecated functions */
-
-/* SSL_CTX_set_tlsext_use_srtp calls SSL_CTX_set_srtp_profiles. It returns zero
- * on success and one on failure.
- *
- * WARNING: this function is dangerous because it breaks the usual return value
- * convention. Use SSL_CTX_set_srtp_profiles instead. */
-OPENSSL_EXPORT int SSL_CTX_set_tlsext_use_srtp(SSL_CTX *ctx,
- const char *profiles);
-
-/* SSL_set_tlsext_use_srtp calls SSL_set_srtp_profiles. It returns zero on
- * success and one on failure.
- *
- * WARNING: this function is dangerous because it breaks the usual return value
- * convention. Use SSL_set_srtp_profiles instead. */
-OPENSSL_EXPORT int SSL_set_tlsext_use_srtp(SSL *ctx, const char *profiles);
-
-
-#ifdef __cplusplus
-} /* extern C */
-#endif
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
-#endif /* OPENSSL_HEADER_SRTP_H */
+/* This header is provided in order to make compiling against code that expects
+ OpenSSL easier. */
+#include "ssl.h"
diff --git a/src/include/openssl/ssl.h b/src/include/openssl/ssl.h
index 2735e15..24bdf8e 100644
--- a/src/include/openssl/ssl.h
+++ b/src/include/openssl/ssl.h
@@ -179,32 +179,9 @@ extern "C" {
OPENSSL_EXPORT int SSL_library_init(void);
-/* Cipher suites. */
-
-/* An SSL_CIPHER represents a cipher suite. */
-typedef struct ssl_cipher_st {
- /* name is the OpenSSL name for the cipher. */
- const char *name;
- /* id is the cipher suite value bitwise OR-d with 0x03000000. */
- uint32_t id;
-
- /* The following are internal fields. See ssl/internal.h for their values. */
-
- uint32_t algorithm_mkey;
- uint32_t algorithm_auth;
- uint32_t algorithm_enc;
- uint32_t algorithm_mac;
- uint32_t algorithm_ssl;
- uint32_t algo_strength;
-
- /* algorithm2 contains extra flags. See ssl/internal.h. */
- uint32_t algorithm2;
-
- /* strength_bits is the strength of the cipher in bits. */
- int strength_bits;
- /* alg_bits is the number of bits of key material used by the algorithm. */
- int alg_bits;
-} SSL_CIPHER;
+/* Cipher suites.
+ *
+ * |SSL_CIPHER| objects represent cipher suites. */
DECLARE_STACK_OF(SSL_CIPHER)
@@ -231,6 +208,15 @@ OPENSSL_EXPORT int SSL_CIPHER_is_AESGCM(const SSL_CIPHER *cipher);
* CHACHA20_POLY1305. */
OPENSSL_EXPORT int SSL_CIPHER_is_CHACHA20POLY1305(const SSL_CIPHER *cipher);
+/* SSL_CIPHER_is_NULL returns one if |cipher| does not encrypt. */
+OPENSSL_EXPORT int SSL_CIPHER_is_NULL(const SSL_CIPHER *cipher);
+
+/* SSL_CIPHER_is_RC4 returns one if |cipher| uses RC4. */
+OPENSSL_EXPORT int SSL_CIPHER_is_RC4(const SSL_CIPHER *cipher);
+
+/* SSL_CIPHER_is_block_cipher returns one if |cipher| is a block cipher. */
+OPENSSL_EXPORT int SSL_CIPHER_is_block_cipher(const SSL_CIPHER *cipher);
+
/* SSL_CIPHER_get_name returns the OpenSSL name of |cipher|. */
OPENSSL_EXPORT const char *SSL_CIPHER_get_name(const SSL_CIPHER *cipher);
@@ -251,10 +237,15 @@ OPENSSL_EXPORT int SSL_CIPHER_get_bits(const SSL_CIPHER *cipher,
int *out_alg_bits);
-/* SSL contexts. */
-
-/* An SSL_METHOD selects whether to use TLS or DTLS. */
-typedef struct ssl_method_st SSL_METHOD;
+/* SSL contexts.
+ *
+ * |SSL_CTX| objects manage shared state and configuration between multiple TLS
+ * or DTLS connections. Whether the connections are TLS or DTLS is selected by
+ * an |SSL_METHOD| on creation.
+ *
+ * |SSL_CTX| are reference-counted and may be shared by connections across
+ * multiple threads. Once shared, functions which change the |SSL_CTX|'s
+ * configuration may not be used. */
/* TLS_method is the |SSL_METHOD| used for TLS (and SSLv3) connections. */
OPENSSL_EXPORT const SSL_METHOD *TLS_method(void);
@@ -263,20 +254,22 @@ OPENSSL_EXPORT const SSL_METHOD *TLS_method(void);
OPENSSL_EXPORT const SSL_METHOD *DTLS_method(void);
/* SSL_CTX_new returns a newly-allocated |SSL_CTX| with default settings or NULL
- * on error. An |SSL_CTX| manages shared state and configuration between
- * multiple TLS or DTLS connections. */
+ * on error. */
OPENSSL_EXPORT SSL_CTX *SSL_CTX_new(const SSL_METHOD *method);
/* SSL_CTX_free releases memory associated with |ctx|. */
OPENSSL_EXPORT void SSL_CTX_free(SSL_CTX *ctx);
-/* SSL connections. */
+/* SSL connections.
+ *
+ * An |SSL| object represents a single TLS or DTLS connection. Although the
+ * shared |SSL_CTX| is thread-safe, an |SSL| is not thread-safe and may only be
+ * used on one thread at a time. */
-/* SSL_new returns a newly-allocated |SSL| using |ctx| or NULL on error. An
- * |SSL| object represents a single TLS or DTLS connection. It inherits settings
- * from |ctx| at the time of creation. Settings may also be individually
- * configured on the connection.
+/* SSL_new returns a newly-allocated |SSL| using |ctx| or NULL on error. The new
+ * connection inherits settings from |ctx| at the time of creation. Settings may
+ * also be individually configured on the connection.
*
* On creation, an |SSL| is not configured to be either a client or server. Call
* |SSL_set_connect_state| or |SSL_set_accept_state| to set this. */
@@ -291,9 +284,183 @@ OPENSSL_EXPORT void SSL_set_connect_state(SSL *ssl);
/* SSL_set_accept_state configures |ssl| to be a server. */
OPENSSL_EXPORT void SSL_set_accept_state(SSL *ssl);
+/* SSL_is_server returns one if |ssl| is configured as a server and zero
+ * otherwise. */
+OPENSSL_EXPORT int SSL_is_server(SSL *ssl);
+
+/* SSL_set_bio configures |ssl| to read from |rbio| and write to |wbio|. |ssl|
+ * takes ownership of the two |BIO|s. If |rbio| and |wbio| are the same, |ssl|
+ * only takes ownership of one reference.
+ *
+ * Calling this function on an already-configured |ssl| is deprecated. */
+OPENSSL_EXPORT void SSL_set_bio(SSL *ssl, BIO *rbio, BIO *wbio);
+
+/* SSL_get_rbio returns the |BIO| that |ssl| reads from. */
+OPENSSL_EXPORT BIO *SSL_get_rbio(const SSL *ssl);
+
+/* SSL_get_wbio returns the |BIO| that |ssl| writes to. */
+OPENSSL_EXPORT BIO *SSL_get_wbio(const SSL *ssl);
+
+/* SSL_do_handshake continues the current handshake. If there is none or the
+ * handshake has completed or False Started, it returns one. Otherwise, it
+ * returns <= 0. The caller should pass the value into |SSL_get_error| to
+ * determine how to proceed.
+ *
+ * TODO(davidben): Ensure 0 is only returned on transport EOF.
+ * https://crbug.com/466303. */
+OPENSSL_EXPORT int SSL_do_handshake(SSL *ssl);
+
+/* SSL_connect configures |ssl| as a client, if unconfigured, and calls
+ * |SSL_do_handshake|. */
+OPENSSL_EXPORT int SSL_connect(SSL *ssl);
+
+/* SSL_accept configures |ssl| as a server, if unconfigured, and calls
+ * |SSL_do_handshake|. */
+OPENSSL_EXPORT int SSL_accept(SSL *ssl);
+
+/* SSL_read reads up to |num| bytes from |ssl| into |buf|. It implicitly runs
+ * any pending handshakes, including renegotiations when enabled. On success, it
+ * returns the number of bytes read. Otherwise, it returns <= 0. The caller
+ * should pass the value into |SSL_get_error| to determine how to proceed.
+ *
+ * TODO(davidben): Ensure 0 is only returned on transport EOF.
+ * https://crbug.com/466303. */
+OPENSSL_EXPORT int SSL_read(SSL *ssl, void *buf, int num);
+
+/* SSL_peek behaves like |SSL_read| but does not consume any bytes returned. */
+OPENSSL_EXPORT int SSL_peek(SSL *ssl, void *buf, int num);
+
+/* SSL_write writes up to |num| bytes from |buf| into |ssl|. It implicitly runs
+ * any pending handshakes, including renegotiations when enabled. On success, it
+ * returns the number of bytes read. Otherwise, it returns <= 0. The caller
+ * should pass the value into |SSL_get_error| to determine how to proceed.
+ *
+ * A non-blocking |SSL_write| differs from non-blocking |write| in that a failed
+ * |SSL_write| still commits to the data passed in. When retrying, the caller
+ * must supply the original write buffer (or a larger one containing the
+ * original as a prefix). By default, retries will fail if they also do not
+ * reuse the same |buf| pointer. This may be relaxed with
+ * |SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER|, but the buffer contents still must be
+ * unchanged.
+ *
+ * By default, |SSL_write| will not return success until all |num| bytes are
+ * written. This may be relaxed with |SSL_MODE_ENABLE_PARTIAL_WRITE|. It allows
+ * |SSL_write| to complete with a partial result when only part of the input was
+ * written in a single record.
+ *
+ * TODO(davidben): Ensure 0 is only returned on transport EOF.
+ * https://crbug.com/466303. */
+OPENSSL_EXPORT int SSL_write(SSL *ssl, const void *buf, int num);
+
+/* SSL_shutdown shuts down |ssl|. On success, it completes in two stages. First,
+ * it returns 0 if |ssl| completed uni-directional shutdown; close_notify has
+ * been sent, but the peer's close_notify has not been received. Most callers
+ * may stop at this point. For bi-directional shutdown, call |SSL_shutdown|
+ * again. It returns 1 if close_notify has been both sent and received.
+ *
+ * If the peer's close_notify arrived first, the first stage is skipped.
+ * |SSL_shutdown| will return 1 once close_notify is sent and skip 0. Callers
+ * only interested in uni-directional shutdown must therefore allow for the
+ * first stage returning either 0 or 1.
+ *
+ * |SSL_shutdown| returns -1 on failure. The caller should pass the return value
+ * into |SSL_get_error| to determine how to proceed. If the underlying |BIO| is
+ * non-blocking, both stages may require retry.
+ *
+ * |SSL_shutdown| must be called to retain |ssl|'s session in the session
+ * cache. Use |SSL_CTX_set_quiet_shutdown| to configure |SSL_shutdown| to
+ * neither send nor wait for close_notify but still retain the session.
+ *
+ * TODO(davidben): Is there any point in the session cache interaction? Remove
+ * it? */
+OPENSSL_EXPORT int SSL_shutdown(SSL *ssl);
+
+/* SSL_get_error returns a |SSL_ERROR_*| value for the most recent operation on
+ * |ssl|. It should be called after an operation failed to determine. */
+OPENSSL_EXPORT int SSL_get_error(const SSL *ssl, int ret_code);
+
+/* SSL_ERROR_NONE indicates the operation succeeded. */
+#define SSL_ERROR_NONE 0
+
+/* SSL_ERROR_SSL indicates the operation failed within the library. The caller
+ * may inspect the error queue for more information. */
+#define SSL_ERROR_SSL 1
+
+/* SSL_ERROR_WANT_READ indicates the operation failed attempting to read from
+ * the transport. The caller may retry the operation when the transport is ready
+ * for reading. */
+#define SSL_ERROR_WANT_READ 2
+
+/* SSL_ERROR_WANT_READ indicates the operation failed attempting to write to
+ * the transport. The caller may retry the operation when the transport is ready
+ * for writing. */
+#define SSL_ERROR_WANT_WRITE 3
+
+/* SSL_ERROR_WANT_X509_LOOKUP indicates the operation failed in calling the
+ * |cert_cb| or |client_cert_cb|. The caller may retry the operation when the
+ * callback is ready to return a certificate or one has been configured
+ * externally.
+ *
+ * See also |SSL_CTX_set_cert_cb| and |SSL_CTX_set_client_cert_cb|. */
+#define SSL_ERROR_WANT_X509_LOOKUP 4
+
+/* SSL_ERROR_WANT_SYSCALL indicates the operation failed externally to the
+ * library. The caller should consult the system-specific error mechanism. This
+ * is typically |errno| but may be something custom if using a custom |BIO|. It
+ * may also be signaled if the transport returned EOF, in which case the
+ * operation's return value will be zero. */
+#define SSL_ERROR_SYSCALL 5
+
+/* SSL_ERROR_ZERO_RETURN indicates the operation failed because the connection
+ * was cleanly shut down with a close_notify alert. */
+#define SSL_ERROR_ZERO_RETURN 6
+
+/* SSL_ERROR_WANT_CONNECT indicates the operation failed attempting to connect
+ * the transport (the |BIO| signaled |BIO_RR_CONNECT|). The caller may retry the
+ * operation when the transport is ready. */
+#define SSL_ERROR_WANT_CONNECT 7
+
+/* SSL_ERROR_WANT_ACCEPT indicates the operation failed attempting to accept a
+ * connection from the transport (the |BIO| signaled |BIO_RR_ACCEPT|). The
+ * caller may retry the operation when the transport is ready.
+ *
+ * TODO(davidben): Remove this. It's used by accept BIOs which are bizarre. */
+#define SSL_ERROR_WANT_ACCEPT 8
+
+/* SSL_ERROR_WANT_CHANNEL_ID_LOOKUP indicates the operation failed looking up
+ * the Channel ID key. The caller may retry the operation when |channel_id_cb|
+ * is ready to return a key or one has been configured with
+ * |SSL_set1_tls_channel_id|.
+ *
+ * See also |SSL_CTX_set_channel_id_cb|. */
+#define SSL_ERROR_WANT_CHANNEL_ID_LOOKUP 9
+
+/* SSL_ERROR_PENDING_SESSION indicates the operation failed because the session
+ * lookup callback indicated the session was unavailable. The caller may retry
+ * the operation when lookup has completed.
+ *
+ * See also |SSL_CTX_sess_set_get_cb| and |SSL_magic_pending_session_ptr|. */
+#define SSL_ERROR_PENDING_SESSION 11
+
+/* SSL_ERROR_PENDING_CERTIFICATE indicates the operation failed because the
+ * early callback indicated certificate lookup was incomplete. The caller may
+ * retry the operation when lookup has completed. Note: when the operation is
+ * retried, the early callback will not be called a second time.
+ *
+ * See also |select_certificate_cb| on |SSL_CTX|. */
+#define SSL_ERROR_PENDING_CERTIFICATE 12
+
+/* SSL_ERROR_WANT_PRIVATE_KEY_OPERATION indicates the operation failed because
+ * a private key operation was unfinished. The caller may retry the operation
+ * when the private key operation is complete.
+ *
+ * See also |SSL_set_private_key_method|. */
+#define SSL_ERROR_WANT_PRIVATE_KEY_OPERATION 13
+
/* Protocol versions. */
+#define DTLS1_VERSION_MAJOR 0xfe
#define SSL3_VERSION_MAJOR 0x03
#define SSL3_VERSION 0x0300
@@ -320,6 +487,11 @@ OPENSSL_EXPORT void SSL_set_min_version(SSL *ssl, uint16_t version);
* |version|. */
OPENSSL_EXPORT void SSL_set_max_version(SSL *ssl, uint16_t version);
+/* SSL_version returns the TLS or DTLS protocol version used by |ssl|, which is
+ * one of the |*_VERSION| values. (E.g. |TLS1_2_VERSION|.) Before the version
+ * is negotiated, the result is undefined. */
+OPENSSL_EXPORT int SSL_version(const SSL *ssl);
+
/* Options.
*
@@ -346,41 +518,14 @@ OPENSSL_EXPORT void SSL_set_max_version(SSL *ssl, uint16_t version);
* |BIO|. Instead, the MTU is configured with |SSL_set_mtu|. */
#define SSL_OP_NO_QUERY_MTU 0x00001000L
-/* SSL_OP_NO_TICKET disables session ticket support (RFC 4507). */
+/* SSL_OP_NO_TICKET disables session ticket support (RFC 5077). */
#define SSL_OP_NO_TICKET 0x00004000L
-/* SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION permits unsafe legacy renegotiation
- * without renegotiation_info (RFC 5746) support. */
-#define SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION 0x00040000L
-
/* SSL_OP_CIPHER_SERVER_PREFERENCE configures servers to select ciphers and
* ECDHE curves according to the server's preferences instead of the
* client's. */
#define SSL_OP_CIPHER_SERVER_PREFERENCE 0x00400000L
-/* The following flags toggle individual protocol versions. This is deprecated.
- * Use |SSL_CTX_set_min_version| and |SSL_CTX_set_max_version| instead. */
-#define SSL_OP_NO_SSLv3 0x02000000L
-#define SSL_OP_NO_TLSv1 0x04000000L
-#define SSL_OP_NO_TLSv1_2 0x08000000L
-#define SSL_OP_NO_TLSv1_1 0x10000000L
-#define SSL_OP_NO_DTLSv1 SSL_OP_NO_TLSv1
-#define SSL_OP_NO_DTLSv1_2 SSL_OP_NO_TLSv1_2
-
-/* The following flags do nothing and are included only to make it easier to
- * compile code with BoringSSL. */
-#define SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS 0
-#define SSL_OP_MICROSOFT_SESS_ID_BUG 0
-#define SSL_OP_NETSCAPE_CHALLENGE_BUG 0
-#define SSL_OP_NO_COMPRESSION 0
-#define SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION 0
-#define SSL_OP_NO_SSLv2 0
-#define SSL_OP_SINGLE_DH_USE 0
-#define SSL_OP_SINGLE_ECDH_USE 0
-#define SSL_OP_SSLREF2_REUSE_CERT_TYPE_BUG 0
-#define SSL_OP_TLS_BLOCK_PADDING_BUG 0
-#define SSL_OP_TLS_ROLLBACK_BUG 0
-
/* SSL_CTX_set_options enables all options set in |options| (which should be one
* or more of the |SSL_OP_*| values, ORed together) in |ctx|. It returns a
* bitmask representing the resulting enabled options. */
@@ -434,10 +579,6 @@ OPENSSL_EXPORT uint32_t SSL_get_options(const SSL *ssl);
* in one RTT. See draft-bmoeller-tls-falsestart-01. */
#define SSL_MODE_ENABLE_FALSE_START 0x00000080L
-/* Deprecated: SSL_MODE_HANDSHAKE_CUTTHROUGH is the same as
- * SSL_MODE_ENABLE_FALSE_START. */
-#define SSL_MODE_HANDSHAKE_CUTTHROUGH SSL_MODE_ENABLE_FALSE_START
-
/* SSL_MODE_CBC_RECORD_SPLITTING causes multi-byte CBC records in SSL 3.0 and
* TLS 1.0 to be split in two: the first record will contain a single byte and
* the second will contain the remainder. This effectively randomises the IV and
@@ -451,21 +592,12 @@ OPENSSL_EXPORT uint32_t SSL_get_options(const SSL *ssl);
/* SSL_MODE_SEND_FALLBACK_SCSV sends TLS_FALLBACK_SCSV in the ClientHello.
* To be set only by applications that reconnect with a downgraded protocol
- * version; see https://tools.ietf.org/html/draft-ietf-tls-downgrade-scsv-05
- * for details.
+ * version; see RFC 7507 for details.
*
* DO NOT ENABLE THIS if your application attempts a normal handshake. Only use
- * this in explicit fallback retries, following the guidance in
- * draft-ietf-tls-downgrade-scsv-05. */
+ * this in explicit fallback retries, following the guidance in RFC 7507. */
#define SSL_MODE_SEND_FALLBACK_SCSV 0x00000400L
-/* The following flags do nothing and are included only to make it easier to
- * compile code with BoringSSL. */
-#define SSL_MODE_AUTO_RETRY 0
-#define SSL_MODE_RELEASE_BUFFERS 0
-#define SSL_MODE_SEND_CLIENTHELLO_TIME 0
-#define SSL_MODE_SEND_SERVERHELLO_TIME 0
-
/* SSL_CTX_set_mode enables all modes set in |mode| (which should be one or more
* of the |SSL_MODE_*| values, ORed together) in |ctx|. It returns a bitmask
* representing the resulting enabled modes. */
@@ -495,8 +627,309 @@ OPENSSL_EXPORT uint32_t SSL_clear_mode(SSL *ssl, uint32_t mode);
OPENSSL_EXPORT uint32_t SSL_get_mode(const SSL *ssl);
+/* Configuring certificates and private keys.
+ *
+ * These functions configure the connection's leaf certificate, private key, and
+ * certificate chain. The certificate chain is ordered leaf to root (as sent on
+ * the wire) but does not include the leaf. Both client and server certificates
+ * use these functions.
+ *
+ * Certificates and keys may be configured before the handshake or dynamically
+ * in the early callback and certificate callback. */
+
+/* SSL_CTX_use_certificate sets |ctx|'s leaf certificate to |x509|. It returns
+ * one on success and zero on failure. */
+OPENSSL_EXPORT int SSL_CTX_use_certificate(SSL_CTX *ctx, X509 *x509);
+
+/* SSL_use_certificate sets |ssl|'s leaf certificate to |x509|. It returns one
+ * on success and zero on failure. */
+OPENSSL_EXPORT int SSL_use_certificate(SSL *ssl, X509 *x509);
+
+/* SSL_CTX_use_PrivateKey sets |ctx|'s private key to |pkey|. It returns one on
+ * success and zero on failure. */
+OPENSSL_EXPORT int SSL_CTX_use_PrivateKey(SSL_CTX *ctx, EVP_PKEY *pkey);
+
+/* SSL_use_PrivateKey sets |ssl|'s private key to |pkey|. It returns one on
+ * success and zero on failure. */
+OPENSSL_EXPORT int SSL_use_PrivateKey(SSL *ssl, EVP_PKEY *pkey);
+
+/* SSL_CTX_set0_chain sets |ctx|'s certificate chain, excluding the leaf, to
+ * |chain|. On success, it returns one and takes ownership of |chain|.
+ * Otherwise, it returns zero. */
+OPENSSL_EXPORT int SSL_CTX_set0_chain(SSL_CTX *ctx, STACK_OF(X509) *chain);
+
+/* SSL_CTX_set1_chain sets |ctx|'s certificate chain, excluding the leaf, to
+ * |chain|. It returns one on success and zero on failure. The caller retains
+ * ownership of |chain| and may release it freely. */
+OPENSSL_EXPORT int SSL_CTX_set1_chain(SSL_CTX *ctx, STACK_OF(X509) *chain);
+
+/* SSL_set0_chain sets |ssl|'s certificate chain, excluding the leaf, to
+ * |chain|. On success, it returns one and takes ownership of |chain|.
+ * Otherwise, it returns zero. */
+OPENSSL_EXPORT int SSL_set0_chain(SSL *ssl, STACK_OF(X509) *chain);
+
+/* SSL_set1_chain sets |ssl|'s certificate chain, excluding the leaf, to
+ * |chain|. It returns one on success and zero on failure. The caller retains
+ * ownership of |chain| and may release it freely. */
+OPENSSL_EXPORT int SSL_set1_chain(SSL *ssl, STACK_OF(X509) *chain);
+
+/* SSL_CTX_add0_chain_cert appends |x509| to |ctx|'s certificate chain. On
+ * success, it returns one and takes ownership of |x509|. Otherwise, it returns
+ * zero. */
+OPENSSL_EXPORT int SSL_CTX_add0_chain_cert(SSL_CTX *ctx, X509 *x509);
+
+/* SSL_CTX_add1_chain_cert appends |x509| to |ctx|'s certificate chain. It
+ * returns one on success and zero on failure. The caller retains ownership of
+ * |x509| and may release it freely. */
+OPENSSL_EXPORT int SSL_CTX_add1_chain_cert(SSL_CTX *ctx, X509 *x509);
+
+/* SSL_add0_chain_cert appends |x509| to |ctx|'s certificate chain. On success,
+ * it returns one and takes ownership of |x509|. Otherwise, it returns zero. */
+OPENSSL_EXPORT int SSL_add0_chain_cert(SSL *ssl, X509 *x509);
+
+/* SSL_CTX_add_extra_chain_cert calls |SSL_CTX_add0_chain_cert|. */
+OPENSSL_EXPORT int SSL_CTX_add_extra_chain_cert(SSL_CTX *ctx, X509 *x509);
+
+/* SSL_add1_chain_cert appends |x509| to |ctx|'s certificate chain. It returns
+ * one on success and zero on failure. The caller retains ownership of |x509|
+ * and may release it freely. */
+OPENSSL_EXPORT int SSL_add1_chain_cert(SSL *ssl, X509 *x509);
+
+/* SSL_CTX_clear_chain_certs clears |ctx|'s certificate chain and returns
+ * one. */
+OPENSSL_EXPORT int SSL_CTX_clear_chain_certs(SSL_CTX *ctx);
+
+/* SSL_CTX_clear_extra_chain_certs calls |SSL_CTX_clear_chain_certs|. */
+OPENSSL_EXPORT int SSL_CTX_clear_extra_chain_certs(SSL_CTX *ctx);
+
+/* SSL_clear_chain_certs clears |ssl|'s certificate chain and returns one. */
+OPENSSL_EXPORT int SSL_clear_chain_certs(SSL *ssl);
+
+/* SSL_CTX_set_cert_cb sets a callback that is called to select a certificate.
+ * The callback returns one on success, zero on internal error, and a negative
+ * number on failure or to pause the handshake. If the handshake is paused,
+ * |SSL_get_error| will return |SSL_ERROR_WANT_X509_LOOKUP|. */
+OPENSSL_EXPORT void SSL_CTX_set_cert_cb(SSL_CTX *ctx,
+ int (*cb)(SSL *ssl, void *arg),
+ void *arg);
+
+/* SSL_set_cert_cb sets a callback that is called to select a certificate. The
+ * callback returns one on success, zero on internal error, and a negative
+ * number on failure or to pause the handshake. If the handshake is paused,
+ * |SSL_get_error| will return |SSL_ERROR_WANT_X509_LOOKUP|. */
+OPENSSL_EXPORT void SSL_set_cert_cb(SSL *ssl, int (*cb)(SSL *ssl, void *arg),
+ void *arg);
+
+/* SSL_certs_clear resets the private key, leaf certificate, and certificate
+ * chain of |ssl|. */
+OPENSSL_EXPORT void SSL_certs_clear(SSL *ssl);
+
+/* SSL_CTX_check_private_key returns one if the certificate and private key
+ * configured in |ctx| are consistent and zero otherwise. */
+OPENSSL_EXPORT int SSL_CTX_check_private_key(const SSL_CTX *ctx);
+
+/* SSL_check_private_key returns one if the certificate and private key
+ * configured in |ssl| are consistent and zero otherwise. */
+OPENSSL_EXPORT int SSL_check_private_key(const SSL *ssl);
+
+/* SSL_CTX_get0_certificate returns |ctx|'s leaf certificate. */
+OPENSSL_EXPORT X509 *SSL_CTX_get0_certificate(const SSL_CTX *ctx);
+
+/* SSL_get_certificate returns |ssl|'s leaf certificate. */
+OPENSSL_EXPORT X509 *SSL_get_certificate(const SSL *ssl);
+
+/* SSL_CTX_get0_privatekey returns |ctx|'s private key. */
+OPENSSL_EXPORT EVP_PKEY *SSL_CTX_get0_privatekey(const SSL_CTX *ctx);
+
+/* SSL_get_privatekey returns |ssl|'s private key. */
+OPENSSL_EXPORT EVP_PKEY *SSL_get_privatekey(const SSL *ssl);
+
+/* SSL_CTX_get0_chain_certs sets |*out_chain| to |ctx|'s certificate chain and
+ * returns one. */
+OPENSSL_EXPORT int SSL_CTX_get0_chain_certs(const SSL_CTX *ctx,
+ STACK_OF(X509) **out_chain);
+
+/* SSL_CTX_get_extra_chain_certs calls |SSL_CTX_get0_chain_certs|. */
+OPENSSL_EXPORT int SSL_CTX_get_extra_chain_certs(const SSL_CTX *ctx,
+ STACK_OF(X509) **out_chain);
+
+/* SSL_get0_chain_certs sets |*out_chain| to |ssl|'s certificate chain and
+ * returns one. */
+OPENSSL_EXPORT int SSL_get0_chain_certs(const SSL *ssl,
+ STACK_OF(X509) **out_chain);
+
+/* SSL_CTX_set_signed_cert_timestamp_list sets the list of signed certificate
+ * timestamps that is sent to clients that request it. The |list| argument must
+ * contain one or more SCT structures serialised as a SignedCertificateTimestamp
+ * List (see https://tools.ietf.org/html/rfc6962#section-3.3) – i.e. each SCT
+ * is prefixed by a big-endian, uint16 length and the concatenation of one or
+ * more such prefixed SCTs are themselves also prefixed by a uint16 length. It
+ * returns one on success and zero on error. The caller retains ownership of
+ * |list|. */
+OPENSSL_EXPORT int SSL_CTX_set_signed_cert_timestamp_list(SSL_CTX *ctx,
+ const uint8_t *list,
+ size_t list_len);
+
+/* SSL_CTX_set_ocsp_response sets the OCSP reponse that is sent to clients
+ * which request it. It returns one on success and zero on error. The caller
+ * retains ownership of |response|. */
+OPENSSL_EXPORT int SSL_CTX_set_ocsp_response(SSL_CTX *ctx,
+ const uint8_t *response,
+ size_t response_len);
+
+/* SSL_set_private_key_digest_prefs copies |num_digests| NIDs from |digest_nids|
+ * into |ssl|. These digests will be used, in decreasing order of preference,
+ * when signing with |ssl|'s private key. It returns one on success and zero on
+ * error. */
+OPENSSL_EXPORT int SSL_set_private_key_digest_prefs(SSL *ssl,
+ const int *digest_nids,
+ size_t num_digests);
+
+
+/* Certificate and private key convenience functions. */
+
+/* SSL_CTX_use_RSAPrivateKey sets |ctx|'s private key to |rsa|. It returns one
+ * on success and zero on failure. */
+OPENSSL_EXPORT int SSL_CTX_use_RSAPrivateKey(SSL_CTX *ctx, RSA *rsa);
+
+/* SSL_use_RSAPrivateKey sets |ctx|'s private key to |rsa|. It returns one on
+ * success and zero on failure. */
+OPENSSL_EXPORT int SSL_use_RSAPrivateKey(SSL *ssl, RSA *rsa);
+
+/* The following functions configure certificates or private keys but take as
+ * input DER-encoded structures. They return one on success and zero on
+ * failure. */
+
+OPENSSL_EXPORT int SSL_CTX_use_certificate_ASN1(SSL_CTX *ctx, int len,
+ const uint8_t *d);
+OPENSSL_EXPORT int SSL_use_certificate_ASN1(SSL *ssl, const uint8_t *der,
+ int len);
+
+OPENSSL_EXPORT int SSL_CTX_use_PrivateKey_ASN1(int pk, SSL_CTX *ctx,
+ const uint8_t *d, long len);
+OPENSSL_EXPORT int SSL_use_PrivateKey_ASN1(int type, SSL *ssl,
+ const uint8_t *d, long len);
+
+OPENSSL_EXPORT int SSL_CTX_use_RSAPrivateKey_ASN1(SSL_CTX *ctx,
+ const uint8_t *der,
+ size_t der_len);
+OPENSSL_EXPORT int SSL_use_RSAPrivateKey_ASN1(SSL *ssl, const uint8_t *der,
+ size_t der_len);
+
+/* The following functions configure certificates or private keys but take as
+ * input files to read from. They return one on success and zero on failure. The
+ * |type| parameter is one of the |SSL_FILETYPE_*| values and determines whether
+ * the file's contents are read as PEM or DER. */
+
+#define SSL_FILETYPE_ASN1 X509_FILETYPE_ASN1
+#define SSL_FILETYPE_PEM X509_FILETYPE_PEM
+
+OPENSSL_EXPORT int SSL_CTX_use_RSAPrivateKey_file(SSL_CTX *ctx,
+ const char *file,
+ int type);
+OPENSSL_EXPORT int SSL_use_RSAPrivateKey_file(SSL *ssl, const char *file,
+ int type);
+
+OPENSSL_EXPORT int SSL_CTX_use_certificate_file(SSL_CTX *ctx, const char *file,
+ int type);
+OPENSSL_EXPORT int SSL_use_certificate_file(SSL *ssl, const char *file,
+ int type);
+
+OPENSSL_EXPORT int SSL_CTX_use_PrivateKey_file(SSL_CTX *ctx, const char *file,
+ int type);
+OPENSSL_EXPORT int SSL_use_PrivateKey_file(SSL *ssl, const char *file,
+ int type);
+
+/* SSL_CTX_use_certificate_file configures certificates for |ctx|. It reads the
+ * contents of |file| as a PEM-encoded leaf certificate followed optionally by
+ * the certificate chain to send to the peer. It returns one on success and zero
+ * on failure. */
+OPENSSL_EXPORT int SSL_CTX_use_certificate_chain_file(SSL_CTX *ctx,
+ const char *file);
+
+/* SSL_CTX_set_default_passwd_cb sets the password callback for PEM-based
+ * convenience functions called on |ctx|. */
+OPENSSL_EXPORT void SSL_CTX_set_default_passwd_cb(SSL_CTX *ctx,
+ pem_password_cb *cb);
+
+/* SSL_CTX_set_default_passwd_cb_userdata sets the userdata parameter for
+ * |ctx|'s password callback. */
+OPENSSL_EXPORT void SSL_CTX_set_default_passwd_cb_userdata(SSL_CTX *ctx,
+ void *data);
+
+
+/* Custom private keys. */
+
+enum ssl_private_key_result_t {
+ ssl_private_key_success,
+ ssl_private_key_retry,
+ ssl_private_key_failure,
+};
+
+/* SSL_PRIVATE_KEY_METHOD describes private key hooks. This is used to off-load
+ * signing operations to a custom, potentially asynchronous, backend. */
+typedef struct ssl_private_key_method_st {
+ /* type returns either |EVP_PKEY_RSA| or |EVP_PKEY_EC| to denote the type of
+ * key used by |ssl|. */
+ int (*type)(SSL *ssl);
+
+ /* max_signature_len returns the maximum length of a signature signed by the
+ * key used by |ssl|. This must be a constant value for a given |ssl|. */
+ size_t (*max_signature_len)(SSL *ssl);
+
+ /* sign signs |in_len| bytes of digest from |in|. |md| is the hash function
+ * used to calculate |in|. On success, it returns |ssl_private_key_success|
+ * and writes at most |max_out| bytes of signature data to |out|. On failure,
+ * it returns |ssl_private_key_failure|. If the operation has not completed,
+ * it returns |ssl_private_key_retry|. |sign| should arrange for the
+ * high-level operation on |ssl| to be retried when the operation is
+ * completed. This will result in a call to |sign_complete|.
+ *
+ * If the key is an RSA key, implementations must use PKCS#1 padding. |in| is
+ * the digest itself, so the DigestInfo prefix, if any, must be prepended by
+ * |sign|. If |md| is |EVP_md5_sha1|, there is no prefix.
+ *
+ * It is an error to call |sign| while another private key operation is in
+ * progress on |ssl|. */
+ enum ssl_private_key_result_t (*sign)(SSL *ssl, uint8_t *out, size_t *out_len,
+ size_t max_out, const EVP_MD *md,
+ const uint8_t *in, size_t in_len);
+
+ /* sign_complete completes a pending |sign| operation. If the operation has
+ * completed, it returns |ssl_private_key_success| and writes the result to
+ * |out| as in |sign|. Otherwise, it returns |ssl_private_key_failure| on
+ * failure and |ssl_private_key_retry| if the operation is still in progress.
+ *
+ * |sign_complete| may be called arbitrarily many times before completion, but
+ * it is an error to call |sign_complete| if there is no pending |sign|
+ * operation in progress on |ssl|. */
+ enum ssl_private_key_result_t (*sign_complete)(SSL *ssl, uint8_t *out,
+ size_t *out_len, size_t max_out);
+} SSL_PRIVATE_KEY_METHOD;
+
+/* SSL_set_private_key_method configures a custom private key on |ssl|.
+ * |key_method| must remain valid for the lifetime of |ssl|. */
+OPENSSL_EXPORT void SSL_set_private_key_method(
+ SSL *ssl, const SSL_PRIVATE_KEY_METHOD *key_method);
+
+
/* Connection information. */
+/* SSL_get_peer_certificate returns the peer's leaf certificate or NULL if the
+ * peer did not use certificates. The caller must call |X509_free| on the
+ * result to release it. */
+OPENSSL_EXPORT X509 *SSL_get_peer_certificate(const SSL *ssl);
+
+/* SSL_get_peer_cert_chain returns the peer's certificate chain or NULL if
+ * unavailable or the peer did not use certificates. For historical reasons,
+ * this may not be available if resuming a serialized |SSL_SESSION|. The caller
+ * does not take ownership of the result.
+ *
+ * WARNING: This function behaves differently between client and server. If
+ * |ssl| is a server, the returned chain does not include the leaf certificate.
+ * If a client, it does. */
+OPENSSL_EXPORT STACK_OF(X509) *SSL_get_peer_cert_chain(const SSL *ssl);
+
/* SSL_get_tls_unique writes at most |max_out| bytes of the tls-unique value
* for |ssl| to |out| and sets |*out_len| to the number of bytes written. It
* returns one on success or zero on error. In general |max_out| should be at
@@ -517,9 +950,1217 @@ OPENSSL_EXPORT uint32_t SSL_get_mode(const SSL *ssl);
OPENSSL_EXPORT int SSL_get_tls_unique(const SSL *ssl, uint8_t *out,
size_t *out_len, size_t max_out);
-/* SSL_initial_handshake_complete returns one if the initial handshake has
- * completed and zero otherwise. */
-OPENSSL_EXPORT int SSL_initial_handshake_complete(const SSL *ssl);
+/* SSL_get_extms_support returns one if the Extended Master Secret
+ * extension was negotiated. Otherwise, it returns zero. */
+OPENSSL_EXPORT int SSL_get_extms_support(const SSL *ssl);
+
+/* SSL_get_current_cipher returns the cipher used in the current outgoing
+ * connection state, or NULL if the null cipher is active. */
+OPENSSL_EXPORT const SSL_CIPHER *SSL_get_current_cipher(const SSL *ssl);
+
+/* SSL_session_reused returns one if |ssl| performed an abbreviated handshake
+ * and zero otherwise.
+ *
+ * TODO(davidben): Hammer down the semantics of this API while a handshake,
+ * initial or renego, is in progress. */
+OPENSSL_EXPORT int SSL_session_reused(const SSL *ssl);
+
+/* SSL_get_secure_renegotiation_support returns one if the peer supports secure
+ * renegotiation (RFC 5746) and zero otherwise. */
+OPENSSL_EXPORT int SSL_get_secure_renegotiation_support(const SSL *ssl);
+
+
+/* Custom extensions.
+ *
+ * The custom extension functions allow TLS extensions to be added to
+ * ClientHello and ServerHello messages. */
+
+/* SSL_custom_ext_add_cb is a callback function that is called when the
+ * ClientHello (for clients) or ServerHello (for servers) is constructed. In
+ * the case of a server, this callback will only be called for a given
+ * extension if the ClientHello contained that extension – it's not possible to
+ * inject extensions into a ServerHello that the client didn't request.
+ *
+ * When called, |extension_value| will contain the extension number that is
+ * being considered for addition (so that a single callback can handle multiple
+ * extensions). If the callback wishes to include the extension, it must set
+ * |*out| to point to |*out_len| bytes of extension contents and return one. In
+ * this case, the corresponding |SSL_custom_ext_free_cb| callback will later be
+ * called with the value of |*out| once that data has been copied.
+ *
+ * If the callback does not wish to add an extension it must return zero.
+ *
+ * Alternatively, the callback can abort the connection by setting
+ * |*out_alert_value| to a TLS alert number and returning -1. */
+typedef int (*SSL_custom_ext_add_cb)(SSL *ssl, unsigned extension_value,
+ const uint8_t **out, size_t *out_len,
+ int *out_alert_value, void *add_arg);
+
+/* SSL_custom_ext_free_cb is a callback function that is called by OpenSSL iff
+ * an |SSL_custom_ext_add_cb| callback previously returned one. In that case,
+ * this callback is called and passed the |out| pointer that was returned by
+ * the add callback. This is to free any dynamically allocated data created by
+ * the add callback. */
+typedef void (*SSL_custom_ext_free_cb)(SSL *ssl, unsigned extension_value,
+ const uint8_t *out, void *add_arg);
+
+/* SSL_custom_ext_parse_cb is a callback function that is called by OpenSSL to
+ * parse an extension from the peer: that is from the ServerHello for a client
+ * and from the ClientHello for a server.
+ *
+ * When called, |extension_value| will contain the extension number and the
+ * contents of the extension are |contents_len| bytes at |contents|.
+ *
+ * The callback must return one to continue the handshake. Otherwise, if it
+ * returns zero, a fatal alert with value |*out_alert_value| is sent and the
+ * handshake is aborted. */
+typedef int (*SSL_custom_ext_parse_cb)(SSL *ssl, unsigned extension_value,
+ const uint8_t *contents,
+ size_t contents_len,
+ int *out_alert_value, void *parse_arg);
+
+/* SSL_extension_supported returns one iff OpenSSL internally handles
+ * extensions of type |extension_value|. This can be used to avoid registering
+ * custom extension handlers for extensions that a future version of OpenSSL
+ * may handle internally. */
+OPENSSL_EXPORT int SSL_extension_supported(unsigned extension_value);
+
+/* SSL_CTX_add_client_custom_ext registers callback functions for handling
+ * custom TLS extensions for client connections.
+ *
+ * If |add_cb| is NULL then an empty extension will be added in each
+ * ClientHello. Otherwise, see the comment for |SSL_custom_ext_add_cb| about
+ * this callback.
+ *
+ * The |free_cb| may be NULL if |add_cb| doesn't dynamically allocate data that
+ * needs to be freed.
+ *
+ * It returns one on success or zero on error. It's always an error to register
+ * callbacks for the same extension twice, or to register callbacks for an
+ * extension that OpenSSL handles internally. See |SSL_extension_supported| to
+ * discover, at runtime, which extensions OpenSSL handles internally. */
+OPENSSL_EXPORT int SSL_CTX_add_client_custom_ext(
+ SSL_CTX *ctx, unsigned extension_value, SSL_custom_ext_add_cb add_cb,
+ SSL_custom_ext_free_cb free_cb, void *add_arg,
+ SSL_custom_ext_parse_cb parse_cb, void *parse_arg);
+
+/* SSL_CTX_add_server_custom_ext is the same as
+ * |SSL_CTX_add_client_custom_ext|, but for server connections.
+ *
+ * Unlike on the client side, if |add_cb| is NULL no extension will be added.
+ * The |add_cb|, if any, will only be called if the ClientHello contained a
+ * matching extension. */
+OPENSSL_EXPORT int SSL_CTX_add_server_custom_ext(
+ SSL_CTX *ctx, unsigned extension_value, SSL_custom_ext_add_cb add_cb,
+ SSL_custom_ext_free_cb free_cb, void *add_arg,
+ SSL_custom_ext_parse_cb parse_cb, void *parse_arg);
+
+
+/* Sessions.
+ *
+ * An |SSL_SESSION| represents an SSL session that may be resumed in an
+ * abbreviated handshake. It is reference-counted and immutable. Once
+ * established, an |SSL_SESSION| may be shared by multiple |SSL| objects on
+ * different threads and must not be modified. */
+
+DECLARE_LHASH_OF(SSL_SESSION)
+
+/* SSL_SESSION_new returns a newly-allocated blank |SSL_SESSION| or NULL on
+ * error. This may be useful in writing tests but otherwise should not be
+ * used outside the library. */
+OPENSSL_EXPORT SSL_SESSION *SSL_SESSION_new(void);
+
+/* SSL_SESSION_up_ref, if |session| is not NULL, increments the reference count
+ * of |session|. It then returns |session|. */
+OPENSSL_EXPORT SSL_SESSION *SSL_SESSION_up_ref(SSL_SESSION *session);
+
+/* SSL_SESSION_free decrements the reference count of |session|. If it reaches
+ * zero, all data referenced by |session| and |session| itself are released. */
+OPENSSL_EXPORT void SSL_SESSION_free(SSL_SESSION *session);
+
+/* SSL_SESSION_to_bytes serializes |in| into a newly allocated buffer and sets
+ * |*out_data| to that buffer and |*out_len| to its length. The caller takes
+ * ownership of the buffer and must call |OPENSSL_free| when done. It returns
+ * one on success and zero on error. */
+OPENSSL_EXPORT int SSL_SESSION_to_bytes(const SSL_SESSION *in,
+ uint8_t **out_data, size_t *out_len);
+
+/* SSL_SESSION_to_bytes_for_ticket serializes |in|, but excludes the session
+ * identification information, namely the session ID and ticket. */
+OPENSSL_EXPORT int SSL_SESSION_to_bytes_for_ticket(const SSL_SESSION *in,
+ uint8_t **out_data,
+ size_t *out_len);
+
+/* SSL_SESSION_from_bytes parses |in_len| bytes from |in| as an SSL_SESSION. It
+ * returns a newly-allocated |SSL_SESSION| on success or NULL on error. */
+OPENSSL_EXPORT SSL_SESSION *SSL_SESSION_from_bytes(const uint8_t *in,
+ size_t in_len);
+
+/* SSL_SESSION_get_version returns a string describing the TLS version |session|
+ * was established at. For example, "TLSv1.2" or "SSLv3". */
+OPENSSL_EXPORT const char *SSL_SESSION_get_version(const SSL_SESSION *session);
+
+/* SSL_SESSION_get_id returns a pointer to a buffer containg |session|'s session
+ * ID and sets |*out_len| to its length. */
+OPENSSL_EXPORT const uint8_t *SSL_SESSION_get_id(const SSL_SESSION *session,
+ unsigned *out_len);
+
+/* SSL_SESSION_get_time returns the time at which |session| was established in
+ * seconds since the UNIX epoch. */
+OPENSSL_EXPORT long SSL_SESSION_get_time(const SSL_SESSION *session);
+
+/* SSL_SESSION_get_timeout returns the lifetime of |session| in seconds. */
+OPENSSL_EXPORT long SSL_SESSION_get_timeout(const SSL_SESSION *session);
+
+/* SSL_SESSION_get_key_exchange_info returns a value that describes the
+ * strength of the asymmetric operation that provides confidentiality to
+ * |session|. Its interpretation depends on the operation used. See the
+ * documentation for this value in the |SSL_SESSION| structure. */
+OPENSSL_EXPORT uint32_t SSL_SESSION_get_key_exchange_info(
+ const SSL_SESSION *session);
+
+/* SSL_SESSION_get0_peer return's the peer leaf certificate stored in
+ * |session|.
+ *
+ * TODO(davidben): This should return a const X509 *. */
+OPENSSL_EXPORT X509 *SSL_SESSION_get0_peer(const SSL_SESSION *session);
+
+/* SSL_SESSION_set_time sets |session|'s creation time to |time| and returns
+ * |time|. This function may be useful in writing tests but otherwise should not
+ * be used. */
+OPENSSL_EXPORT long SSL_SESSION_set_time(SSL_SESSION *session, long time);
+
+/* SSL_SESSION_set_time sets |session|'s timeout to |timeout| and returns one.
+ * This function may be useful in writing tests but otherwise should not be
+ * used. */
+OPENSSL_EXPORT long SSL_SESSION_set_timeout(SSL_SESSION *session, long timeout);
+
+/* SSL_SESSION_set1_id_context sets |session|'s session ID context (see
+ * |SSL_CTX_set_session_id_context|) to |sid_ctx|. It returns one on success and
+ * zero on error. This function may be useful in writing tests but otherwise
+ * should not be used. */
+OPENSSL_EXPORT int SSL_SESSION_set1_id_context(SSL_SESSION *session,
+ const uint8_t *sid_ctx,
+ unsigned sid_ctx_len);
+
+
+/* Session caching.
+ *
+ * Session caching allows clients to reconnect to a server based on saved
+ * parameters from a previous connection.
+ *
+ * For a server, the library implements a built-in internal session cache as an
+ * in-memory hash table. One may also register callbacks to implement a custom
+ * external session cache. An external cache may be used in addition to or
+ * instead of the internal one. Use |SSL_CTX_set_session_cache_mode| to toggle
+ * the internal cache.
+ *
+ * For a client, the only option is an external session cache. Prior to
+ * handshaking, the consumer should look up a session externally (keyed, for
+ * instance, by hostname) and use |SSL_set_session| to configure which session
+ * to offer. The callbacks may be used to determine when new sessions are
+ * available.
+ *
+ * Note that offering or accepting a session short-circuits most parameter
+ * negotiation. Resuming sessions across different configurations may result in
+ * surprising behavor. So, for instance, a client implementing a version
+ * fallback should shard its session cache by maximum protocol version. */
+
+/* SSL_SESS_CACHE_OFF disables all session caching. */
+#define SSL_SESS_CACHE_OFF 0x0000
+
+/* SSL_SESS_CACHE_CLIENT enables session caching for a client.
+ *
+ * TODO(davidben): The internal cache is useless on the client. Always act as if
+ * SSL_SESS_CACHE_NO_INTERNAL is set. https://crbug.com/531194. Also see TODO
+ * attached to |SSL_CTX_sess_set_new_cb|. */
+#define SSL_SESS_CACHE_CLIENT 0x0001
+
+/* SSL_SESS_CACHE_SERVER enables session caching for a server. */
+#define SSL_SESS_CACHE_SERVER 0x0002
+
+/* SSL_SESS_CACHE_SERVER enables session caching for both client and server. */
+#define SSL_SESS_CACHE_BOTH (SSL_SESS_CACHE_CLIENT | SSL_SESS_CACHE_SERVER)
+
+/* SSL_SESS_CACHE_NO_AUTO_CLEAR disables automatically calling
+ * |SSL_CTX_flush_sessions| every 255 connections. */
+#define SSL_SESS_CACHE_NO_AUTO_CLEAR 0x0080
+
+/* SSL_SESS_CACHE_NO_INTERNAL_LOOKUP disables looking up a session from the
+ * internal session cache. */
+#define SSL_SESS_CACHE_NO_INTERNAL_LOOKUP 0x0100
+
+/* SSL_SESS_CACHE_NO_INTERNAL_STORE disables storing sessions in the internal
+ * session cache. */
+#define SSL_SESS_CACHE_NO_INTERNAL_STORE 0x0200
+
+/* SSL_SESS_CACHE_NO_INTERNAL disables the internal session cache. */
+#define SSL_SESS_CACHE_NO_INTERNAL \
+ (SSL_SESS_CACHE_NO_INTERNAL_LOOKUP | SSL_SESS_CACHE_NO_INTERNAL_STORE)
+
+/* SSL_CTX_set_session_cache_mode sets the session cache mode bits for |ctx| to
+ * |mode|. It returns the previous value. */
+OPENSSL_EXPORT int SSL_CTX_set_session_cache_mode(SSL_CTX *ctx, int mode);
+
+/* SSL_CTX_get_session_cache_mode returns the session cache mode bits for
+ * |ctx| */
+OPENSSL_EXPORT int SSL_CTX_get_session_cache_mode(const SSL_CTX *ctx);
+
+ /* SSL_set_session, for a client, configures |ssl| to offer to resume |session|
+ * in the initial handshake. */
+OPENSSL_EXPORT int SSL_set_session(SSL *ssl, SSL_SESSION *session);
+
+/* SSL_get_session returns a non-owning pointer to |ssl|'s session. Prior to the
+ * initial handshake beginning, this is the session to be offered, set by
+ * |SSL_set_session|. After a handshake has finished, this is the currently
+ * active session. Its behavior is undefined while a handshake is progress. */
+OPENSSL_EXPORT SSL_SESSION *SSL_get_session(const SSL *ssl);
+
+/* SSL_get0_session is an alias for |SSL_get_session|. */
+#define SSL_get0_session SSL_get_session
+
+/* SSL_get1_session acts like |SSL_get_session| but returns a new reference to
+ * the session. */
+OPENSSL_EXPORT SSL_SESSION *SSL_get1_session(SSL *ssl);
+
+/* SSL_DEFAULT_SESSION_TIMEOUT is the default lifetime, in seconds, of a
+ * session. */
+#define SSL_DEFAULT_SESSION_TIMEOUT (2 * 60 * 60)
+
+/* SSL_CTX_set_timeout sets the lifetime, in seconds, of sessions created in
+ * |ctx| to |timeout|. */
+OPENSSL_EXPORT long SSL_CTX_set_timeout(SSL_CTX *ctx, long timeout);
+
+/* SSL_CTX_get_timeout returns the lifetime, in seconds, of sessions created in
+ * |ctx|. */
+OPENSSL_EXPORT long SSL_CTX_get_timeout(const SSL_CTX *ctx);
+
+/* SSL_CTX_set_session_id_context sets |ctx|'s session ID context to |sid_ctx|.
+ * It returns one on success and zero on error. The session ID context is an
+ * application-defined opaque byte string. A session will not be used in a
+ * connection without a matching session ID context.
+ *
+ * For a server, if |SSL_VERIFY_PEER| is enabled, it is an error to not set a
+ * session ID context.
+ *
+ * TODO(davidben): Is that check needed? That seems a special case of taking
+ * care not to cross-resume across configuration changes, and this is only
+ * relevant if a server requires client auth. */
+OPENSSL_EXPORT int SSL_CTX_set_session_id_context(SSL_CTX *ctx,
+ const uint8_t *sid_ctx,
+ unsigned sid_ctx_len);
+
+/* SSL_set_session_id_context sets |ssl|'s session ID context to |sid_ctx|. It
+ * returns one on success and zero on error. See also
+ * |SSL_CTX_set_session_id_context|. */
+OPENSSL_EXPORT int SSL_set_session_id_context(SSL *ssl, const uint8_t *sid_ctx,
+ unsigned sid_ctx_len);
+
+/* SSL_SESSION_CACHE_MAX_SIZE_DEFAULT is the default maximum size of a session
+ * cache. */
+#define SSL_SESSION_CACHE_MAX_SIZE_DEFAULT (1024 * 20)
+
+/* SSL_CTX_sess_set_cache_size sets the maximum size of |ctx|'s internal session
+ * cache to |size|. It returns the previous value. */
+OPENSSL_EXPORT unsigned long SSL_CTX_sess_set_cache_size(SSL_CTX *ctx,
+ unsigned long size);
+
+/* SSL_CTX_sess_get_cache_size returns the maximum size of |ctx|'s internal
+ * session cache. */
+OPENSSL_EXPORT unsigned long SSL_CTX_sess_get_cache_size(const SSL_CTX *ctx);
+
+/* SSL_CTX_sessions returns |ctx|'s internal session cache. */
+OPENSSL_EXPORT LHASH_OF(SSL_SESSION) *SSL_CTX_sessions(SSL_CTX *ctx);
+
+/* SSL_CTX_sess_number returns the number of sessions in |ctx|'s internal
+ * session cache. */
+OPENSSL_EXPORT size_t SSL_CTX_sess_number(const SSL_CTX *ctx);
+
+/* SSL_CTX_add_session inserts |session| into |ctx|'s internal session cache. It
+ * returns one on success and zero on error or if |ctx| already included a
+ * session with that session ID. The caller retains its reference to
+ * |session|. */
+OPENSSL_EXPORT int SSL_CTX_add_session(SSL_CTX *ctx, SSL_SESSION *session);
+
+/* SSL_CTX_remove_session removes |session| from |ctx|'s internal session cache.
+ * It returns one on success and zero on error or if no session with a matching
+ * ID was found. */
+OPENSSL_EXPORT int SSL_CTX_remove_session(SSL_CTX *ctx, SSL_SESSION *session);
+
+/* SSL_CTX_flush_sessions removes all sessions from |ctx| which have expired as
+ * of time |time|. If |time| is zero, all sessions are removed. */
+OPENSSL_EXPORT void SSL_CTX_flush_sessions(SSL_CTX *ctx, long time);
+
+/* SSL_CTX_sess_set_new_cb sets the callback to be called when a new session is
+ * established and ready to be cached. If the session cache is disabled (the
+ * appropriate one of |SSL_SESS_CACHE_CLIENT| or |SSL_SESS_CACHE_SERVER| is
+ * unset), the callback is not called.
+ *
+ * The callback is passed a reference to |session|. It returns one if it takes
+ * ownership and zero otherwise.
+ *
+ * Note: For a client, the callback may be called on abbreviated handshakes if a
+ * ticket is renewed. Further, it may not be called until some time after
+ * |SSL_do_handshake| or |SSL_connect| completes if False Start is enabled. Thus
+ * it's recommended to use this callback over checking |SSL_session_reused| on
+ * handshake completion.
+ *
+ * TODO(davidben): Conditioning callbacks on |SSL_SESS_CACHE_CLIENT| or
+ * |SSL_SESS_CACHE_SERVER| doesn't make any sense when one could just as easily
+ * not supply the callbacks. Removing that condition and the client internal
+ * cache would simplify things. */
+OPENSSL_EXPORT void SSL_CTX_sess_set_new_cb(
+ SSL_CTX *ctx, int (*new_session_cb)(SSL *ssl, SSL_SESSION *session));
+
+/* SSL_CTX_sess_get_new_cb returns the callback set by
+ * |SSL_CTX_sess_set_new_cb|. */
+OPENSSL_EXPORT int (*SSL_CTX_sess_get_new_cb(SSL_CTX *ctx))(
+ SSL *ssl, SSL_SESSION *session);
+
+/* SSL_CTX_sess_set_remove_cb sets a callback which is called when a session is
+ * removed from the internal session cache.
+ *
+ * TODO(davidben): What is the point of this callback? It seems useless since it
+ * only fires on sessions in the internal cache. */
+OPENSSL_EXPORT void SSL_CTX_sess_set_remove_cb(
+ SSL_CTX *ctx,
+ void (*remove_session_cb)(SSL_CTX *ctx, SSL_SESSION *session));
+
+/* SSL_CTX_sess_get_remove_cb returns the callback set by
+ * |SSL_CTX_sess_set_remove_cb|. */
+OPENSSL_EXPORT void (*SSL_CTX_sess_get_remove_cb(SSL_CTX *ctx))(
+ SSL_CTX *ctx, SSL_SESSION *session);
+
+/* SSL_CTX_sess_set_get_cb sets a callback to look up a session by ID for a
+ * server. The callback is passed the session ID and should return a matching
+ * |SSL_SESSION| or NULL if not found. It should set |*out_copy| to zero and
+ * return a new reference to the session. This callback is not used for a
+ * client.
+ *
+ * For historical reasons, if |*out_copy| is set to one (default), the SSL
+ * library will take a new reference to the returned |SSL_SESSION|, expecting
+ * the callback to return a non-owning pointer. This is not recommended. If
+ * |ctx| and thus the callback is used on multiple threads, the session may be
+ * removed and invalidated before the SSL library calls |SSL_SESSION_up_ref|,
+ * whereas the callback may synchronize internally.
+ *
+ * To look up a session asynchronously, the callback may return
+ * |SSL_magic_pending_session_ptr|. See the documentation for that function and
+ * |SSL_ERROR_PENDING_SESSION|.
+ *
+ * If the internal session cache is enabled, the callback is only consulted if
+ * the internal cache does not return a match. */
+OPENSSL_EXPORT void SSL_CTX_sess_set_get_cb(
+ SSL_CTX *ctx,
+ SSL_SESSION *(*get_session_cb)(SSL *ssl, uint8_t *id, int id_len,
+ int *out_copy));
+
+/* SSL_CTX_sess_get_get_cb returns the callback set by
+ * |SSL_CTX_sess_set_get_cb|. */
+OPENSSL_EXPORT SSL_SESSION *(*SSL_CTX_sess_get_get_cb(SSL_CTX *ctx))(
+ SSL *ssl, uint8_t *id, int id_len, int *out_copy);
+
+/* SSL_magic_pending_session_ptr returns a magic |SSL_SESSION|* which indicates
+ * that the session isn't currently unavailable. |SSL_get_error| will then
+ * return |SSL_ERROR_PENDING_SESSION| and the handshake can be retried later
+ * when the lookup has completed. */
+OPENSSL_EXPORT SSL_SESSION *SSL_magic_pending_session_ptr(void);
+
+/* GEN_SESSION_CB is a callback to generate session IDs for |ssl|. It returns
+ * one on success and zero on error. On success, the generated ID is written to
+ * |id| and |*id_len| set to the length. On entry, |*id_len| is the maximum
+ * length of the ID, but the callback may shorten it if desired. It is an error
+ * for the callback to set the size to zero.
+ *
+ * Callbacks may use |SSL_has_matching_session_id| to check that the generated
+ * ID is unique. */
+typedef int (*GEN_SESSION_CB)(const SSL *ssl, uint8_t *id, unsigned *id_len);
+
+/* SSL_CTX_set_generate_session_id sets the session ID callback of |ctx| to
+ * |cb| and returns one. It will be called on the server when establishing a new
+ * session. */
+OPENSSL_EXPORT int SSL_CTX_set_generate_session_id(SSL_CTX *ctx,
+ GEN_SESSION_CB cb);
+
+/* SSL_set_generate_session_id sets the session ID callback of |ssl| to |cb| and
+ * returns one. It will be called on the server when establishing a new
+ * session. */
+OPENSSL_EXPORT int SSL_set_generate_session_id(SSL *ssl, GEN_SESSION_CB cb);
+
+/* SSL_has_matching_session_id returns one if |ssl|'s session cache has a
+ * session of value |id| and zero otherwise. */
+OPENSSL_EXPORT int SSL_has_matching_session_id(const SSL *ssl,
+ const uint8_t *id,
+ unsigned id_len);
+
+
+/* Session tickets.
+ *
+ * Session tickets, from RFC 5077, allow session resumption without server-side
+ * state. Session tickets are supported in by default but may be disabled with
+ * |SSL_OP_NO_TICKET|.
+ *
+ * On the client, ticket-based sessions use the same APIs as ID-based tickets.
+ * Callers do not need to handle them differently.
+ *
+ * On the server, tickets are encrypted and authenticated with a secret key. By
+ * default, an |SSL_CTX| generates a key on creation. Tickets are minted and
+ * processed transparently. The following functions may be used to configure a
+ * persistent key or implement more custom behavior. */
+
+/* SSL_CTX_get_tlsext_ticket_keys writes |ctx|'s session ticket key material to
+ * |len| bytes of |out|. It returns one on success and zero if |len| is not
+ * 48. If |out| is NULL, it returns 48 instead. */
+OPENSSL_EXPORT int SSL_CTX_get_tlsext_ticket_keys(SSL_CTX *ctx, void *out,
+ size_t len);
+
+/* SSL_CTX_set_tlsext_ticket_keys sets |ctx|'s session ticket key material to
+ * |len| bytes of |in|. It returns one on success and zero if |len| is not
+ * 48. If |in| is NULL, it returns 48 instead. */
+OPENSSL_EXPORT int SSL_CTX_set_tlsext_ticket_keys(SSL_CTX *ctx, const void *in,
+ size_t len);
+
+/* SSL_TICKET_KEY_NAME_LEN is the length of the key name prefix of a session
+ * ticket. */
+#define SSL_TICKET_KEY_NAME_LEN 16
+
+/* SSL_CTX_set_tlsext_ticket_key_cb sets the ticket callback to |callback| and
+ * returns one. |callback| will be called when encrypting a new ticket and when
+ * decrypting a ticket from the client.
+ *
+ * In both modes, |ctx| and |hmac_ctx| will already have been initialized with
+ * |EVP_CIPHER_CTX_init| and |HMAC_CTX_init|, respectively. |callback|
+ * configures |hmac_ctx| with an HMAC digest and key, and configures |ctx|
+ * for encryption or decryption, based on the mode.
+ *
+ * When encrypting a new ticket, |encrypt| will be one. It writes a public
+ * 16-byte key name to |key_name| and a fresh IV to |iv|. The output IV length
+ * must match |EVP_CIPHER_CTX_iv_length| of the cipher selected. In this mode,
+ * |callback| returns 1 on success and -1 on error.
+ *
+ * When decrypting a ticket, |encrypt| will be zero. |key_name| will point to a
+ * 16-byte key name and |iv| points to an IV. The length of the IV consumed must
+ * match |EVP_CIPHER_CTX_iv_length| of the cipher selected. In this mode,
+ * |callback| returns -1 to abort the handshake, 0 if decrypting the ticket
+ * failed, and 1 or 2 on success. If it returns 2, the ticket will be renewed.
+ * This may be used to re-key the ticket.
+ *
+ * WARNING: |callback| wildly breaks the usual return value convention and is
+ * called in two different modes. */
+OPENSSL_EXPORT int SSL_CTX_set_tlsext_ticket_key_cb(
+ SSL_CTX *ctx, int (*callback)(SSL *ssl, uint8_t *key_name, uint8_t *iv,
+ EVP_CIPHER_CTX *ctx, HMAC_CTX *hmac_ctx,
+ int encrypt));
+
+
+/* Elliptic curve Diffie-Hellman.
+ *
+ * Cipher suites using an ECDHE key exchange perform Diffie-Hellman over an
+ * elliptic curve negotiated by both endpoints. See RFC 4492. Only named curves
+ * are supported. ECDHE is always enabled, but the curve preferences may be
+ * configured with these functions.
+ *
+ * A client may use |SSL_SESSION_get_key_exchange_info| to determine the curve
+ * selected. */
+
+/* SSL_CTX_set1_curves sets the preferred curves for |ctx| to be |curves|. Each
+ * element of |curves| should be a curve nid. It returns one on success and
+ * zero on failure. */
+OPENSSL_EXPORT int SSL_CTX_set1_curves(SSL_CTX *ctx, const int *curves,
+ size_t curves_len);
+
+/* SSL_set1_curves sets the preferred curves for |ssl| to be |curves|. Each
+ * element of |curves| should be a curve nid. It returns one on success and
+ * zero on failure. */
+OPENSSL_EXPORT int SSL_set1_curves(SSL *ssl, const int *curves,
+ size_t curves_len);
+
+/* SSL_CTX_set_tmp_ecdh configures |ctx| to use the curve from |ecdh| as the
+ * curve for ephemeral ECDH keys. For historical reasons, this API expects an
+ * |EC_KEY|, but only the curve is used. It returns one on success and zero on
+ * error. If unset, an appropriate curve will be chosen based on curve
+ * preferences. (This is recommended.) */
+OPENSSL_EXPORT int SSL_CTX_set_tmp_ecdh(SSL_CTX *ctx, const EC_KEY *ec_key);
+
+/* SSL_set_tmp_ecdh configures |ssl| to use the curve from |ecdh| as the curve
+ * for ephemeral ECDH keys. For historical reasons, this API expects an
+ * |EC_KEY|, but only the curve is used. It returns one on success and zero on
+ * error. If unset, an appropriate curve will be chosen based on curve
+ * preferences. (This is recommended.) */
+OPENSSL_EXPORT int SSL_set_tmp_ecdh(SSL *ssl, const EC_KEY *ec_key);
+
+/* SSL_CTX_set_tmp_ecdh_callback configures |ctx| to use |callback| to determine
+ * the curve for ephemeral ECDH keys. |callback| should ignore |is_export| and
+ * |keylength| and return an |EC_KEY| of the selected curve or NULL on
+ * error. Only the curve is used, so the |EC_KEY| needn't have a generated
+ * keypair.
+ *
+ * If the callback is unset, an appropriate curve will be chosen based on curve
+ * preferences. (This is recommended.)
+ *
+ * WARNING: The caller does not take ownership of the resulting |EC_KEY|, so
+ * |callback| must save and release the object elsewhere. */
+OPENSSL_EXPORT void SSL_CTX_set_tmp_ecdh_callback(
+ SSL_CTX *ctx, EC_KEY *(*callback)(SSL *ssl, int is_export, int keylength));
+
+/* SSL_set_tmp_ecdh_callback configures |ssl| to use |callback| to determine the
+ * curve for ephemeral ECDH keys. |callback| should ignore |is_export| and
+ * |keylength| and return an |EC_KEY| of the selected curve or NULL on
+ * error. Only the curve is used, so the |EC_KEY| needn't have a generated
+ * keypair.
+ *
+ * If the callback is unset, an appropriate curve will be chosen based on curve
+ * preferences. (This is recommended.)
+ *
+ * WARNING: The caller does not take ownership of the resulting |EC_KEY|, so
+ * |callback| must save and release the object elsewhere. */
+OPENSSL_EXPORT void SSL_set_tmp_ecdh_callback(
+ SSL *ssl, EC_KEY *(*callback)(SSL *ssl, int is_export, int keylength));
+
+/* SSL_get_curve_name returns a human-readable name for the elliptic curve
+ * specified by the given TLS curve id, or NULL if the curve if unknown. */
+OPENSSL_EXPORT const char *SSL_get_curve_name(uint16_t curve_id);
+
+
+/* Multiplicative Diffie-Hellman.
+ *
+ * Cipher suites using a DHE key exchange perform Diffie-Hellman over a
+ * multiplicative group selected by the server. These ciphers are disabled for a
+ * server unless a group is chosen with one of these functions.
+ *
+ * A client may use |SSL_SESSION_get_key_exchange_info| to determine the size of
+ * the selected group's prime, but note that servers may select degenerate
+ * groups. */
+
+/* SSL_CTX_set_tmp_dh configures |ctx| to use the group from |dh| as the group
+ * for DHE. Only the group is used, so |dh| needn't have a keypair. It returns
+ * one on success and zero on error. */
+OPENSSL_EXPORT int SSL_CTX_set_tmp_dh(SSL_CTX *ctx, const DH *dh);
+
+/* SSL_set_tmp_dh configures |ssl| to use the group from |dh| as the group for
+ * DHE. Only the group is used, so |dh| needn't have a keypair. It returns one
+ * on success and zero on error. */
+OPENSSL_EXPORT int SSL_set_tmp_dh(SSL *ssl, const DH *dh);
+
+/* SSL_CTX_set_tmp_dh_callback configures |ctx| to use |callback| to determine
+ * the group for DHE ciphers. |callback| should ignore |is_export| and
+ * |keylength| and return a |DH| of the selected group or NULL on error. Only
+ * the parameters are used, so the |DH| needn't have a generated keypair.
+ *
+ * WARNING: The caller does not take ownership of the resulting |DH|, so
+ * |callback| must save and release the object elsewhere. */
+OPENSSL_EXPORT void SSL_CTX_set_tmp_dh_callback(
+ SSL_CTX *ctx, DH *(*callback)(SSL *ssl, int is_export, int keylength));
+
+/* SSL_set_tmp_dh_callback configures |ssl| to use |callback| to determine the
+ * group for DHE ciphers. |callback| should ignore |is_export| and |keylength|
+ * and return a |DH| of the selected group or NULL on error. Only the
+ * parameters are used, so the |DH| needn't have a generated keypair.
+ *
+ * WARNING: The caller does not take ownership of the resulting |DH|, so
+ * |callback| must save and release the object elsewhere. */
+OPENSSL_EXPORT void SSL_set_tmp_dh_callback(SSL *ssl,
+ DH *(*dh)(SSL *ssl, int is_export,
+ int keylength));
+
+
+/* Certificate verification.
+ *
+ * SSL may authenticate either endpoint with an X.509 certificate. Typically
+ * this is used to authenticate the server to the client. These functions
+ * configure certificate verification.
+ *
+ * WARNING: By default, certificate verification errors on a client are not
+ * fatal. See |SSL_VERIFY_NONE| This may be configured with
+ * |SSL_CTX_set_verify|.
+ *
+ * By default clients are anonymous but a server may request a certificate from
+ * the client by setting |SSL_VERIFY_PEER|.
+ *
+ * Many of these functions use OpenSSL's legacy X.509 stack which is
+ * underdocumented and deprecated, but the replacement isn't ready yet. For
+ * now, consumers may use the existing stack or bypass it by performing
+ * certificate verification externally. This may be done with
+ * |SSL_CTX_set_cert_verify_callback| or by extracting the chain with
+ * |SSL_get_peer_cert_chain| after the handshake. In the future, functions will
+ * be added to use the SSL stack without depending on any part of the legacy
+ * X.509 and ASN.1 stack. */
+
+/* SSL_VERIFY_NONE, on a client, verifies the server certificate but does not
+ * make errors fatal. The result may be checked with |SSL_get_verify_result|. On
+ * a server it does not request a client certificate. This is the default. */
+#define SSL_VERIFY_NONE 0x00
+
+/* SSL_VERIFY_PEER, on a client, makes server certificate errors fatal. On a
+ * server it requests a client certificate and makes errors fatal. However,
+ * anonymous clients are still allowed. See
+ * |SSL_VERIFY_FAIL_IF_NO_PEER_CERT|. */
+#define SSL_VERIFY_PEER 0x01
+
+/* SSL_VERIFY_FAIL_IF_NO_PEER_CERT configures a server to reject connections if
+ * the client declines to send a certificate. Otherwise |SSL_VERIFY_PEER| still
+ * allows anonymous clients. */
+#define SSL_VERIFY_FAIL_IF_NO_PEER_CERT 0x02
+
+/* SSL_VERIFY_PEER_IF_NO_OBC configures a server to request a client certificate
+ * if and only if Channel ID is not negotiated. */
+#define SSL_VERIFY_PEER_IF_NO_OBC 0x04
+
+/* SSL_CTX_set_verify configures certificate verification behavior. |mode| is
+ * one of the |SSL_VERIFY_*| values defined above. |callback|, if not NULL, is
+ * used to customize certificate verification. See the behavior of
+ * |X509_STORE_CTX_set_verify_cb|.
+ *
+ * The callback may use |SSL_get_ex_data_X509_STORE_CTX_idx| with
+ * |X509_STORE_CTX_get_ex_data| to look up the |SSL| from |store_ctx|. */
+OPENSSL_EXPORT void SSL_CTX_set_verify(
+ SSL_CTX *ctx, int mode, int (*callback)(int ok, X509_STORE_CTX *store_ctx));
+
+/* SSL_set_verify configures certificate verification behavior. |mode| is one of
+ * the |SSL_VERIFY_*| values defined above. |callback|, if not NULL, is used to
+ * customize certificate verification. See the behavior of
+ * |X509_STORE_CTX_set_verify_cb|.
+ *
+ * The callback may use |SSL_get_ex_data_X509_STORE_CTX_idx| with
+ * |X509_STORE_CTX_get_ex_data| to look up the |SSL| from |store_ctx|. */
+OPENSSL_EXPORT void SSL_set_verify(SSL *ssl, int mode,
+ int (*callback)(int ok,
+ X509_STORE_CTX *store_ctx));
+
+/* SSL_CTX_get_verify_mode returns |ctx|'s verify mode, set by
+ * |SSL_CTX_set_verify|. */
+OPENSSL_EXPORT int SSL_CTX_get_verify_mode(const SSL_CTX *ctx);
+
+/* SSL_get_verify_mode returns |ssl|'s verify mode, set by |SSL_CTX_set_verify|
+ * or |SSL_set_verify|. */
+OPENSSL_EXPORT int SSL_get_verify_mode(const SSL *ssl);
+
+/* SSL_CTX_get_verify_callback returns the callback set by
+ * |SSL_CTX_set_verify|. */
+OPENSSL_EXPORT int (*SSL_CTX_get_verify_callback(const SSL_CTX *ctx))(
+ int ok, X509_STORE_CTX *store_ctx);
+
+/* SSL_get_verify_callback returns the callback set by |SSL_CTX_set_verify| or
+ * |SSL_set_verify|. */
+OPENSSL_EXPORT int (*SSL_get_verify_callback(const SSL *ssl))(
+ int ok, X509_STORE_CTX *store_ctx);
+
+/* SSL_CTX_set_verify_depth sets the maximum depth of a certificate chain
+ * accepted in verification. This number does not include the leaf, so a depth
+ * of 1 allows the leaf and one CA certificate. */
+OPENSSL_EXPORT void SSL_CTX_set_verify_depth(SSL_CTX *ctx, int depth);
+
+/* SSL_set_verify_depth sets the maximum depth of a certificate chain accepted
+ * in verification. This number does not include the leaf, so a depth of 1
+ * allows the leaf and one CA certificate. */
+OPENSSL_EXPORT void SSL_set_verify_depth(SSL *ssl, int depth);
+
+/* SSL_CTX_get_verify_depth returns the maximum depth of a certificate accepted
+ * in verification. */
+OPENSSL_EXPORT int SSL_CTX_get_verify_depth(const SSL_CTX *ctx);
+
+/* SSL_get_verify_depth returns the maximum depth of a certificate accepted in
+ * verification. */
+OPENSSL_EXPORT int SSL_get_verify_depth(const SSL *ssl);
+
+/* SSL_CTX_set1_param sets verification parameters from |param|. It returns one
+ * on success and zero on failure. The caller retains ownership of |param|. */
+OPENSSL_EXPORT int SSL_CTX_set1_param(SSL_CTX *ctx,
+ const X509_VERIFY_PARAM *param);
+
+/* SSL_set1_param sets verification parameters from |param|. It returns one on
+ * success and zero on failure. The caller retains ownership of |param|. */
+OPENSSL_EXPORT int SSL_set1_param(SSL *ssl,
+ const X509_VERIFY_PARAM *param);
+
+/* SSL_CTX_get0_param returns |ctx|'s |X509_VERIFY_PARAM| for certificate
+ * verification. The caller must not release the returned pointer but may call
+ * functions on it to configure it. */
+OPENSSL_EXPORT X509_VERIFY_PARAM *SSL_CTX_get0_param(SSL_CTX *ctx);
+
+/* SSL_get0_param returns |ssl|'s |X509_VERIFY_PARAM| for certificate
+ * verification. The caller must not release the returned pointer but may call
+ * functions on it to configure it. */
+OPENSSL_EXPORT X509_VERIFY_PARAM *SSL_get0_param(SSL *ssl);
+
+/* SSL_CTX_set_purpose sets |ctx|'s |X509_VERIFY_PARAM|'s 'purpose' parameter to
+ * |purpose|. It returns one on success and zero on error. */
+OPENSSL_EXPORT int SSL_CTX_set_purpose(SSL_CTX *ctx, int purpose);
+
+/* SSL_set_purpose sets |ssl|'s |X509_VERIFY_PARAM|'s 'purpose' parameter to
+ * |purpose|. It returns one on success and zero on error. */
+OPENSSL_EXPORT int SSL_set_purpose(SSL *ssl, int purpose);
+
+/* SSL_CTX_set_trust sets |ctx|'s |X509_VERIFY_PARAM|'s 'trust' parameter to
+ * |trust|. It returns one on success and zero on error. */
+OPENSSL_EXPORT int SSL_CTX_set_trust(SSL_CTX *ctx, int trust);
+
+/* SSL_set_trust sets |ssl|'s |X509_VERIFY_PARAM|'s 'trust' parameter to
+ * |trust|. It returns one on success and zero on error. */
+OPENSSL_EXPORT int SSL_set_trust(SSL *ssl, int trust);
+
+/* SSL_CTX_set_cert_store sets |ctx|'s certificate store to |store|. It takes
+ * ownership of |store|. The store is used for certificate verification.
+ *
+ * The store is also used for the auto-chaining feature, but this is deprecated.
+ * See also |SSL_MODE_NO_AUTO_CHAIN|. */
+OPENSSL_EXPORT void SSL_CTX_set_cert_store(SSL_CTX *ctx, X509_STORE *store);
+
+/* SSL_CTX_get_cert_store returns |ctx|'s certificate store. */
+OPENSSL_EXPORT X509_STORE *SSL_CTX_get_cert_store(const SSL_CTX *ctx);
+
+/* SSL_CTX_set_default_verify_paths loads the OpenSSL system-default trust
+ * anchors into |ctx|'s store. It returns one on success and zero on failure. */
+OPENSSL_EXPORT int SSL_CTX_set_default_verify_paths(SSL_CTX *ctx);
+
+/* SSL_CTX_load_verify_locations loads trust anchors into |ctx|'s store from
+ * |ca_file| and |ca_dir|, either of which may be NULL. If |ca_file| is passed,
+ * it is opened and PEM-encoded CA certificates are read. If |ca_dir| is passed,
+ * it is treated as a directory in OpenSSL's hashed directory format. It returns
+ * one on success and zero on failure.
+ *
+ * See
+ * https://www.openssl.org/docs/manmaster/ssl/SSL_CTX_load_verify_locations.html
+ * for documentation on the directory format. */
+OPENSSL_EXPORT int SSL_CTX_load_verify_locations(SSL_CTX *ctx,
+ const char *ca_file,
+ const char *ca_dir);
+
+/* SSL_get_verify_result returns the result of certificate verification. It is
+ * either |X509_V_OK| or a |X509_V_ERR_*| value. */
+OPENSSL_EXPORT long SSL_get_verify_result(const SSL *ssl);
+
+/* SSL_set_verify_result overrides the result of certificate verification. */
+OPENSSL_EXPORT void SSL_set_verify_result(SSL *ssl, long result);
+
+/* SSL_get_ex_data_X509_STORE_CTX_idx returns the ex_data index used to look up
+ * the |SSL| associated with an |X509_STORE_CTX| in the verify callback. */
+OPENSSL_EXPORT int SSL_get_ex_data_X509_STORE_CTX_idx(void);
+
+/* SSL_CTX_set_cert_verify_callback sets a custom callback to be called on
+ * certificate verification rather than |X509_verify_cert|. |store_ctx| contains
+ * the verification parameters. The callback should return one on success and
+ * zero on fatal error. It may use |X509_STORE_CTX_set_error| to set a
+ * verification result.
+ *
+ * The callback may use either the |arg| parameter or
+ * |SSL_get_ex_data_X509_STORE_CTX_idx| to recover the associated |SSL|
+ * object. */
+OPENSSL_EXPORT void SSL_CTX_set_cert_verify_callback(
+ SSL_CTX *ctx, int (*callback)(X509_STORE_CTX *store_ctx, void *arg),
+ void *arg);
+
+
+/* Client certificate CA list.
+ *
+ * When requesting a client certificate, a server may advertise a list of
+ * certificate authorities which are accepted. These functions may be used to
+ * configure this list. */
+
+/* SSL_set_client_CA_list sets |ssl|'s client certificate CA list to
+ * |name_list|. It takes ownership of |name_list|. */
+OPENSSL_EXPORT void SSL_set_client_CA_list(SSL *ssl,
+ STACK_OF(X509_NAME) *name_list);
+
+/* SSL_CTX_set_client_CA_list sets |ctx|'s client certificate CA list to
+ * |name_list|. It takes ownership of |name_list|. */
+OPENSSL_EXPORT void SSL_CTX_set_client_CA_list(SSL_CTX *ctx,
+ STACK_OF(X509_NAME) *name_list);
+
+/* SSL_get_client_CA_list returns |ssl|'s client certificate CA list. */
+OPENSSL_EXPORT STACK_OF(X509_NAME) *SSL_get_client_CA_list(const SSL *ssl);
+
+/* SSL_CTX_get_client_CA_list returns |ctx|'s client certificate CA list. */
+OPENSSL_EXPORT STACK_OF(X509_NAME) *
+ SSL_CTX_get_client_CA_list(const SSL_CTX *ctx);
+
+/* SSL_add_client_CA appends |x509|'s subject to the client certificate CA list.
+ * It returns one on success or zero on error. The caller retains ownership of
+ * |x509|. */
+OPENSSL_EXPORT int SSL_add_client_CA(SSL *ssl, X509 *x509);
+
+/* SSL_CTX_add_client_CA appends |x509|'s subject to the client certificate CA
+ * list. It returns one on success or zero on error. The caller retains
+ * ownership of |x509|. */
+OPENSSL_EXPORT int SSL_CTX_add_client_CA(SSL_CTX *ctx, X509 *x509);
+
+/* SSL_load_client_CA_file opens |file| and reads PEM-encoded certificates from
+ * it. It returns a newly-allocated stack of the certificate subjects or NULL
+ * on error. */
+OPENSSL_EXPORT STACK_OF(X509_NAME) *SSL_load_client_CA_file(const char *file);
+
+/* SSL_dup_CA_list makes a deep copy of |list|. It returns the new list on
+ * success or NULL on allocation error. */
+OPENSSL_EXPORT STACK_OF(X509_NAME) *SSL_dup_CA_list(STACK_OF(X509_NAME) *list);
+
+/* SSL_add_file_cert_subjects_to_stack behaves like |SSL_load_client_CA_file|
+ * but appends the result to |out|. It returns one on success or zero on
+ * error. */
+OPENSSL_EXPORT int SSL_add_file_cert_subjects_to_stack(STACK_OF(X509_NAME) *out,
+ const char *file);
+
+/* SSL_add_dir_cert_subjects_to_stack lists files in directory |dir|. It calls
+ * |SSL_add_file_cert_subjects_to_stack| on each file and returns one on success
+ * or zero on error. */
+OPENSSL_EXPORT int SSL_add_dir_cert_subjects_to_stack(STACK_OF(X509_NAME) *out,
+ const char *dir);
+
+
+/* Application-layer protocol negotation.
+ *
+ * The ALPN extension (RFC 7301) allows negotiating different application-layer
+ * protocols over a single port. This is used, for example, to negotiate
+ * HTTP/2. */
+
+/* SSL_CTX_set_alpn_protos sets the client ALPN protocol list on |ctx| to
+ * |protos|. |protos| must be in wire-format (i.e. a series of non-empty, 8-bit
+ * length-prefixed strings). It returns zero on success and one on failure.
+ * Configuring this list enables ALPN on a client.
+ *
+ * WARNING: this function is dangerous because it breaks the usual return value
+ * convention. */
+OPENSSL_EXPORT int SSL_CTX_set_alpn_protos(SSL_CTX *ctx, const uint8_t *protos,
+ unsigned protos_len);
+
+/* SSL_set_alpn_protos sets the client ALPN protocol list on |ssl| to |protos|.
+ * |protos| must be in wire-format (i.e. a series of non-empty, 8-bit
+ * length-prefixed strings). It returns zero on success and one on failure.
+ * Configuring this list enables ALPN on a client.
+ *
+ * WARNING: this function is dangerous because it breaks the usual return value
+ * convention. */
+OPENSSL_EXPORT int SSL_set_alpn_protos(SSL *ssl, const uint8_t *protos,
+ unsigned protos_len);
+
+/* SSL_CTX_set_alpn_select_cb sets a callback function on |ctx| that is called
+ * during ClientHello processing in order to select an ALPN protocol from the
+ * client's list of offered protocols. Configuring this callback enables ALPN on
+ * a server.
+ *
+ * The callback is passed a wire-format (i.e. a series of non-empty, 8-bit
+ * length-prefixed strings) ALPN protocol list in |in|. It should set |*out| and
+ * |*out_len| to the selected protocol and return |SSL_TLSEXT_ERR_OK| on
+ * success. It does not pass ownership of the buffer. Otherwise, it should
+ * return |SSL_TLSEXT_ERR_NOACK|. Other |SSL_TLSEXT_ERR_*| values are
+ * unimplemented and will be treated as |SSL_TLSEXT_ERR_NOACK|. */
+OPENSSL_EXPORT void SSL_CTX_set_alpn_select_cb(
+ SSL_CTX *ctx, int (*cb)(SSL *ssl, const uint8_t **out, uint8_t *out_len,
+ const uint8_t *in, unsigned in_len, void *arg),
+ void *arg);
+
+/* SSL_get0_alpn_selected gets the selected ALPN protocol (if any) from |ssl|.
+ * On return it sets |*out_data| to point to |*out_len| bytes of protocol name
+ * (not including the leading length-prefix byte). If the server didn't respond
+ * with a negotiated protocol then |*out_len| will be zero. */
+OPENSSL_EXPORT void SSL_get0_alpn_selected(const SSL *ssl,
+ const uint8_t **out_data,
+ unsigned *out_len);
+
+
+/* Next protocol negotiation.
+ *
+ * The NPN extension (draft-agl-tls-nextprotoneg-03) is the predecessor to ALPN
+ * and deprecated in favor of it. */
+
+/* SSL_CTX_set_next_protos_advertised_cb sets a callback that is called when a
+ * TLS server needs a list of supported protocols for Next Protocol
+ * Negotiation. The returned list must be in wire format. The list is returned
+ * by setting |*out| to point to it and |*out_len| to its length. This memory
+ * will not be modified, but one should assume that |ssl| keeps a reference to
+ * it.
+ *
+ * The callback should return |SSL_TLSEXT_ERR_OK| if it wishes to advertise.
+ * Otherwise, no such extension will be included in the ServerHello. */
+OPENSSL_EXPORT void SSL_CTX_set_next_protos_advertised_cb(
+ SSL_CTX *ctx,
+ int (*cb)(SSL *ssl, const uint8_t **out, unsigned *out_len, void *arg),
+ void *arg);
+
+/* SSL_CTX_set_next_proto_select_cb sets a callback that is called when a client
+ * needs to select a protocol from the server's provided list. |*out| must be
+ * set to point to the selected protocol (which may be within |in|). The length
+ * of the protocol name must be written into |*out_len|. The server's advertised
+ * protocols are provided in |in| and |in_len|. The callback can assume that
+ * |in| is syntactically valid.
+ *
+ * The client must select a protocol. It is fatal to the connection if this
+ * callback returns a value other than |SSL_TLSEXT_ERR_OK|.
+ *
+ * Configuring this callback enables NPN on a client. */
+OPENSSL_EXPORT void SSL_CTX_set_next_proto_select_cb(
+ SSL_CTX *ctx, int (*cb)(SSL *ssl, uint8_t **out, uint8_t *out_len,
+ const uint8_t *in, unsigned in_len, void *arg),
+ void *arg);
+
+/* SSL_get0_next_proto_negotiated sets |*out_data| and |*out_len| to point to
+ * the client's requested protocol for this connection. If the client didn't
+ * request any protocol, then |*out_data| is set to NULL.
+ *
+ * Note that the client can request any protocol it chooses. The value returned
+ * from this function need not be a member of the list of supported protocols
+ * provided by the server. */
+OPENSSL_EXPORT void SSL_get0_next_proto_negotiated(const SSL *ssl,
+ const uint8_t **out_data,
+ unsigned *out_len);
+
+/* SSL_select_next_proto implements the standard protocol selection. It is
+ * expected that this function is called from the callback set by
+ * |SSL_CTX_set_next_proto_select_cb|.
+ *
+ * The protocol data is assumed to be a vector of 8-bit, length prefixed byte
+ * strings. The length byte itself is not included in the length. A byte
+ * string of length 0 is invalid. No byte string may be truncated.
+ *
+ * The current, but experimental algorithm for selecting the protocol is:
+ *
+ * 1) If the server doesn't support NPN then this is indicated to the
+ * callback. In this case, the client application has to abort the connection
+ * or have a default application level protocol.
+ *
+ * 2) If the server supports NPN, but advertises an empty list then the
+ * client selects the first protcol in its list, but indicates via the
+ * API that this fallback case was enacted.
+ *
+ * 3) Otherwise, the client finds the first protocol in the server's list
+ * that it supports and selects this protocol. This is because it's
+ * assumed that the server has better information about which protocol
+ * a client should use.
+ *
+ * 4) If the client doesn't support any of the server's advertised
+ * protocols, then this is treated the same as case 2.
+ *
+ * It returns either |OPENSSL_NPN_NEGOTIATED| if a common protocol was found, or
+ * |OPENSSL_NPN_NO_OVERLAP| if the fallback case was reached. */
+OPENSSL_EXPORT int SSL_select_next_proto(uint8_t **out, uint8_t *out_len,
+ const uint8_t *server,
+ unsigned server_len,
+ const uint8_t *client,
+ unsigned client_len);
+
+#define OPENSSL_NPN_UNSUPPORTED 0
+#define OPENSSL_NPN_NEGOTIATED 1
+#define OPENSSL_NPN_NO_OVERLAP 2
+
+
+/* Channel ID.
+ *
+ * See draft-balfanz-tls-channelid-01. */
+
+/* SSL_CTX_enable_tls_channel_id either configures a TLS server to accept TLS
+ * Channel IDs from clients, or configures a client to send TLS Channel IDs to
+ * a server. It returns one. */
+OPENSSL_EXPORT int SSL_CTX_enable_tls_channel_id(SSL_CTX *ctx);
+
+/* SSL_enable_tls_channel_id either configures a TLS server to accept TLS
+ * Channel IDs from clients, or configures a client to send TLS Channel IDs to
+ * server. It returns one. */
+OPENSSL_EXPORT int SSL_enable_tls_channel_id(SSL *ssl);
+
+/* SSL_CTX_set1_tls_channel_id configures a TLS client to send a TLS Channel ID
+ * to compatible servers. |private_key| must be a P-256 EC key. It returns one
+ * on success and zero on error. */
+OPENSSL_EXPORT int SSL_CTX_set1_tls_channel_id(SSL_CTX *ctx,
+ EVP_PKEY *private_key);
+
+/* SSL_set1_tls_channel_id configures a TLS client to send a TLS Channel ID to
+ * compatible servers. |private_key| must be a P-256 EC key. It returns one on
+ * success and zero on error. */
+OPENSSL_EXPORT int SSL_set1_tls_channel_id(SSL *ssl, EVP_PKEY *private_key);
+
+/* SSL_get_tls_channel_id gets the client's TLS Channel ID from a server |SSL*|
+ * and copies up to the first |max_out| bytes into |out|. The Channel ID
+ * consists of the client's P-256 public key as an (x,y) pair where each is a
+ * 32-byte, big-endian field element. It returns 0 if the client didn't offer a
+ * Channel ID and the length of the complete Channel ID otherwise. */
+OPENSSL_EXPORT size_t SSL_get_tls_channel_id(SSL *ssl, uint8_t *out,
+ size_t max_out);
+
+/* SSL_CTX_set_channel_id_cb sets a callback to be called when a TLS Channel ID
+ * is requested. The callback may set |*out_pkey| to a key, passing a reference
+ * to the caller. If none is returned, the handshake will pause and
+ * |SSL_get_error| will return |SSL_ERROR_WANT_CHANNEL_ID_LOOKUP|.
+ *
+ * See also |SSL_ERROR_WANT_CHANNEL_ID_LOOKUP|. */
+OPENSSL_EXPORT void SSL_CTX_set_channel_id_cb(
+ SSL_CTX *ctx, void (*channel_id_cb)(SSL *ssl, EVP_PKEY **out_pkey));
+
+/* SSL_CTX_get_channel_id_cb returns the callback set by
+ * |SSL_CTX_set_channel_id_cb|. */
+OPENSSL_EXPORT void (*SSL_CTX_get_channel_id_cb(SSL_CTX *ctx))(
+ SSL *ssl, EVP_PKEY **out_pkey);
+
+
+/* DTLS-SRTP.
+ *
+ * See RFC 5764. */
+
+/* An SRTP_PROTECTION_PROFILE is an SRTP profile for use with the use_srtp
+ * extension. */
+struct srtp_protection_profile_st {
+ const char *name;
+ unsigned long id;
+} /* SRTP_PROTECTION_PROFILE */;
+
+DECLARE_STACK_OF(SRTP_PROTECTION_PROFILE)
+
+/* SRTP_* define constants for SRTP profiles. */
+#define SRTP_AES128_CM_SHA1_80 0x0001
+#define SRTP_AES128_CM_SHA1_32 0x0002
+#define SRTP_AES128_F8_SHA1_80 0x0003
+#define SRTP_AES128_F8_SHA1_32 0x0004
+#define SRTP_NULL_SHA1_80 0x0005
+#define SRTP_NULL_SHA1_32 0x0006
+
+/* SSL_CTX_set_srtp_profiles enables SRTP for all SSL objects created from
+ * |ctx|. |profile| contains a colon-separated list of profile names. It returns
+ * one on success and zero on failure. */
+OPENSSL_EXPORT int SSL_CTX_set_srtp_profiles(SSL_CTX *ctx,
+ const char *profiles);
+
+/* SSL_set_srtp_profiles enables SRTP for |ssl|. |profile| contains a
+ * colon-separated list of profile names. It returns one on success and zero on
+ * failure. */
+OPENSSL_EXPORT int SSL_set_srtp_profiles(SSL *ssl, const char *profiles);
+
+/* SSL_get_srtp_profiles returns the SRTP profiles supported by |ssl|. */
+OPENSSL_EXPORT STACK_OF(SRTP_PROTECTION_PROFILE) *SSL_get_srtp_profiles(
+ SSL *ssl);
+
+/* SSL_get_selected_srtp_profile returns the selected SRTP profile, or NULL if
+ * SRTP was not negotiated. */
+OPENSSL_EXPORT const SRTP_PROTECTION_PROFILE *SSL_get_selected_srtp_profile(
+ SSL *ssl);
+
+
+/* Pre-shared keys.
+ *
+ * Connections may be configured with PSK (Pre-Shared Key) cipher suites. These
+ * authenticate using out-of-band pre-shared keys rather than certificates. See
+ * RFC 4279.
+ *
+ * This implementation uses NUL-terminated C strings for identities and identity
+ * hints, so values with a NUL character are not supported. (RFC 4279 does not
+ * specify the format of an identity.) */
+
+/* PSK_MAX_IDENTITY_LEN is the maximum supported length of a PSK identity,
+ * excluding the NUL terminator. */
+#define PSK_MAX_IDENTITY_LEN 128
+
+/* PSK_MAX_PSK_LEN is the maximum supported length of a pre-shared key. */
+#define PSK_MAX_PSK_LEN 256
+
+/* SSL_CTX_set_psk_client_callback sets the callback to be called when PSK is
+ * negotiated on the client. This callback must be set to enable PSK cipher
+ * suites on the client.
+ *
+ * The callback is passed the identity hint in |hint| or NULL if none was
+ * provided. It should select a PSK identity and write the identity and the
+ * corresponding PSK to |identity| and |psk|, respectively. The identity is
+ * written as a NUL-terminated C string of length (excluding the NUL terminator)
+ * at most |max_identity_len|. The PSK's length must be at most |max_psk_len|.
+ * The callback returns the length of the PSK or 0 if no suitable identity was
+ * found. */
+OPENSSL_EXPORT void SSL_CTX_set_psk_client_callback(
+ SSL_CTX *ctx,
+ unsigned (*psk_client_callback)(
+ SSL *ssl, const char *hint, char *identity,
+ unsigned max_identity_len, uint8_t *psk, unsigned max_psk_len));
+
+/* SSL_set_psk_client_callback sets the callback to be called when PSK is
+ * negotiated on the client. This callback must be set to enable PSK cipher
+ * suites on the client. See also |SSL_CTX_set_psk_client_callback|. */
+OPENSSL_EXPORT void SSL_set_psk_client_callback(
+ SSL *ssl, unsigned (*psk_client_callback)(SSL *ssl, const char *hint,
+ char *identity,
+ unsigned max_identity_len,
+ uint8_t *psk,
+ unsigned max_psk_len));
+
+/* SSL_CTX_set_psk_server_callback sets the callback to be called when PSK is
+ * negotiated on the server. This callback must be set to enable PSK cipher
+ * suites on the server.
+ *
+ * The callback is passed the identity in |identity|. It should write a PSK of
+ * length at most |max_psk_len| to |psk| and return the number of bytes written
+ * or zero if the PSK identity is unknown. */
+OPENSSL_EXPORT void SSL_CTX_set_psk_server_callback(
+ SSL_CTX *ctx,
+ unsigned (*psk_server_callback)(SSL *ssl, const char *identity,
+ uint8_t *psk,
+ unsigned max_psk_len));
+
+/* SSL_set_psk_server_callback sets the callback to be called when PSK is
+ * negotiated on the server. This callback must be set to enable PSK cipher
+ * suites on the server. See also |SSL_CTX_set_psk_server_callback|. */
+OPENSSL_EXPORT void SSL_set_psk_server_callback(
+ SSL *ssl,
+ unsigned (*psk_server_callback)(SSL *ssl, const char *identity,
+ uint8_t *psk,
+ unsigned max_psk_len));
+
+/* SSL_CTX_use_psk_identity_hint configures server connections to advertise an
+ * identity hint of |identity_hint|. It returns one on success and zero on
+ * error. */
+OPENSSL_EXPORT int SSL_CTX_use_psk_identity_hint(SSL_CTX *ctx,
+ const char *identity_hint);
+
+/* SSL_use_psk_identity_hint configures server connections to advertise an
+ * identity hint of |identity_hint|. It returns one on success and zero on
+ * error. */
+OPENSSL_EXPORT int SSL_use_psk_identity_hint(SSL *ssl,
+ const char *identity_hint);
+
+/* SSL_get_psk_identity_hint returns the PSK identity hint advertised for |ssl|
+ * or NULL if there is none. */
+OPENSSL_EXPORT const char *SSL_get_psk_identity_hint(const SSL *ssl);
+
+/* SSL_get_psk_identity, after the handshake completes, returns the PSK identity
+ * that was negotiated by |ssl| or NULL if PSK was not used. */
+OPENSSL_EXPORT const char *SSL_get_psk_identity(const SSL *ssl);
+
+
+/* ex_data functions.
+ *
+ * See |ex_data.h| for details. */
+
+OPENSSL_EXPORT int SSL_set_ex_data(SSL *ssl, int idx, void *data);
+OPENSSL_EXPORT void *SSL_get_ex_data(const SSL *ssl, int idx);
+OPENSSL_EXPORT int SSL_get_ex_new_index(long argl, void *argp,
+ CRYPTO_EX_new *new_func,
+ CRYPTO_EX_dup *dup_func,
+ CRYPTO_EX_free *free_func);
+
+OPENSSL_EXPORT int SSL_SESSION_set_ex_data(SSL_SESSION *session, int idx,
+ void *data);
+OPENSSL_EXPORT void *SSL_SESSION_get_ex_data(const SSL_SESSION *session,
+ int idx);
+OPENSSL_EXPORT int SSL_SESSION_get_ex_new_index(long argl, void *argp,
+ CRYPTO_EX_new *new_func,
+ CRYPTO_EX_dup *dup_func,
+ CRYPTO_EX_free *free_func);
+
+OPENSSL_EXPORT int SSL_CTX_set_ex_data(SSL_CTX *ctx, int idx, void *data);
+OPENSSL_EXPORT void *SSL_CTX_get_ex_data(const SSL_CTX *ctx, int idx);
+OPENSSL_EXPORT int SSL_CTX_get_ex_new_index(long argl, void *argp,
+ CRYPTO_EX_new *new_func,
+ CRYPTO_EX_dup *dup_func,
+ CRYPTO_EX_free *free_func);
+
+
+/* Obscure functions. */
+
+/* SSL_get_rc4_state sets |*read_key| and |*write_key| to the RC4 states for
+ * the read and write directions. It returns one on success or zero if |ssl|
+ * isn't using an RC4-based cipher suite. */
+OPENSSL_EXPORT int SSL_get_rc4_state(const SSL *ssl, const RC4_KEY **read_key,
+ const RC4_KEY **write_key);
+
+/* SSL_get_structure_sizes returns the sizes of the SSL, SSL_CTX and
+ * SSL_SESSION structures so that a test can ensure that outside code agrees on
+ * these values. */
+OPENSSL_EXPORT void SSL_get_structure_sizes(size_t *ssl_size,
+ size_t *ssl_ctx_size,
+ size_t *ssl_session_size);
/* Underdocumented functions.
@@ -611,127 +2252,14 @@ OPENSSL_EXPORT int SSL_initial_handshake_complete(const SSL *ssl);
#define SSL_SENT_SHUTDOWN 1
#define SSL_RECEIVED_SHUTDOWN 2
-#define SSL_FILETYPE_ASN1 X509_FILETYPE_ASN1
-#define SSL_FILETYPE_PEM X509_FILETYPE_PEM
-
typedef struct ssl_protocol_method_st SSL_PROTOCOL_METHOD;
-typedef struct ssl_session_st SSL_SESSION;
-typedef struct tls_sigalgs_st TLS_SIGALGS;
typedef struct ssl_conf_ctx_st SSL_CONF_CTX;
typedef struct ssl3_enc_method SSL3_ENC_METHOD;
-/* SRTP protection profiles for use with the use_srtp extension (RFC 5764). */
-typedef struct srtp_protection_profile_st {
- const char *name;
- unsigned long id;
-} SRTP_PROTECTION_PROFILE;
-
-DECLARE_STACK_OF(SRTP_PROTECTION_PROFILE)
-
-/* An SSL_SESSION represents an SSL session that may be resumed in an
- * abbreviated handshake. */
-struct ssl_session_st {
- int ssl_version; /* what ssl version session info is being kept in here? */
-
- int master_key_length;
- uint8_t master_key[SSL_MAX_MASTER_KEY_LENGTH];
- /* session_id - valid? */
- unsigned int session_id_length;
- uint8_t session_id[SSL_MAX_SSL_SESSION_ID_LENGTH];
- /* this is used to determine whether the session is being reused in
- * the appropriate context. It is up to the application to set this,
- * via SSL_new */
- unsigned int sid_ctx_length;
- uint8_t sid_ctx[SSL_MAX_SID_CTX_LENGTH];
-
- char *psk_identity;
- /* Used to indicate that session resumption is not allowed. Applications can
- * also set this bit for a new session via not_resumable_session_cb to
- * disable session caching and tickets. */
- int not_resumable;
-
- /* The cert is the certificate used to establish this connection
- *
- * TODO(davidben): Remove this field. It is not serialized as part of the
- * session, but some APIs access it. Certificate-related fields, where not
- * redundant with |peer|, should be added to the session. Others should
- * probably not be retained across resumptions. */
- struct sess_cert_st /* SESS_CERT */ *sess_cert;
-
- /* This is the cert for the other end. On clients, it will be the same as
- * sess_cert->peer_key->x509 (the latter is not enough as sess_cert is not
- * retained in the external representation of sessions, see ssl_asn1.c). */
- X509 *peer;
- /* when app_verify_callback accepts a session where the peer's certificate is
- * not ok, we must remember the error for session reuse: */
- long verify_result; /* only for servers */
-
- CRYPTO_refcount_t references;
- long timeout;
- long time;
-
- const SSL_CIPHER *cipher;
-
- CRYPTO_EX_DATA ex_data; /* application specific data */
-
- /* These are used to make removal of session-ids more efficient and to
- * implement a maximum cache size. */
- SSL_SESSION *prev, *next;
- char *tlsext_hostname;
- /* RFC4507 info */
- uint8_t *tlsext_tick; /* Session ticket */
- size_t tlsext_ticklen; /* Session ticket length */
- uint32_t tlsext_tick_lifetime_hint; /* Session lifetime hint in seconds */
-
- size_t tlsext_signed_cert_timestamp_list_length;
- uint8_t *tlsext_signed_cert_timestamp_list; /* Server's list. */
-
- /* The OCSP response that came with the session. */
- size_t ocsp_response_length;
- uint8_t *ocsp_response;
-
- char peer_sha256_valid; /* Non-zero if peer_sha256 is valid */
- uint8_t
- peer_sha256[SHA256_DIGEST_LENGTH]; /* SHA256 of peer certificate */
-
- /* original_handshake_hash contains the handshake hash (either SHA-1+MD5 or
- * SHA-2, depending on TLS version) for the original, full handshake that
- * created a session. This is used by Channel IDs during resumption. */
- uint8_t original_handshake_hash[EVP_MAX_MD_SIZE];
- unsigned int original_handshake_hash_len;
-
- /* extended_master_secret is true if the master secret in this session was
- * generated using EMS and thus isn't vulnerable to the Triple Handshake
- * attack. */
- char extended_master_secret;
-};
-
-
-/* Cert related flags */
-/* Many implementations ignore some aspects of the TLS standards such as
- * enforcing certifcate chain algorithms. When this is set we enforce them. */
-#define SSL_CERT_FLAG_TLS_STRICT 0x00000001L
-
-/* Flags for building certificate chains */
-/* Treat any existing certificates as untrusted CAs */
-#define SSL_BUILD_CHAIN_FLAG_UNTRUSTED 0x1
-/* Don't include root CA in chain */
-#define SSL_BUILD_CHAIN_FLAG_NO_ROOT 0x2
-/* Just check certificates already there */
-#define SSL_BUILD_CHAIN_FLAG_CHECK 0x4
-/* Ignore verification errors */
-#define SSL_BUILD_CHAIN_FLAG_IGNORE_ERROR 0x8
-/* Clear verification errors from queue */
-#define SSL_BUILD_CHAIN_FLAG_CLEAR_ERROR 0x10
-
/* SSL_set_mtu sets the |ssl|'s MTU in DTLS to |mtu|. It returns one on success
* and zero on failure. */
OPENSSL_EXPORT int SSL_set_mtu(SSL *ssl, unsigned mtu);
-/* SSL_get_secure_renegotiation_support returns one if the peer supports secure
- * renegotiation (RFC 5746) and zero otherwise. */
-OPENSSL_EXPORT int SSL_get_secure_renegotiation_support(const SSL *ssl);
-
/* SSL_CTX_set_msg_callback installs |cb| as the message callback for |ctx|.
* This callback will be called when sending or receiving low-level record
* headers, complete handshake messages, ChangeCipherSpec, and alerts.
@@ -777,26 +2305,6 @@ typedef struct ssl_aead_ctx_st SSL_AEAD_CTX;
#define SSL_MAX_CERT_LIST_DEFAULT 1024 * 100 /* 100k max cert list */
-#define SSL_SESSION_CACHE_MAX_SIZE_DEFAULT (1024 * 20)
-
-#define SSL_DEFAULT_SESSION_TIMEOUT (2 * 60 * 60)
-
-/* This callback type is used inside SSL_CTX, SSL, and in the functions that
- * set them. It is used to override the generation of SSL/TLS session IDs in a
- * server. Return value should be zero on an error, non-zero to proceed. Also,
- * callbacks should themselves check if the id they generate is unique
- * otherwise the SSL handshake will fail with an error - callbacks can do this
- * using the 'ssl' value they're passed by;
- * SSL_has_matching_session_id(ssl, id, *id_len)
- * The length value passed in is set at the maximum size the session ID can be.
- * In SSLv2 this is 16 bytes, whereas SSLv3/TLSv1 it is 32 bytes. The callback
- * can alter this length to be less if desired, but under SSLv2 session IDs are
- * supposed to be fixed at 16 bytes so the id will be padded after the callback
- * returns in this case. It is also an error for the callback to set the size
- * to zero. */
-typedef int (*GEN_SESSION_CB)(const SSL *ssl, uint8_t *id,
- unsigned int *id_len);
-
/* ssl_early_callback_ctx is passed to certain callbacks that are called very
* early on during the server handshake. At this point, much of the SSL* hasn't
* been filled out and only the ClientHello can be depended on. */
@@ -823,6 +2331,511 @@ OPENSSL_EXPORT char SSL_early_callback_ctx_extension_get(
const struct ssl_early_callback_ctx *ctx, uint16_t extension_type,
const uint8_t **out_data, size_t *out_len);
+OPENSSL_EXPORT void SSL_CTX_set_info_callback(SSL_CTX *ctx,
+ void (*cb)(const SSL *ssl,
+ int type, int val));
+OPENSSL_EXPORT void (*SSL_CTX_get_info_callback(SSL_CTX *ctx))(const SSL *ssl,
+ int type,
+ int val);
+OPENSSL_EXPORT void SSL_CTX_set_client_cert_cb(
+ SSL_CTX *ctx,
+ int (*client_cert_cb)(SSL *ssl, X509 **x509, EVP_PKEY **pkey));
+OPENSSL_EXPORT int (*SSL_CTX_get_client_cert_cb(SSL_CTX *ctx))(SSL *ssl,
+ X509 **x509,
+ EVP_PKEY **pkey);
+/* SSL_enable_signed_cert_timestamps causes |ssl| (which must be the client end
+ * of a connection) to request SCTs from the server. See
+ * https://tools.ietf.org/html/rfc6962. It returns one. */
+OPENSSL_EXPORT int SSL_enable_signed_cert_timestamps(SSL *ssl);
+
+/* SSL_CTX_enable_signed_cert_timestamps enables SCT requests on all client SSL
+ * objects created from |ctx|. */
+OPENSSL_EXPORT void SSL_CTX_enable_signed_cert_timestamps(SSL_CTX *ctx);
+
+/* SSL_enable_ocsp_stapling causes |ssl| (which must be the client end of a
+ * connection) to request a stapled OCSP response from the server. It returns
+ * one. */
+OPENSSL_EXPORT int SSL_enable_ocsp_stapling(SSL *ssl);
+
+/* SSL_CTX_enable_ocsp_stapling enables OCSP stapling on all client SSL objects
+ * created from |ctx|. */
+OPENSSL_EXPORT void SSL_CTX_enable_ocsp_stapling(SSL_CTX *ctx);
+
+/* SSL_get0_signed_cert_timestamp_list sets |*out| and |*out_len| to point to
+ * |*out_len| bytes of SCT information from the server. This is only valid if
+ * |ssl| is a client. The SCT information is a SignedCertificateTimestampList
+ * (including the two leading length bytes).
+ * See https://tools.ietf.org/html/rfc6962#section-3.3
+ * If no SCT was received then |*out_len| will be zero on return.
+ *
+ * WARNING: the returned data is not guaranteed to be well formed. */
+OPENSSL_EXPORT void SSL_get0_signed_cert_timestamp_list(const SSL *ssl,
+ const uint8_t **out,
+ size_t *out_len);
+
+/* SSL_get0_ocsp_response sets |*out| and |*out_len| to point to |*out_len|
+ * bytes of an OCSP response from the server. This is the DER encoding of an
+ * OCSPResponse type as defined in RFC 2560.
+ *
+ * WARNING: the returned data is not guaranteed to be well formed. */
+OPENSSL_EXPORT void SSL_get0_ocsp_response(const SSL *ssl, const uint8_t **out,
+ size_t *out_len);
+
+/* SSL_set_reject_peer_renegotiations controls whether renegotiation attempts by
+ * the peer are rejected. It may be set at any point in a connection's lifetime
+ * to control future renegotiations programmatically. By default, renegotiations
+ * are rejected. (Renegotiations requested by a client are always rejected.) */
+OPENSSL_EXPORT void SSL_set_reject_peer_renegotiations(SSL *ssl, int reject);
+
+#define SSL_NOTHING 1
+#define SSL_WRITING 2
+#define SSL_READING 3
+#define SSL_X509_LOOKUP 4
+#define SSL_CHANNEL_ID_LOOKUP 5
+#define SSL_PENDING_SESSION 7
+#define SSL_CERTIFICATE_SELECTION_PENDING 8
+#define SSL_PRIVATE_KEY_OPERATION 9
+
+/* These will only be used when doing non-blocking IO */
+#define SSL_want_nothing(s) (SSL_want(s) == SSL_NOTHING)
+#define SSL_want_read(s) (SSL_want(s) == SSL_READING)
+#define SSL_want_write(s) (SSL_want(s) == SSL_WRITING)
+#define SSL_want_x509_lookup(s) (SSL_want(s) == SSL_X509_LOOKUP)
+#define SSL_want_channel_id_lookup(s) (SSL_want(s) == SSL_CHANNEL_ID_LOOKUP)
+#define SSL_want_session(s) (SSL_want(s) == SSL_PENDING_SESSION)
+#define SSL_want_certificate(s) \
+ (SSL_want(s) == SSL_CERTIFICATE_SELECTION_PENDING)
+#define SSL_want_private_key_operation(s) \
+ (SSL_want(s) == SSL_PRIVATE_KEY_OPERATION)
+
+/* The following are the possible values for ssl->state are are used to
+ * indicate where we are up to in the SSL connection establishment. The macros
+ * that follow are about the only things you should need to use and even then,
+ * only when using non-blocking IO. It can also be useful to work out where you
+ * were when the connection failed */
+
+#define SSL_ST_CONNECT 0x1000
+#define SSL_ST_ACCEPT 0x2000
+#define SSL_ST_MASK 0x0FFF
+#define SSL_ST_INIT (SSL_ST_CONNECT | SSL_ST_ACCEPT)
+#define SSL_ST_OK 0x03
+#define SSL_ST_RENEGOTIATE (0x04 | SSL_ST_INIT)
+
+#define SSL_CB_LOOP 0x01
+#define SSL_CB_EXIT 0x02
+#define SSL_CB_READ 0x04
+#define SSL_CB_WRITE 0x08
+#define SSL_CB_ALERT 0x4000 /* used in callback */
+#define SSL_CB_READ_ALERT (SSL_CB_ALERT | SSL_CB_READ)
+#define SSL_CB_WRITE_ALERT (SSL_CB_ALERT | SSL_CB_WRITE)
+#define SSL_CB_ACCEPT_LOOP (SSL_ST_ACCEPT | SSL_CB_LOOP)
+#define SSL_CB_ACCEPT_EXIT (SSL_ST_ACCEPT | SSL_CB_EXIT)
+#define SSL_CB_CONNECT_LOOP (SSL_ST_CONNECT | SSL_CB_LOOP)
+#define SSL_CB_CONNECT_EXIT (SSL_ST_CONNECT | SSL_CB_EXIT)
+#define SSL_CB_HANDSHAKE_START 0x10
+#define SSL_CB_HANDSHAKE_DONE 0x20
+
+/* Is the SSL_connection established? */
+#define SSL_get_state(a) SSL_state(a)
+#define SSL_is_init_finished(a) (SSL_state(a) == SSL_ST_OK)
+#define SSL_in_init(a) (SSL_state(a) & SSL_ST_INIT)
+#define SSL_in_connect_init(a) (SSL_state(a) & SSL_ST_CONNECT)
+#define SSL_in_accept_init(a) (SSL_state(a) & SSL_ST_ACCEPT)
+
+/* SSL_in_false_start returns one if |s| has a pending unfinished handshake that
+ * is in False Start. |SSL_write| may be called at this point without waiting
+ * for the peer, but |SSL_read| will require the handshake to be completed. */
+OPENSSL_EXPORT int SSL_in_false_start(const SSL *s);
+
+/* Obtain latest Finished message
+ * -- that we sent (SSL_get_finished)
+ * -- that we expected from peer (SSL_get_peer_finished).
+ * Returns length (0 == no Finished so far), copies up to 'count' bytes. */
+OPENSSL_EXPORT size_t SSL_get_finished(const SSL *s, void *buf, size_t count);
+OPENSSL_EXPORT size_t SSL_get_peer_finished(const SSL *s, void *buf, size_t count);
+
+#define d2i_SSL_SESSION_bio(bp, s_id) \
+ ASN1_d2i_bio_of(SSL_SESSION, SSL_SESSION_new, d2i_SSL_SESSION, bp, s_id)
+#define i2d_SSL_SESSION_bio(bp, s_id) \
+ ASN1_i2d_bio_of(SSL_SESSION, i2d_SSL_SESSION, bp, s_id)
+
+DECLARE_PEM_rw(SSL_SESSION, SSL_SESSION)
+
+/* make_errors.go reserves error codes above 1000 for manually-assigned errors.
+ * This value must be kept in sync with reservedReasonCode in make_errors.h */
+#define SSL_AD_REASON_OFFSET \
+ 1000 /* offset to get SSL_R_... value from SSL_AD_... */
+
+/* These alert types are for SSLv3 and TLSv1 */
+#define SSL_AD_CLOSE_NOTIFY SSL3_AD_CLOSE_NOTIFY
+#define SSL_AD_UNEXPECTED_MESSAGE SSL3_AD_UNEXPECTED_MESSAGE /* fatal */
+#define SSL_AD_BAD_RECORD_MAC SSL3_AD_BAD_RECORD_MAC /* fatal */
+#define SSL_AD_DECRYPTION_FAILED TLS1_AD_DECRYPTION_FAILED
+#define SSL_AD_RECORD_OVERFLOW TLS1_AD_RECORD_OVERFLOW
+#define SSL_AD_DECOMPRESSION_FAILURE SSL3_AD_DECOMPRESSION_FAILURE /* fatal */
+#define SSL_AD_HANDSHAKE_FAILURE SSL3_AD_HANDSHAKE_FAILURE /* fatal */
+#define SSL_AD_NO_CERTIFICATE SSL3_AD_NO_CERTIFICATE /* Not for TLS */
+#define SSL_AD_BAD_CERTIFICATE SSL3_AD_BAD_CERTIFICATE
+#define SSL_AD_UNSUPPORTED_CERTIFICATE SSL3_AD_UNSUPPORTED_CERTIFICATE
+#define SSL_AD_CERTIFICATE_REVOKED SSL3_AD_CERTIFICATE_REVOKED
+#define SSL_AD_CERTIFICATE_EXPIRED SSL3_AD_CERTIFICATE_EXPIRED
+#define SSL_AD_CERTIFICATE_UNKNOWN SSL3_AD_CERTIFICATE_UNKNOWN
+#define SSL_AD_ILLEGAL_PARAMETER SSL3_AD_ILLEGAL_PARAMETER /* fatal */
+#define SSL_AD_UNKNOWN_CA TLS1_AD_UNKNOWN_CA /* fatal */
+#define SSL_AD_ACCESS_DENIED TLS1_AD_ACCESS_DENIED /* fatal */
+#define SSL_AD_DECODE_ERROR TLS1_AD_DECODE_ERROR /* fatal */
+#define SSL_AD_DECRYPT_ERROR TLS1_AD_DECRYPT_ERROR
+#define SSL_AD_EXPORT_RESTRICTION TLS1_AD_EXPORT_RESTRICTION /* fatal */
+#define SSL_AD_PROTOCOL_VERSION TLS1_AD_PROTOCOL_VERSION /* fatal */
+#define SSL_AD_INSUFFICIENT_SECURITY TLS1_AD_INSUFFICIENT_SECURITY /* fatal */
+#define SSL_AD_INTERNAL_ERROR TLS1_AD_INTERNAL_ERROR /* fatal */
+#define SSL_AD_USER_CANCELLED TLS1_AD_USER_CANCELLED
+#define SSL_AD_NO_RENEGOTIATION TLS1_AD_NO_RENEGOTIATION
+#define SSL_AD_UNSUPPORTED_EXTENSION TLS1_AD_UNSUPPORTED_EXTENSION
+#define SSL_AD_CERTIFICATE_UNOBTAINABLE TLS1_AD_CERTIFICATE_UNOBTAINABLE
+#define SSL_AD_UNRECOGNIZED_NAME TLS1_AD_UNRECOGNIZED_NAME
+#define SSL_AD_BAD_CERTIFICATE_STATUS_RESPONSE \
+ TLS1_AD_BAD_CERTIFICATE_STATUS_RESPONSE
+#define SSL_AD_BAD_CERTIFICATE_HASH_VALUE TLS1_AD_BAD_CERTIFICATE_HASH_VALUE
+#define SSL_AD_UNKNOWN_PSK_IDENTITY TLS1_AD_UNKNOWN_PSK_IDENTITY /* fatal */
+#define SSL_AD_INAPPROPRIATE_FALLBACK SSL3_AD_INAPPROPRIATE_FALLBACK /* fatal */
+
+/* DTLSv1_get_timeout queries the next DTLS handshake timeout. If there is a
+ * timeout in progress, it sets |*out| to the time remaining and returns one.
+ * Otherwise, it returns zero.
+ *
+ * When the timeout expires, call |DTLSv1_handle_timeout| to handle the
+ * retransmit behavior.
+ *
+ * NOTE: This function must be queried again whenever the handshake state
+ * machine changes, including when |DTLSv1_handle_timeout| is called. */
+OPENSSL_EXPORT int DTLSv1_get_timeout(const SSL *ssl, struct timeval *out);
+
+/* DTLSv1_handle_timeout is called when a DTLS handshake timeout expires. If no
+ * timeout had expired, it returns 0. Otherwise, it retransmits the previous
+ * flight of handshake messages and returns 1. If too many timeouts had expired
+ * without progress or an error occurs, it returns -1.
+ *
+ * NOTE: The caller's external timer should be compatible with the one |ssl|
+ * queries within some fudge factor. Otherwise, the call will be a no-op, but
+ * |DTLSv1_get_timeout| will return an updated timeout.
+ *
+ * WARNING: This function breaks the usual return value convention. */
+OPENSSL_EXPORT int DTLSv1_handle_timeout(SSL *ssl);
+
+/* SSL_total_renegotiations returns the total number of renegotiation handshakes
+ * peformed by |ssl|. This includes the pending renegotiation, if any. */
+OPENSSL_EXPORT int SSL_total_renegotiations(const SSL *ssl);
+
+/* SSL_get0_certificate_types, for a client, sets |*out_types| to an array
+ * containing the client certificate types requested by a server. It returns the
+ * length of the array. */
+OPENSSL_EXPORT size_t SSL_get0_certificate_types(SSL *ssl,
+ const uint8_t **out_types);
+
+OPENSSL_EXPORT int SSL_CTX_set_cipher_list(SSL_CTX *, const char *str);
+OPENSSL_EXPORT int SSL_CTX_set_cipher_list_tls10(SSL_CTX *, const char *str);
+OPENSSL_EXPORT int SSL_CTX_set_cipher_list_tls11(SSL_CTX *, const char *str);
+OPENSSL_EXPORT int SSL_want(const SSL *s);
+
+OPENSSL_EXPORT int SSL_get_fd(const SSL *s);
+OPENSSL_EXPORT int SSL_get_rfd(const SSL *s);
+OPENSSL_EXPORT int SSL_get_wfd(const SSL *s);
+OPENSSL_EXPORT const char *SSL_get_cipher_list(const SSL *s, int n);
+OPENSSL_EXPORT int SSL_pending(const SSL *s);
+OPENSSL_EXPORT int SSL_set_fd(SSL *s, int fd);
+OPENSSL_EXPORT int SSL_set_rfd(SSL *s, int fd);
+OPENSSL_EXPORT int SSL_set_wfd(SSL *s, int fd);
+OPENSSL_EXPORT int SSL_set_cipher_list(SSL *s, const char *str);
+
+OPENSSL_EXPORT const char *SSL_state_string(const SSL *s);
+OPENSSL_EXPORT const char *SSL_state_string_long(const SSL *s);
+
+OPENSSL_EXPORT int SSL_SESSION_print_fp(FILE *fp, const SSL_SESSION *ses);
+OPENSSL_EXPORT int SSL_SESSION_print(BIO *fp, const SSL_SESSION *ses);
+
+OPENSSL_EXPORT STACK_OF(SSL_CIPHER) *SSL_get_ciphers(const SSL *s);
+
+/* SSL_renegotiate_pending returns one if |ssl| is in the middle of a
+ * renegotiation. */
+OPENSSL_EXPORT int SSL_renegotiate_pending(SSL *ssl);
+
+OPENSSL_EXPORT const char *SSL_alert_type_string_long(int value);
+OPENSSL_EXPORT const char *SSL_alert_type_string(int value);
+OPENSSL_EXPORT const char *SSL_alert_desc_string_long(int value);
+OPENSSL_EXPORT const char *SSL_alert_desc_string(int value);
+
+OPENSSL_EXPORT void SSL_CTX_set_quiet_shutdown(SSL_CTX *ctx, int mode);
+OPENSSL_EXPORT int SSL_CTX_get_quiet_shutdown(const SSL_CTX *ctx);
+OPENSSL_EXPORT void SSL_set_quiet_shutdown(SSL *ssl, int mode);
+OPENSSL_EXPORT int SSL_get_quiet_shutdown(const SSL *ssl);
+OPENSSL_EXPORT void SSL_set_shutdown(SSL *ssl, int mode);
+OPENSSL_EXPORT int SSL_get_shutdown(const SSL *ssl);
+OPENSSL_EXPORT SSL_CTX *SSL_get_SSL_CTX(const SSL *ssl);
+OPENSSL_EXPORT SSL_CTX *SSL_set_SSL_CTX(SSL *ssl, SSL_CTX *ctx);
+OPENSSL_EXPORT void SSL_set_info_callback(SSL *ssl,
+ void (*cb)(const SSL *ssl, int type,
+ int val));
+OPENSSL_EXPORT void (*SSL_get_info_callback(const SSL *ssl))(const SSL *ssl,
+ int type, int val);
+OPENSSL_EXPORT int SSL_state(const SSL *ssl);
+
+/* SSL_CTX_get_max_cert_list returns the maximum length, in bytes, of a peer
+ * certificate chain accepted by |ctx|. */
+OPENSSL_EXPORT size_t SSL_CTX_get_max_cert_list(const SSL_CTX *ctx);
+
+/* SSL_CTX_set_max_cert_list sets the maximum length, in bytes, of a peer
+ * certificate chain to |max_cert_list|. This affects how much memory may be
+ * consumed during the handshake. */
+OPENSSL_EXPORT void SSL_CTX_set_max_cert_list(SSL_CTX *ctx,
+ size_t max_cert_list);
+
+/* SSL_get_max_cert_list returns the maximum length, in bytes, of a peer
+ * certificate chain accepted by |ssl|. */
+OPENSSL_EXPORT size_t SSL_get_max_cert_list(const SSL *ssl);
+
+/* SSL_set_max_cert_list sets the maximum length, in bytes, of a peer
+ * certificate chain to |max_cert_list|. This affects how much memory may be
+ * consumed during the handshake. */
+OPENSSL_EXPORT void SSL_set_max_cert_list(SSL *ssl, size_t max_cert_list);
+
+/* SSL_CTX_set_max_send_fragment sets the maximum length, in bytes, of records
+ * sent by |ctx|. Beyond this length, handshake messages and application data
+ * will be split into multiple records. */
+OPENSSL_EXPORT void SSL_CTX_set_max_send_fragment(SSL_CTX *ctx,
+ size_t max_send_fragment);
+
+/* SSL_set_max_send_fragment sets the maximum length, in bytes, of records
+ * sent by |ssl|. Beyond this length, handshake messages and application data
+ * will be split into multiple records. */
+OPENSSL_EXPORT void SSL_set_max_send_fragment(SSL *ssl,
+ size_t max_send_fragment);
+
+/* SSL_CTX_set_dos_protection_cb sets a callback that is called once the
+ * resumption decision for a ClientHello has been made. It can return 1 to
+ * allow the handshake to continue or zero to cause the handshake to abort. */
+OPENSSL_EXPORT void SSL_CTX_set_dos_protection_cb(
+ SSL_CTX *ctx, int (*cb)(const struct ssl_early_callback_ctx *));
+
+
+/* Deprecated functions. */
+
+/* SSL_CIPHER_description writes a description of |cipher| into |buf| and
+ * returns |buf|. If |buf| is NULL, it returns a newly allocated string, to be
+ * freed with |OPENSSL_free|, or NULL on error.
+ *
+ * The description includes a trailing newline and has the form:
+ * AES128-SHA SSLv3 Kx=RSA Au=RSA Enc=AES(128) Mac=SHA1
+ *
+ * Consider |SSL_CIPHER_get_name| or |SSL_CIPHER_get_rfc_name| instead. */
+OPENSSL_EXPORT const char *SSL_CIPHER_description(const SSL_CIPHER *cipher,
+ char *buf, int len);
+
+/* SSL_CIPHER_get_version returns the string "TLSv1/SSLv3". */
+OPENSSL_EXPORT const char *SSL_CIPHER_get_version(const SSL_CIPHER *cipher);
+
+typedef void COMP_METHOD;
+
+/* SSL_COMP_get_compression_methods returns NULL. */
+OPENSSL_EXPORT COMP_METHOD *SSL_COMP_get_compression_methods(void);
+
+/* SSL_COMP_add_compression_method returns one. */
+OPENSSL_EXPORT int SSL_COMP_add_compression_method(int id, COMP_METHOD *cm);
+
+/* SSL_COMP_get_name returns NULL. */
+OPENSSL_EXPORT const char *SSL_COMP_get_name(const COMP_METHOD *comp);
+
+/* SSLv23_method calls |TLS_method|. */
+OPENSSL_EXPORT const SSL_METHOD *SSLv23_method(void);
+
+/* Version-specific methods behave exactly like |TLS_method| and |DTLS_method|
+ * except they also call |SSL_CTX_set_min_version| and |SSL_CTX_set_max_version|
+ * to lock connections to that protocol version. */
+OPENSSL_EXPORT const SSL_METHOD *SSLv3_method(void);
+OPENSSL_EXPORT const SSL_METHOD *TLSv1_method(void);
+OPENSSL_EXPORT const SSL_METHOD *TLSv1_1_method(void);
+OPENSSL_EXPORT const SSL_METHOD *TLSv1_2_method(void);
+OPENSSL_EXPORT const SSL_METHOD *DTLSv1_method(void);
+OPENSSL_EXPORT const SSL_METHOD *DTLSv1_2_method(void);
+
+/* Client- and server-specific methods call their corresponding generic
+ * methods. */
+OPENSSL_EXPORT const SSL_METHOD *SSLv23_server_method(void);
+OPENSSL_EXPORT const SSL_METHOD *SSLv23_client_method(void);
+OPENSSL_EXPORT const SSL_METHOD *SSLv3_server_method(void);
+OPENSSL_EXPORT const SSL_METHOD *SSLv3_client_method(void);
+OPENSSL_EXPORT const SSL_METHOD *TLSv1_server_method(void);
+OPENSSL_EXPORT const SSL_METHOD *TLSv1_client_method(void);
+OPENSSL_EXPORT const SSL_METHOD *TLSv1_1_server_method(void);
+OPENSSL_EXPORT const SSL_METHOD *TLSv1_1_client_method(void);
+OPENSSL_EXPORT const SSL_METHOD *TLSv1_2_server_method(void);
+OPENSSL_EXPORT const SSL_METHOD *TLSv1_2_client_method(void);
+OPENSSL_EXPORT const SSL_METHOD *DTLS_server_method(void);
+OPENSSL_EXPORT const SSL_METHOD *DTLS_client_method(void);
+OPENSSL_EXPORT const SSL_METHOD *DTLSv1_server_method(void);
+OPENSSL_EXPORT const SSL_METHOD *DTLSv1_client_method(void);
+OPENSSL_EXPORT const SSL_METHOD *DTLSv1_2_server_method(void);
+OPENSSL_EXPORT const SSL_METHOD *DTLSv1_2_client_method(void);
+
+/* SSL_clear resets |ssl| to allow another connection and returns one on success
+ * or zero on failure. It returns most configuration state but releases memory
+ * associated with the current connection.
+ *
+ * Free |ssl| and create a new one instead. */
+OPENSSL_EXPORT int SSL_clear(SSL *ssl);
+
+/* SSL_CTX_set_tmp_rsa_callback does nothing. */
+OPENSSL_EXPORT void SSL_CTX_set_tmp_rsa_callback(
+ SSL_CTX *ctx, RSA *(*cb)(SSL *ssl, int is_export, int keylength));
+
+/* SSL_set_tmp_rsa_callback does nothing. */
+OPENSSL_EXPORT void SSL_set_tmp_rsa_callback(SSL *ssl,
+ RSA *(*cb)(SSL *ssl, int is_export,
+ int keylength));
+
+/* SSL_CTX_sess_connect returns zero. */
+OPENSSL_EXPORT int SSL_CTX_sess_connect(const SSL_CTX *ctx);
+
+/* SSL_CTX_sess_connect_good returns zero. */
+OPENSSL_EXPORT int SSL_CTX_sess_connect_good(const SSL_CTX *ctx);
+
+/* SSL_CTX_sess_connect_renegotiate returns zero. */
+OPENSSL_EXPORT int SSL_CTX_sess_connect_renegotiate(const SSL_CTX *ctx);
+
+/* SSL_CTX_sess_accept returns zero. */
+OPENSSL_EXPORT int SSL_CTX_sess_accept(const SSL_CTX *ctx);
+
+/* SSL_CTX_sess_accept_renegotiate returns zero. */
+OPENSSL_EXPORT int SSL_CTX_sess_accept_renegotiate(const SSL_CTX *ctx);
+
+/* SSL_CTX_sess_accept_good returns zero. */
+OPENSSL_EXPORT int SSL_CTX_sess_accept_good(const SSL_CTX *ctx);
+
+/* SSL_CTX_sess_hits returns zero. */
+OPENSSL_EXPORT int SSL_CTX_sess_hits(const SSL_CTX *ctx);
+
+/* SSL_CTX_sess_cb_hits returns zero. */
+OPENSSL_EXPORT int SSL_CTX_sess_cb_hits(const SSL_CTX *ctx);
+
+/* SSL_CTX_sess_misses returns zero. */
+OPENSSL_EXPORT int SSL_CTX_sess_misses(const SSL_CTX *ctx);
+
+/* SSL_CTX_sess_timeouts returns zero. */
+OPENSSL_EXPORT int SSL_CTX_sess_timeouts(const SSL_CTX *ctx);
+
+/* SSL_CTX_sess_cache_full returns zero. */
+OPENSSL_EXPORT int SSL_CTX_sess_cache_full(const SSL_CTX *ctx);
+
+/* SSL_cutthrough_complete calls |SSL_in_false_start|. */
+OPENSSL_EXPORT int SSL_cutthrough_complete(const SSL *s);
+
+/* SSL_num_renegotiations calls |SSL_total_renegotiations|. */
+OPENSSL_EXPORT int SSL_num_renegotiations(const SSL *ssl);
+
+/* SSL_CTX_need_tmp_RSA returns zero. */
+OPENSSL_EXPORT int SSL_CTX_need_tmp_RSA(const SSL_CTX *ctx);
+
+/* SSL_need_tmp_RSA returns zero. */
+OPENSSL_EXPORT int SSL_need_tmp_RSA(const SSL *ssl);
+
+/* SSL_CTX_set_tmp_rsa returns one. */
+OPENSSL_EXPORT int SSL_CTX_set_tmp_rsa(SSL_CTX *ctx, const RSA *rsa);
+
+/* SSL_set_tmp_rsa returns one. */
+OPENSSL_EXPORT int SSL_set_tmp_rsa(SSL *ssl, const RSA *rsa);
+
+/* SSL_CTX_get_read_ahead returns zero. */
+OPENSSL_EXPORT int SSL_CTX_get_read_ahead(const SSL_CTX *ctx);
+
+/* SSL_CTX_set_read_ahead does nothing. */
+OPENSSL_EXPORT void SSL_CTX_set_read_ahead(SSL_CTX *ctx, int yes);
+
+/* SSL_get_read_ahead returns zero. */
+OPENSSL_EXPORT int SSL_get_read_ahead(const SSL *s);
+
+/* SSL_set_read_ahead does nothing. */
+OPENSSL_EXPORT void SSL_set_read_ahead(SSL *s, int yes);
+
+/* SSL_renegotiate put an error on the error queue and returns zero. */
+OPENSSL_EXPORT int SSL_renegotiate(SSL *ssl);
+
+/* SSL_set_state does nothing. */
+OPENSSL_EXPORT void SSL_set_state(SSL *ssl, int state);
+
+/* SSL_MODE_HANDSHAKE_CUTTHROUGH is the same as SSL_MODE_ENABLE_FALSE_START. */
+#define SSL_MODE_HANDSHAKE_CUTTHROUGH SSL_MODE_ENABLE_FALSE_START
+
+/* i2d_SSL_SESSION serializes |in| to the bytes pointed to by |*pp|. On success,
+ * it returns the number of bytes written and advances |*pp| by that many bytes.
+ * On failure, it returns -1. If |pp| is NULL, no bytes are written and only the
+ * length is returned.
+ *
+ * Use |SSL_SESSION_to_bytes| instead. */
+OPENSSL_EXPORT int i2d_SSL_SESSION(SSL_SESSION *in, uint8_t **pp);
+
+/* d2i_SSL_SESSION parses a serialized session from the |length| bytes pointed
+ * to by |*pp|. It returns the new |SSL_SESSION| and advances |*pp| by the
+ * number of bytes consumed on success and NULL on failure. The caller takes
+ * ownership of the new session and must call |SSL_SESSION_free| when done.
+ *
+ * If |a| is non-NULL, |*a| is released and set the new |SSL_SESSION|.
+ *
+ * Use |SSL_SESSION_from_bytes| instead. */
+OPENSSL_EXPORT SSL_SESSION *d2i_SSL_SESSION(SSL_SESSION **a, const uint8_t **pp,
+ long length);
+
+/* ERR_load_SSL_strings does nothing. */
+OPENSSL_EXPORT void ERR_load_SSL_strings(void);
+
+/* SSL_load_error_strings does nothing. */
+OPENSSL_EXPORT void SSL_load_error_strings(void);
+
+/* SSL_CTX_set_tlsext_use_srtp calls |SSL_CTX_set_srtp_profiles|. It returns
+ * zero on success and one on failure.
+ *
+ * WARNING: this function is dangerous because it breaks the usual return value
+ * convention. Use |SSL_CTX_set_srtp_profiles| instead. */
+OPENSSL_EXPORT int SSL_CTX_set_tlsext_use_srtp(SSL_CTX *ctx,
+ const char *profiles);
+
+/* SSL_set_tlsext_use_srtp calls |SSL_set_srtp_profiles|. It returns zero on
+ * success and one on failure.
+ *
+ * WARNING: this function is dangerous because it breaks the usual return value
+ * convention. Use |SSL_set_srtp_profiles| instead. */
+OPENSSL_EXPORT int SSL_set_tlsext_use_srtp(SSL *ssl, const char *profiles);
+
+/* SSL_get_current_compression returns NULL. */
+OPENSSL_EXPORT const COMP_METHOD *SSL_get_current_compression(SSL *s);
+
+/* SSL_get_current_expansion returns NULL. */
+OPENSSL_EXPORT const COMP_METHOD *SSL_get_current_expansion(SSL *s);
+
+#define SSL_set_app_data(s, arg) (SSL_set_ex_data(s, 0, (char *)arg))
+#define SSL_get_app_data(s) (SSL_get_ex_data(s, 0))
+#define SSL_SESSION_set_app_data(s, a) \
+ (SSL_SESSION_set_ex_data(s, 0, (char *)a))
+#define SSL_SESSION_get_app_data(s) (SSL_SESSION_get_ex_data(s, 0))
+#define SSL_CTX_get_app_data(ctx) (SSL_CTX_get_ex_data(ctx, 0))
+#define SSL_CTX_set_app_data(ctx, arg) \
+ (SSL_CTX_set_ex_data(ctx, 0, (char *)arg))
+
+#define OpenSSL_add_ssl_algorithms() SSL_library_init()
+#define SSLeay_add_ssl_algorithms() SSL_library_init()
+
+#define SSL_get_cipher(ssl) SSL_CIPHER_get_name(SSL_get_current_cipher(ssl))
+#define SSL_get_cipher_bits(ssl, out_alg_bits) \
+ SSL_CIPHER_get_bits(SSL_get_current_cipher(ssl), out_alg_bits)
+#define SSL_get_cipher_version(ssl) \
+ SSL_CIPHER_get_version(SSL_get_current_cipher(ssl))
+#define SSL_get_cipher_name(ssl) \
+ SSL_CIPHER_get_name(SSL_get_current_cipher(ssl))
+#define SSL_get_time(session) SSL_SESSION_get_time(session)
+#define SSL_set_time(session, time) SSL_SESSION_set_time((session), (time))
+#define SSL_get_timeout(session) SSL_SESSION_get_timeout(session)
+#define SSL_set_timeout(session, timeout) \
+ SSL_SESSION_set_timeout((session), (timeout))
+
typedef struct ssl_comp_st SSL_COMP;
struct ssl_comp_st {
@@ -832,7 +2845,165 @@ struct ssl_comp_st {
};
DECLARE_STACK_OF(SSL_COMP)
-DECLARE_LHASH_OF(SSL_SESSION)
+
+/* The following flags toggle individual protocol versions. This is deprecated.
+ * Use |SSL_CTX_set_min_version| and |SSL_CTX_set_max_version| instead. */
+#define SSL_OP_NO_SSLv3 0x02000000L
+#define SSL_OP_NO_TLSv1 0x04000000L
+#define SSL_OP_NO_TLSv1_2 0x08000000L
+#define SSL_OP_NO_TLSv1_1 0x10000000L
+#define SSL_OP_NO_DTLSv1 SSL_OP_NO_TLSv1
+#define SSL_OP_NO_DTLSv1_2 SSL_OP_NO_TLSv1_2
+
+/* The following flags do nothing and are included only to make it easier to
+ * compile code with BoringSSL. */
+#define SSL_MODE_AUTO_RETRY 0
+#define SSL_MODE_RELEASE_BUFFERS 0
+#define SSL_MODE_SEND_CLIENTHELLO_TIME 0
+#define SSL_MODE_SEND_SERVERHELLO_TIME 0
+#define SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION 0
+#define SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS 0
+#define SSL_OP_EPHEMERAL_RSA 0
+#define SSL_OP_MICROSOFT_SESS_ID_BUG 0
+#define SSL_OP_MSIE_SSLV2_RSA_PADDING 0
+#define SSL_OP_NETSCAPE_CA_DN_BUG 0
+#define SSL_OP_NETSCAPE_CHALLENGE_BUG 0
+#define SSL_OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG 0
+#define SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG 0
+#define SSL_OP_NO_COMPRESSION 0
+#define SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION 0
+#define SSL_OP_NO_SSLv2 0
+#define SSL_OP_PKCS1_CHECK_1 0
+#define SSL_OP_PKCS1_CHECK_2 0
+#define SSL_OP_SINGLE_DH_USE 0
+#define SSL_OP_SINGLE_ECDH_USE 0
+#define SSL_OP_SSLEAY_080_CLIENT_DH_BUG 0
+#define SSL_OP_SSLREF2_REUSE_CERT_TYPE_BUG 0
+#define SSL_OP_TLS_BLOCK_PADDING_BUG 0
+#define SSL_OP_TLS_ROLLBACK_BUG 0
+#define SSL_VERIFY_CLIENT_ONCE 0
+
+/* SSL_cache_hit calls |SSL_session_resumed|. */
+OPENSSL_EXPORT int SSL_cache_hit(SSL *ssl);
+
+/* SSL_get_default_timeout returns |SSL_DEFAULT_SESSION_TIMEOUT|. */
+OPENSSL_EXPORT long SSL_get_default_timeout(const SSL *ssl);
+
+/* SSL_get_version returns a string describing the TLS version used by |ssl|.
+ * For example, "TLSv1.2" or "SSLv3". */
+OPENSSL_EXPORT const char *SSL_get_version(const SSL *ssl);
+
+
+/* Private structures.
+ *
+ * This structures are exposed for historical reasons, but access to them is
+ * deprecated. */
+
+struct ssl_cipher_st {
+ /* name is the OpenSSL name for the cipher. */
+ const char *name;
+ /* id is the cipher suite value bitwise OR-d with 0x03000000. */
+ uint32_t id;
+
+ /* The following are internal fields. See ssl/internal.h for their values. */
+
+ uint32_t algorithm_mkey;
+ uint32_t algorithm_auth;
+ uint32_t algorithm_enc;
+ uint32_t algorithm_mac;
+ uint32_t algorithm_ssl;
+ uint32_t algo_strength;
+ uint32_t algorithm_prf;
+
+ /* strength_bits is the strength of the cipher in bits. */
+ int strength_bits;
+ /* alg_bits is the number of bits of key material used by the algorithm. */
+ int alg_bits;
+};
+
+struct ssl_session_st {
+ int ssl_version; /* what ssl version session info is being kept in here? */
+
+ int master_key_length;
+ uint8_t master_key[SSL_MAX_MASTER_KEY_LENGTH];
+ /* session_id - valid? */
+ unsigned int session_id_length;
+ uint8_t session_id[SSL_MAX_SSL_SESSION_ID_LENGTH];
+ /* this is used to determine whether the session is being reused in
+ * the appropriate context. It is up to the application to set this,
+ * via SSL_new */
+ unsigned int sid_ctx_length;
+ uint8_t sid_ctx[SSL_MAX_SID_CTX_LENGTH];
+
+ char *psk_identity;
+ /* Used to indicate that session resumption is not allowed. Applications can
+ * also set this bit for a new session via not_resumable_session_cb to
+ * disable session caching and tickets. */
+ int not_resumable;
+
+ /* peer is the peer's certificate. */
+ X509 *peer;
+
+ /* cert_chain is the certificate chain sent by the peer. NOTE: for historical
+ * reasons, when a client (so the peer is a server), the chain includes
+ * |peer|, but when a server it does not. */
+ STACK_OF(X509) *cert_chain;
+
+ /* when app_verify_callback accepts a session where the peer's certificate is
+ * not ok, we must remember the error for session reuse: */
+ long verify_result; /* only for servers */
+
+ CRYPTO_refcount_t references;
+ long timeout;
+ long time;
+
+ const SSL_CIPHER *cipher;
+
+ /* key_exchange_info contains an indication of the size of the asymmetric
+ * primitive used in the handshake that created this session. In the event
+ * that two asymmetric operations are used, this value applies to the one
+ * that controls the confidentiality of the connection. Its interpretation
+ * depends on the primitive that was used; as specified by the cipher suite:
+ * DHE: the size, in bits, of the multiplicative group.
+ * RSA: the size, in bits, of the modulus.
+ * ECDHE: the TLS id for the curve.
+ *
+ * A zero indicates that the value is unknown. */
+ uint32_t key_exchange_info;
+
+ CRYPTO_EX_DATA ex_data; /* application specific data */
+
+ /* These are used to make removal of session-ids more efficient and to
+ * implement a maximum cache size. */
+ SSL_SESSION *prev, *next;
+ char *tlsext_hostname;
+ /* RFC4507 info */
+ uint8_t *tlsext_tick; /* Session ticket */
+ size_t tlsext_ticklen; /* Session ticket length */
+ uint32_t tlsext_tick_lifetime_hint; /* Session lifetime hint in seconds */
+
+ size_t tlsext_signed_cert_timestamp_list_length;
+ uint8_t *tlsext_signed_cert_timestamp_list; /* Server's list. */
+
+ /* The OCSP response that came with the session. */
+ size_t ocsp_response_length;
+ uint8_t *ocsp_response;
+
+ char peer_sha256_valid; /* Non-zero if peer_sha256 is valid */
+ uint8_t
+ peer_sha256[SHA256_DIGEST_LENGTH]; /* SHA256 of peer certificate */
+
+ /* original_handshake_hash contains the handshake hash (either SHA-1+MD5 or
+ * SHA-2, depending on TLS version) for the original, full handshake that
+ * created a session. This is used by Channel IDs during resumption. */
+ uint8_t original_handshake_hash[EVP_MAX_MD_SIZE];
+ unsigned int original_handshake_hash_len;
+
+ /* extended_master_secret is true if the master secret in this session was
+ * generated using EMS and thus isn't vulnerable to the Triple Handshake
+ * attack. */
+ char extended_master_secret;
+};
/* ssl_cipher_preference_list_st contains a list of SSL_CIPHERs with
* equal-preference groups. For TLS clients, the groups are moot because the
@@ -887,6 +3058,17 @@ struct ssl_ctx_st {
struct ssl_cipher_preference_list_st *cipher_list;
/* same as above but sorted for lookup */
STACK_OF(SSL_CIPHER) *cipher_list_by_id;
+
+ /* cipher_list_tls10 is the list of ciphers when TLS 1.0 or greater is in
+ * use. This only applies to server connections as, for clients, the version
+ * number is known at connect time and so the cipher list can be set then. If
+ * |cipher_list_tls11| is non-NULL then this applies only to TLS 1.0
+ * connections.
+ *
+ * TODO(agl): this exists to assist in the death of SSLv3. It can hopefully
+ * be removed after that. */
+ struct ssl_cipher_preference_list_st *cipher_list_tls10;
+
/* cipher_list_tls11 is the list of ciphers when TLS 1.1 or greater is in
* use. This only applies to server connections as, for clients, the version
* number is known at connect time and so the cipher list can be set then. */
@@ -930,10 +3112,8 @@ struct ssl_ctx_st {
CRYPTO_refcount_t references;
/* if defined, these override the X509_verify_cert() calls */
- int (*app_verify_callback)(X509_STORE_CTX *, void *);
+ int (*app_verify_callback)(X509_STORE_CTX *store_ctx, void *arg);
void *app_verify_arg;
- /* before OpenSSL 0.9.7, 'app_verify_arg' was ignored ('app_verify_callback'
- * was called with just one argument) */
/* Default password callback. */
pem_password_cb *default_passwd_callback;
@@ -945,12 +3125,14 @@ struct ssl_ctx_st {
int (*client_cert_cb)(SSL *ssl, X509 **x509, EVP_PKEY **pkey);
/* get channel id callback */
- void (*channel_id_cb)(SSL *ssl, EVP_PKEY **pkey);
+ void (*channel_id_cb)(SSL *ssl, EVP_PKEY **out_pkey);
CRYPTO_EX_DATA ex_data;
- STACK_OF(X509) *extra_certs;
-
+ /* custom_*_extensions stores any callback sets for custom extensions. Note
+ * that these pointers will be NULL if the stack would otherwise be empty. */
+ STACK_OF(SSL_CUSTOM_EXTENSION) *client_custom_extensions;
+ STACK_OF(SSL_CUSTOM_EXTENSION) *server_custom_extensions;
/* Default values used when no per-SSL value is defined follow */
@@ -1011,7 +3193,7 @@ struct ssl_ctx_st {
int (*tlsext_servername_callback)(SSL *, int *, void *);
void *tlsext_servername_arg;
/* RFC 4507 session ticket keys */
- uint8_t tlsext_tick_key_name[16];
+ uint8_t tlsext_tick_key_name[SSL_TICKET_KEY_NAME_LEN];
uint8_t tlsext_tick_hmac_key[16];
uint8_t tlsext_tick_aes_key[16];
/* Callback to support customisation of ticket key setting */
@@ -1040,13 +3222,13 @@ struct ssl_ctx_st {
/* For a server, this contains a callback function by which the set of
* advertised protocols can be provided. */
- int (*next_protos_advertised_cb)(SSL *s, const uint8_t **buf,
- unsigned int *len, void *arg);
+ int (*next_protos_advertised_cb)(SSL *ssl, const uint8_t **out,
+ unsigned *out_len, void *arg);
void *next_protos_advertised_cb_arg;
/* For a client, this contains a callback function that selects the
* next protocol from the list provided by the server. */
- int (*next_proto_select_cb)(SSL *s, uint8_t **out, uint8_t *outlen,
- const uint8_t *in, unsigned int inlen, void *arg);
+ int (*next_proto_select_cb)(SSL *ssl, uint8_t **out, uint8_t *out_len,
+ const uint8_t *in, unsigned in_len, void *arg);
void *next_proto_select_cb_arg;
/* ALPN information
@@ -1060,8 +3242,8 @@ struct ssl_ctx_st {
* in: points to the client's list of supported protocols in
* wire-format.
* inlen: the length of |in|. */
- int (*alpn_select_cb)(SSL *s, const uint8_t **out, uint8_t *outlen,
- const uint8_t *in, unsigned int inlen, void *arg);
+ int (*alpn_select_cb)(SSL *s, const uint8_t **out, uint8_t *out_len,
+ const uint8_t *in, unsigned in_len, void *arg);
void *alpn_select_cb_arg;
/* For a client, this contains the list of supported protocols in wire
@@ -1073,27 +3255,29 @@ struct ssl_ctx_st {
STACK_OF(SRTP_PROTECTION_PROFILE) *srtp_profiles;
/* EC extension values inherited by SSL structure */
- size_t tlsext_ecpointformatlist_length;
- uint8_t *tlsext_ecpointformatlist;
size_t tlsext_ellipticcurvelist_length;
uint16_t *tlsext_ellipticcurvelist;
/* If true, a client will advertise the Channel ID extension and a server
* will echo it. */
char tlsext_channel_id_enabled;
- /* tlsext_channel_id_enabled_new is a hack to support both old and new
- * ChannelID signatures. It indicates that a client should advertise the new
- * ChannelID extension number. */
- char tlsext_channel_id_enabled_new;
/* The client's Channel ID private key. */
EVP_PKEY *tlsext_channel_id_private;
/* If true, a client will request certificate timestamps. */
char signed_cert_timestamps_enabled;
+ /* Signed certificate timestamp list to be sent to the client, if requested */
+ uint8_t *signed_cert_timestamp_list;
+ size_t signed_cert_timestamp_list_length;
+
/* If true, a client will request a stapled OCSP response. */
char ocsp_stapling_enabled;
+ /* OCSP response to be sent to the client, if requested. */
+ uint8_t *ocsp_response;
+ size_t ocsp_response_length;
+
/* If not NULL, session key material will be logged to this BIO for debugging
* purposes. The format matches NSS's and is readable by Wireshark. */
BIO *keylog_bio;
@@ -1103,193 +3287,6 @@ struct ssl_ctx_st {
void (*current_time_cb)(const SSL *ssl, struct timeval *out_clock);
};
-OPENSSL_EXPORT LHASH_OF(SSL_SESSION) *SSL_CTX_sessions(SSL_CTX *ctx);
-
-/* SSL_CTX_sess_number returns the number of sessions in |ctx|'s internal
- * session cache. */
-OPENSSL_EXPORT size_t SSL_CTX_sess_number(const SSL_CTX *ctx);
-
-OPENSSL_EXPORT void SSL_CTX_sess_set_new_cb(
- SSL_CTX *ctx, int (*new_session_cb)(SSL *ssl, SSL_SESSION *sess));
-OPENSSL_EXPORT int (*SSL_CTX_sess_get_new_cb(SSL_CTX *ctx))(SSL *ssl,
- SSL_SESSION *sess);
-OPENSSL_EXPORT void SSL_CTX_sess_set_remove_cb(
- SSL_CTX *ctx,
- void (*remove_session_cb)(SSL_CTX *ctx, SSL_SESSION *sess));
-OPENSSL_EXPORT void (*SSL_CTX_sess_get_remove_cb(SSL_CTX *ctx))(
- SSL_CTX *ctx, SSL_SESSION *sess);
-OPENSSL_EXPORT void SSL_CTX_sess_set_get_cb(
- SSL_CTX *ctx,
- SSL_SESSION *(*get_session_cb)(SSL *ssl, uint8_t *data, int len,
- int *copy));
-OPENSSL_EXPORT SSL_SESSION *(*SSL_CTX_sess_get_get_cb(SSL_CTX *ctx))(
- SSL *ssl, uint8_t *data, int len, int *copy);
-/* SSL_magic_pending_session_ptr returns a magic SSL_SESSION* which indicates
- * that the session isn't currently unavailable. SSL_get_error will then return
- * SSL_ERROR_PENDING_SESSION and the handshake can be retried later when the
- * lookup has completed. */
-OPENSSL_EXPORT SSL_SESSION *SSL_magic_pending_session_ptr(void);
-OPENSSL_EXPORT void SSL_CTX_set_info_callback(SSL_CTX *ctx,
- void (*cb)(const SSL *ssl,
- int type, int val));
-OPENSSL_EXPORT void (*SSL_CTX_get_info_callback(SSL_CTX *ctx))(const SSL *ssl,
- int type,
- int val);
-OPENSSL_EXPORT void SSL_CTX_set_client_cert_cb(
- SSL_CTX *ctx,
- int (*client_cert_cb)(SSL *ssl, X509 **x509, EVP_PKEY **pkey));
-OPENSSL_EXPORT int (*SSL_CTX_get_client_cert_cb(SSL_CTX *ctx))(SSL *ssl,
- X509 **x509,
- EVP_PKEY **pkey);
-OPENSSL_EXPORT void SSL_CTX_set_channel_id_cb(
- SSL_CTX *ctx, void (*channel_id_cb)(SSL *ssl, EVP_PKEY **pkey));
-OPENSSL_EXPORT void (*SSL_CTX_get_channel_id_cb(SSL_CTX *ctx))(SSL *ssl,
- EVP_PKEY **pkey);
-
-/* SSL_enable_signed_cert_timestamps causes |ssl| (which must be the client end
- * of a connection) to request SCTs from the server. See
- * https://tools.ietf.org/html/rfc6962. It returns one. */
-OPENSSL_EXPORT int SSL_enable_signed_cert_timestamps(SSL *ssl);
-
-/* SSL_CTX_enable_signed_cert_timestamps enables SCT requests on all client SSL
- * objects created from |ctx|. */
-OPENSSL_EXPORT void SSL_CTX_enable_signed_cert_timestamps(SSL_CTX *ctx);
-
-/* SSL_enable_ocsp_stapling causes |ssl| (which must be the client end of a
- * connection) to request a stapled OCSP response from the server. It returns
- * one. */
-OPENSSL_EXPORT int SSL_enable_ocsp_stapling(SSL *ssl);
-
-/* SSL_CTX_enable_ocsp_stapling enables OCSP stapling on all client SSL objects
- * created from |ctx|. */
-OPENSSL_EXPORT void SSL_CTX_enable_ocsp_stapling(SSL_CTX *ctx);
-
-/* SSL_get0_signed_cert_timestamp_list sets |*out| and |*out_len| to point to
- * |*out_len| bytes of SCT information from the server. This is only valid if
- * |ssl| is a client. The SCT information is a SignedCertificateTimestampList
- * (including the two leading length bytes).
- * See https://tools.ietf.org/html/rfc6962#section-3.3
- * If no SCT was received then |*out_len| will be zero on return.
- *
- * WARNING: the returned data is not guaranteed to be well formed. */
-OPENSSL_EXPORT void SSL_get0_signed_cert_timestamp_list(const SSL *ssl,
- const uint8_t **out,
- size_t *out_len);
-
-/* SSL_get0_ocsp_response sets |*out| and |*out_len| to point to |*out_len|
- * bytes of an OCSP response from the server. This is the DER encoding of an
- * OCSPResponse type as defined in RFC 2560.
- *
- * WARNING: the returned data is not guaranteed to be well formed. */
-OPENSSL_EXPORT void SSL_get0_ocsp_response(const SSL *ssl, const uint8_t **out,
- size_t *out_len);
-
-OPENSSL_EXPORT void SSL_CTX_set_next_protos_advertised_cb(
- SSL_CTX *s,
- int (*cb)(SSL *ssl, const uint8_t **out, unsigned int *outlen, void *arg),
- void *arg);
-OPENSSL_EXPORT void SSL_CTX_set_next_proto_select_cb(
- SSL_CTX *s, int (*cb)(SSL *ssl, uint8_t **out, uint8_t *outlen,
- const uint8_t *in, unsigned int inlen, void *arg),
- void *arg);
-OPENSSL_EXPORT void SSL_get0_next_proto_negotiated(const SSL *s,
- const uint8_t **data,
- unsigned *len);
-
-OPENSSL_EXPORT int SSL_select_next_proto(uint8_t **out, uint8_t *outlen,
- const uint8_t *in, unsigned int inlen,
- const uint8_t *client,
- unsigned int client_len);
-
-#define OPENSSL_NPN_UNSUPPORTED 0
-#define OPENSSL_NPN_NEGOTIATED 1
-#define OPENSSL_NPN_NO_OVERLAP 2
-
-/* SSL_CTX_set_alpn_protos sets the ALPN protocol list on |ctx| to |protos|.
- * |protos| must be in wire-format (i.e. a series of non-empty, 8-bit
- * length-prefixed strings). It returns zero on success and one on failure.
- *
- * WARNING: this function is dangerous because it breaks the usual return value
- * convention. */
-OPENSSL_EXPORT int SSL_CTX_set_alpn_protos(SSL_CTX *ctx, const uint8_t *protos,
- unsigned protos_len);
-
-/* SSL_set_alpn_protos sets the ALPN protocol list on |ssl| to |protos|.
- * |protos| must be in wire-format (i.e. a series of non-empty, 8-bit
- * length-prefixed strings). It returns zero on success and one on failure.
- *
- * WARNING: this function is dangerous because it breaks the usual return value
- * convention. */
-OPENSSL_EXPORT int SSL_set_alpn_protos(SSL *ssl, const uint8_t *protos,
- unsigned protos_len);
-
-OPENSSL_EXPORT void SSL_CTX_set_alpn_select_cb(
- SSL_CTX *ctx, int (*cb)(SSL *ssl, const uint8_t **out, uint8_t *outlen,
- const uint8_t *in, unsigned int inlen, void *arg),
- void *arg);
-OPENSSL_EXPORT void SSL_get0_alpn_selected(const SSL *ssl, const uint8_t **data,
- unsigned *len);
-
-/* SSL_enable_fastradio_padding controls whether fastradio padding is enabled
- * on |ssl|. If it is, ClientHello messages are padded to 1024 bytes. This
- * causes 3G radios to switch to DCH mode (high data rate). */
-OPENSSL_EXPORT void SSL_enable_fastradio_padding(SSL *ssl, char on_off);
-
-/* SSL_set_reject_peer_renegotiations controls whether renegotiation attempts by
- * the peer are rejected. It may be set at any point in a connection's lifetime
- * to control future renegotiations programmatically. By default, renegotiations
- * are rejected. (Renegotiations requested by a client are always rejected.) */
-OPENSSL_EXPORT void SSL_set_reject_peer_renegotiations(SSL *ssl, int reject);
-
-/* the maximum length of the buffer given to callbacks containing the resulting
- * identity/psk */
-#define PSK_MAX_IDENTITY_LEN 128
-#define PSK_MAX_PSK_LEN 256
-OPENSSL_EXPORT void SSL_CTX_set_psk_client_callback(
- SSL_CTX *ctx,
- unsigned int (*psk_client_callback)(
- SSL *ssl, const char *hint, char *identity,
- unsigned int max_identity_len, uint8_t *psk, unsigned int max_psk_len));
-OPENSSL_EXPORT void SSL_set_psk_client_callback(
- SSL *ssl, unsigned int (*psk_client_callback)(SSL *ssl, const char *hint,
- char *identity,
- unsigned int max_identity_len,
- uint8_t *psk,
- unsigned int max_psk_len));
-OPENSSL_EXPORT void SSL_CTX_set_psk_server_callback(
- SSL_CTX *ctx,
- unsigned int (*psk_server_callback)(SSL *ssl, const char *identity,
- uint8_t *psk,
- unsigned int max_psk_len));
-OPENSSL_EXPORT void SSL_set_psk_server_callback(
- SSL *ssl,
- unsigned int (*psk_server_callback)(SSL *ssl, const char *identity,
- uint8_t *psk,
- unsigned int max_psk_len));
-OPENSSL_EXPORT int SSL_CTX_use_psk_identity_hint(SSL_CTX *ctx,
- const char *identity_hint);
-OPENSSL_EXPORT int SSL_use_psk_identity_hint(SSL *s, const char *identity_hint);
-OPENSSL_EXPORT const char *SSL_get_psk_identity_hint(const SSL *s);
-OPENSSL_EXPORT const char *SSL_get_psk_identity(const SSL *s);
-
-#define SSL_NOTHING 1
-#define SSL_WRITING 2
-#define SSL_READING 3
-#define SSL_X509_LOOKUP 4
-#define SSL_CHANNEL_ID_LOOKUP 5
-#define SSL_PENDING_SESSION 7
-#define SSL_CERTIFICATE_SELECTION_PENDING 8
-
-/* These will only be used when doing non-blocking IO */
-#define SSL_want_nothing(s) (SSL_want(s) == SSL_NOTHING)
-#define SSL_want_read(s) (SSL_want(s) == SSL_READING)
-#define SSL_want_write(s) (SSL_want(s) == SSL_WRITING)
-#define SSL_want_x509_lookup(s) (SSL_want(s) == SSL_X509_LOOKUP)
-#define SSL_want_channel_id_lookup(s) (SSL_want(s) == SSL_CHANNEL_ID_LOOKUP)
-#define SSL_want_session(s) (SSL_want(s) == SSL_PENDING_SESSION)
-#define SSL_want_certificate(s) \
- (SSL_want(s) == SSL_CERTIFICATE_SELECTION_PENDING)
-
struct ssl_st {
/* version is the protocol version. */
int version;
@@ -1345,7 +3342,6 @@ struct ssl_st {
int shutdown; /* we have shut things down, 0x01 sent, 0x02
* for received */
int state; /* where we are */
- int rstate; /* where we are when reading */
BUF_MEM *init_buf; /* buffer used during init */
uint8_t *init_msg; /* pointer to handshake message body, set by
@@ -1353,10 +3349,6 @@ struct ssl_st {
int init_num; /* amount read/written */
int init_off; /* amount read/written */
- /* used internally to point at a raw packet */
- uint8_t *packet;
- unsigned int packet_length;
-
struct ssl3_state_st *s3; /* SSLv3 variables */
struct dtls1_state_st *d1; /* DTLSv1 variables */
@@ -1429,13 +3421,8 @@ struct ssl_st {
* SSLv3/TLS rollback check */
uint16_t max_send_fragment;
char *tlsext_hostname;
- /* should_ack_sni is true if the SNI extension should be acked. This is
- * only used by a server. */
- char should_ack_sni;
/* RFC4507 session ticket expected to be received or sent */
int tlsext_ticket_expected;
- size_t tlsext_ecpointformatlist_length;
- uint8_t *tlsext_ecpointformatlist; /* our list */
size_t tlsext_ellipticcurvelist_length;
uint16_t *tlsext_ellipticcurvelist; /* our list */
@@ -1467,9 +3454,8 @@ struct ssl_st {
/* Enable signed certificate time stamps. Currently client only. */
char signed_cert_timestamps_enabled;
- /* Enable OCSP stapling. Currently client only.
- * TODO(davidben): Add a server-side implementation when it becomes
- * necesary. */
+ /* ocsp_stapling_enabled is only used by client connections and indicates
+ * whether OCSP stapling will be requested. */
char ocsp_stapling_enabled;
/* For a client, this contains the list of supported protocols in wire
@@ -1477,11 +3463,6 @@ struct ssl_st {
uint8_t *alpn_client_proto_list;
unsigned alpn_client_proto_list_len;
- /* fastradio_padding, if true, causes ClientHellos to be padded to 1024
- * bytes. This ensures that the cellular radio is fast forwarded to DCH (high
- * data rate) state in 3G networks. */
- char fastradio_padding;
-
/* accept_peer_renegotiations, if one, accepts renegotiation attempts from the
* peer. Otherwise, they will be rejected with a fatal error. */
char accept_peer_renegotiations;
@@ -1493,950 +3474,6 @@ struct ssl_st {
EVP_MD_CTX *read_hash;
};
-/* compatibility */
-#define SSL_set_app_data(s, arg) (SSL_set_ex_data(s, 0, (char *)arg))
-#define SSL_get_app_data(s) (SSL_get_ex_data(s, 0))
-#define SSL_SESSION_set_app_data(s, a) \
- (SSL_SESSION_set_ex_data(s, 0, (char *)a))
-#define SSL_SESSION_get_app_data(s) (SSL_SESSION_get_ex_data(s, 0))
-#define SSL_CTX_get_app_data(ctx) (SSL_CTX_get_ex_data(ctx, 0))
-#define SSL_CTX_set_app_data(ctx, arg) \
- (SSL_CTX_set_ex_data(ctx, 0, (char *)arg))
-
-/* The following are the possible values for ssl->state are are used to
- * indicate where we are up to in the SSL connection establishment. The macros
- * that follow are about the only things you should need to use and even then,
- * only when using non-blocking IO. It can also be useful to work out where you
- * were when the connection failed */
-
-#define SSL_ST_CONNECT 0x1000
-#define SSL_ST_ACCEPT 0x2000
-#define SSL_ST_MASK 0x0FFF
-#define SSL_ST_INIT (SSL_ST_CONNECT | SSL_ST_ACCEPT)
-#define SSL_ST_OK 0x03
-#define SSL_ST_RENEGOTIATE (0x04 | SSL_ST_INIT)
-
-#define SSL_CB_LOOP 0x01
-#define SSL_CB_EXIT 0x02
-#define SSL_CB_READ 0x04
-#define SSL_CB_WRITE 0x08
-#define SSL_CB_ALERT 0x4000 /* used in callback */
-#define SSL_CB_READ_ALERT (SSL_CB_ALERT | SSL_CB_READ)
-#define SSL_CB_WRITE_ALERT (SSL_CB_ALERT | SSL_CB_WRITE)
-#define SSL_CB_ACCEPT_LOOP (SSL_ST_ACCEPT | SSL_CB_LOOP)
-#define SSL_CB_ACCEPT_EXIT (SSL_ST_ACCEPT | SSL_CB_EXIT)
-#define SSL_CB_CONNECT_LOOP (SSL_ST_CONNECT | SSL_CB_LOOP)
-#define SSL_CB_CONNECT_EXIT (SSL_ST_CONNECT | SSL_CB_EXIT)
-#define SSL_CB_HANDSHAKE_START 0x10
-#define SSL_CB_HANDSHAKE_DONE 0x20
-
-/* Is the SSL_connection established? */
-#define SSL_get_state(a) SSL_state(a)
-#define SSL_is_init_finished(a) (SSL_state(a) == SSL_ST_OK)
-#define SSL_in_init(a) (SSL_state(a) & SSL_ST_INIT)
-#define SSL_in_connect_init(a) (SSL_state(a) & SSL_ST_CONNECT)
-#define SSL_in_accept_init(a) (SSL_state(a) & SSL_ST_ACCEPT)
-
-/* SSL_in_false_start returns one if |s| has a pending unfinished handshake that
- * is in False Start. |SSL_write| may be called at this point without waiting
- * for the peer, but |SSL_read| will require the handshake to be completed. */
-OPENSSL_EXPORT int SSL_in_false_start(const SSL *s);
-
-/* The following 2 states are kept in ssl->rstate when reads fail,
- * you should not need these */
-#define SSL_ST_READ_HEADER 0xF0
-#define SSL_ST_READ_BODY 0xF1
-#define SSL_ST_READ_DONE 0xF2
-
-/* Obtain latest Finished message
- * -- that we sent (SSL_get_finished)
- * -- that we expected from peer (SSL_get_peer_finished).
- * Returns length (0 == no Finished so far), copies up to 'count' bytes. */
-OPENSSL_EXPORT size_t SSL_get_finished(const SSL *s, void *buf, size_t count);
-OPENSSL_EXPORT size_t SSL_get_peer_finished(const SSL *s, void *buf, size_t count);
-
-/* use either SSL_VERIFY_NONE or SSL_VERIFY_PEER, the last 3 options
- * are 'ored' with SSL_VERIFY_PEER if they are desired */
-#define SSL_VERIFY_NONE 0x00
-#define SSL_VERIFY_PEER 0x01
-#define SSL_VERIFY_FAIL_IF_NO_PEER_CERT 0x02
-/* SSL_VERIFY_CLIENT_ONCE does nothing. */
-#define SSL_VERIFY_CLIENT_ONCE 0x04
-#define SSL_VERIFY_PEER_IF_NO_OBC 0x08
-
-#define OpenSSL_add_ssl_algorithms() SSL_library_init()
-#define SSLeay_add_ssl_algorithms() SSL_library_init()
-
-/* For backward compatibility */
-#define SSL_get_cipher(s) SSL_CIPHER_get_name(SSL_get_current_cipher(s))
-#define SSL_get_cipher_bits(s, np) \
- SSL_CIPHER_get_bits(SSL_get_current_cipher(s), np)
-#define SSL_get_cipher_version(s) \
- SSL_CIPHER_get_version(SSL_get_current_cipher(s))
-#define SSL_get_cipher_name(s) SSL_CIPHER_get_name(SSL_get_current_cipher(s))
-#define SSL_get_time(a) SSL_SESSION_get_time(a)
-#define SSL_set_time(a, b) SSL_SESSION_set_time((a), (b))
-#define SSL_get_timeout(a) SSL_SESSION_get_timeout(a)
-#define SSL_set_timeout(a, b) SSL_SESSION_set_timeout((a), (b))
-
-#define d2i_SSL_SESSION_bio(bp, s_id) \
- ASN1_d2i_bio_of(SSL_SESSION, SSL_SESSION_new, d2i_SSL_SESSION, bp, s_id)
-#define i2d_SSL_SESSION_bio(bp, s_id) \
- ASN1_i2d_bio_of(SSL_SESSION, i2d_SSL_SESSION, bp, s_id)
-
-DECLARE_PEM_rw(SSL_SESSION, SSL_SESSION)
-
-/* make_errors.go reserves error codes above 1000 for manually-assigned errors.
- * This value must be kept in sync with reservedReasonCode in make_errors.h */
-#define SSL_AD_REASON_OFFSET \
- 1000 /* offset to get SSL_R_... value from SSL_AD_... */
-
-/* These alert types are for SSLv3 and TLSv1 */
-#define SSL_AD_CLOSE_NOTIFY SSL3_AD_CLOSE_NOTIFY
-#define SSL_AD_UNEXPECTED_MESSAGE SSL3_AD_UNEXPECTED_MESSAGE /* fatal */
-#define SSL_AD_BAD_RECORD_MAC SSL3_AD_BAD_RECORD_MAC /* fatal */
-#define SSL_AD_DECRYPTION_FAILED TLS1_AD_DECRYPTION_FAILED
-#define SSL_AD_RECORD_OVERFLOW TLS1_AD_RECORD_OVERFLOW
-#define SSL_AD_DECOMPRESSION_FAILURE SSL3_AD_DECOMPRESSION_FAILURE /* fatal */
-#define SSL_AD_HANDSHAKE_FAILURE SSL3_AD_HANDSHAKE_FAILURE /* fatal */
-#define SSL_AD_NO_CERTIFICATE SSL3_AD_NO_CERTIFICATE /* Not for TLS */
-#define SSL_AD_BAD_CERTIFICATE SSL3_AD_BAD_CERTIFICATE
-#define SSL_AD_UNSUPPORTED_CERTIFICATE SSL3_AD_UNSUPPORTED_CERTIFICATE
-#define SSL_AD_CERTIFICATE_REVOKED SSL3_AD_CERTIFICATE_REVOKED
-#define SSL_AD_CERTIFICATE_EXPIRED SSL3_AD_CERTIFICATE_EXPIRED
-#define SSL_AD_CERTIFICATE_UNKNOWN SSL3_AD_CERTIFICATE_UNKNOWN
-#define SSL_AD_ILLEGAL_PARAMETER SSL3_AD_ILLEGAL_PARAMETER /* fatal */
-#define SSL_AD_UNKNOWN_CA TLS1_AD_UNKNOWN_CA /* fatal */
-#define SSL_AD_ACCESS_DENIED TLS1_AD_ACCESS_DENIED /* fatal */
-#define SSL_AD_DECODE_ERROR TLS1_AD_DECODE_ERROR /* fatal */
-#define SSL_AD_DECRYPT_ERROR TLS1_AD_DECRYPT_ERROR
-#define SSL_AD_EXPORT_RESTRICTION TLS1_AD_EXPORT_RESTRICTION /* fatal */
-#define SSL_AD_PROTOCOL_VERSION TLS1_AD_PROTOCOL_VERSION /* fatal */
-#define SSL_AD_INSUFFICIENT_SECURITY TLS1_AD_INSUFFICIENT_SECURITY /* fatal */
-#define SSL_AD_INTERNAL_ERROR TLS1_AD_INTERNAL_ERROR /* fatal */
-#define SSL_AD_USER_CANCELLED TLS1_AD_USER_CANCELLED
-#define SSL_AD_NO_RENEGOTIATION TLS1_AD_NO_RENEGOTIATION
-#define SSL_AD_UNSUPPORTED_EXTENSION TLS1_AD_UNSUPPORTED_EXTENSION
-#define SSL_AD_CERTIFICATE_UNOBTAINABLE TLS1_AD_CERTIFICATE_UNOBTAINABLE
-#define SSL_AD_UNRECOGNIZED_NAME TLS1_AD_UNRECOGNIZED_NAME
-#define SSL_AD_BAD_CERTIFICATE_STATUS_RESPONSE \
- TLS1_AD_BAD_CERTIFICATE_STATUS_RESPONSE
-#define SSL_AD_BAD_CERTIFICATE_HASH_VALUE TLS1_AD_BAD_CERTIFICATE_HASH_VALUE
-#define SSL_AD_UNKNOWN_PSK_IDENTITY TLS1_AD_UNKNOWN_PSK_IDENTITY /* fatal */
-#define SSL_AD_INAPPROPRIATE_FALLBACK SSL3_AD_INAPPROPRIATE_FALLBACK /* fatal */
-
-#define SSL_ERROR_NONE 0
-#define SSL_ERROR_SSL 1
-#define SSL_ERROR_WANT_READ 2
-#define SSL_ERROR_WANT_WRITE 3
-#define SSL_ERROR_WANT_X509_LOOKUP 4
-#define SSL_ERROR_SYSCALL 5 /* look at error stack/return value/errno */
-#define SSL_ERROR_ZERO_RETURN 6
-#define SSL_ERROR_WANT_CONNECT 7
-#define SSL_ERROR_WANT_ACCEPT 8
-#define SSL_ERROR_WANT_CHANNEL_ID_LOOKUP 9
-#define SSL_ERROR_PENDING_SESSION 11
-#define SSL_ERROR_PENDING_CERTIFICATE 12
-
-#define SSL_CTRL_EXTRA_CHAIN_CERT 14
-
-/* see tls1.h for macros based on these */
-#define SSL_CTRL_GET_TLSEXT_TICKET_KEYS 58
-#define SSL_CTRL_SET_TLSEXT_TICKET_KEYS 59
-
-#define SSL_CTRL_SET_SRP_ARG 78
-#define SSL_CTRL_SET_TLS_EXT_SRP_USERNAME 79
-#define SSL_CTRL_SET_TLS_EXT_SRP_STRENGTH 80
-#define SSL_CTRL_SET_TLS_EXT_SRP_PASSWORD 81
-
-#define SSL_CTRL_GET_EXTRA_CHAIN_CERTS 82
-#define SSL_CTRL_CLEAR_EXTRA_CHAIN_CERTS 83
-
-#define SSL_CTRL_CHAIN 88
-#define SSL_CTRL_CHAIN_CERT 89
-
-#define SSL_CTRL_GET_CURVES 90
-#define SSL_CTRL_SET_CURVES 91
-#define SSL_CTRL_SET_CURVES_LIST 92
-#define SSL_CTRL_SET_SIGALGS 97
-#define SSL_CTRL_SET_SIGALGS_LIST 98
-#define SSL_CTRL_SET_CLIENT_SIGALGS 101
-#define SSL_CTRL_SET_CLIENT_SIGALGS_LIST 102
-#define SSL_CTRL_GET_CLIENT_CERT_TYPES 103
-#define SSL_CTRL_SET_CLIENT_CERT_TYPES 104
-#define SSL_CTRL_BUILD_CERT_CHAIN 105
-#define SSL_CTRL_SET_VERIFY_CERT_STORE 106
-#define SSL_CTRL_SET_CHAIN_CERT_STORE 107
-#define SSL_CTRL_GET_SERVER_TMP_KEY 109
-#define SSL_CTRL_GET_EC_POINT_FORMATS 111
-
-#define SSL_CTRL_GET_CHAIN_CERTS 115
-#define SSL_CTRL_SELECT_CURRENT_CERT 116
-
-/* DTLSv1_get_timeout queries the next DTLS handshake timeout. If there is a
- * timeout in progress, it sets |*out| to the time remaining and returns one.
- * Otherwise, it returns zero.
- *
- * When the timeout expires, call |DTLSv1_handle_timeout| to handle the
- * retransmit behavior.
- *
- * NOTE: This function must be queried again whenever the handshake state
- * machine changes, including when |DTLSv1_handle_timeout| is called. */
-OPENSSL_EXPORT int DTLSv1_get_timeout(const SSL *ssl, struct timeval *out);
-
-/* DTLSv1_handle_timeout is called when a DTLS handshake timeout expires. If no
- * timeout had expired, it returns 0. Otherwise, it retransmits the previous
- * flight of handshake messages and returns 1. If too many timeouts had expired
- * without progress or an error occurs, it returns -1.
- *
- * NOTE: The caller's external timer should be compatible with the one |ssl|
- * queries within some fudge factor. Otherwise, the call will be a no-op, but
- * |DTLSv1_get_timeout| will return an updated timeout.
- *
- * WARNING: This function breaks the usual return value convention. */
-OPENSSL_EXPORT int DTLSv1_handle_timeout(SSL *ssl);
-
-/* SSL_session_reused returns one if |ssl| performed an abbreviated handshake
- * and zero otherwise.
- *
- * TODO(davidben): Hammer down the semantics of this API while a handshake,
- * initial or renego, is in progress. */
-OPENSSL_EXPORT int SSL_session_reused(const SSL *ssl);
-
-/* SSL_total_renegotiations returns the total number of renegotiation handshakes
- * peformed by |ssl|. This includes the pending renegotiation, if any. */
-OPENSSL_EXPORT int SSL_total_renegotiations(const SSL *ssl);
-
-/* SSL_CTX_set_tmp_dh configures |ctx| to use the group from |dh| as the group
- * for DHE. Only the group is used, so |dh| needn't have a keypair. It returns
- * one on success and zero on error. */
-OPENSSL_EXPORT int SSL_CTX_set_tmp_dh(SSL_CTX *ctx, const DH *dh);
-
-/* SSL_set_tmp_dh configures |ssl| to use the group from |dh| as the group for
- * DHE. Only the group is used, so |dh| needn't have a keypair. It returns one
- * on success and zero on error. */
-OPENSSL_EXPORT int SSL_set_tmp_dh(SSL *ssl, const DH *dh);
-
-/* SSL_CTX_set_tmp_ecdh configures |ctx| to use the curve from |ecdh| as the
- * curve for ephemeral ECDH keys. For historical reasons, this API expects an
- * |EC_KEY|, but only the curve is used. It returns one on success and zero on
- * error. If unset, an appropriate curve will be chosen automatically. (This is
- * recommended.) */
-OPENSSL_EXPORT int SSL_CTX_set_tmp_ecdh(SSL_CTX *ctx, const EC_KEY *ec_key);
-
-/* SSL_set_tmp_ecdh configures |ssl| to use the curve from |ecdh| as the curve
- * for ephemeral ECDH keys. For historical reasons, this API expects an
- * |EC_KEY|, but only the curve is used. It returns one on success and zero on
- * error. If unset, an appropriate curve will be chosen automatically. (This is
- * recommended.) */
-OPENSSL_EXPORT int SSL_set_tmp_ecdh(SSL *ssl, const EC_KEY *ec_key);
-
-/* SSL_CTX_enable_tls_channel_id either configures a TLS server to accept TLS
- * client IDs from clients, or configures a client to send TLS client IDs to
- * a server. It returns one. */
-OPENSSL_EXPORT int SSL_CTX_enable_tls_channel_id(SSL_CTX *ctx);
-
-/* SSL_enable_tls_channel_id either configures a TLS server to accept TLS
- * client IDs from clients, or configure a client to send TLS client IDs to
- * server. It returns one. */
-OPENSSL_EXPORT int SSL_enable_tls_channel_id(SSL *ssl);
-
-/* SSL_CTX_set1_tls_channel_id configures a TLS client to send a TLS Channel ID
- * to compatible servers. |private_key| must be a P-256 EC key. It returns one
- * on success and zero on error. */
-OPENSSL_EXPORT int SSL_CTX_set1_tls_channel_id(SSL_CTX *ctx,
- EVP_PKEY *private_key);
-
-/* SSL_set1_tls_channel_id configures a TLS client to send a TLS Channel ID to
- * compatible servers. |private_key| must be a P-256 EC key. It returns one on
- * success and zero on error. */
-OPENSSL_EXPORT int SSL_set1_tls_channel_id(SSL *ssl, EVP_PKEY *private_key);
-
-/* SSL_get_tls_channel_id gets the client's TLS Channel ID from a server SSL*
- * and copies up to the first |max_out| bytes into |out|. The Channel ID
- * consists of the client's P-256 public key as an (x,y) pair where each is a
- * 32-byte, big-endian field element. It returns 0 if the client didn't offer a
- * Channel ID and the length of the complete Channel ID otherwise. */
-OPENSSL_EXPORT size_t SSL_get_tls_channel_id(SSL *ssl, uint8_t *out,
- size_t max_out);
-
-#define SSL_CTX_add_extra_chain_cert(ctx, x509) \
- SSL_CTX_ctrl(ctx, SSL_CTRL_EXTRA_CHAIN_CERT, 0, (char *)x509)
-#define SSL_CTX_get_extra_chain_certs(ctx, px509) \
- SSL_CTX_ctrl(ctx, SSL_CTRL_GET_EXTRA_CHAIN_CERTS, 0, px509)
-#define SSL_CTX_get_extra_chain_certs_only(ctx, px509) \
- SSL_CTX_ctrl(ctx, SSL_CTRL_GET_EXTRA_CHAIN_CERTS, 1, px509)
-#define SSL_CTX_clear_extra_chain_certs(ctx) \
- SSL_CTX_ctrl(ctx, SSL_CTRL_CLEAR_EXTRA_CHAIN_CERTS, 0, NULL)
-
-#define SSL_CTX_set0_chain(ctx, sk) \
- SSL_CTX_ctrl(ctx, SSL_CTRL_CHAIN, 0, (char *)sk)
-#define SSL_CTX_set1_chain(ctx, sk) \
- SSL_CTX_ctrl(ctx, SSL_CTRL_CHAIN, 1, (char *)sk)
-#define SSL_CTX_add0_chain_cert(ctx, x509) \
- SSL_CTX_ctrl(ctx, SSL_CTRL_CHAIN_CERT, 0, (char *)x509)
-#define SSL_CTX_add1_chain_cert(ctx, x509) \
- SSL_CTX_ctrl(ctx, SSL_CTRL_CHAIN_CERT, 1, (char *)x509)
-#define SSL_CTX_get0_chain_certs(ctx, px509) \
- SSL_CTX_ctrl(ctx, SSL_CTRL_GET_CHAIN_CERTS, 0, px509)
-#define SSL_CTX_clear_chain_certs(ctx) SSL_CTX_set0_chain(ctx, NULL)
-#define SSL_CTX_build_cert_chain(ctx, flags) \
- SSL_CTX_ctrl(ctx, SSL_CTRL_BUILD_CERT_CHAIN, flags, NULL)
-#define SSL_CTX_select_current_cert(ctx, x509) \
- SSL_CTX_ctrl(ctx, SSL_CTRL_SELECT_CURRENT_CERT, 0, (char *)x509)
-
-#define SSL_CTX_set0_verify_cert_store(ctx, st) \
- SSL_CTX_ctrl(ctx, SSL_CTRL_SET_VERIFY_CERT_STORE, 0, (char *)st)
-#define SSL_CTX_set1_verify_cert_store(ctx, st) \
- SSL_CTX_ctrl(ctx, SSL_CTRL_SET_VERIFY_CERT_STORE, 1, (char *)st)
-#define SSL_CTX_set0_chain_cert_store(ctx, st) \
- SSL_CTX_ctrl(ctx, SSL_CTRL_SET_CHAIN_CERT_STORE, 0, (char *)st)
-#define SSL_CTX_set1_chain_cert_store(ctx, st) \
- SSL_CTX_ctrl(ctx, SSL_CTRL_SET_CHAIN_CERT_STORE, 1, (char *)st)
-
-#define SSL_set0_chain(ctx, sk) SSL_ctrl(ctx, SSL_CTRL_CHAIN, 0, (char *)sk)
-#define SSL_set1_chain(ctx, sk) SSL_ctrl(ctx, SSL_CTRL_CHAIN, 1, (char *)sk)
-#define SSL_add0_chain_cert(ctx, x509) \
- SSL_ctrl(ctx, SSL_CTRL_CHAIN_CERT, 0, (char *)x509)
-#define SSL_add1_chain_cert(ctx, x509) \
- SSL_ctrl(ctx, SSL_CTRL_CHAIN_CERT, 1, (char *)x509)
-#define SSL_get0_chain_certs(ctx, px509) \
- SSL_ctrl(ctx, SSL_CTRL_GET_CHAIN_CERTS, 0, px509)
-#define SSL_clear_chain_certs(ctx) SSL_set0_chain(ctx, NULL)
-#define SSL_build_cert_chain(s, flags) \
- SSL_ctrl(s, SSL_CTRL_BUILD_CERT_CHAIN, flags, NULL)
-#define SSL_select_current_cert(ctx, x509) \
- SSL_ctrl(ctx, SSL_CTRL_SELECT_CURRENT_CERT, 0, (char *)x509)
-
-#define SSL_set0_verify_cert_store(s, st) \
- SSL_ctrl(s, SSL_CTRL_SET_VERIFY_CERT_STORE, 0, (char *)st)
-#define SSL_set1_verify_cert_store(s, st) \
- SSL_ctrl(s, SSL_CTRL_SET_VERIFY_CERT_STORE, 1, (char *)st)
-#define SSL_set0_chain_cert_store(s, st) \
- SSL_ctrl(s, SSL_CTRL_SET_CHAIN_CERT_STORE, 0, (char *)st)
-#define SSL_set1_chain_cert_store(s, st) \
- SSL_ctrl(s, SSL_CTRL_SET_CHAIN_CERT_STORE, 1, (char *)st)
-
-#define SSL_get1_curves(ctx, s) SSL_ctrl(ctx, SSL_CTRL_GET_CURVES, 0, (char *)s)
-#define SSL_CTX_set1_curves(ctx, clist, clistlen) \
- SSL_CTX_ctrl(ctx, SSL_CTRL_SET_CURVES, clistlen, (char *)clist)
-#define SSL_CTX_set1_curves_list(ctx, s) \
- SSL_CTX_ctrl(ctx, SSL_CTRL_SET_CURVES_LIST, 0, (char *)s)
-#define SSL_set1_curves(ctx, clist, clistlen) \
- SSL_ctrl(ctx, SSL_CTRL_SET_CURVES, clistlen, (char *)clist)
-#define SSL_set1_curves_list(ctx, s) \
- SSL_ctrl(ctx, SSL_CTRL_SET_CURVES_LIST, 0, (char *)s)
-
-#define SSL_CTX_set1_sigalgs(ctx, slist, slistlen) \
- SSL_CTX_ctrl(ctx, SSL_CTRL_SET_SIGALGS, slistlen, (int *)slist)
-#define SSL_CTX_set1_sigalgs_list(ctx, s) \
- SSL_CTX_ctrl(ctx, SSL_CTRL_SET_SIGALGS_LIST, 0, (char *)s)
-#define SSL_set1_sigalgs(ctx, slist, slistlen) \
- SSL_ctrl(ctx, SSL_CTRL_SET_SIGALGS, clistlen, (int *)slist)
-#define SSL_set1_sigalgs_list(ctx, s) \
- SSL_ctrl(ctx, SSL_CTRL_SET_SIGALGS_LIST, 0, (char *)s)
-
-#define SSL_CTX_set1_client_sigalgs(ctx, slist, slistlen) \
- SSL_CTX_ctrl(ctx, SSL_CTRL_SET_CLIENT_SIGALGS, slistlen, (int *)slist)
-#define SSL_CTX_set1_client_sigalgs_list(ctx, s) \
- SSL_CTX_ctrl(ctx, SSL_CTRL_SET_CLIENT_SIGALGS_LIST, 0, (char *)s)
-#define SSL_set1_client_sigalgs(ctx, slist, slistlen) \
- SSL_ctrl(ctx, SSL_CTRL_SET_CLIENT_SIGALGS, clistlen, (int *)slist)
-#define SSL_set1_client_sigalgs_list(ctx, s) \
- SSL_ctrl(ctx, SSL_CTRL_SET_CLIENT_SIGALGS_LIST, 0, (char *)s)
-
-#define SSL_get0_certificate_types(s, clist) \
- SSL_ctrl(s, SSL_CTRL_GET_CLIENT_CERT_TYPES, 0, (char *)clist)
-
-#define SSL_CTX_set1_client_certificate_types(ctx, clist, clistlen) \
- SSL_CTX_ctrl(ctx, SSL_CTRL_SET_CLIENT_CERT_TYPES, clistlen, (char *)clist)
-#define SSL_set1_client_certificate_types(s, clist, clistlen) \
- SSL_ctrl(s, SSL_CTRL_SET_CLIENT_CERT_TYPES, clistlen, (char *)clist)
-
-#define SSL_get_server_tmp_key(s, pk) \
- SSL_ctrl(s, SSL_CTRL_GET_SERVER_TMP_KEY, 0, pk)
-
-#define SSL_get0_ec_point_formats(s, plst) \
- SSL_ctrl(s, SSL_CTRL_GET_EC_POINT_FORMATS, 0, (char *)plst)
-
-OPENSSL_EXPORT int SSL_CTX_set_cipher_list(SSL_CTX *, const char *str);
-OPENSSL_EXPORT int SSL_CTX_set_cipher_list_tls11(SSL_CTX *, const char *str);
-OPENSSL_EXPORT long SSL_CTX_set_timeout(SSL_CTX *ctx, long t);
-OPENSSL_EXPORT long SSL_CTX_get_timeout(const SSL_CTX *ctx);
-OPENSSL_EXPORT X509_STORE *SSL_CTX_get_cert_store(const SSL_CTX *);
-OPENSSL_EXPORT void SSL_CTX_set_cert_store(SSL_CTX *, X509_STORE *);
-OPENSSL_EXPORT int SSL_want(const SSL *s);
-
-OPENSSL_EXPORT void SSL_CTX_flush_sessions(SSL_CTX *ctx, long tm);
-
-/* SSL_get_current_cipher returns the cipher used in the current outgoing
- * connection state, or NULL if the null cipher is active. */
-OPENSSL_EXPORT const SSL_CIPHER *SSL_get_current_cipher(const SSL *s);
-
-OPENSSL_EXPORT int SSL_get_fd(const SSL *s);
-OPENSSL_EXPORT int SSL_get_rfd(const SSL *s);
-OPENSSL_EXPORT int SSL_get_wfd(const SSL *s);
-OPENSSL_EXPORT const char *SSL_get_cipher_list(const SSL *s, int n);
-OPENSSL_EXPORT int SSL_pending(const SSL *s);
-OPENSSL_EXPORT int SSL_set_fd(SSL *s, int fd);
-OPENSSL_EXPORT int SSL_set_rfd(SSL *s, int fd);
-OPENSSL_EXPORT int SSL_set_wfd(SSL *s, int fd);
-OPENSSL_EXPORT void SSL_set_bio(SSL *s, BIO *rbio, BIO *wbio);
-OPENSSL_EXPORT BIO *SSL_get_rbio(const SSL *s);
-OPENSSL_EXPORT BIO *SSL_get_wbio(const SSL *s);
-OPENSSL_EXPORT int SSL_set_cipher_list(SSL *s, const char *str);
-OPENSSL_EXPORT int SSL_get_verify_mode(const SSL *s);
-OPENSSL_EXPORT int SSL_get_verify_depth(const SSL *s);
-OPENSSL_EXPORT int (*SSL_get_verify_callback(const SSL *s))(int,
- X509_STORE_CTX *);
-OPENSSL_EXPORT void SSL_set_verify(SSL *s, int mode,
- int (*callback)(int ok,
- X509_STORE_CTX *ctx));
-OPENSSL_EXPORT void SSL_set_verify_depth(SSL *s, int depth);
-OPENSSL_EXPORT void SSL_set_cert_cb(SSL *s, int (*cb)(SSL *ssl, void *arg),
- void *arg);
-OPENSSL_EXPORT int SSL_use_RSAPrivateKey(SSL *ssl, RSA *rsa);
-OPENSSL_EXPORT int SSL_use_RSAPrivateKey_ASN1(SSL *ssl, uint8_t *d, long len);
-OPENSSL_EXPORT int SSL_use_PrivateKey(SSL *ssl, EVP_PKEY *pkey);
-OPENSSL_EXPORT int SSL_use_PrivateKey_ASN1(int pk, SSL *ssl, const uint8_t *d,
- long len);
-OPENSSL_EXPORT int SSL_use_certificate(SSL *ssl, X509 *x);
-OPENSSL_EXPORT int SSL_use_certificate_ASN1(SSL *ssl, const uint8_t *d,
- int len);
-
-OPENSSL_EXPORT int SSL_use_RSAPrivateKey_file(SSL *ssl, const char *file,
- int type);
-OPENSSL_EXPORT int SSL_use_PrivateKey_file(SSL *ssl, const char *file,
- int type);
-OPENSSL_EXPORT int SSL_use_certificate_file(SSL *ssl, const char *file,
- int type);
-OPENSSL_EXPORT int SSL_CTX_use_RSAPrivateKey_file(SSL_CTX *ctx,
- const char *file, int type);
-OPENSSL_EXPORT int SSL_CTX_use_PrivateKey_file(SSL_CTX *ctx, const char *file,
- int type);
-OPENSSL_EXPORT int SSL_CTX_use_certificate_file(SSL_CTX *ctx, const char *file,
- int type);
-OPENSSL_EXPORT int SSL_CTX_use_certificate_chain_file(
- SSL_CTX *ctx, const char *file); /* PEM type */
-OPENSSL_EXPORT STACK_OF(X509_NAME) *SSL_load_client_CA_file(const char *file);
-OPENSSL_EXPORT int SSL_add_file_cert_subjects_to_stack(STACK_OF(X509_NAME) *
- stackCAs,
- const char *file);
-OPENSSL_EXPORT int SSL_add_dir_cert_subjects_to_stack(STACK_OF(X509_NAME) *
- stackCAs,
- const char *dir);
-
-/* SSL_load_error_strings does nothing. */
-OPENSSL_EXPORT void SSL_load_error_strings(void);
-
-OPENSSL_EXPORT const char *SSL_state_string(const SSL *s);
-OPENSSL_EXPORT const char *SSL_rstate_string(const SSL *s);
-OPENSSL_EXPORT const char *SSL_state_string_long(const SSL *s);
-OPENSSL_EXPORT const char *SSL_rstate_string_long(const SSL *s);
-OPENSSL_EXPORT long SSL_SESSION_get_time(const SSL_SESSION *s);
-OPENSSL_EXPORT long SSL_SESSION_set_time(SSL_SESSION *s, long t);
-OPENSSL_EXPORT long SSL_SESSION_get_timeout(const SSL_SESSION *s);
-OPENSSL_EXPORT long SSL_SESSION_set_timeout(SSL_SESSION *s, long t);
-OPENSSL_EXPORT X509 *SSL_SESSION_get0_peer(SSL_SESSION *s);
-OPENSSL_EXPORT int SSL_SESSION_set1_id_context(SSL_SESSION *s,
- const uint8_t *sid_ctx,
- unsigned int sid_ctx_len);
-
-OPENSSL_EXPORT SSL_SESSION *SSL_SESSION_new(void);
-OPENSSL_EXPORT const uint8_t *SSL_SESSION_get_id(const SSL_SESSION *s,
- unsigned int *len);
-OPENSSL_EXPORT int SSL_SESSION_print_fp(FILE *fp, const SSL_SESSION *ses);
-OPENSSL_EXPORT int SSL_SESSION_print(BIO *fp, const SSL_SESSION *ses);
-
-/* SSL_SESSION_up_ref, if |session| is not NULL, increments the reference count
- * of |session|. It then returns |session|. */
-OPENSSL_EXPORT SSL_SESSION *SSL_SESSION_up_ref(SSL_SESSION *session);
-
-/* SSL_SESSION_free decrements the reference count of |session|. If it reaches
- * zero, all data referenced by |session| and |session| itself are released. */
-OPENSSL_EXPORT void SSL_SESSION_free(SSL_SESSION *session);
-
-OPENSSL_EXPORT int SSL_set_session(SSL *to, SSL_SESSION *session);
-OPENSSL_EXPORT int SSL_CTX_add_session(SSL_CTX *s, SSL_SESSION *c);
-OPENSSL_EXPORT int SSL_CTX_remove_session(SSL_CTX *, SSL_SESSION *c);
-OPENSSL_EXPORT int SSL_CTX_set_generate_session_id(SSL_CTX *, GEN_SESSION_CB);
-OPENSSL_EXPORT int SSL_set_generate_session_id(SSL *, GEN_SESSION_CB);
-OPENSSL_EXPORT int SSL_has_matching_session_id(const SSL *ssl,
- const uint8_t *id,
- unsigned int id_len);
-
-/* SSL_SESSION_to_bytes serializes |in| into a newly allocated buffer and sets
- * |*out_data| to that buffer and |*out_len| to its length. The caller takes
- * ownership of the buffer and must call |OPENSSL_free| when done. It returns
- * one on success and zero on error. */
-OPENSSL_EXPORT int SSL_SESSION_to_bytes(SSL_SESSION *in, uint8_t **out_data,
- size_t *out_len);
-
-/* SSL_SESSION_to_bytes_for_ticket serializes |in|, but excludes the session
- * identification information, namely the session ID and ticket. */
-OPENSSL_EXPORT int SSL_SESSION_to_bytes_for_ticket(SSL_SESSION *in,
- uint8_t **out_data,
- size_t *out_len);
-
-/* SSL_SESSION_from_bytes parses |in_len| bytes from |in| as an SSL_SESSION. It
- * returns a newly-allocated |SSL_SESSION| on success or NULL on error. */
-OPENSSL_EXPORT SSL_SESSION *SSL_SESSION_from_bytes(const uint8_t *in,
- size_t in_len);
-
-/* Deprecated: i2d_SSL_SESSION serializes |in| to the bytes pointed to by
- * |*pp|. On success, it returns the number of bytes written and advances |*pp|
- * by that many bytes. On failure, it returns -1. If |pp| is NULL, no bytes are
- * written and only the length is returned.
- *
- * Use |SSL_SESSION_to_bytes| instead. */
-OPENSSL_EXPORT int i2d_SSL_SESSION(SSL_SESSION *in, uint8_t **pp);
-
-/* Deprecated: d2i_SSL_SESSION parses a serialized session from the |length|
- * bytes pointed to by |*pp|. It returns the new |SSL_SESSION| and advances
- * |*pp| by the number of bytes consumed on success and NULL on failure. The
- * caller takes ownership of the new session and must call |SSL_SESSION_free|
- * when done.
- *
- * If |a| is non-NULL, |*a| is released and set the new |SSL_SESSION|.
- *
- * Use |SSL_SESSION_from_bytes| instead. */
-OPENSSL_EXPORT SSL_SESSION *d2i_SSL_SESSION(SSL_SESSION **a, const uint8_t **pp,
- long length);
-
-OPENSSL_EXPORT X509 *SSL_get_peer_certificate(const SSL *s);
-
-OPENSSL_EXPORT STACK_OF(X509) *SSL_get_peer_cert_chain(const SSL *s);
-
-OPENSSL_EXPORT int SSL_CTX_get_verify_mode(const SSL_CTX *ctx);
-OPENSSL_EXPORT int SSL_CTX_get_verify_depth(const SSL_CTX *ctx);
-OPENSSL_EXPORT int (*SSL_CTX_get_verify_callback(const SSL_CTX *ctx))(
- int, X509_STORE_CTX *);
-OPENSSL_EXPORT void SSL_CTX_set_verify(SSL_CTX *ctx, int mode,
- int (*callback)(int, X509_STORE_CTX *));
-OPENSSL_EXPORT void SSL_CTX_set_verify_depth(SSL_CTX *ctx, int depth);
-OPENSSL_EXPORT void SSL_CTX_set_cert_verify_callback(
- SSL_CTX *ctx, int (*cb)(X509_STORE_CTX *, void *), void *arg);
-OPENSSL_EXPORT void SSL_CTX_set_cert_cb(SSL_CTX *c,
- int (*cb)(SSL *ssl, void *arg),
- void *arg);
-OPENSSL_EXPORT int SSL_CTX_use_RSAPrivateKey(SSL_CTX *ctx, RSA *rsa);
-OPENSSL_EXPORT int SSL_CTX_use_RSAPrivateKey_ASN1(SSL_CTX *ctx,
- const uint8_t *d, long len);
-OPENSSL_EXPORT int SSL_CTX_use_PrivateKey(SSL_CTX *ctx, EVP_PKEY *pkey);
-OPENSSL_EXPORT int SSL_CTX_use_PrivateKey_ASN1(int pk, SSL_CTX *ctx,
- const uint8_t *d, long len);
-OPENSSL_EXPORT int SSL_CTX_use_certificate(SSL_CTX *ctx, X509 *x);
-OPENSSL_EXPORT int SSL_CTX_use_certificate_ASN1(SSL_CTX *ctx, int len,
- const uint8_t *d);
-
-OPENSSL_EXPORT void SSL_CTX_set_default_passwd_cb(SSL_CTX *ctx,
- pem_password_cb *cb);
-OPENSSL_EXPORT void SSL_CTX_set_default_passwd_cb_userdata(SSL_CTX *ctx,
- void *u);
-
-OPENSSL_EXPORT int SSL_CTX_check_private_key(const SSL_CTX *ctx);
-OPENSSL_EXPORT int SSL_check_private_key(const SSL *ctx);
-
-OPENSSL_EXPORT int SSL_CTX_set_session_id_context(SSL_CTX *ctx,
- const uint8_t *sid_ctx,
- unsigned int sid_ctx_len);
-
-OPENSSL_EXPORT int SSL_set_session_id_context(SSL *ssl, const uint8_t *sid_ctx,
- unsigned int sid_ctx_len);
-
-OPENSSL_EXPORT int SSL_CTX_set_purpose(SSL_CTX *s, int purpose);
-OPENSSL_EXPORT int SSL_set_purpose(SSL *s, int purpose);
-OPENSSL_EXPORT int SSL_CTX_set_trust(SSL_CTX *s, int trust);
-OPENSSL_EXPORT int SSL_set_trust(SSL *s, int trust);
-
-OPENSSL_EXPORT int SSL_CTX_set1_param(SSL_CTX *ctx, X509_VERIFY_PARAM *vpm);
-OPENSSL_EXPORT int SSL_set1_param(SSL *ssl, X509_VERIFY_PARAM *vpm);
-
-OPENSSL_EXPORT X509_VERIFY_PARAM *SSL_CTX_get0_param(SSL_CTX *ctx);
-OPENSSL_EXPORT X509_VERIFY_PARAM *SSL_get0_param(SSL *ssl);
-
-OPENSSL_EXPORT void SSL_certs_clear(SSL *s);
-OPENSSL_EXPORT int SSL_accept(SSL *ssl);
-OPENSSL_EXPORT int SSL_connect(SSL *ssl);
-OPENSSL_EXPORT int SSL_read(SSL *ssl, void *buf, int num);
-OPENSSL_EXPORT int SSL_peek(SSL *ssl, void *buf, int num);
-OPENSSL_EXPORT int SSL_write(SSL *ssl, const void *buf, int num);
-OPENSSL_EXPORT long SSL_ctrl(SSL *ssl, int cmd, long larg, void *parg);
-OPENSSL_EXPORT long SSL_CTX_ctrl(SSL_CTX *ctx, int cmd, long larg, void *parg);
-
-OPENSSL_EXPORT int SSL_get_error(const SSL *s, int ret_code);
-/* SSL_get_version returns a string describing the TLS version used by |s|. For
- * example, "TLSv1.2" or "SSLv3". */
-OPENSSL_EXPORT const char *SSL_get_version(const SSL *s);
-/* SSL_SESSION_get_version returns a string describing the TLS version used by
- * |sess|. For example, "TLSv1.2" or "SSLv3". */
-OPENSSL_EXPORT const char *SSL_SESSION_get_version(const SSL_SESSION *sess);
-
-OPENSSL_EXPORT STACK_OF(SSL_CIPHER) *SSL_get_ciphers(const SSL *s);
-
-OPENSSL_EXPORT int SSL_do_handshake(SSL *s);
-
-/* SSL_renegotiate_pending returns one if |ssl| is in the middle of a
- * renegotiation. */
-OPENSSL_EXPORT int SSL_renegotiate_pending(SSL *ssl);
-
-OPENSSL_EXPORT int SSL_shutdown(SSL *s);
-
-OPENSSL_EXPORT const char *SSL_alert_type_string_long(int value);
-OPENSSL_EXPORT const char *SSL_alert_type_string(int value);
-OPENSSL_EXPORT const char *SSL_alert_desc_string_long(int value);
-OPENSSL_EXPORT const char *SSL_alert_desc_string(int value);
-
-OPENSSL_EXPORT void SSL_set_client_CA_list(SSL *s,
- STACK_OF(X509_NAME) *name_list);
-OPENSSL_EXPORT void SSL_CTX_set_client_CA_list(SSL_CTX *ctx,
- STACK_OF(X509_NAME) *name_list);
-OPENSSL_EXPORT STACK_OF(X509_NAME) *SSL_get_client_CA_list(const SSL *s);
-OPENSSL_EXPORT STACK_OF(X509_NAME) *
- SSL_CTX_get_client_CA_list(const SSL_CTX *s);
-OPENSSL_EXPORT int SSL_add_client_CA(SSL *ssl, X509 *x);
-OPENSSL_EXPORT int SSL_CTX_add_client_CA(SSL_CTX *ctx, X509 *x);
-
-OPENSSL_EXPORT long SSL_get_default_timeout(const SSL *s);
-
-OPENSSL_EXPORT STACK_OF(X509_NAME) *SSL_dup_CA_list(STACK_OF(X509_NAME) *sk);
-
-OPENSSL_EXPORT X509 *SSL_get_certificate(const SSL *ssl);
-OPENSSL_EXPORT EVP_PKEY *SSL_get_privatekey(const SSL *ssl);
-
-OPENSSL_EXPORT X509 *SSL_CTX_get0_certificate(const SSL_CTX *ctx);
-OPENSSL_EXPORT EVP_PKEY *SSL_CTX_get0_privatekey(const SSL_CTX *ctx);
-
-OPENSSL_EXPORT void SSL_CTX_set_quiet_shutdown(SSL_CTX *ctx, int mode);
-OPENSSL_EXPORT int SSL_CTX_get_quiet_shutdown(const SSL_CTX *ctx);
-OPENSSL_EXPORT void SSL_set_quiet_shutdown(SSL *ssl, int mode);
-OPENSSL_EXPORT int SSL_get_quiet_shutdown(const SSL *ssl);
-OPENSSL_EXPORT void SSL_set_shutdown(SSL *ssl, int mode);
-OPENSSL_EXPORT int SSL_get_shutdown(const SSL *ssl);
-OPENSSL_EXPORT int SSL_version(const SSL *ssl);
-OPENSSL_EXPORT int SSL_CTX_set_default_verify_paths(SSL_CTX *ctx);
-OPENSSL_EXPORT int SSL_CTX_load_verify_locations(SSL_CTX *ctx,
- const char *CAfile,
- const char *CApath);
-#define SSL_get0_session SSL_get_session /* just peek at pointer */
-OPENSSL_EXPORT SSL_SESSION *SSL_get_session(const SSL *ssl);
-OPENSSL_EXPORT SSL_SESSION *SSL_get1_session(
- SSL *ssl); /* obtain a reference count */
-OPENSSL_EXPORT SSL_CTX *SSL_get_SSL_CTX(const SSL *ssl);
-OPENSSL_EXPORT SSL_CTX *SSL_set_SSL_CTX(SSL *ssl, SSL_CTX *ctx);
-OPENSSL_EXPORT void SSL_set_info_callback(SSL *ssl,
- void (*cb)(const SSL *ssl, int type,
- int val));
-OPENSSL_EXPORT void (*SSL_get_info_callback(const SSL *ssl))(const SSL *ssl,
- int type, int val);
-OPENSSL_EXPORT int SSL_state(const SSL *ssl);
-
-OPENSSL_EXPORT void SSL_set_verify_result(SSL *ssl, long v);
-OPENSSL_EXPORT long SSL_get_verify_result(const SSL *ssl);
-
-OPENSSL_EXPORT int SSL_set_ex_data(SSL *ssl, int idx, void *data);
-OPENSSL_EXPORT void *SSL_get_ex_data(const SSL *ssl, int idx);
-OPENSSL_EXPORT int SSL_get_ex_new_index(long argl, void *argp,
- CRYPTO_EX_new *new_func,
- CRYPTO_EX_dup *dup_func,
- CRYPTO_EX_free *free_func);
-
-OPENSSL_EXPORT int SSL_SESSION_set_ex_data(SSL_SESSION *ss, int idx,
- void *data);
-OPENSSL_EXPORT void *SSL_SESSION_get_ex_data(const SSL_SESSION *ss, int idx);
-OPENSSL_EXPORT int SSL_SESSION_get_ex_new_index(long argl, void *argp,
- CRYPTO_EX_new *new_func,
- CRYPTO_EX_dup *dup_func,
- CRYPTO_EX_free *free_func);
-
-OPENSSL_EXPORT int SSL_CTX_set_ex_data(SSL_CTX *ssl, int idx, void *data);
-OPENSSL_EXPORT void *SSL_CTX_get_ex_data(const SSL_CTX *ssl, int idx);
-OPENSSL_EXPORT int SSL_CTX_get_ex_new_index(long argl, void *argp,
- CRYPTO_EX_new *new_func,
- CRYPTO_EX_dup *dup_func,
- CRYPTO_EX_free *free_func);
-
-OPENSSL_EXPORT int SSL_get_ex_data_X509_STORE_CTX_idx(void);
-
-/* SSL_CTX_sess_set_cache_size sets the maximum size of |ctx|'s session cache to
- * |size|. It returns the previous value. */
-OPENSSL_EXPORT unsigned long SSL_CTX_sess_set_cache_size(SSL_CTX *ctx,
- unsigned long size);
-
-/* SSL_CTX_sess_get_cache_size returns the maximum size of |ctx|'s session
- * cache. */
-OPENSSL_EXPORT unsigned long SSL_CTX_sess_get_cache_size(const SSL_CTX *ctx);
-
-/* SSL_SESS_CACHE_* are the possible session cache mode bits.
- * TODO(davidben): Document. */
-#define SSL_SESS_CACHE_OFF 0x0000
-#define SSL_SESS_CACHE_CLIENT 0x0001
-#define SSL_SESS_CACHE_SERVER 0x0002
-#define SSL_SESS_CACHE_BOTH (SSL_SESS_CACHE_CLIENT | SSL_SESS_CACHE_SERVER)
-#define SSL_SESS_CACHE_NO_AUTO_CLEAR 0x0080
-#define SSL_SESS_CACHE_NO_INTERNAL_LOOKUP 0x0100
-#define SSL_SESS_CACHE_NO_INTERNAL_STORE 0x0200
-#define SSL_SESS_CACHE_NO_INTERNAL \
- (SSL_SESS_CACHE_NO_INTERNAL_LOOKUP | SSL_SESS_CACHE_NO_INTERNAL_STORE)
-
-/* SSL_CTX_set_session_cache_mode sets the session cache mode bits for |ctx| to
- * |mode|. It returns the previous value. */
-OPENSSL_EXPORT int SSL_CTX_set_session_cache_mode(SSL_CTX *ctx, int mode);
-
-/* SSL_CTX_get_session_cache_mode returns the session cache mode bits for
- * |ctx| */
-OPENSSL_EXPORT int SSL_CTX_get_session_cache_mode(const SSL_CTX *ctx);
-
-/* SSL_CTX_get_max_cert_list returns the maximum length, in bytes, of a peer
- * certificate chain accepted by |ctx|. */
-OPENSSL_EXPORT size_t SSL_CTX_get_max_cert_list(const SSL_CTX *ctx);
-
-/* SSL_CTX_set_max_cert_list sets the maximum length, in bytes, of a peer
- * certificate chain to |max_cert_list|. This affects how much memory may be
- * consumed during the handshake. */
-OPENSSL_EXPORT void SSL_CTX_set_max_cert_list(SSL_CTX *ctx,
- size_t max_cert_list);
-
-/* SSL_get_max_cert_list returns the maximum length, in bytes, of a peer
- * certificate chain accepted by |ssl|. */
-OPENSSL_EXPORT size_t SSL_get_max_cert_list(const SSL *ssl);
-
-/* SSL_set_max_cert_list sets the maximum length, in bytes, of a peer
- * certificate chain to |max_cert_list|. This affects how much memory may be
- * consumed during the handshake. */
-OPENSSL_EXPORT void SSL_set_max_cert_list(SSL *ssl, size_t max_cert_list);
-
-/* SSL_CTX_set_max_send_fragment sets the maximum length, in bytes, of records
- * sent by |ctx|. Beyond this length, handshake messages and application data
- * will be split into multiple records. */
-OPENSSL_EXPORT void SSL_CTX_set_max_send_fragment(SSL_CTX *ctx,
- size_t max_send_fragment);
-
-/* SSL_set_max_send_fragment sets the maximum length, in bytes, of records
- * sent by |ssl|. Beyond this length, handshake messages and application data
- * will be split into multiple records. */
-OPENSSL_EXPORT void SSL_set_max_send_fragment(SSL *ssl,
- size_t max_send_fragment);
-
-/* SSL_CTX_set_tmp_dh_callback configures |ctx| to use |callback| to determine
- * the group for DHE ciphers. |callback| should ignore |is_export| and
- * |keylength| and return a |DH| of the selected group or NULL on error. Only
- * the parameters are used, so the |DH| needn't have a generated keypair.
- *
- * WARNING: The caller does not take ownership of the resulting |DH|, so
- * |callback| must save and release the object elsewhere. */
-OPENSSL_EXPORT void SSL_CTX_set_tmp_dh_callback(
- SSL_CTX *ctx, DH *(*callback)(SSL *ssl, int is_export, int keylength));
-
-/* SSL_set_tmp_dh_callback configures |ssl| to use |callback| to determine the
- * group for DHE ciphers. |callback| should ignore |is_export| and |keylength|
- * and return a |DH| of the selected group or NULL on error. Only the
- * parameters are used, so the |DH| needn't have a generated keypair.
- *
- * WARNING: The caller does not take ownership of the resulting |DH|, so
- * |callback| must save and release the object elsewhere. */
-OPENSSL_EXPORT void SSL_set_tmp_dh_callback(SSL *ssl,
- DH *(*dh)(SSL *ssl, int is_export,
- int keylength));
-
-/* SSL_CTX_set_tmp_ecdh_callback configures |ctx| to use |callback| to determine
- * the curve for ephemeral ECDH keys. |callback| should ignore |is_export| and
- * |keylength| and return an |EC_KEY| of the selected curve or NULL on
- * error. Only the curve is used, so the |EC_KEY| needn't have a generated
- * keypair.
- *
- * If the callback is unset, an appropriate curve will be chosen automatically.
- * (This is recommended.)
- *
- * WARNING: The caller does not take ownership of the resulting |EC_KEY|, so
- * |callback| must save and release the object elsewhere. */
-OPENSSL_EXPORT void SSL_CTX_set_tmp_ecdh_callback(
- SSL_CTX *ctx, EC_KEY *(*callback)(SSL *ssl, int is_export, int keylength));
-
-/* SSL_set_tmp_ecdh_callback configures |ssl| to use |callback| to determine the
- * curve for ephemeral ECDH keys. |callback| should ignore |is_export| and
- * |keylength| and return an |EC_KEY| of the selected curve or NULL on
- * error. Only the curve is used, so the |EC_KEY| needn't have a generated
- * keypair.
- *
- * If the callback is unset, an appropriate curve will be chosen automatically.
- * (This is recommended.)
- *
- * WARNING: The caller does not take ownership of the resulting |EC_KEY|, so
- * |callback| must save and release the object elsewhere. */
-OPENSSL_EXPORT void SSL_set_tmp_ecdh_callback(
- SSL *ssl, EC_KEY *(*callback)(SSL *ssl, int is_export, int keylength));
-
-OPENSSL_EXPORT const void *SSL_get_current_compression(SSL *s);
-OPENSSL_EXPORT const void *SSL_get_current_expansion(SSL *s);
-
-OPENSSL_EXPORT int SSL_cache_hit(SSL *s);
-OPENSSL_EXPORT int SSL_is_server(SSL *s);
-
-/* SSL_CTX_set_dos_protection_cb sets a callback that is called once the
- * resumption decision for a ClientHello has been made. It can return 1 to
- * allow the handshake to continue or zero to cause the handshake to abort. */
-OPENSSL_EXPORT void SSL_CTX_set_dos_protection_cb(
- SSL_CTX *ctx, int (*cb)(const struct ssl_early_callback_ctx *));
-
-/* SSL_get_structure_sizes returns the sizes of the SSL, SSL_CTX and
- * SSL_SESSION structures so that a test can ensure that outside code agrees on
- * these values. */
-OPENSSL_EXPORT void SSL_get_structure_sizes(size_t *ssl_size,
- size_t *ssl_ctx_size,
- size_t *ssl_session_size);
-
-OPENSSL_EXPORT void ERR_load_SSL_strings(void);
-
-/* SSL_get_rc4_state sets |*read_key| and |*write_key| to the RC4 states for
- * the read and write directions. It returns one on success or zero if |ssl|
- * isn't using an RC4-based cipher suite. */
-OPENSSL_EXPORT int SSL_get_rc4_state(const SSL *ssl, const RC4_KEY **read_key,
- const RC4_KEY **write_key);
-
-
-/* Deprecated functions. */
-
-/* SSL_CIPHER_description writes a description of |cipher| into |buf| and
- * returns |buf|. If |buf| is NULL, it returns a newly allocated string, to be
- * freed with |OPENSSL_free|, or NULL on error.
- *
- * The description includes a trailing newline and has the form:
- * AES128-SHA SSLv3 Kx=RSA Au=RSA Enc=AES(128) Mac=SHA1
- *
- * Consider |SSL_CIPHER_get_name| or |SSL_CIPHER_get_rfc_name| instead. */
-OPENSSL_EXPORT const char *SSL_CIPHER_description(const SSL_CIPHER *cipher,
- char *buf, int len);
-
-/* SSL_CIPHER_get_version returns the string "TLSv1/SSLv3". */
-OPENSSL_EXPORT const char *SSL_CIPHER_get_version(const SSL_CIPHER *cipher);
-
-/* SSL_COMP_get_compression_methods returns NULL. */
-OPENSSL_EXPORT void *SSL_COMP_get_compression_methods(void);
-
-/* SSL_COMP_add_compression_method returns one. */
-OPENSSL_EXPORT int SSL_COMP_add_compression_method(int id, void *cm);
-
-/* SSL_COMP_get_name returns NULL. */
-OPENSSL_EXPORT const char *SSL_COMP_get_name(const void *comp);
-
-/* SSLv23_method calls |TLS_method|. */
-OPENSSL_EXPORT const SSL_METHOD *SSLv23_method(void);
-
-/* Version-specific methods behave exactly like |TLS_method| and |DTLS_method|
- * except they also call |SSL_CTX_set_min_version| and |SSL_CTX_set_max_version|
- * to lock connections to that protocol version. */
-OPENSSL_EXPORT const SSL_METHOD *SSLv3_method(void);
-OPENSSL_EXPORT const SSL_METHOD *TLSv1_method(void);
-OPENSSL_EXPORT const SSL_METHOD *TLSv1_1_method(void);
-OPENSSL_EXPORT const SSL_METHOD *TLSv1_2_method(void);
-OPENSSL_EXPORT const SSL_METHOD *DTLSv1_method(void);
-OPENSSL_EXPORT const SSL_METHOD *DTLSv1_2_method(void);
-
-/* Client- and server-specific methods call their corresponding generic
- * methods. */
-OPENSSL_EXPORT const SSL_METHOD *SSLv23_server_method(void);
-OPENSSL_EXPORT const SSL_METHOD *SSLv23_client_method(void);
-OPENSSL_EXPORT const SSL_METHOD *SSLv3_server_method(void);
-OPENSSL_EXPORT const SSL_METHOD *SSLv3_client_method(void);
-OPENSSL_EXPORT const SSL_METHOD *TLSv1_server_method(void);
-OPENSSL_EXPORT const SSL_METHOD *TLSv1_client_method(void);
-OPENSSL_EXPORT const SSL_METHOD *TLSv1_1_server_method(void);
-OPENSSL_EXPORT const SSL_METHOD *TLSv1_1_client_method(void);
-OPENSSL_EXPORT const SSL_METHOD *TLSv1_2_server_method(void);
-OPENSSL_EXPORT const SSL_METHOD *TLSv1_2_client_method(void);
-OPENSSL_EXPORT const SSL_METHOD *DTLS_server_method(void);
-OPENSSL_EXPORT const SSL_METHOD *DTLS_client_method(void);
-OPENSSL_EXPORT const SSL_METHOD *DTLSv1_server_method(void);
-OPENSSL_EXPORT const SSL_METHOD *DTLSv1_client_method(void);
-OPENSSL_EXPORT const SSL_METHOD *DTLSv1_2_server_method(void);
-OPENSSL_EXPORT const SSL_METHOD *DTLSv1_2_client_method(void);
-
-/* SSL_clear resets |ssl| to allow another connection and returns one on success
- * or zero on failure. It returns most configuration state but releases memory
- * associated with the current connection.
- *
- * Free |ssl| and create a new one instead. */
-OPENSSL_EXPORT int SSL_clear(SSL *ssl);
-
-/* SSL_CTX_set_tmp_rsa_callback does nothing. */
-OPENSSL_EXPORT void SSL_CTX_set_tmp_rsa_callback(
- SSL_CTX *ctx, RSA *(*cb)(SSL *ssl, int is_export, int keylength));
-
-/* SSL_set_tmp_rsa_callback does nothing. */
-OPENSSL_EXPORT void SSL_set_tmp_rsa_callback(SSL *ssl,
- RSA *(*cb)(SSL *ssl, int is_export,
- int keylength));
-
-/* SSL_CTX_sess_connect returns zero. */
-OPENSSL_EXPORT int SSL_CTX_sess_connect(const SSL_CTX *ctx);
-
-/* SSL_CTX_sess_connect_good returns zero. */
-OPENSSL_EXPORT int SSL_CTX_sess_connect_good(const SSL_CTX *ctx);
-
-/* SSL_CTX_sess_connect_renegotiate returns zero. */
-OPENSSL_EXPORT int SSL_CTX_sess_connect_renegotiate(const SSL_CTX *ctx);
-
-/* SSL_CTX_sess_accept returns zero. */
-OPENSSL_EXPORT int SSL_CTX_sess_accept(const SSL_CTX *ctx);
-
-/* SSL_CTX_sess_accept_renegotiate returns zero. */
-OPENSSL_EXPORT int SSL_CTX_sess_accept_renegotiate(const SSL_CTX *ctx);
-
-/* SSL_CTX_sess_accept_good returns zero. */
-OPENSSL_EXPORT int SSL_CTX_sess_accept_good(const SSL_CTX *ctx);
-
-/* SSL_CTX_sess_hits returns zero. */
-OPENSSL_EXPORT int SSL_CTX_sess_hits(const SSL_CTX *ctx);
-
-/* SSL_CTX_sess_cb_hits returns zero. */
-OPENSSL_EXPORT int SSL_CTX_sess_cb_hits(const SSL_CTX *ctx);
-
-/* SSL_CTX_sess_misses returns zero. */
-OPENSSL_EXPORT int SSL_CTX_sess_misses(const SSL_CTX *ctx);
-
-/* SSL_CTX_sess_timeouts returns zero. */
-OPENSSL_EXPORT int SSL_CTX_sess_timeouts(const SSL_CTX *ctx);
-
-/* SSL_CTX_sess_cache_full returns zero. */
-OPENSSL_EXPORT int SSL_CTX_sess_cache_full(const SSL_CTX *ctx);
-
-/* SSL_cutthrough_complete calls |SSL_in_false_start|. */
-OPENSSL_EXPORT int SSL_cutthrough_complete(const SSL *s);
-
-/* SSL_num_renegotiations calls |SSL_total_renegotiations|. */
-OPENSSL_EXPORT int SSL_num_renegotiations(const SSL *ssl);
-
-/* SSL_CTX_need_tmp_RSA returns zero. */
-OPENSSL_EXPORT int SSL_CTX_need_tmp_RSA(const SSL_CTX *ctx);
-
-/* SSL_need_tmp_RSA returns zero. */
-OPENSSL_EXPORT int SSL_need_tmp_RSA(const SSL *ssl);
-
-/* SSL_CTX_set_tmp_rsa returns one. */
-OPENSSL_EXPORT int SSL_CTX_set_tmp_rsa(SSL_CTX *ctx, const RSA *rsa);
-
-/* SSL_set_tmp_rsa returns one. */
-OPENSSL_EXPORT int SSL_set_tmp_rsa(SSL *ssl, const RSA *rsa);
-
-/* SSL_CTX_get_read_head returns zero. */
-OPENSSL_EXPORT int SSL_CTX_get_read_ahead(const SSL_CTX *ctx);
-
-/* SSL_CTX_set_read_ahead does nothing. */
-OPENSSL_EXPORT void SSL_CTX_set_read_ahead(SSL_CTX *ctx, int yes);
-
-/* SSL_get_read_head returns zero. */
-OPENSSL_EXPORT int SSL_get_read_ahead(const SSL *s);
-
-/* SSL_set_read_ahead does nothing. */
-OPENSSL_EXPORT void SSL_set_read_ahead(SSL *s, int yes);
-
-/* SSL_renegotiate put an error on the error queue and returns zero. */
-OPENSSL_EXPORT int SSL_renegotiate(SSL *ssl);
-
-/* SSL_set_state does nothing. */
-OPENSSL_EXPORT void SSL_set_state(SSL *ssl, int state);
-
/* Android compatibility section.
*
@@ -2465,99 +3502,133 @@ OPENSSL_EXPORT const char *SSLeay_version(int unused);
*
* Historically, a number of APIs were implemented in OpenSSL as macros and
* constants to 'ctrl' functions. To avoid breaking #ifdefs in consumers, this
- * section defines a number of legacy macros. */
+ * section defines a number of legacy macros.
+ *
+ * Although using either the CTRL values or their wrapper macros in #ifdefs is
+ * still supported, the CTRL values may not be passed to |SSL_ctrl| and
+ * |SSL_CTX_ctrl|. Call the functions (previously wrapper macros) instead. */
-#define SSL_CTRL_NEED_TMP_RSA doesnt_exist
-#define SSL_CTRL_SET_TMP_RSA doesnt_exist
-#define SSL_CTRL_SET_TMP_DH doesnt_exist
-#define SSL_CTRL_SET_TMP_ECDH doesnt_exist
-#define SSL_CTRL_SET_TMP_RSA_CB doesnt_exist
-#define SSL_CTRL_SET_TMP_DH_CB doesnt_exist
-#define SSL_CTRL_SET_TMP_ECDH_CB doesnt_exist
-#define SSL_CTRL_GET_SESSION_REUSED doesnt_exist
+#define DTLS_CTRL_GET_TIMEOUT doesnt_exist
+#define DTLS_CTRL_HANDLE_TIMEOUT doesnt_exist
+#define SSL_CTRL_CHAIN doesnt_exist
+#define SSL_CTRL_CHAIN_CERT doesnt_exist
+#define SSL_CTRL_CHANNEL_ID doesnt_exist
+#define SSL_CTRL_CLEAR_EXTRA_CHAIN_CERTS doesnt_exist
+#define SSL_CTRL_CLEAR_MODE doesnt_exist
+#define SSL_CTRL_CLEAR_OPTIONS doesnt_exist
+#define SSL_CTRL_EXTRA_CHAIN_CERT doesnt_exist
+#define SSL_CTRL_GET_CHAIN_CERTS doesnt_exist
+#define SSL_CTRL_GET_CHANNEL_ID doesnt_exist
+#define SSL_CTRL_GET_CLIENT_CERT_TYPES doesnt_exist
+#define SSL_CTRL_GET_EXTRA_CHAIN_CERTS doesnt_exist
+#define SSL_CTRL_GET_MAX_CERT_LIST doesnt_exist
#define SSL_CTRL_GET_NUM_RENEGOTIATIONS doesnt_exist
+#define SSL_CTRL_GET_READ_AHEAD doesnt_exist
+#define SSL_CTRL_GET_RI_SUPPORT doesnt_exist
+#define SSL_CTRL_GET_SESSION_REUSED doesnt_exist
+#define SSL_CTRL_GET_SESS_CACHE_MODE doesnt_exist
+#define SSL_CTRL_GET_SESS_CACHE_SIZE doesnt_exist
+#define SSL_CTRL_GET_TLSEXT_TICKET_KEYS doesnt_exist
#define SSL_CTRL_GET_TOTAL_RENEGOTIATIONS doesnt_exist
+#define SSL_CTRL_MODE doesnt_exist
+#define SSL_CTRL_NEED_TMP_RSA doesnt_exist
+#define SSL_CTRL_OPTIONS doesnt_exist
+#define SSL_CTRL_SESS_NUMBER doesnt_exist
+#define SSL_CTRL_SET_CHANNEL_ID doesnt_exist
+#define SSL_CTRL_SET_CURVES doesnt_exist
+#define SSL_CTRL_SET_MAX_CERT_LIST doesnt_exist
+#define SSL_CTRL_SET_MAX_SEND_FRAGMENT doesnt_exist
#define SSL_CTRL_SET_MSG_CALLBACK doesnt_exist
#define SSL_CTRL_SET_MSG_CALLBACK_ARG doesnt_exist
#define SSL_CTRL_SET_MTU doesnt_exist
-#define SSL_CTRL_SESS_NUMBER doesnt_exist
-#define SSL_CTRL_OPTIONS doesnt_exist
-#define SSL_CTRL_MODE doesnt_exist
-#define SSL_CTRL_GET_READ_AHEAD doesnt_exist
#define SSL_CTRL_SET_READ_AHEAD doesnt_exist
-#define SSL_CTRL_SET_SESS_CACHE_SIZE doesnt_exist
-#define SSL_CTRL_GET_SESS_CACHE_SIZE doesnt_exist
#define SSL_CTRL_SET_SESS_CACHE_MODE doesnt_exist
-#define SSL_CTRL_GET_SESS_CACHE_MODE doesnt_exist
-#define SSL_CTRL_GET_MAX_CERT_LIST doesnt_exist
-#define SSL_CTRL_SET_MAX_CERT_LIST doesnt_exist
-#define SSL_CTRL_SET_MAX_SEND_FRAGMENT doesnt_exist
-#define SSL_CTRL_SET_TLSEXT_SERVERNAME_CB doesnt_exist
-#define SSL_CTRL_SET_TLSEXT_SERVERNAME_ARG doesnt_exist
+#define SSL_CTRL_SET_SESS_CACHE_SIZE doesnt_exist
#define SSL_CTRL_SET_TLSEXT_HOSTNAME doesnt_exist
+#define SSL_CTRL_SET_TLSEXT_SERVERNAME_ARG doesnt_exist
+#define SSL_CTRL_SET_TLSEXT_SERVERNAME_CB doesnt_exist
+#define SSL_CTRL_SET_TLSEXT_TICKET_KEYS doesnt_exist
#define SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB doesnt_exist
-#define DTLS_CTRL_GET_TIMEOUT doesnt_exist
-#define DTLS_CTRL_HANDLE_TIMEOUT doesnt_exist
-#define SSL_CTRL_GET_RI_SUPPORT doesnt_exist
-#define SSL_CTRL_CLEAR_OPTIONS doesnt_exist
-#define SSL_CTRL_CLEAR_MODE doesnt_exist
-#define SSL_CTRL_CHANNEL_ID doesnt_exist
-#define SSL_CTRL_GET_CHANNEL_ID doesnt_exist
-#define SSL_CTRL_SET_CHANNEL_ID doesnt_exist
+#define SSL_CTRL_SET_TMP_DH doesnt_exist
+#define SSL_CTRL_SET_TMP_DH_CB doesnt_exist
+#define SSL_CTRL_SET_TMP_ECDH doesnt_exist
+#define SSL_CTRL_SET_TMP_ECDH_CB doesnt_exist
+#define SSL_CTRL_SET_TMP_RSA doesnt_exist
+#define SSL_CTRL_SET_TMP_RSA_CB doesnt_exist
-#define SSL_CTX_need_tmp_RSA SSL_CTX_need_tmp_RSA
-#define SSL_need_tmp_RSA SSL_need_tmp_RSA
-#define SSL_CTX_set_tmp_rsa SSL_CTX_set_tmp_rsa
-#define SSL_set_tmp_rsa SSL_set_tmp_rsa
-#define SSL_CTX_set_tmp_dh SSL_CTX_set_tmp_dh
-#define SSL_set_tmp_dh SSL_set_tmp_dh
-#define SSL_CTX_set_tmp_ecdh SSL_CTX_set_tmp_ecdh
-#define SSL_set_tmp_ecdh SSL_set_tmp_ecdh
-#define SSL_session_reused SSL_session_reused
-#define SSL_num_renegotiations SSL_num_renegotiations
-#define SSL_total_renegotiations SSL_total_renegotiations
-#define SSL_CTX_set_msg_callback_arg SSL_CTX_set_msg_callback_arg
-#define SSL_set_msg_callback_arg SSL_set_msg_callback_arg
-#define SSL_set_mtu SSL_set_mtu
-#define SSL_CTX_sess_number SSL_CTX_sess_number
-#define SSL_CTX_get_options SSL_CTX_get_options
-#define SSL_CTX_set_options SSL_CTX_set_options
-#define SSL_get_options SSL_get_options
-#define SSL_set_options SSL_set_options
+#define DTLSv1_get_timeout DTLSv1_get_timeout
+#define DTLSv1_handle_timeout DTLSv1_handle_timeout
+#define SSL_CTX_add0_chain_cert SSL_CTX_add0_chain_cert
+#define SSL_CTX_add1_chain_cert SSL_CTX_add1_chain_cert
+#define SSL_CTX_add_extra_chain_cert SSL_CTX_add_extra_chain_cert
+#define SSL_CTX_clear_extra_chain_certs SSL_CTX_clear_extra_chain_certs
+#define SSL_CTX_clear_chain_certs SSL_CTX_clear_chain_certs
+#define SSL_CTX_clear_mode SSL_CTX_clear_mode
+#define SSL_CTX_clear_options SSL_CTX_clear_options
+#define SSL_CTX_enable_tls_channel_id SSL_CTX_enable_tls_channel_id
+#define SSL_CTX_get0_chain_certs SSL_CTX_get0_chain_certs
+#define SSL_CTX_get_extra_chain_certs SSL_CTX_get_extra_chain_certs
+#define SSL_CTX_get_max_cert_list SSL_CTX_get_max_cert_list
#define SSL_CTX_get_mode SSL_CTX_get_mode
-#define SSL_CTX_set_mode SSL_CTX_set_mode
-#define SSL_get_mode SSL_get_mode
-#define SSL_set_mode SSL_set_mode
+#define SSL_CTX_get_options SSL_CTX_get_options
#define SSL_CTX_get_read_ahead SSL_CTX_get_read_ahead
-#define SSL_CTX_set_read_ahead SSL_CTX_set_read_ahead
-#define SSL_CTX_sess_set_cache_size SSL_CTX_sess_set_cache_size
-#define SSL_CTX_sess_get_cache_size SSL_CTX_sess_get_cache_size
-#define SSL_CTX_set_session_cache_mode SSL_CTX_set_session_cache_mode
#define SSL_CTX_get_session_cache_mode SSL_CTX_get_session_cache_mode
-#define SSL_CTX_get_max_cert_list SSL_CTX_get_max_cert_list
-#define SSL_get_max_cert_list SSL_get_max_cert_list
+#define SSL_CTX_get_tlsext_ticket_keys SSL_CTX_get_tlsext_ticket_keys
+#define SSL_CTX_need_tmp_RSA SSL_CTX_need_tmp_RSA
+#define SSL_CTX_sess_get_cache_size SSL_CTX_sess_get_cache_size
+#define SSL_CTX_sess_number SSL_CTX_sess_number
+#define SSL_CTX_sess_set_cache_size SSL_CTX_sess_set_cache_size
+#define SSL_CTX_set0_chain SSL_CTX_set0_chain
+#define SSL_CTX_set1_chain SSL_CTX_set1_chain
+#define SSL_CTX_set1_curves SSL_CTX_set1_curves
+#define SSL_CTX_set1_tls_channel_id SSL_CTX_set1_tls_channel_id
#define SSL_CTX_set_max_cert_list SSL_CTX_set_max_cert_list
-#define SSL_set_max_cert_list SSL_set_max_cert_list
#define SSL_CTX_set_max_send_fragment SSL_CTX_set_max_send_fragment
-#define SSL_set_max_send_fragment SSL_set_max_send_fragment
+#define SSL_CTX_set_mode SSL_CTX_set_mode
+#define SSL_CTX_set_msg_callback_arg SSL_CTX_set_msg_callback_arg
+#define SSL_CTX_set_options SSL_CTX_set_options
+#define SSL_CTX_set_read_ahead SSL_CTX_set_read_ahead
+#define SSL_CTX_set_session_cache_mode SSL_CTX_set_session_cache_mode
+#define SSL_CTX_set_tlsext_servername_arg SSL_CTX_set_tlsext_servername_arg
#define SSL_CTX_set_tlsext_servername_callback \
SSL_CTX_set_tlsext_servername_callback
-#define SSL_CTX_set_tlsext_servername_arg SSL_CTX_set_tlsext_servername_arg
-#define SSL_set_tlsext_host_name SSL_set_tlsext_host_name
#define SSL_CTX_set_tlsext_ticket_key_cb SSL_CTX_set_tlsext_ticket_key_cb
-#define DTLSv1_get_timeout DTLSv1_get_timeout
-#define DTLSv1_handle_timeout DTLSv1_handle_timeout
-#define SSL_get_secure_renegotiation_support \
- SSL_get_secure_renegotiation_support
-#define SSL_CTX_clear_options SSL_CTX_clear_options
-#define SSL_clear_options SSL_clear_options
-#define SSL_CTX_clear_mode SSL_CTX_clear_mode
+#define SSL_CTX_set_tlsext_ticket_keys SSL_CTX_set_tlsext_ticket_keys
+#define SSL_CTX_set_tmp_dh SSL_CTX_set_tmp_dh
+#define SSL_CTX_set_tmp_ecdh SSL_CTX_set_tmp_ecdh
+#define SSL_CTX_set_tmp_rsa SSL_CTX_set_tmp_rsa
+#define SSL_add0_chain_cert SSL_add0_chain_cert
+#define SSL_add1_chain_cert SSL_add1_chain_cert
+#define SSL_clear_chain_certs SSL_clear_chain_certs
#define SSL_clear_mode SSL_clear_mode
-#define SSL_CTX_enable_tls_channel_id SSL_CTX_enable_tls_channel_id
+#define SSL_clear_options SSL_clear_options
#define SSL_enable_tls_channel_id SSL_enable_tls_channel_id
-#define SSL_set1_tls_channel_id SSL_set1_tls_channel_id
-#define SSL_CTX_set1_tls_channel_id SSL_CTX_set1_tls_channel_id
+#define SSL_get0_certificate_types SSL_get0_certificate_types
+#define SSL_get0_chain_certs SSL_get0_chain_certs
+#define SSL_get_max_cert_list SSL_get_max_cert_list
+#define SSL_get_mode SSL_get_mode
+#define SSL_get_options SSL_get_options
+#define SSL_get_secure_renegotiation_support \
+ SSL_get_secure_renegotiation_support
#define SSL_get_tls_channel_id SSL_get_tls_channel_id
+#define SSL_need_tmp_RSA SSL_need_tmp_RSA
+#define SSL_num_renegotiations SSL_num_renegotiations
+#define SSL_session_reused SSL_session_reused
+#define SSL_set0_chain SSL_set0_chain
+#define SSL_set1_chain SSL_set1_chain
+#define SSL_set1_curves SSL_set1_curves
+#define SSL_set1_tls_channel_id SSL_set1_tls_channel_id
+#define SSL_set_max_cert_list SSL_set_max_cert_list
+#define SSL_set_max_send_fragment SSL_set_max_send_fragment
+#define SSL_set_mode SSL_set_mode
+#define SSL_set_msg_callback_arg SSL_set_msg_callback_arg
+#define SSL_set_mtu SSL_set_mtu
+#define SSL_set_options SSL_set_options
+#define SSL_set_tlsext_host_name SSL_set_tlsext_host_name
+#define SSL_set_tmp_dh SSL_set_tmp_dh
+#define SSL_set_tmp_ecdh SSL_set_tmp_ecdh
+#define SSL_set_tmp_rsa SSL_set_tmp_rsa
+#define SSL_total_renegotiations SSL_total_renegotiations
#if defined(__cplusplus)
@@ -2572,196 +3643,14 @@ OPENSSL_EXPORT const char *SSLeay_version(int unused);
* headers introduces circular dependencies and is inconsistent. The function
* declarations should move to ssl.h. Many of the constants can probably be
* pruned or unexported. */
-#include <openssl/ssl2.h>
#include <openssl/ssl3.h>
#include <openssl/tls1.h> /* This is mostly sslv3 with a few tweaks */
-#include <openssl/ssl23.h>
-#include <openssl/srtp.h> /* Support for the use_srtp extension */
/* BEGIN ERROR CODES */
/* The following lines are auto generated by the script make_errors.go. Any
* changes made after this point may be overwritten when the script is next run.
*/
-#define SSL_F_SSL_CTX_check_private_key 100
-#define SSL_F_SSL_CTX_new 101
-#define SSL_F_SSL_CTX_set_cipher_list 102
-#define SSL_F_SSL_CTX_set_cipher_list_tls11 103
-#define SSL_F_SSL_CTX_set_session_id_context 104
-#define SSL_F_SSL_CTX_use_PrivateKey 105
-#define SSL_F_SSL_CTX_use_PrivateKey_ASN1 106
-#define SSL_F_SSL_CTX_use_PrivateKey_file 107
-#define SSL_F_SSL_CTX_use_RSAPrivateKey 108
-#define SSL_F_SSL_CTX_use_RSAPrivateKey_ASN1 109
-#define SSL_F_SSL_CTX_use_RSAPrivateKey_file 110
-#define SSL_F_SSL_CTX_use_certificate 111
-#define SSL_F_SSL_CTX_use_certificate_ASN1 112
-#define SSL_F_SSL_CTX_use_certificate_chain_file 113
-#define SSL_F_SSL_CTX_use_certificate_file 114
-#define SSL_F_SSL_CTX_use_psk_identity_hint 115
-#define SSL_F_SSL_SESSION_new 116
-#define SSL_F_SSL_SESSION_print_fp 117
-#define SSL_F_SSL_SESSION_set1_id_context 118
-#define SSL_F_SSL_SESSION_to_bytes_full 119
-#define SSL_F_SSL_accept 120
-#define SSL_F_SSL_add_dir_cert_subjects_to_stack 121
-#define SSL_F_SSL_add_file_cert_subjects_to_stack 122
-#define SSL_F_SSL_check_private_key 123
-#define SSL_F_SSL_clear 124
-#define SSL_F_SSL_connect 125
-#define SSL_F_SSL_do_handshake 126
-#define SSL_F_SSL_load_client_CA_file 127
-#define SSL_F_SSL_new 128
-#define SSL_F_SSL_peek 129
-#define SSL_F_SSL_read 130
-#define SSL_F_SSL_renegotiate 131
-#define SSL_F_SSL_set_cipher_list 132
-#define SSL_F_SSL_set_fd 133
-#define SSL_F_SSL_set_rfd 134
-#define SSL_F_SSL_set_session_id_context 135
-#define SSL_F_SSL_set_wfd 136
-#define SSL_F_SSL_shutdown 137
-#define SSL_F_SSL_use_PrivateKey 138
-#define SSL_F_SSL_use_PrivateKey_ASN1 139
-#define SSL_F_SSL_use_PrivateKey_file 140
-#define SSL_F_SSL_use_RSAPrivateKey 141
-#define SSL_F_SSL_use_RSAPrivateKey_ASN1 142
-#define SSL_F_SSL_use_RSAPrivateKey_file 143
-#define SSL_F_SSL_use_certificate 144
-#define SSL_F_SSL_use_certificate_ASN1 145
-#define SSL_F_SSL_use_certificate_file 146
-#define SSL_F_SSL_use_psk_identity_hint 147
-#define SSL_F_SSL_write 148
-#define SSL_F_d2i_SSL_SESSION 149
-#define SSL_F_SSL_SESSION_parse_octet_string 150
-#define SSL_F_SSL_SESSION_parse_string 151
-#define SSL_F_do_ssl3_write 152
-#define SSL_F_dtls1_accept 153
-#define SSL_F_dtls1_buffer_record 154
-#define SSL_F_dtls1_check_timeout_num 155
-#define SSL_F_dtls1_connect 156
-#define SSL_F_dtls1_do_write 157
-#define SSL_F_dtls1_get_hello_verify 158
-#define SSL_F_dtls1_get_message 159
-#define SSL_F_dtls1_get_message_fragment 160
-#define SSL_F_dtls1_preprocess_fragment 161
-#define SSL_F_dtls1_process_record 162
-#define SSL_F_dtls1_read_bytes 163
-#define SSL_F_dtls1_send_hello_verify_request 164
-#define SSL_F_dtls1_write_app_data 165
-#define SSL_F_i2d_SSL_SESSION 166
-#define SSL_F_ssl3_accept 167
-#define SSL_F_ssl3_cert_verify_hash 169
-#define SSL_F_ssl3_check_cert_and_algorithm 170
-#define SSL_F_ssl3_connect 171
-#define SSL_F_ssl3_ctrl 172
-#define SSL_F_ssl3_ctx_ctrl 173
-#define SSL_F_ssl3_digest_cached_records 174
-#define SSL_F_ssl3_do_change_cipher_spec 175
-#define SSL_F_ssl3_expect_change_cipher_spec 176
-#define SSL_F_ssl3_get_cert_status 177
-#define SSL_F_ssl3_get_cert_verify 178
-#define SSL_F_ssl3_get_certificate_request 179
-#define SSL_F_ssl3_get_channel_id 180
-#define SSL_F_ssl3_get_client_certificate 181
-#define SSL_F_ssl3_get_client_hello 182
-#define SSL_F_ssl3_get_client_key_exchange 183
-#define SSL_F_ssl3_get_finished 184
-#define SSL_F_ssl3_get_initial_bytes 185
-#define SSL_F_ssl3_get_message 186
-#define SSL_F_ssl3_get_new_session_ticket 187
-#define SSL_F_ssl3_get_next_proto 188
-#define SSL_F_ssl3_get_record 189
-#define SSL_F_ssl3_get_server_certificate 190
-#define SSL_F_ssl3_get_server_done 191
-#define SSL_F_ssl3_get_server_hello 192
-#define SSL_F_ssl3_get_server_key_exchange 193
-#define SSL_F_ssl3_get_v2_client_hello 194
-#define SSL_F_ssl3_handshake_mac 195
-#define SSL_F_ssl3_prf 196
-#define SSL_F_ssl3_read_bytes 197
-#define SSL_F_ssl3_read_n 198
-#define SSL_F_ssl3_send_cert_verify 199
-#define SSL_F_ssl3_send_certificate_request 200
-#define SSL_F_ssl3_send_channel_id 201
-#define SSL_F_ssl3_send_client_certificate 202
-#define SSL_F_ssl3_send_client_hello 203
-#define SSL_F_ssl3_send_client_key_exchange 204
-#define SSL_F_ssl3_send_server_certificate 205
-#define SSL_F_ssl3_send_server_hello 206
-#define SSL_F_ssl3_send_server_key_exchange 207
-#define SSL_F_ssl3_setup_read_buffer 208
-#define SSL_F_ssl3_setup_write_buffer 209
-#define SSL_F_ssl3_write_bytes 210
-#define SSL_F_ssl3_write_pending 211
-#define SSL_F_ssl_add_cert_chain 212
-#define SSL_F_ssl_add_cert_to_buf 213
-#define SSL_F_ssl_add_clienthello_renegotiate_ext 214
-#define SSL_F_ssl_add_clienthello_tlsext 215
-#define SSL_F_ssl_add_clienthello_use_srtp_ext 216
-#define SSL_F_ssl_add_serverhello_renegotiate_ext 217
-#define SSL_F_ssl_add_serverhello_tlsext 218
-#define SSL_F_ssl_add_serverhello_use_srtp_ext 219
-#define SSL_F_ssl_build_cert_chain 220
-#define SSL_F_ssl_bytes_to_cipher_list 221
-#define SSL_F_ssl_cert_dup 222
-#define SSL_F_ssl_cert_inst 223
-#define SSL_F_ssl_cert_new 224
-#define SSL_F_ssl_check_serverhello_tlsext 225
-#define SSL_F_ssl_check_srvr_ecc_cert_and_alg 226
-#define SSL_F_ssl_cipher_process_rulestr 227
-#define SSL_F_ssl_cipher_strength_sort 228
-#define SSL_F_ssl_create_cipher_list 229
-#define SSL_F_ssl_ctx_log_master_secret 230
-#define SSL_F_ssl_ctx_log_rsa_client_key_exchange 231
-#define SSL_F_ssl_ctx_make_profiles 232
-#define SSL_F_ssl_get_new_session 233
-#define SSL_F_ssl_get_prev_session 234
-#define SSL_F_ssl_get_server_cert_index 235
-#define SSL_F_ssl_get_sign_pkey 236
-#define SSL_F_ssl_init_wbio_buffer 237
-#define SSL_F_ssl_parse_clienthello_renegotiate_ext 238
-#define SSL_F_ssl_parse_clienthello_tlsext 239
-#define SSL_F_ssl_parse_clienthello_use_srtp_ext 240
-#define SSL_F_ssl_parse_serverhello_renegotiate_ext 241
-#define SSL_F_ssl_parse_serverhello_tlsext 242
-#define SSL_F_ssl_parse_serverhello_use_srtp_ext 243
-#define SSL_F_ssl_scan_clienthello_tlsext 244
-#define SSL_F_ssl_scan_serverhello_tlsext 245
-#define SSL_F_ssl_sess_cert_new 246
-#define SSL_F_ssl_set_cert 247
-#define SSL_F_ssl_set_pkey 248
-#define SSL_F_ssl_verify_cert_chain 252
-#define SSL_F_tls12_check_peer_sigalg 253
-#define SSL_F_tls1_aead_ctx_init 254
-#define SSL_F_tls1_cert_verify_mac 255
-#define SSL_F_tls1_change_cipher_state 256
-#define SSL_F_tls1_change_cipher_state_aead 257
-#define SSL_F_tls1_check_duplicate_extensions 258
-#define SSL_F_tls1_enc 259
-#define SSL_F_tls1_export_keying_material 260
-#define SSL_F_tls1_prf 261
-#define SSL_F_tls1_setup_key_block 262
-#define SSL_F_dtls1_get_buffered_message 263
-#define SSL_F_dtls1_process_fragment 264
-#define SSL_F_dtls1_hm_fragment_new 265
-#define SSL_F_ssl3_seal_record 266
-#define SSL_F_ssl3_record_sequence_update 267
-#define SSL_F_SSL_CTX_set_tmp_dh 268
-#define SSL_F_SSL_CTX_set_tmp_ecdh 269
-#define SSL_F_SSL_set_tmp_dh 270
-#define SSL_F_SSL_set_tmp_ecdh 271
-#define SSL_F_SSL_CTX_set1_tls_channel_id 272
-#define SSL_F_SSL_set1_tls_channel_id 273
-#define SSL_F_SSL_set_tlsext_host_name 274
-#define SSL_F_ssl3_output_cert_chain 275
-#define SSL_F_SSL_AEAD_CTX_new 276
-#define SSL_F_SSL_AEAD_CTX_open 277
-#define SSL_F_SSL_AEAD_CTX_seal 278
-#define SSL_F_dtls1_seal_record 279
-#define SSL_F_SSL_SESSION_from_bytes 280
-#define SSL_F_SSL_SESSION_parse 281
-#define SSL_F_ssl3_check_certificate_for_cipher 282
#define SSL_R_APP_DATA_IN_HANDSHAKE 100
#define SSL_R_ATTEMPT_TO_REUSE_SESSION_IN_DIFFERENT_CONTEXT 101
#define SSL_R_BAD_ALERT 102
@@ -2940,6 +3829,15 @@ OPENSSL_EXPORT const char *SSLeay_version(int unused);
#define SSL_R_RESUMED_EMS_SESSION_WITHOUT_EMS_EXTENSION 275
#define SSL_R_EMS_STATE_INCONSISTENT 276
#define SSL_R_RESUMED_NON_EMS_SESSION_WITH_EMS_EXTENSION 277
+#define SSL_R_TOO_MANY_WARNING_ALERTS 278
+#define SSL_R_UNEXPECTED_EXTENSION 279
+#define SSL_R_SIGNATURE_ALGORITHMS_EXTENSION_SENT_BY_SERVER 280
+#define SSL_R_ERROR_ADDING_EXTENSION 281
+#define SSL_R_ERROR_PARSING_EXTENSION 282
+#define SSL_R_MISSING_EXTENSION 283
+#define SSL_R_CUSTOM_EXTENSION_CONTENTS_TOO_LARGE 284
+#define SSL_R_CUSTOM_EXTENSION_ERROR 285
+#define SSL_R_NEGOTIATED_BOTH_NPN_AND_ALPN 286
#define SSL_R_SSLV3_ALERT_CLOSE_NOTIFY 1000
#define SSL_R_SSLV3_ALERT_UNEXPECTED_MESSAGE 1010
#define SSL_R_SSLV3_ALERT_BAD_RECORD_MAC 1020
diff --git a/src/include/openssl/ssl2.h b/src/include/openssl/ssl2.h
deleted file mode 100644
index b8401fa..0000000
--- a/src/include/openssl/ssl2.h
+++ /dev/null
@@ -1,268 +0,0 @@
-/* ssl/ssl2.h */
-/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
- * All rights reserved.
- *
- * This package is an SSL implementation written
- * by Eric Young (eay@cryptsoft.com).
- * The implementation was written so as to conform with Netscapes SSL.
- *
- * This library is free for commercial and non-commercial use as long as
- * the following conditions are aheared to. The following conditions
- * apply to all code found in this distribution, be it the RC4, RSA,
- * lhash, DES, etc., code; not just the SSL code. The SSL documentation
- * included with this distribution is covered by the same copyright terms
- * except that the holder is Tim Hudson (tjh@cryptsoft.com).
- *
- * Copyright remains Eric Young's, and as such any Copyright notices in
- * the code are not to be removed.
- * If this package is used in a product, Eric Young should be given attribution
- * as the author of the parts of the library used.
- * This can be in the form of a textual message at program startup or
- * in documentation (online or textual) provided with the package.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * "This product includes cryptographic software written by
- * Eric Young (eay@cryptsoft.com)"
- * The word 'cryptographic' can be left out if the rouines from the library
- * being used are not cryptographic related :-).
- * 4. If you include any Windows specific code (or a derivative thereof) from
- * the apps directory (application code) you must include an acknowledgement:
- * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
- *
- * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * The licence and distribution terms for any publically available version or
- * derivative of this code cannot be changed. i.e. this code cannot simply be
- * copied and put under another distribution licence
- * [including the GNU Public Licence.]
- */
-
-#ifndef HEADER_SSL2_H
-#define HEADER_SSL2_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* Protocol Version Codes */
-#define SSL2_VERSION 0x0002
-#define SSL2_VERSION_MAJOR 0x00
-#define SSL2_VERSION_MINOR 0x02
-/* #define SSL2_CLIENT_VERSION 0x0002 */
-/* #define SSL2_SERVER_VERSION 0x0002 */
-
-/* Protocol Message Codes */
-#define SSL2_MT_ERROR 0
-#define SSL2_MT_CLIENT_HELLO 1
-#define SSL2_MT_CLIENT_MASTER_KEY 2
-#define SSL2_MT_CLIENT_FINISHED 3
-#define SSL2_MT_SERVER_HELLO 4
-#define SSL2_MT_SERVER_VERIFY 5
-#define SSL2_MT_SERVER_FINISHED 6
-#define SSL2_MT_REQUEST_CERTIFICATE 7
-#define SSL2_MT_CLIENT_CERTIFICATE 8
-
-/* Error Message Codes */
-#define SSL2_PE_UNDEFINED_ERROR 0x0000
-#define SSL2_PE_NO_CIPHER 0x0001
-#define SSL2_PE_NO_CERTIFICATE 0x0002
-#define SSL2_PE_BAD_CERTIFICATE 0x0004
-#define SSL2_PE_UNSUPPORTED_CERTIFICATE_TYPE 0x0006
-
-/* Cipher Kind Values */
-#define SSL2_CK_NULL_WITH_MD5 0x02000000 /* v3 */
-#define SSL2_CK_RC4_128_WITH_MD5 0x02010080
-#define SSL2_CK_RC4_128_EXPORT40_WITH_MD5 0x02020080
-#define SSL2_CK_RC2_128_CBC_WITH_MD5 0x02030080
-#define SSL2_CK_RC2_128_CBC_EXPORT40_WITH_MD5 0x02040080
-#define SSL2_CK_IDEA_128_CBC_WITH_MD5 0x02050080
-#define SSL2_CK_DES_64_CBC_WITH_MD5 0x02060040
-#define SSL2_CK_DES_64_CBC_WITH_SHA 0x02060140 /* v3 */
-#define SSL2_CK_DES_192_EDE3_CBC_WITH_MD5 0x020700c0
-#define SSL2_CK_DES_192_EDE3_CBC_WITH_SHA 0x020701c0 /* v3 */
-#define SSL2_CK_RC4_64_WITH_MD5 0x02080080 /* MS hack */
-
-#define SSL2_CK_DES_64_CFB64_WITH_MD5_1 0x02ff0800 /* SSLeay */
-#define SSL2_CK_NULL 0x02ff0810 /* SSLeay */
-
-#define SSL2_TXT_DES_64_CFB64_WITH_MD5_1 "DES-CFB-M1"
-#define SSL2_TXT_NULL_WITH_MD5 "NULL-MD5"
-#define SSL2_TXT_RC4_128_WITH_MD5 "RC4-MD5"
-#define SSL2_TXT_RC4_128_EXPORT40_WITH_MD5 "EXP-RC4-MD5"
-#define SSL2_TXT_RC2_128_CBC_WITH_MD5 "RC2-CBC-MD5"
-#define SSL2_TXT_RC2_128_CBC_EXPORT40_WITH_MD5 "EXP-RC2-CBC-MD5"
-#define SSL2_TXT_IDEA_128_CBC_WITH_MD5 "IDEA-CBC-MD5"
-#define SSL2_TXT_DES_64_CBC_WITH_MD5 "DES-CBC-MD5"
-#define SSL2_TXT_DES_64_CBC_WITH_SHA "DES-CBC-SHA"
-#define SSL2_TXT_DES_192_EDE3_CBC_WITH_MD5 "DES-CBC3-MD5"
-#define SSL2_TXT_DES_192_EDE3_CBC_WITH_SHA "DES-CBC3-SHA"
-#define SSL2_TXT_RC4_64_WITH_MD5 "RC4-64-MD5"
-
-#define SSL2_TXT_NULL "NULL"
-
-/* Flags for the SSL_CIPHER.algorithm2 field */
-#define SSL2_CF_5_BYTE_ENC 0x01
-#define SSL2_CF_8_BYTE_ENC 0x02
-
-/* Certificate Type Codes */
-#define SSL2_CT_X509_CERTIFICATE 0x01
-
-/* Authentication Type Code */
-#define SSL2_AT_MD5_WITH_RSA_ENCRYPTION 0x01
-
-#define SSL2_MAX_SSL_SESSION_ID_LENGTH 32
-
-/* Upper/Lower Bounds */
-#define SSL2_MAX_MASTER_KEY_LENGTH_IN_BITS 256
-#ifdef OPENSSL_SYS_MPE
-#define SSL2_MAX_RECORD_LENGTH_2_BYTE_HEADER 29998u
-#else
-#define SSL2_MAX_RECORD_LENGTH_2_BYTE_HEADER 32767u /* 2^15-1 */
-#endif
-#define SSL2_MAX_RECORD_LENGTH_3_BYTE_HEADER 16383 /* 2^14-1 */
-
-#define SSL2_CHALLENGE_LENGTH 16
-/*#define SSL2_CHALLENGE_LENGTH 32 */
-#define SSL2_MIN_CHALLENGE_LENGTH 16
-#define SSL2_MAX_CHALLENGE_LENGTH 32
-#define SSL2_CONNECTION_ID_LENGTH 16
-#define SSL2_MAX_CONNECTION_ID_LENGTH 16
-#define SSL2_SSL_SESSION_ID_LENGTH 16
-#define SSL2_MAX_CERT_CHALLENGE_LENGTH 32
-#define SSL2_MIN_CERT_CHALLENGE_LENGTH 16
-#define SSL2_MAX_KEY_MATERIAL_LENGTH 24
-
-#ifndef OPENSSL_NO_SSL_INTERN
-
-typedef struct ssl2_state_st
- {
- int three_byte_header;
- int clear_text; /* clear text */
- int escape; /* not used in SSLv2 */
- int ssl2_rollback; /* used if SSLv23 rolled back to SSLv2 */
-
- /* non-blocking io info, used to make sure the same
- * args were passwd */
- unsigned int wnum; /* number of bytes sent so far */
- int wpend_tot;
- const unsigned char *wpend_buf;
-
- int wpend_off; /* offset to data to write */
- int wpend_len; /* number of bytes passwd to write */
- int wpend_ret; /* number of bytes to return to caller */
-
- /* buffer raw data */
- int rbuf_left;
- int rbuf_offs;
- unsigned char *rbuf;
- unsigned char *wbuf;
-
- unsigned char *write_ptr;/* used to point to the start due to
- * 2/3 byte header. */
-
- unsigned int padding;
- unsigned int rlength; /* passed to ssl2_enc */
- int ract_data_length; /* Set when things are encrypted. */
- unsigned int wlength; /* passed to ssl2_enc */
- int wact_data_length; /* Set when things are decrypted. */
- unsigned char *ract_data;
- unsigned char *wact_data;
- unsigned char *mac_data;
-
- unsigned char *read_key;
- unsigned char *write_key;
-
- /* Stuff specifically to do with this SSL session */
- unsigned int challenge_length;
- unsigned char challenge[SSL2_MAX_CHALLENGE_LENGTH];
- unsigned int conn_id_length;
- unsigned char conn_id[SSL2_MAX_CONNECTION_ID_LENGTH];
- unsigned int key_material_length;
- unsigned char key_material[SSL2_MAX_KEY_MATERIAL_LENGTH*2];
-
- unsigned long read_sequence;
- unsigned long write_sequence;
-
- struct {
- unsigned int conn_id_length;
- unsigned int cert_type;
- unsigned int cert_length;
- unsigned int csl;
- unsigned int clear;
- unsigned int enc;
- unsigned char ccl[SSL2_MAX_CERT_CHALLENGE_LENGTH];
- unsigned int cipher_spec_length;
- unsigned int session_id_length;
- unsigned int clen;
- unsigned int rlen;
- } tmp;
- } SSL2_STATE;
-
-#endif
-
-/* SSLv2 */
-/* client */
-#define SSL2_ST_SEND_CLIENT_HELLO_A (0x10|SSL_ST_CONNECT)
-#define SSL2_ST_SEND_CLIENT_HELLO_B (0x11|SSL_ST_CONNECT)
-#define SSL2_ST_GET_SERVER_HELLO_A (0x20|SSL_ST_CONNECT)
-#define SSL2_ST_GET_SERVER_HELLO_B (0x21|SSL_ST_CONNECT)
-#define SSL2_ST_SEND_CLIENT_MASTER_KEY_A (0x30|SSL_ST_CONNECT)
-#define SSL2_ST_SEND_CLIENT_MASTER_KEY_B (0x31|SSL_ST_CONNECT)
-#define SSL2_ST_SEND_CLIENT_FINISHED_A (0x40|SSL_ST_CONNECT)
-#define SSL2_ST_SEND_CLIENT_FINISHED_B (0x41|SSL_ST_CONNECT)
-#define SSL2_ST_SEND_CLIENT_CERTIFICATE_A (0x50|SSL_ST_CONNECT)
-#define SSL2_ST_SEND_CLIENT_CERTIFICATE_B (0x51|SSL_ST_CONNECT)
-#define SSL2_ST_SEND_CLIENT_CERTIFICATE_C (0x52|SSL_ST_CONNECT)
-#define SSL2_ST_SEND_CLIENT_CERTIFICATE_D (0x53|SSL_ST_CONNECT)
-#define SSL2_ST_GET_SERVER_VERIFY_A (0x60|SSL_ST_CONNECT)
-#define SSL2_ST_GET_SERVER_VERIFY_B (0x61|SSL_ST_CONNECT)
-#define SSL2_ST_GET_SERVER_FINISHED_A (0x70|SSL_ST_CONNECT)
-#define SSL2_ST_GET_SERVER_FINISHED_B (0x71|SSL_ST_CONNECT)
-#define SSL2_ST_CLIENT_START_ENCRYPTION (0x80|SSL_ST_CONNECT)
-#define SSL2_ST_X509_GET_CLIENT_CERTIFICATE (0x90|SSL_ST_CONNECT)
-/* server */
-#define SSL2_ST_GET_CLIENT_HELLO_A (0x10|SSL_ST_ACCEPT)
-#define SSL2_ST_GET_CLIENT_HELLO_B (0x11|SSL_ST_ACCEPT)
-#define SSL2_ST_GET_CLIENT_HELLO_C (0x12|SSL_ST_ACCEPT)
-#define SSL2_ST_SEND_SERVER_HELLO_A (0x20|SSL_ST_ACCEPT)
-#define SSL2_ST_SEND_SERVER_HELLO_B (0x21|SSL_ST_ACCEPT)
-#define SSL2_ST_GET_CLIENT_MASTER_KEY_A (0x30|SSL_ST_ACCEPT)
-#define SSL2_ST_GET_CLIENT_MASTER_KEY_B (0x31|SSL_ST_ACCEPT)
-#define SSL2_ST_SEND_SERVER_VERIFY_A (0x40|SSL_ST_ACCEPT)
-#define SSL2_ST_SEND_SERVER_VERIFY_B (0x41|SSL_ST_ACCEPT)
-#define SSL2_ST_SEND_SERVER_VERIFY_C (0x42|SSL_ST_ACCEPT)
-#define SSL2_ST_GET_CLIENT_FINISHED_A (0x50|SSL_ST_ACCEPT)
-#define SSL2_ST_GET_CLIENT_FINISHED_B (0x51|SSL_ST_ACCEPT)
-#define SSL2_ST_SEND_SERVER_FINISHED_A (0x60|SSL_ST_ACCEPT)
-#define SSL2_ST_SEND_SERVER_FINISHED_B (0x61|SSL_ST_ACCEPT)
-#define SSL2_ST_SEND_REQUEST_CERTIFICATE_A (0x70|SSL_ST_ACCEPT)
-#define SSL2_ST_SEND_REQUEST_CERTIFICATE_B (0x71|SSL_ST_ACCEPT)
-#define SSL2_ST_SEND_REQUEST_CERTIFICATE_C (0x72|SSL_ST_ACCEPT)
-#define SSL2_ST_SEND_REQUEST_CERTIFICATE_D (0x73|SSL_ST_ACCEPT)
-#define SSL2_ST_SERVER_START_ENCRYPTION (0x80|SSL_ST_ACCEPT)
-#define SSL2_ST_X509_GET_SERVER_CERTIFICATE (0x90|SSL_ST_ACCEPT)
-
-#ifdef __cplusplus
-}
-#endif
-#endif
-
diff --git a/src/include/openssl/ssl23.h b/src/include/openssl/ssl23.h
deleted file mode 100644
index df395a8..0000000
--- a/src/include/openssl/ssl23.h
+++ /dev/null
@@ -1,85 +0,0 @@
-/* ssl/ssl23.h */
-/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
- * All rights reserved.
- *
- * This package is an SSL implementation written
- * by Eric Young (eay@cryptsoft.com).
- * The implementation was written so as to conform with Netscapes SSL.
- *
- * This library is free for commercial and non-commercial use as long as
- * the following conditions are aheared to. The following conditions
- * apply to all code found in this distribution, be it the RC4, RSA,
- * lhash, DES, etc., code; not just the SSL code. The SSL documentation
- * included with this distribution is covered by the same copyright terms
- * except that the holder is Tim Hudson (tjh@cryptsoft.com).
- *
- * Copyright remains Eric Young's, and as such any Copyright notices in
- * the code are not to be removed.
- * If this package is used in a product, Eric Young should be given attribution
- * as the author of the parts of the library used.
- * This can be in the form of a textual message at program startup or
- * in documentation (online or textual) provided with the package.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * "This product includes cryptographic software written by
- * Eric Young (eay@cryptsoft.com)"
- * The word 'cryptographic' can be left out if the rouines from the library
- * being used are not cryptographic related :-).
- * 4. If you include any Windows specific code (or a derivative thereof) from
- * the apps directory (application code) you must include an acknowledgement:
- * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
- *
- * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * The licence and distribution terms for any publically available version or
- * derivative of this code cannot be changed. i.e. this code cannot simply be
- * copied and put under another distribution licence
- * [including the GNU Public Licence.]
- */
-
-#ifndef HEADER_SSL23_H
-#define HEADER_SSL23_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-
-/*client */
-/* write to server */
-#define SSL23_ST_CW_CLNT_HELLO_A (0x210 | SSL_ST_CONNECT)
-#define SSL23_ST_CW_CLNT_HELLO_B (0x211 | SSL_ST_CONNECT)
-/* read from server */
-#define SSL23_ST_CR_SRVR_HELLO_A (0x220 | SSL_ST_CONNECT)
-#define SSL23_ST_CR_SRVR_HELLO_B (0x221 | SSL_ST_CONNECT)
-
-/* server */
-/* read from client */
-#define SSL23_ST_SR_CLNT_HELLO (0x210 | SSL_ST_ACCEPT)
-#define SSL23_ST_SR_V2_CLNT_HELLO (0x220 | SSL_ST_ACCEPT)
-#define SSL23_ST_SR_SWITCH_VERSION (0x230 | SSL_ST_ACCEPT)
-
-
-#ifdef __cplusplus
-}
-#endif
-#endif
diff --git a/src/include/openssl/ssl3.h b/src/include/openssl/ssl3.h
index 640a228..1f6ca31 100644
--- a/src/include/openssl/ssl3.h
+++ b/src/include/openssl/ssl3.h
@@ -127,11 +127,14 @@
extern "C" {
#endif
+/* These are kept to support clients that negotiates higher protocol versions
+ * using SSLv2 client hello records. */
+#define SSL2_MT_CLIENT_HELLO 1
+#define SSL2_VERSION 0x0002
-/* Signalling cipher suite value: from RFC5746 */
+/* Signalling cipher suite value from RFC 5746. */
#define SSL3_CK_SCSV 0x030000FF
-/* Fallback signalling cipher suite value: not IANA assigned.
- * See https://tools.ietf.org/html/draft-bmoeller-tls-downgrade-scsv-01 */
+/* Fallback signalling cipher suite value from RFC 7507. */
#define SSL3_CK_FALLBACK_SCSV 0x03005600
#define SSL3_CK_RSA_NULL_MD5 0x03000001
@@ -269,29 +272,11 @@ OPENSSL_COMPILE_ASSERT(
#define SSL3_MD_CLIENT_FINISHED_CONST "\x43\x4C\x4E\x54"
#define SSL3_MD_SERVER_FINISHED_CONST "\x53\x52\x56\x52"
-#define SSL3_VERSION 0x0300
-#define SSL3_VERSION_MAJOR 0x03
-#define SSL3_VERSION_MINOR 0x00
-
#define SSL3_RT_CHANGE_CIPHER_SPEC 20
#define SSL3_RT_ALERT 21
#define SSL3_RT_HANDSHAKE 22
#define SSL3_RT_APPLICATION_DATA 23
-/* Pseudo content types to indicate additional parameters */
-#define TLS1_RT_CRYPTO 0x1000
-#define TLS1_RT_CRYPTO_PREMASTER (TLS1_RT_CRYPTO | 0x1)
-#define TLS1_RT_CRYPTO_CLIENT_RANDOM (TLS1_RT_CRYPTO | 0x2)
-#define TLS1_RT_CRYPTO_SERVER_RANDOM (TLS1_RT_CRYPTO | 0x3)
-#define TLS1_RT_CRYPTO_MASTER (TLS1_RT_CRYPTO | 0x4)
-
-#define TLS1_RT_CRYPTO_READ 0x0000
-#define TLS1_RT_CRYPTO_WRITE 0x0100
-#define TLS1_RT_CRYPTO_MAC (TLS1_RT_CRYPTO | 0x5)
-#define TLS1_RT_CRYPTO_KEY (TLS1_RT_CRYPTO | 0x6)
-#define TLS1_RT_CRYPTO_IV (TLS1_RT_CRYPTO | 0x7)
-#define TLS1_RT_CRYPTO_FIXED_IV (TLS1_RT_CRYPTO | 0x8)
-
/* Pseudo content type for SSL/TLS header info */
#define SSL3_RT_HEADER 0x100
@@ -322,22 +307,17 @@ typedef struct ssl3_record_st {
/* data is a non-owning pointer to the record contents. The total length of
* the buffer is |off| + |length|. */
uint8_t *data;
- /* epoch, in DTLS, is the epoch number of the record. */
- uint16_t epoch;
- /* seq_num, in DTLS, is the sequence number of the record. The top two bytes
- * are always zero.
- *
- * TODO(davidben): This is confusing. They should include the epoch or the
- * field should be six bytes. */
- uint8_t seq_num[8];
} SSL3_RECORD;
typedef struct ssl3_buffer_st {
- uint8_t *buf; /* at least SSL3_RT_MAX_PACKET_SIZE bytes, see
- ssl3_setup_buffers() */
- size_t len; /* buffer size */
- int offset; /* where to 'copy from' */
- int left; /* how many bytes left */
+ /* buf is the memory allocated for this buffer. */
+ uint8_t *buf;
+ /* offset is the offset into |buf| which the buffer contents start at. */
+ uint16_t offset;
+ /* len is the length of the buffer contents from |buf| + |offset|. */
+ uint16_t len;
+ /* cap is how much memory beyond |buf| + |offset| is available. */
+ uint16_t cap;
} SSL3_BUFFER;
#define SSL3_CT_RSA_SIGN 1
@@ -369,9 +349,6 @@ typedef struct ssl3_state_st {
/* flags for countermeasure against known-IV weakness */
int need_record_splitting;
- /* The value of 'extra' when the buffers were initialized */
- int init_extra;
-
/* have_version is true if the connection's final version is known. Otherwise
* the version has not been negotiated yet. */
char have_version;
@@ -380,13 +357,10 @@ typedef struct ssl3_state_st {
* completed. */
char initial_handshake_complete;
- /* sniff_buffer is used by the server in the initial handshake to read a
- * V2ClientHello before the record layer is initialized. */
- BUF_MEM *sniff_buffer;
- size_t sniff_buffer_len;
-
- SSL3_BUFFER rbuf; /* read IO goes into here */
- SSL3_BUFFER wbuf; /* write IO goes into here */
+ /* read_buffer holds data from the transport to be processed. */
+ SSL3_BUFFER read_buffer;
+ /* write_buffer holds data to be written to the transport. */
+ SSL3_BUFFER write_buffer;
SSL3_RECORD rrec; /* each decoded record goes in here */
@@ -402,11 +376,15 @@ typedef struct ssl3_state_st {
int wpend_ret; /* number of bytes submitted */
const uint8_t *wpend_buf;
- /* used during startup, digest all incoming/outgoing packets */
- BIO *handshake_buffer;
- /* When set of handshake digests is determined, buffer is hashed and freed
- * and MD_CTX-es for all required digests are stored in this array */
- EVP_MD_CTX **handshake_dgst;
+ /* handshake_buffer, if non-NULL, contains the handshake transcript. */
+ BUF_MEM *handshake_buffer;
+ /* handshake_hash, if initialized with an |EVP_MD|, maintains the handshake
+ * hash. For TLS 1.1 and below, it is the SHA-1 half. */
+ EVP_MD_CTX handshake_hash;
+ /* handshake_md5, if initialized with an |EVP_MD|, maintains the MD5 half of
+ * the handshake hash for TLS 1.1 and below. */
+ EVP_MD_CTX handshake_md5;
+
/* this is set whenerver we see a change_cipher_spec message come in when we
* are not looking for one */
int change_cipher_spec;
@@ -420,6 +398,13 @@ typedef struct ssl3_state_st {
int total_renegotiations;
+ /* empty_record_count is the number of consecutive empty records received. */
+ uint8_t empty_record_count;
+
+ /* warning_alert_count is the number of consecutive warning alerts
+ * received. */
+ uint8_t warning_alert_count;
+
/* State pertaining to the pending handshake.
*
* TODO(davidben): State is current spread all over the place. Move
@@ -446,6 +431,34 @@ typedef struct ssl3_state_st {
int reuse_message;
+ union {
+ /* sent is a bitset where the bits correspond to elements of kExtensions
+ * in t1_lib.c. Each bit is set if that extension was sent in a
+ * ClientHello. It's not used by servers. */
+ uint32_t sent;
+ /* received is a bitset, like |sent|, but is used by servers to record
+ * which extensions were received from a client. */
+ uint32_t received;
+ } extensions;
+
+ union {
+ /* sent is a bitset where the bits correspond to elements of
+ * |client_custom_extensions| in the |SSL_CTX|. Each bit is set if that
+ * extension was sent in a ClientHello. It's not used by servers. */
+ uint16_t sent;
+ /* received is a bitset, like |sent|, but is used by servers to record
+ * which custom extensions were received from a client. The bits here
+ * correspond to |server_custom_extensions|. */
+ uint16_t received;
+ } custom_extensions;
+
+ /* SNI extension */
+
+ /* should_ack_sni is used by a server and indicates that the SNI extension
+ * should be echoed in the ServerHello. */
+ unsigned should_ack_sni:1;
+
+
/* Client-only: cert_req determines if a client certificate is to be sent.
* This is 0 if no client Certificate message is to be sent, 1 if there is
* a client certificate, and 2 to send an empty client Certificate
@@ -474,13 +487,12 @@ typedef struct ssl3_state_st {
int cert_request;
/* certificate_status_expected is true if OCSP stapling was negotiated and
- * the server is expected to send a CertificateStatus message. */
- char certificate_status_expected;
+ * the server is expected to send a CertificateStatus message. (This is
+ * used on both the client and server sides.) */
+ unsigned certificate_status_expected:1;
- /* peer_ecpointformatlist contains the EC point formats advertised by the
- * peer. */
- uint8_t *peer_ecpointformatlist;
- size_t peer_ecpointformatlist_length;
+ /* ocsp_stapling_requested is true if a client requested OCSP stapling. */
+ unsigned ocsp_stapling_requested:1;
/* Server-only: peer_ellipticcurvelist contains the EC curve IDs advertised
* by the peer. This is only set on the server's end. The server does not
@@ -507,6 +519,12 @@ typedef struct ssl3_state_st {
/* Client-only: in_false_start is one if there is a pending handshake in
* False Start. The client may write data at this point. */
char in_false_start;
+
+ /* peer_dh_tmp, on a client, is the server's DHE public key. */
+ DH *peer_dh_tmp;
+
+ /* peer_ecdh_tmp, on a client, is the server's ECDHE public key. */
+ EC_KEY *peer_ecdh_tmp;
} tmp;
/* Connection binding to prevent renegotiation attacks */
@@ -533,11 +551,6 @@ typedef struct ssl3_state_st {
* Channel IDs and that tlsext_channel_id will be valid after the
* handshake. */
char tlsext_channel_id_valid;
- /* tlsext_channel_id_new means that the updated Channel ID extension was
- * negotiated. This is a temporary hack in the code to support both forms of
- * Channel ID extension while we transition to the new format, which fixed a
- * security issue. */
- char tlsext_channel_id_new;
/* For a server:
* If |tlsext_channel_id_valid| is true, then this contains the
* verified Channel ID from the client: a P256 point, (x,y), where
@@ -550,6 +563,7 @@ typedef struct ssl3_state_st {
/* extra state */
#define SSL3_ST_CW_FLUSH (0x100 | SSL_ST_CONNECT)
#define SSL3_ST_FALSE_START (0x101 | SSL_ST_CONNECT)
+#define SSL3_ST_VERIFY_SERVER_CERT (0x102 | SSL_ST_CONNECT)
/* write to server */
#define SSL3_ST_CW_CLNT_HELLO_A (0x110 | SSL_ST_CONNECT)
#define SSL3_ST_CW_CLNT_HELLO_B (0x111 | SSL_ST_CONNECT)
@@ -575,6 +589,7 @@ typedef struct ssl3_state_st {
#define SSL3_ST_CW_KEY_EXCH_B (0x181 | SSL_ST_CONNECT)
#define SSL3_ST_CW_CERT_VRFY_A (0x190 | SSL_ST_CONNECT)
#define SSL3_ST_CW_CERT_VRFY_B (0x191 | SSL_ST_CONNECT)
+#define SSL3_ST_CW_CERT_VRFY_C (0x192 | SSL_ST_CONNECT)
#define SSL3_ST_CW_CHANGE_A (0x1A0 | SSL_ST_CONNECT)
#define SSL3_ST_CW_CHANGE_B (0x1A1 | SSL_ST_CONNECT)
#define SSL3_ST_CW_NEXT_PROTO_A (0x200 | SSL_ST_CONNECT)
@@ -613,6 +628,7 @@ typedef struct ssl3_state_st {
#define SSL3_ST_SW_CERT_B (0x141 | SSL_ST_ACCEPT)
#define SSL3_ST_SW_KEY_EXCH_A (0x150 | SSL_ST_ACCEPT)
#define SSL3_ST_SW_KEY_EXCH_B (0x151 | SSL_ST_ACCEPT)
+#define SSL3_ST_SW_KEY_EXCH_C (0x152 | SSL_ST_ACCEPT)
#define SSL3_ST_SW_CERT_REQ_A (0x160 | SSL_ST_ACCEPT)
#define SSL3_ST_SW_CERT_REQ_B (0x161 | SSL_ST_ACCEPT)
#define SSL3_ST_SW_SRVR_DONE_A (0x170 | SSL_ST_ACCEPT)
diff --git a/src/include/openssl/stack.h b/src/include/openssl/stack.h
index 350fa14..b600b43 100644
--- a/src/include/openssl/stack.h
+++ b/src/include/openssl/stack.h
@@ -111,11 +111,6 @@ typedef struct stack_st {
#define STACK_OF(type) struct stack_st_##type
-#define DEFINE_STACK_OF(type) \
-STACK_OF(type) {\
- _STACK stack; \
-}
-
#define DECLARE_STACK_OF(type) STACK_OF(type);
/* The make_macros.sh script in this directory parses the following lines and
@@ -140,12 +135,14 @@ STACK_OF(type) {\
* STACK_OF:GENERAL_NAMES
* STACK_OF:GENERAL_SUBTREE
* STACK_OF:MIME_HEADER
- * STACK_OF:PKCS7_SIGNER_INFO
* STACK_OF:PKCS7_RECIP_INFO
+ * STACK_OF:PKCS7_SIGNER_INFO
* STACK_OF:POLICYINFO
* STACK_OF:POLICYQUALINFO
* STACK_OF:POLICY_MAPPING
+ * STACK_OF:RSA_additional_prime
* STACK_OF:SSL_COMP
+ * STACK_OF:SSL_CUSTOM_EXTENSION
* STACK_OF:STACK_OF_X509_NAME_ENTRY
* STACK_OF:SXNETID
* STACK_OF:X509
diff --git a/src/include/openssl/stack_macros.h b/src/include/openssl/stack_macros.h
index dadcf6b..08097af 100644
--- a/src/include/openssl/stack_macros.h
+++ b/src/include/openssl/stack_macros.h
@@ -1511,6 +1511,93 @@
copy_func), \
CHECKED_CAST(void (*)(void *), void (*)(MIME_HEADER *), free_func)))
+/* PKCS7_RECIP_INFO */
+#define sk_PKCS7_RECIP_INFO_new(comp) \
+ ((STACK_OF(PKCS7_RECIP_INFO) *)sk_new(CHECKED_CAST( \
+ stack_cmp_func, \
+ int (*)(const PKCS7_RECIP_INFO **a, const PKCS7_RECIP_INFO **b), comp)))
+
+#define sk_PKCS7_RECIP_INFO_new_null() \
+ ((STACK_OF(PKCS7_RECIP_INFO) *)sk_new_null())
+
+#define sk_PKCS7_RECIP_INFO_num(sk) \
+ sk_num(CHECKED_CAST(_STACK *, STACK_OF(PKCS7_RECIP_INFO) *, sk))
+
+#define sk_PKCS7_RECIP_INFO_zero(sk) \
+ sk_zero(CHECKED_CAST(_STACK *, STACK_OF(PKCS7_RECIP_INFO) *, sk));
+
+#define sk_PKCS7_RECIP_INFO_value(sk, i) \
+ ((PKCS7_RECIP_INFO *)sk_value( \
+ CHECKED_CAST(_STACK *, const STACK_OF(PKCS7_RECIP_INFO) *, sk), (i)))
+
+#define sk_PKCS7_RECIP_INFO_set(sk, i, p) \
+ ((PKCS7_RECIP_INFO *)sk_set( \
+ CHECKED_CAST(_STACK *, STACK_OF(PKCS7_RECIP_INFO) *, sk), (i), \
+ CHECKED_CAST(void *, PKCS7_RECIP_INFO *, p)))
+
+#define sk_PKCS7_RECIP_INFO_free(sk) \
+ sk_free(CHECKED_CAST(_STACK *, STACK_OF(PKCS7_RECIP_INFO) *, sk))
+
+#define sk_PKCS7_RECIP_INFO_pop_free(sk, free_func) \
+ sk_pop_free( \
+ CHECKED_CAST(_STACK *, STACK_OF(PKCS7_RECIP_INFO) *, sk), \
+ CHECKED_CAST(void (*)(void *), void (*)(PKCS7_RECIP_INFO *), free_func))
+
+#define sk_PKCS7_RECIP_INFO_insert(sk, p, where) \
+ sk_insert(CHECKED_CAST(_STACK *, STACK_OF(PKCS7_RECIP_INFO) *, sk), \
+ CHECKED_CAST(void *, PKCS7_RECIP_INFO *, p), (where))
+
+#define sk_PKCS7_RECIP_INFO_delete(sk, where) \
+ ((PKCS7_RECIP_INFO *)sk_delete( \
+ CHECKED_CAST(_STACK *, STACK_OF(PKCS7_RECIP_INFO) *, sk), (where)))
+
+#define sk_PKCS7_RECIP_INFO_delete_ptr(sk, p) \
+ ((PKCS7_RECIP_INFO *)sk_delete_ptr( \
+ CHECKED_CAST(_STACK *, STACK_OF(PKCS7_RECIP_INFO) *, sk), \
+ CHECKED_CAST(void *, PKCS7_RECIP_INFO *, p)))
+
+#define sk_PKCS7_RECIP_INFO_find(sk, out_index, p) \
+ sk_find(CHECKED_CAST(_STACK *, STACK_OF(PKCS7_RECIP_INFO) *, sk), \
+ (out_index), CHECKED_CAST(void *, PKCS7_RECIP_INFO *, p))
+
+#define sk_PKCS7_RECIP_INFO_shift(sk) \
+ ((PKCS7_RECIP_INFO *)sk_shift( \
+ CHECKED_CAST(_STACK *, STACK_OF(PKCS7_RECIP_INFO) *, sk)))
+
+#define sk_PKCS7_RECIP_INFO_push(sk, p) \
+ sk_push(CHECKED_CAST(_STACK *, STACK_OF(PKCS7_RECIP_INFO) *, sk), \
+ CHECKED_CAST(void *, PKCS7_RECIP_INFO *, p))
+
+#define sk_PKCS7_RECIP_INFO_pop(sk) \
+ ((PKCS7_RECIP_INFO *)sk_pop( \
+ CHECKED_CAST(_STACK *, STACK_OF(PKCS7_RECIP_INFO) *, sk)))
+
+#define sk_PKCS7_RECIP_INFO_dup(sk) \
+ ((STACK_OF(PKCS7_RECIP_INFO) *)sk_dup( \
+ CHECKED_CAST(_STACK *, const STACK_OF(PKCS7_RECIP_INFO) *, sk)))
+
+#define sk_PKCS7_RECIP_INFO_sort(sk) \
+ sk_sort(CHECKED_CAST(_STACK *, STACK_OF(PKCS7_RECIP_INFO) *, sk))
+
+#define sk_PKCS7_RECIP_INFO_is_sorted(sk) \
+ sk_is_sorted(CHECKED_CAST(_STACK *, const STACK_OF(PKCS7_RECIP_INFO) *, sk))
+
+#define sk_PKCS7_RECIP_INFO_set_cmp_func(sk, comp) \
+ ((int (*)(const PKCS7_RECIP_INFO **a, const PKCS7_RECIP_INFO **b)) \
+ sk_set_cmp_func( \
+ CHECKED_CAST(_STACK *, STACK_OF(PKCS7_RECIP_INFO) *, sk), \
+ CHECKED_CAST(stack_cmp_func, int (*)(const PKCS7_RECIP_INFO **a, \
+ const PKCS7_RECIP_INFO **b), \
+ comp)))
+
+#define sk_PKCS7_RECIP_INFO_deep_copy(sk, copy_func, free_func) \
+ ((STACK_OF(PKCS7_RECIP_INFO) *)sk_deep_copy( \
+ CHECKED_CAST(const _STACK *, const STACK_OF(PKCS7_RECIP_INFO) *, sk), \
+ CHECKED_CAST(void *(*)(void *), \
+ PKCS7_RECIP_INFO *(*)(PKCS7_RECIP_INFO *), copy_func), \
+ CHECKED_CAST(void (*)(void *), void (*)(PKCS7_RECIP_INFO *), \
+ free_func)))
+
/* PKCS7_SIGNER_INFO */
#define sk_PKCS7_SIGNER_INFO_new(comp) \
((STACK_OF(PKCS7_SIGNER_INFO) *)sk_new(CHECKED_CAST( \
@@ -1599,93 +1686,6 @@
CHECKED_CAST(void (*)(void *), void (*)(PKCS7_SIGNER_INFO *), \
free_func)))
-/* PKCS7_RECIP_INFO */
-#define sk_PKCS7_RECIP_INFO_new(comp) \
- ((STACK_OF(PKCS7_RECIP_INFO) *)sk_new(CHECKED_CAST( \
- stack_cmp_func, \
- int (*)(const PKCS7_RECIP_INFO **a, const PKCS7_RECIP_INFO **b), comp)))
-
-#define sk_PKCS7_RECIP_INFO_new_null() \
- ((STACK_OF(PKCS7_RECIP_INFO) *)sk_new_null())
-
-#define sk_PKCS7_RECIP_INFO_num(sk) \
- sk_num(CHECKED_CAST(_STACK *, STACK_OF(PKCS7_RECIP_INFO) *, sk))
-
-#define sk_PKCS7_RECIP_INFO_zero(sk) \
- sk_zero(CHECKED_CAST(_STACK *, STACK_OF(PKCS7_RECIP_INFO) *, sk));
-
-#define sk_PKCS7_RECIP_INFO_value(sk, i) \
- ((PKCS7_RECIP_INFO *)sk_value( \
- CHECKED_CAST(_STACK *, const STACK_OF(PKCS7_RECIP_INFO) *, sk), (i)))
-
-#define sk_PKCS7_RECIP_INFO_set(sk, i, p) \
- ((PKCS7_RECIP_INFO *)sk_set( \
- CHECKED_CAST(_STACK *, STACK_OF(PKCS7_RECIP_INFO) *, sk), (i), \
- CHECKED_CAST(void *, PKCS7_RECIP_INFO *, p)))
-
-#define sk_PKCS7_RECIP_INFO_free(sk) \
- sk_free(CHECKED_CAST(_STACK *, STACK_OF(PKCS7_RECIP_INFO) *, sk))
-
-#define sk_PKCS7_RECIP_INFO_pop_free(sk, free_func) \
- sk_pop_free( \
- CHECKED_CAST(_STACK *, STACK_OF(PKCS7_RECIP_INFO) *, sk), \
- CHECKED_CAST(void (*)(void *), void (*)(PKCS7_RECIP_INFO *), free_func))
-
-#define sk_PKCS7_RECIP_INFO_insert(sk, p, where) \
- sk_insert(CHECKED_CAST(_STACK *, STACK_OF(PKCS7_RECIP_INFO) *, sk), \
- CHECKED_CAST(void *, PKCS7_RECIP_INFO *, p), (where))
-
-#define sk_PKCS7_RECIP_INFO_delete(sk, where) \
- ((PKCS7_RECIP_INFO *)sk_delete( \
- CHECKED_CAST(_STACK *, STACK_OF(PKCS7_RECIP_INFO) *, sk), (where)))
-
-#define sk_PKCS7_RECIP_INFO_delete_ptr(sk, p) \
- ((PKCS7_RECIP_INFO *)sk_delete_ptr( \
- CHECKED_CAST(_STACK *, STACK_OF(PKCS7_RECIP_INFO) *, sk), \
- CHECKED_CAST(void *, PKCS7_RECIP_INFO *, p)))
-
-#define sk_PKCS7_RECIP_INFO_find(sk, out_index, p) \
- sk_find(CHECKED_CAST(_STACK *, STACK_OF(PKCS7_RECIP_INFO) *, sk), \
- (out_index), CHECKED_CAST(void *, PKCS7_RECIP_INFO *, p))
-
-#define sk_PKCS7_RECIP_INFO_shift(sk) \
- ((PKCS7_RECIP_INFO *)sk_shift( \
- CHECKED_CAST(_STACK *, STACK_OF(PKCS7_RECIP_INFO) *, sk)))
-
-#define sk_PKCS7_RECIP_INFO_push(sk, p) \
- sk_push(CHECKED_CAST(_STACK *, STACK_OF(PKCS7_RECIP_INFO) *, sk), \
- CHECKED_CAST(void *, PKCS7_RECIP_INFO *, p))
-
-#define sk_PKCS7_RECIP_INFO_pop(sk) \
- ((PKCS7_RECIP_INFO *)sk_pop( \
- CHECKED_CAST(_STACK *, STACK_OF(PKCS7_RECIP_INFO) *, sk)))
-
-#define sk_PKCS7_RECIP_INFO_dup(sk) \
- ((STACK_OF(PKCS7_RECIP_INFO) *)sk_dup( \
- CHECKED_CAST(_STACK *, const STACK_OF(PKCS7_RECIP_INFO) *, sk)))
-
-#define sk_PKCS7_RECIP_INFO_sort(sk) \
- sk_sort(CHECKED_CAST(_STACK *, STACK_OF(PKCS7_RECIP_INFO) *, sk))
-
-#define sk_PKCS7_RECIP_INFO_is_sorted(sk) \
- sk_is_sorted(CHECKED_CAST(_STACK *, const STACK_OF(PKCS7_RECIP_INFO) *, sk))
-
-#define sk_PKCS7_RECIP_INFO_set_cmp_func(sk, comp) \
- ((int (*)(const PKCS7_RECIP_INFO **a, const PKCS7_RECIP_INFO **b)) \
- sk_set_cmp_func( \
- CHECKED_CAST(_STACK *, STACK_OF(PKCS7_RECIP_INFO) *, sk), \
- CHECKED_CAST(stack_cmp_func, int (*)(const PKCS7_RECIP_INFO **a, \
- const PKCS7_RECIP_INFO **b), \
- comp)))
-
-#define sk_PKCS7_RECIP_INFO_deep_copy(sk, copy_func, free_func) \
- ((STACK_OF(PKCS7_RECIP_INFO) *)sk_deep_copy( \
- CHECKED_CAST(const _STACK *, const STACK_OF(PKCS7_RECIP_INFO) *, sk), \
- CHECKED_CAST(void *(*)(void *), \
- PKCS7_RECIP_INFO *(*)(PKCS7_RECIP_INFO *), copy_func), \
- CHECKED_CAST(void (*)(void *), void (*)(PKCS7_RECIP_INFO *), \
- free_func)))
-
/* POLICYINFO */
#define sk_POLICYINFO_new(comp) \
((STACK_OF(POLICYINFO) *)sk_new(CHECKED_CAST( \
@@ -1937,6 +1937,99 @@
copy_func), \
CHECKED_CAST(void (*)(void *), void (*)(POLICY_MAPPING *), free_func)))
+/* RSA_additional_prime */
+#define sk_RSA_additional_prime_new(comp) \
+ ((STACK_OF(RSA_additional_prime) *)sk_new(CHECKED_CAST( \
+ stack_cmp_func, \
+ int (*)(const RSA_additional_prime **a, const RSA_additional_prime **b), \
+ comp)))
+
+#define sk_RSA_additional_prime_new_null() \
+ ((STACK_OF(RSA_additional_prime) *)sk_new_null())
+
+#define sk_RSA_additional_prime_num(sk) \
+ sk_num(CHECKED_CAST(_STACK *, STACK_OF(RSA_additional_prime) *, sk))
+
+#define sk_RSA_additional_prime_zero(sk) \
+ sk_zero(CHECKED_CAST(_STACK *, STACK_OF(RSA_additional_prime) *, sk));
+
+#define sk_RSA_additional_prime_value(sk, i) \
+ ((RSA_additional_prime *)sk_value( \
+ CHECKED_CAST(_STACK *, const STACK_OF(RSA_additional_prime) *, sk), \
+ (i)))
+
+#define sk_RSA_additional_prime_set(sk, i, p) \
+ ((RSA_additional_prime *)sk_set( \
+ CHECKED_CAST(_STACK *, STACK_OF(RSA_additional_prime) *, sk), (i), \
+ CHECKED_CAST(void *, RSA_additional_prime *, p)))
+
+#define sk_RSA_additional_prime_free(sk) \
+ sk_free(CHECKED_CAST(_STACK *, STACK_OF(RSA_additional_prime) *, sk))
+
+#define sk_RSA_additional_prime_pop_free(sk, free_func) \
+ sk_pop_free(CHECKED_CAST(_STACK *, STACK_OF(RSA_additional_prime) *, sk), \
+ CHECKED_CAST(void (*)(void *), void (*)(RSA_additional_prime *), \
+ free_func))
+
+#define sk_RSA_additional_prime_insert(sk, p, where) \
+ sk_insert(CHECKED_CAST(_STACK *, STACK_OF(RSA_additional_prime) *, sk), \
+ CHECKED_CAST(void *, RSA_additional_prime *, p), (where))
+
+#define sk_RSA_additional_prime_delete(sk, where) \
+ ((RSA_additional_prime *)sk_delete( \
+ CHECKED_CAST(_STACK *, STACK_OF(RSA_additional_prime) *, sk), (where)))
+
+#define sk_RSA_additional_prime_delete_ptr(sk, p) \
+ ((RSA_additional_prime *)sk_delete_ptr( \
+ CHECKED_CAST(_STACK *, STACK_OF(RSA_additional_prime) *, sk), \
+ CHECKED_CAST(void *, RSA_additional_prime *, p)))
+
+#define sk_RSA_additional_prime_find(sk, out_index, p) \
+ sk_find(CHECKED_CAST(_STACK *, STACK_OF(RSA_additional_prime) *, sk), \
+ (out_index), CHECKED_CAST(void *, RSA_additional_prime *, p))
+
+#define sk_RSA_additional_prime_shift(sk) \
+ ((RSA_additional_prime *)sk_shift( \
+ CHECKED_CAST(_STACK *, STACK_OF(RSA_additional_prime) *, sk)))
+
+#define sk_RSA_additional_prime_push(sk, p) \
+ sk_push(CHECKED_CAST(_STACK *, STACK_OF(RSA_additional_prime) *, sk), \
+ CHECKED_CAST(void *, RSA_additional_prime *, p))
+
+#define sk_RSA_additional_prime_pop(sk) \
+ ((RSA_additional_prime *)sk_pop( \
+ CHECKED_CAST(_STACK *, STACK_OF(RSA_additional_prime) *, sk)))
+
+#define sk_RSA_additional_prime_dup(sk) \
+ ((STACK_OF(RSA_additional_prime) *)sk_dup( \
+ CHECKED_CAST(_STACK *, const STACK_OF(RSA_additional_prime) *, sk)))
+
+#define sk_RSA_additional_prime_sort(sk) \
+ sk_sort(CHECKED_CAST(_STACK *, STACK_OF(RSA_additional_prime) *, sk))
+
+#define sk_RSA_additional_prime_is_sorted(sk) \
+ sk_is_sorted( \
+ CHECKED_CAST(_STACK *, const STACK_OF(RSA_additional_prime) *, sk))
+
+#define sk_RSA_additional_prime_set_cmp_func(sk, comp) \
+ ((int (*)(const RSA_additional_prime **a, const RSA_additional_prime **b)) \
+ sk_set_cmp_func( \
+ CHECKED_CAST(_STACK *, STACK_OF(RSA_additional_prime) *, sk), \
+ CHECKED_CAST(stack_cmp_func, \
+ int (*)(const RSA_additional_prime **a, \
+ const RSA_additional_prime **b), \
+ comp)))
+
+#define sk_RSA_additional_prime_deep_copy(sk, copy_func, free_func) \
+ ((STACK_OF(RSA_additional_prime) *)sk_deep_copy( \
+ CHECKED_CAST(const _STACK *, const STACK_OF(RSA_additional_prime) *, \
+ sk), \
+ CHECKED_CAST(void *(*)(void *), \
+ RSA_additional_prime *(*)(RSA_additional_prime *), \
+ copy_func), \
+ CHECKED_CAST(void (*)(void *), void (*)(RSA_additional_prime *), \
+ free_func)))
+
/* SSL_COMP */
#define sk_SSL_COMP_new(comp) \
((STACK_OF(SSL_COMP) *)sk_new(CHECKED_CAST( \
@@ -2013,6 +2106,99 @@
CHECKED_CAST(void *(*)(void *), SSL_COMP *(*)(SSL_COMP *), copy_func), \
CHECKED_CAST(void (*)(void *), void (*)(SSL_COMP *), free_func)))
+/* SSL_CUSTOM_EXTENSION */
+#define sk_SSL_CUSTOM_EXTENSION_new(comp) \
+ ((STACK_OF(SSL_CUSTOM_EXTENSION) *)sk_new(CHECKED_CAST( \
+ stack_cmp_func, \
+ int (*)(const SSL_CUSTOM_EXTENSION **a, const SSL_CUSTOM_EXTENSION **b), \
+ comp)))
+
+#define sk_SSL_CUSTOM_EXTENSION_new_null() \
+ ((STACK_OF(SSL_CUSTOM_EXTENSION) *)sk_new_null())
+
+#define sk_SSL_CUSTOM_EXTENSION_num(sk) \
+ sk_num(CHECKED_CAST(_STACK *, STACK_OF(SSL_CUSTOM_EXTENSION) *, sk))
+
+#define sk_SSL_CUSTOM_EXTENSION_zero(sk) \
+ sk_zero(CHECKED_CAST(_STACK *, STACK_OF(SSL_CUSTOM_EXTENSION) *, sk));
+
+#define sk_SSL_CUSTOM_EXTENSION_value(sk, i) \
+ ((SSL_CUSTOM_EXTENSION *)sk_value( \
+ CHECKED_CAST(_STACK *, const STACK_OF(SSL_CUSTOM_EXTENSION) *, sk), \
+ (i)))
+
+#define sk_SSL_CUSTOM_EXTENSION_set(sk, i, p) \
+ ((SSL_CUSTOM_EXTENSION *)sk_set( \
+ CHECKED_CAST(_STACK *, STACK_OF(SSL_CUSTOM_EXTENSION) *, sk), (i), \
+ CHECKED_CAST(void *, SSL_CUSTOM_EXTENSION *, p)))
+
+#define sk_SSL_CUSTOM_EXTENSION_free(sk) \
+ sk_free(CHECKED_CAST(_STACK *, STACK_OF(SSL_CUSTOM_EXTENSION) *, sk))
+
+#define sk_SSL_CUSTOM_EXTENSION_pop_free(sk, free_func) \
+ sk_pop_free(CHECKED_CAST(_STACK *, STACK_OF(SSL_CUSTOM_EXTENSION) *, sk), \
+ CHECKED_CAST(void (*)(void *), void (*)(SSL_CUSTOM_EXTENSION *), \
+ free_func))
+
+#define sk_SSL_CUSTOM_EXTENSION_insert(sk, p, where) \
+ sk_insert(CHECKED_CAST(_STACK *, STACK_OF(SSL_CUSTOM_EXTENSION) *, sk), \
+ CHECKED_CAST(void *, SSL_CUSTOM_EXTENSION *, p), (where))
+
+#define sk_SSL_CUSTOM_EXTENSION_delete(sk, where) \
+ ((SSL_CUSTOM_EXTENSION *)sk_delete( \
+ CHECKED_CAST(_STACK *, STACK_OF(SSL_CUSTOM_EXTENSION) *, sk), (where)))
+
+#define sk_SSL_CUSTOM_EXTENSION_delete_ptr(sk, p) \
+ ((SSL_CUSTOM_EXTENSION *)sk_delete_ptr( \
+ CHECKED_CAST(_STACK *, STACK_OF(SSL_CUSTOM_EXTENSION) *, sk), \
+ CHECKED_CAST(void *, SSL_CUSTOM_EXTENSION *, p)))
+
+#define sk_SSL_CUSTOM_EXTENSION_find(sk, out_index, p) \
+ sk_find(CHECKED_CAST(_STACK *, STACK_OF(SSL_CUSTOM_EXTENSION) *, sk), \
+ (out_index), CHECKED_CAST(void *, SSL_CUSTOM_EXTENSION *, p))
+
+#define sk_SSL_CUSTOM_EXTENSION_shift(sk) \
+ ((SSL_CUSTOM_EXTENSION *)sk_shift( \
+ CHECKED_CAST(_STACK *, STACK_OF(SSL_CUSTOM_EXTENSION) *, sk)))
+
+#define sk_SSL_CUSTOM_EXTENSION_push(sk, p) \
+ sk_push(CHECKED_CAST(_STACK *, STACK_OF(SSL_CUSTOM_EXTENSION) *, sk), \
+ CHECKED_CAST(void *, SSL_CUSTOM_EXTENSION *, p))
+
+#define sk_SSL_CUSTOM_EXTENSION_pop(sk) \
+ ((SSL_CUSTOM_EXTENSION *)sk_pop( \
+ CHECKED_CAST(_STACK *, STACK_OF(SSL_CUSTOM_EXTENSION) *, sk)))
+
+#define sk_SSL_CUSTOM_EXTENSION_dup(sk) \
+ ((STACK_OF(SSL_CUSTOM_EXTENSION) *)sk_dup( \
+ CHECKED_CAST(_STACK *, const STACK_OF(SSL_CUSTOM_EXTENSION) *, sk)))
+
+#define sk_SSL_CUSTOM_EXTENSION_sort(sk) \
+ sk_sort(CHECKED_CAST(_STACK *, STACK_OF(SSL_CUSTOM_EXTENSION) *, sk))
+
+#define sk_SSL_CUSTOM_EXTENSION_is_sorted(sk) \
+ sk_is_sorted( \
+ CHECKED_CAST(_STACK *, const STACK_OF(SSL_CUSTOM_EXTENSION) *, sk))
+
+#define sk_SSL_CUSTOM_EXTENSION_set_cmp_func(sk, comp) \
+ ((int (*)(const SSL_CUSTOM_EXTENSION **a, const SSL_CUSTOM_EXTENSION **b)) \
+ sk_set_cmp_func( \
+ CHECKED_CAST(_STACK *, STACK_OF(SSL_CUSTOM_EXTENSION) *, sk), \
+ CHECKED_CAST(stack_cmp_func, \
+ int (*)(const SSL_CUSTOM_EXTENSION **a, \
+ const SSL_CUSTOM_EXTENSION **b), \
+ comp)))
+
+#define sk_SSL_CUSTOM_EXTENSION_deep_copy(sk, copy_func, free_func) \
+ ((STACK_OF(SSL_CUSTOM_EXTENSION) *)sk_deep_copy( \
+ CHECKED_CAST(const _STACK *, const STACK_OF(SSL_CUSTOM_EXTENSION) *, \
+ sk), \
+ CHECKED_CAST(void *(*)(void *), \
+ SSL_CUSTOM_EXTENSION *(*)(SSL_CUSTOM_EXTENSION *), \
+ copy_func), \
+ CHECKED_CAST(void (*)(void *), void (*)(SSL_CUSTOM_EXTENSION *), \
+ free_func)))
+
/* STACK_OF_X509_NAME_ENTRY */
#define sk_STACK_OF_X509_NAME_ENTRY_new(comp) \
((STACK_OF(STACK_OF_X509_NAME_ENTRY) *)sk_new(CHECKED_CAST( \
@@ -3591,25 +3777,25 @@
#define sk_void_new_null() ((STACK_OF(void)*)sk_new_null())
-#define sk_void_num(sk) sk_num(CHECKED_CAST(_STACK *, STACK_OF(void)*, sk))
+#define sk_void_num(sk) sk_num(CHECKED_CAST(_STACK *, STACK_OF(void) *, sk))
-#define sk_void_zero(sk) sk_zero(CHECKED_CAST(_STACK *, STACK_OF(void)*, sk));
+#define sk_void_zero(sk) sk_zero(CHECKED_CAST(_STACK *, STACK_OF(void) *, sk));
#define sk_void_value(sk, i) \
- ((void *)sk_value(CHECKED_CAST(_STACK *, const STACK_OF(void)*, sk), (i)))
+ ((void *)sk_value(CHECKED_CAST(_STACK *, const STACK_OF(void) *, sk), (i)))
#define sk_void_set(sk, i, p) \
((void *)sk_set(CHECKED_CAST(_STACK *, STACK_OF(void)*, sk), (i), \
CHECKED_CAST(void *, void *, p)))
-#define sk_void_free(sk) sk_free(CHECKED_CAST(_STACK *, STACK_OF(void)*, sk))
+#define sk_void_free(sk) sk_free(CHECKED_CAST(_STACK *, STACK_OF(void) *, sk))
-#define sk_void_pop_free(sk, free_func) \
- sk_pop_free(CHECKED_CAST(_STACK *, STACK_OF(void)*, sk), \
+#define sk_void_pop_free(sk, free_func) \
+ sk_pop_free(CHECKED_CAST(_STACK *, STACK_OF(void) *, sk), \
CHECKED_CAST(void (*)(void *), void (*)(void *), free_func))
-#define sk_void_insert(sk, p, where) \
- sk_insert(CHECKED_CAST(_STACK *, STACK_OF(void)*, sk), \
+#define sk_void_insert(sk, p, where) \
+ sk_insert(CHECKED_CAST(_STACK *, STACK_OF(void) *, sk), \
CHECKED_CAST(void *, void *, p), (where))
#define sk_void_delete(sk, where) \
@@ -3619,27 +3805,27 @@
((void *)sk_delete_ptr(CHECKED_CAST(_STACK *, STACK_OF(void)*, sk), \
CHECKED_CAST(void *, void *, p)))
-#define sk_void_find(sk, out_index, p) \
- sk_find(CHECKED_CAST(_STACK *, STACK_OF(void)*, sk), (out_index), \
+#define sk_void_find(sk, out_index, p) \
+ sk_find(CHECKED_CAST(_STACK *, STACK_OF(void) *, sk), (out_index), \
CHECKED_CAST(void *, void *, p))
#define sk_void_shift(sk) \
((void *)sk_shift(CHECKED_CAST(_STACK *, STACK_OF(void)*, sk)))
-#define sk_void_push(sk, p) \
- sk_push(CHECKED_CAST(_STACK *, STACK_OF(void)*, sk), \
+#define sk_void_push(sk, p) \
+ sk_push(CHECKED_CAST(_STACK *, STACK_OF(void) *, sk), \
CHECKED_CAST(void *, void *, p))
#define sk_void_pop(sk) \
((void *)sk_pop(CHECKED_CAST(_STACK *, STACK_OF(void)*, sk)))
#define sk_void_dup(sk) \
- ((STACK_OF(void)*)sk_dup(CHECKED_CAST(_STACK *, const STACK_OF(void)*, sk)))
+ ((STACK_OF(void)*)sk_dup(CHECKED_CAST(_STACK *, const STACK_OF(void) *, sk)))
-#define sk_void_sort(sk) sk_sort(CHECKED_CAST(_STACK *, STACK_OF(void)*, sk))
+#define sk_void_sort(sk) sk_sort(CHECKED_CAST(_STACK *, STACK_OF(void) *, sk))
#define sk_void_is_sorted(sk) \
- sk_is_sorted(CHECKED_CAST(_STACK *, const STACK_OF(void)*, sk))
+ sk_is_sorted(CHECKED_CAST(_STACK *, const STACK_OF(void) *, sk))
#define sk_void_set_cmp_func(sk, comp) \
((int (*)(const void **a, const void **b))sk_set_cmp_func( \
@@ -3649,7 +3835,7 @@
#define sk_void_deep_copy(sk, copy_func, free_func) \
((STACK_OF(void)*)sk_deep_copy( \
- CHECKED_CAST(const _STACK *, const STACK_OF(void)*, sk), \
+ CHECKED_CAST(const _STACK *, const STACK_OF(void) *, sk), \
CHECKED_CAST(void *(*)(void *), void *(*)(void *), copy_func), \
CHECKED_CAST(void (*)(void *), void (*)(void *), free_func)))
diff --git a/src/include/openssl/tls1.h b/src/include/openssl/tls1.h
index f2bee27..7d16b55 100644
--- a/src/include/openssl/tls1.h
+++ b/src/include/openssl/tls1.h
@@ -209,7 +209,7 @@ extern "C" {
#define TLSEXT_TYPE_signature_algorithms 13
/* ExtensionType value from RFC5764 */
-#define TLSEXT_TYPE_use_srtp 14
+#define TLSEXT_TYPE_srtp 14
/* ExtensionType value from RFC5620 */
#define TLSEXT_TYPE_heartbeat 15
@@ -239,8 +239,7 @@ extern "C" {
#define TLSEXT_TYPE_next_proto_neg 13172
/* This is not an IANA defined extension number */
-#define TLSEXT_TYPE_channel_id 30031
-#define TLSEXT_TYPE_channel_id_new 30032
+#define TLSEXT_TYPE_channel_id 30032
/* NameType value from RFC 3546 */
#define TLSEXT_NAMETYPE_host_name 0
@@ -291,14 +290,6 @@ OPENSSL_EXPORT int SSL_export_keying_material(
SSL *s, uint8_t *out, size_t out_len, const char *label, size_t label_len,
const uint8_t *context, size_t context_len, int use_context);
-OPENSSL_EXPORT int SSL_get_sigalgs(SSL *s, int idx, int *psign, int *phash,
- int *psignandhash, uint8_t *rsig,
- uint8_t *rhash);
-
-OPENSSL_EXPORT int SSL_get_shared_sigalgs(SSL *s, int idx, int *psign,
- int *phash, int *psignandhash,
- uint8_t *rsig, uint8_t *rhash);
-
/* SSL_set_tlsext_host_name, for a client, configures |ssl| to advertise |name|
* in the server_name extension. It returns one on success and zero on error. */
OPENSSL_EXPORT int SSL_set_tlsext_host_name(SSL *ssl, const char *name);
@@ -322,39 +313,6 @@ OPENSSL_EXPORT int SSL_CTX_set_tlsext_servername_callback(
* callback and returns one. See |SSL_CTX_set_tlsext_servername_callback|. */
OPENSSL_EXPORT int SSL_CTX_set_tlsext_servername_arg(SSL_CTX *ctx, void *arg);
-#define SSL_CTX_get_tlsext_ticket_keys(ctx, keys, keylen) \
- SSL_CTX_ctrl((ctx), SSL_CTRL_GET_TLSEXT_TICKET_KEYS, (keylen), (keys))
-#define SSL_CTX_set_tlsext_ticket_keys(ctx, keys, keylen) \
- SSL_CTX_ctrl((ctx), SSL_CTRL_SET_TLSEXT_TICKET_KEYS, (keylen), (keys))
-
-/* SSL_CTX_set_tlsext_ticket_key_cb sets the ticket callback to |callback| and
- * returns one. |callback| will be called when encrypting a new ticket and when
- * decrypting a ticket from the client.
- *
- * In both modes, |ctx| and |hmac_ctx| will already have been initialized with
- * |EVP_CIPHER_CTX_init| and |HMAC_CTX_init|, respectively. |callback|
- * configures |hmac_ctx| with an HMAC digest and key, and configures |ctx|
- * for encryption or decryption, based on the mode.
- *
- * When encrypting a new ticket, |encrypt| will be one. It writes a public
- * 16-byte key name to |key_name| and a fresh IV to |iv|. The output IV length
- * must match |EVP_CIPHER_CTX_iv_length| of the cipher selected. In this mode,
- * |callback| returns 1 on success and -1 on error.
- *
- * When decrypting a ticket, |encrypt| will be zero. |key_name| will point to a
- * 16-byte key name and |iv| points to an IV. The length of the IV consumed must
- * match |EVP_CIPHER_CTX_iv_length| of the cipher selected. In this mode,
- * |callback| returns -1 to abort the handshake, 0 if decrypting the ticket
- * failed, and 1 or 2 on success. If it returns 2, the ticket will be renewed.
- * This may be used to re-key the ticket.
- *
- * WARNING: |callback| wildly breaks the usual return value convention and is
- * called in two different modes. */
-OPENSSL_EXPORT int SSL_CTX_set_tlsext_ticket_key_cb(
- SSL_CTX *ctx, int (*callback)(SSL *ssl, uint8_t *key_name, uint8_t *iv,
- EVP_CIPHER_CTX *ctx, HMAC_CTX *hmac_ctx,
- int encrypt));
-
/* PSK ciphersuites from 4279 */
#define TLS1_CK_PSK_WITH_RC4_128_SHA 0x0300008A
#define TLS1_CK_PSK_WITH_3DES_EDE_CBC_SHA 0x0300008B
@@ -514,7 +472,6 @@ OPENSSL_EXPORT int SSL_CTX_set_tlsext_ticket_key_cb(
#define TLS1_CK_ECDHE_RSA_CHACHA20_POLY1305 0x0300CC13
#define TLS1_CK_ECDHE_ECDSA_CHACHA20_POLY1305 0x0300CC14
-#define TLS1_CK_DHE_RSA_CHACHA20_POLY1305 0x0300CC15
/* XXX
* Inconsistency alert:
diff --git a/src/include/openssl/x509.h b/src/include/openssl/x509.h
index 69c7da6..f6b3af0 100644
--- a/src/include/openssl/x509.h
+++ b/src/include/openssl/x509.h
@@ -102,22 +102,22 @@ extern "C" {
#define X509v3_KU_DECIPHER_ONLY 0x8000
#define X509v3_KU_UNDEF 0xffff
-typedef struct X509_objects_st
+struct X509_objects_st
{
int nid;
int (*a2i)(void);
int (*i2a)(void);
- } X509_OBJECTS;
+ } /* X509_OBJECTS */;
DECLARE_ASN1_SET_OF(X509_ALGOR)
typedef STACK_OF(X509_ALGOR) X509_ALGORS;
-typedef struct X509_val_st
+struct X509_val_st
{
ASN1_TIME *notBefore;
ASN1_TIME *notAfter;
- } X509_VAL;
+ } /* X509_VAL */;
struct X509_pubkey_st
{
@@ -126,25 +126,25 @@ struct X509_pubkey_st
EVP_PKEY *pkey;
};
-typedef struct X509_sig_st
+struct X509_sig_st
{
X509_ALGOR *algor;
ASN1_OCTET_STRING *digest;
- } X509_SIG;
+ } /* X509_SIG */;
-typedef struct X509_name_entry_st
+struct X509_name_entry_st
{
ASN1_OBJECT *object;
ASN1_STRING *value;
int set;
int size; /* temp variable */
- } X509_NAME_ENTRY;
+ } /* X509_NAME_ENTRY */;
DECLARE_STACK_OF(X509_NAME_ENTRY)
DECLARE_ASN1_SET_OF(X509_NAME_ENTRY)
/* we always keep X509_NAMEs in 2 forms. */
-typedef struct X509_name_st
+struct X509_name_st
{
STACK_OF(X509_NAME_ENTRY) *entries;
int modified; /* true if 'bytes' needs to be built */
@@ -156,18 +156,18 @@ typedef struct X509_name_st
/* unsigned long hash; Keep the hash around for lookups */
unsigned char *canon_enc;
int canon_enclen;
- } X509_NAME;
+ } /* X509_NAME */;
DECLARE_STACK_OF(X509_NAME)
#define X509_EX_V_NETSCAPE_HACK 0x8000
#define X509_EX_V_INIT 0x0001
-typedef struct X509_extension_st
+struct X509_extension_st
{
ASN1_OBJECT *object;
ASN1_BOOLEAN critical;
ASN1_OCTET_STRING *value;
- } X509_EXTENSION;
+ } /* X509_EXTENSION */;
typedef STACK_OF(X509_EXTENSION) X509_EXTENSIONS;
@@ -175,7 +175,7 @@ DECLARE_STACK_OF(X509_EXTENSION)
DECLARE_ASN1_SET_OF(X509_EXTENSION)
/* a sequence of these are used */
-typedef struct x509_attributes_st
+struct x509_attributes_st
{
ASN1_OBJECT *object;
int single; /* 0 for a set, 1 for a single item (which is wrong) */
@@ -184,13 +184,13 @@ typedef struct x509_attributes_st
/* 0 */ STACK_OF(ASN1_TYPE) *set;
/* 1 */ ASN1_TYPE *single;
} value;
- } X509_ATTRIBUTE;
+ } /* X509_ATTRIBUTE */;
DECLARE_STACK_OF(X509_ATTRIBUTE)
DECLARE_ASN1_SET_OF(X509_ATTRIBUTE)
-typedef struct X509_req_info_st
+struct X509_req_info_st
{
ASN1_ENCODING enc;
ASN1_INTEGER *version;
@@ -198,17 +198,17 @@ typedef struct X509_req_info_st
X509_PUBKEY *pubkey;
/* d=2 hl=2 l= 0 cons: cont: 00 */
STACK_OF(X509_ATTRIBUTE) *attributes; /* [ 0 ] */
- } X509_REQ_INFO;
+ } /* X509_REQ_INFO */;
-typedef struct X509_req_st
+struct X509_req_st
{
X509_REQ_INFO *req_info;
X509_ALGOR *sig_alg;
ASN1_BIT_STRING *signature;
CRYPTO_refcount_t references;
- } X509_REQ;
+ } /* X509_REQ */;
-typedef struct x509_cinf_st
+struct x509_cinf_st
{
ASN1_INTEGER *version; /* [ 0 ] default of v1 */
ASN1_INTEGER *serialNumber;
@@ -221,7 +221,7 @@ typedef struct x509_cinf_st
ASN1_BIT_STRING *subjectUID; /* [ 2 ] optional in v2 */
STACK_OF(X509_EXTENSION) *extensions; /* [ 3 ] optional in v3 */
ASN1_ENCODING enc;
- } X509_CINF;
+ } /* X509_CINF */;
/* This stuff is certificate "auxiliary info"
* it contains details which are useful in certificate
@@ -229,14 +229,14 @@ typedef struct x509_cinf_st
* the end of the certificate itself
*/
-typedef struct x509_cert_aux_st
+struct x509_cert_aux_st
{
STACK_OF(ASN1_OBJECT) *trust; /* trusted uses */
STACK_OF(ASN1_OBJECT) *reject; /* rejected uses */
ASN1_UTF8STRING *alias; /* "friendly name" */
ASN1_OCTET_STRING *keyid; /* key id of private key */
STACK_OF(X509_ALGOR) *other; /* other unspecified info */
- } X509_CERT_AUX;
+ } /* X509_CERT_AUX */;
struct x509_st
{
@@ -269,21 +269,21 @@ DECLARE_ASN1_SET_OF(X509)
/* This is used for a table of trust checking functions */
-typedef struct x509_trust_st {
+struct x509_trust_st {
int trust;
int flags;
int (*check_trust)(struct x509_trust_st *, X509 *, int);
char *name;
int arg1;
void *arg2;
-} X509_TRUST;
+} /* X509_TRUST */;
DECLARE_STACK_OF(X509_TRUST)
-typedef struct x509_cert_pair_st {
+struct x509_cert_pair_st {
X509 *forward;
X509 *reverse;
-} X509_CERT_PAIR;
+} /* X509_CERT_PAIR */;
/* standard trust ids */
@@ -403,7 +403,7 @@ struct x509_revoked_st
DECLARE_STACK_OF(X509_REVOKED)
DECLARE_ASN1_SET_OF(X509_REVOKED)
-typedef struct X509_crl_info_st
+struct X509_crl_info_st
{
ASN1_INTEGER *version;
X509_ALGOR *sig_alg;
@@ -413,7 +413,7 @@ typedef struct X509_crl_info_st
STACK_OF(X509_REVOKED) *revoked;
STACK_OF(X509_EXTENSION) /* [0] */ *extensions;
ASN1_ENCODING enc;
- } X509_CRL_INFO;
+ } /* X509_CRL_INFO */;
struct X509_crl_st
{
@@ -441,7 +441,7 @@ struct X509_crl_st
DECLARE_STACK_OF(X509_CRL)
DECLARE_ASN1_SET_OF(X509_CRL)
-typedef struct private_key_st
+struct private_key_st
{
int version;
/* The PKCS#8 data types */
@@ -458,10 +458,10 @@ typedef struct private_key_st
/* expanded version of 'enc_algor' */
EVP_CIPHER_INFO cipher;
- } X509_PKEY;
+ } /* X509_PKEY */;
#ifndef OPENSSL_NO_EVP
-typedef struct X509_info_st
+struct X509_info_st
{
X509 *x509;
X509_CRL *crl;
@@ -471,7 +471,7 @@ typedef struct X509_info_st
int enc_len;
char *enc_data;
- } X509_INFO;
+ } /* X509_INFO */;
DECLARE_STACK_OF(X509_INFO)
#endif
@@ -480,25 +480,25 @@ DECLARE_STACK_OF(X509_INFO)
* Pat Richard <patr@x509.com> and are used to manipulate
* Netscapes spki structures - useful if you are writing a CA web page
*/
-typedef struct Netscape_spkac_st
+struct Netscape_spkac_st
{
X509_PUBKEY *pubkey;
ASN1_IA5STRING *challenge; /* challenge sent in atlas >= PR2 */
- } NETSCAPE_SPKAC;
+ } /* NETSCAPE_SPKAC */;
-typedef struct Netscape_spki_st
+struct Netscape_spki_st
{
NETSCAPE_SPKAC *spkac; /* signed public key and challenge */
X509_ALGOR *sig_algor;
ASN1_BIT_STRING *signature;
- } NETSCAPE_SPKI;
+ } /* NETSCAPE_SPKI */;
/* Netscape certificate sequence structure */
-typedef struct Netscape_certificate_sequence
+struct Netscape_certificate_sequence
{
ASN1_OBJECT *type;
STACK_OF(X509) *certs;
- } NETSCAPE_CERT_SEQUENCE;
+ } /* NETSCAPE_CERT_SEQUENCE */;
/* Unused (and iv length is wrong)
typedef struct CBCParameter_st
@@ -509,24 +509,24 @@ typedef struct CBCParameter_st
/* Password based encryption structure */
-typedef struct PBEPARAM_st {
+struct PBEPARAM_st {
ASN1_OCTET_STRING *salt;
ASN1_INTEGER *iter;
-} PBEPARAM;
+} /* PBEPARAM */;
/* Password based encryption V2 structures */
-typedef struct PBE2PARAM_st {
+struct PBE2PARAM_st {
X509_ALGOR *keyfunc;
X509_ALGOR *encryption;
-} PBE2PARAM;
+} /* PBE2PARAM */;
-typedef struct PBKDF2PARAM_st {
+struct PBKDF2PARAM_st {
ASN1_TYPE *salt; /* Usually OCTET STRING but could be anything */
ASN1_INTEGER *iter;
ASN1_INTEGER *keylength;
X509_ALGOR *prf;
-} PBKDF2PARAM;
+} /* PBKDF2PARAM */;
/* PKCS#8 private key info structure */
@@ -896,6 +896,7 @@ OPENSSL_EXPORT int X509_CRL_set_issuer_name(X509_CRL *x, X509_NAME *name);
OPENSSL_EXPORT int X509_CRL_set_lastUpdate(X509_CRL *x, const ASN1_TIME *tm);
OPENSSL_EXPORT int X509_CRL_set_nextUpdate(X509_CRL *x, const ASN1_TIME *tm);
OPENSSL_EXPORT int X509_CRL_sort(X509_CRL *crl);
+OPENSSL_EXPORT void X509_CRL_up_ref(X509_CRL *crl);
OPENSSL_EXPORT int X509_REVOKED_set_serialNumber(X509_REVOKED *x, ASN1_INTEGER *serial);
OPENSSL_EXPORT int X509_REVOKED_set_revocationDate(X509_REVOKED *r, ASN1_TIME *tm);
@@ -1217,65 +1218,6 @@ OPENSSL_EXPORT int PKCS7_get_PEM_CRLs(STACK_OF(X509_CRL) *out_crls,
}
#endif
-#define X509_F_ASN1_digest 100
-#define X509_F_ASN1_item_sign_ctx 101
-#define X509_F_ASN1_item_verify 102
-#define X509_F_NETSCAPE_SPKI_b64_decode 103
-#define X509_F_NETSCAPE_SPKI_b64_encode 104
-#define X509_F_PKCS7_get_certificates 105
-#define X509_F_X509_ATTRIBUTE_create_by_NID 106
-#define X509_F_X509_ATTRIBUTE_create_by_OBJ 107
-#define X509_F_X509_ATTRIBUTE_create_by_txt 108
-#define X509_F_X509_ATTRIBUTE_get0_data 109
-#define X509_F_X509_ATTRIBUTE_set1_data 110
-#define X509_F_X509_CRL_add0_revoked 111
-#define X509_F_X509_CRL_diff 112
-#define X509_F_X509_CRL_print_fp 113
-#define X509_F_X509_EXTENSION_create_by_NID 114
-#define X509_F_X509_EXTENSION_create_by_OBJ 115
-#define X509_F_X509_INFO_new 116
-#define X509_F_X509_NAME_ENTRY_create_by_NID 117
-#define X509_F_X509_NAME_ENTRY_create_by_txt 118
-#define X509_F_X509_NAME_ENTRY_set_object 119
-#define X509_F_X509_NAME_add_entry 120
-#define X509_F_X509_NAME_oneline 121
-#define X509_F_X509_NAME_print 122
-#define X509_F_X509_PKEY_new 123
-#define X509_F_X509_PUBKEY_get 124
-#define X509_F_X509_PUBKEY_set 125
-#define X509_F_X509_REQ_check_private_key 126
-#define X509_F_X509_REQ_to_X509 127
-#define X509_F_X509_STORE_CTX_get1_issuer 128
-#define X509_F_X509_STORE_CTX_init 129
-#define X509_F_X509_STORE_CTX_new 130
-#define X509_F_X509_STORE_CTX_purpose_inherit 131
-#define X509_F_X509_STORE_add_cert 132
-#define X509_F_X509_STORE_add_crl 133
-#define X509_F_X509_TRUST_add 134
-#define X509_F_X509_TRUST_set 135
-#define X509_F_X509_check_private_key 136
-#define X509_F_X509_get_pubkey_parameters 137
-#define X509_F_X509_load_cert_crl_file 138
-#define X509_F_X509_load_cert_file 139
-#define X509_F_X509_load_crl_file 140
-#define X509_F_X509_print_ex_fp 141
-#define X509_F_X509_to_X509_REQ 142
-#define X509_F_X509_verify_cert 143
-#define X509_F_X509at_add1_attr 144
-#define X509_F_X509v3_add_ext 145
-#define X509_F_add_cert_dir 146
-#define X509_F_by_file_ctrl 147
-#define X509_F_check_policy 148
-#define X509_F_dir_ctrl 149
-#define X509_F_get_cert_by_subject 150
-#define X509_F_i2d_DSA_PUBKEY 151
-#define X509_F_i2d_EC_PUBKEY 152
-#define X509_F_i2d_RSA_PUBKEY 153
-#define X509_F_x509_name_encode 154
-#define X509_F_x509_name_ex_d2i 155
-#define X509_F_x509_name_ex_new 156
-#define X509_F_pkcs7_parse_header 157
-#define X509_F_PKCS7_get_CRLs 158
#define X509_R_AKID_MISMATCH 100
#define X509_R_BAD_PKCS7_VERSION 101
#define X509_R_BAD_X509_FILETYPE 102
diff --git a/src/include/openssl/x509v3.h b/src/include/openssl/x509v3.h
index 5caa5c1..b7b8ba7 100644
--- a/src/include/openssl/x509v3.h
+++ b/src/include/openssl/x509v3.h
@@ -731,63 +731,6 @@ void ERR_load_X509V3_strings(void);
#ifdef __cplusplus
}
#endif
-#define X509V3_F_SXNET_add_id_INTEGER 100
-#define X509V3_F_SXNET_add_id_asc 101
-#define X509V3_F_SXNET_add_id_ulong 102
-#define X509V3_F_SXNET_get_id_asc 103
-#define X509V3_F_SXNET_get_id_ulong 104
-#define X509V3_F_X509V3_EXT_add 105
-#define X509V3_F_X509V3_EXT_add_alias 106
-#define X509V3_F_X509V3_EXT_free 107
-#define X509V3_F_X509V3_EXT_i2d 108
-#define X509V3_F_X509V3_EXT_nconf 109
-#define X509V3_F_X509V3_add1_i2d 110
-#define X509V3_F_X509V3_add_value 111
-#define X509V3_F_X509V3_get_section 112
-#define X509V3_F_X509V3_get_string 113
-#define X509V3_F_X509V3_get_value_bool 114
-#define X509V3_F_X509V3_parse_list 115
-#define X509V3_F_X509_PURPOSE_add 116
-#define X509V3_F_X509_PURPOSE_set 117
-#define X509V3_F_a2i_GENERAL_NAME 118
-#define X509V3_F_copy_email 119
-#define X509V3_F_copy_issuer 120
-#define X509V3_F_do_dirname 121
-#define X509V3_F_do_ext_i2d 122
-#define X509V3_F_do_ext_nconf 123
-#define X509V3_F_gnames_from_sectname 124
-#define X509V3_F_hex_to_string 125
-#define X509V3_F_i2s_ASN1_ENUMERATED 126
-#define X509V3_F_i2s_ASN1_IA5STRING 127
-#define X509V3_F_i2s_ASN1_INTEGER 128
-#define X509V3_F_i2v_AUTHORITY_INFO_ACCESS 129
-#define X509V3_F_notice_section 130
-#define X509V3_F_nref_nos 131
-#define X509V3_F_policy_section 132
-#define X509V3_F_process_pci_value 133
-#define X509V3_F_r2i_certpol 134
-#define X509V3_F_r2i_pci 135
-#define X509V3_F_s2i_ASN1_IA5STRING 136
-#define X509V3_F_s2i_ASN1_INTEGER 137
-#define X509V3_F_s2i_ASN1_OCTET_STRING 138
-#define X509V3_F_s2i_skey_id 139
-#define X509V3_F_set_dist_point_name 140
-#define X509V3_F_string_to_hex 141
-#define X509V3_F_v2i_ASN1_BIT_STRING 142
-#define X509V3_F_v2i_AUTHORITY_INFO_ACCESS 143
-#define X509V3_F_v2i_AUTHORITY_KEYID 144
-#define X509V3_F_v2i_BASIC_CONSTRAINTS 145
-#define X509V3_F_v2i_EXTENDED_KEY_USAGE 146
-#define X509V3_F_v2i_GENERAL_NAMES 147
-#define X509V3_F_v2i_GENERAL_NAME_ex 148
-#define X509V3_F_v2i_NAME_CONSTRAINTS 149
-#define X509V3_F_v2i_POLICY_CONSTRAINTS 150
-#define X509V3_F_v2i_POLICY_MAPPINGS 151
-#define X509V3_F_v2i_crld 152
-#define X509V3_F_v2i_idp 153
-#define X509V3_F_v2i_issuer_alt 154
-#define X509V3_F_v2i_subject_alt 155
-#define X509V3_F_v3_generic_extension 156
#define X509V3_R_BAD_IP_ADDRESS 100
#define X509V3_R_BAD_OBJECT 101
#define X509V3_R_BN_DEC2BN_ERROR 102
diff --git a/src/ssl/CMakeLists.txt b/src/ssl/CMakeLists.txt
index cf5a29d..2785dcf 100644
--- a/src/ssl/CMakeLists.txt
+++ b/src/ssl/CMakeLists.txt
@@ -1,10 +1,11 @@
-include_directories(. .. ../include)
+include_directories(../include)
add_subdirectory(pqueue)
add_library(
ssl
+ custom_extensions.c
d1_both.c
d1_clnt.c
d1_lib.c
@@ -12,6 +13,7 @@ add_library(
d1_pkt.c
d1_srtp.c
d1_srvr.c
+ dtls_record.c
s3_both.c
s3_clnt.c
s3_enc.c
@@ -20,18 +22,19 @@ add_library(
s3_pkt.c
s3_srvr.c
ssl_aead_ctx.c
- ssl_algs.c
ssl_asn1.c
+ ssl_buffer.c
ssl_cert.c
ssl_cipher.c
+ ssl_file.c
ssl_lib.c
ssl_rsa.c
- ssl_sess.c
+ ssl_session.c
ssl_stat.c
ssl_txt.c
t1_enc.c
t1_lib.c
- t1_reneg.c
+ tls_record.c
$<TARGET_OBJECTS:pqueue>
)
diff --git a/src/ssl/custom_extensions.c b/src/ssl/custom_extensions.c
new file mode 100644
index 0000000..c94543d
--- /dev/null
+++ b/src/ssl/custom_extensions.c
@@ -0,0 +1,257 @@
+/* Copyright (c) 2014, Google Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
+
+#include <openssl/ssl.h>
+
+#include <assert.h>
+#include <string.h>
+
+#include <openssl/bytestring.h>
+#include <openssl/err.h>
+#include <openssl/mem.h>
+#include <openssl/stack.h>
+
+#include "internal.h"
+
+
+void SSL_CUSTOM_EXTENSION_free(SSL_CUSTOM_EXTENSION *custom_extension) {
+ OPENSSL_free(custom_extension);
+}
+
+static const SSL_CUSTOM_EXTENSION *custom_ext_find(
+ STACK_OF(SSL_CUSTOM_EXTENSION) *stack,
+ unsigned *out_index, uint16_t value) {
+ size_t i;
+ for (i = 0; i < sk_SSL_CUSTOM_EXTENSION_num(stack); i++) {
+ const SSL_CUSTOM_EXTENSION *ext = sk_SSL_CUSTOM_EXTENSION_value(stack, i);
+ if (ext->value == value) {
+ if (out_index != NULL) {
+ *out_index = i;
+ }
+ return ext;
+ }
+ }
+
+ return NULL;
+}
+
+/* default_add_callback is used as the |add_callback| when the user doesn't
+ * provide one. For servers, it does nothing while, for clients, it causes an
+ * empty extension to be included. */
+static int default_add_callback(SSL *ssl, unsigned extension_value,
+ const uint8_t **out, size_t *out_len,
+ int *out_alert_value, void *add_arg) {
+ if (ssl->server) {
+ return 0;
+ }
+ *out_len = 0;
+ return 1;
+}
+
+static int custom_ext_add_hello(SSL *ssl, CBB *extensions) {
+ STACK_OF(SSL_CUSTOM_EXTENSION) *stack = ssl->ctx->client_custom_extensions;
+ if (ssl->server) {
+ stack = ssl->ctx->server_custom_extensions;
+ }
+
+ if (stack == NULL) {
+ return 1;
+ }
+
+ size_t i;
+ for (i = 0; i < sk_SSL_CUSTOM_EXTENSION_num(stack); i++) {
+ const SSL_CUSTOM_EXTENSION *ext = sk_SSL_CUSTOM_EXTENSION_value(stack, i);
+
+ if (ssl->server &&
+ !(ssl->s3->tmp.custom_extensions.received & (1u << i))) {
+ /* Servers cannot echo extensions that the client didn't send. */
+ continue;
+ }
+
+ const uint8_t *contents;
+ size_t contents_len;
+ int alert = SSL_AD_DECODE_ERROR;
+ CBB contents_cbb;
+
+ switch (ext->add_callback(ssl, ext->value, &contents, &contents_len, &alert,
+ ext->add_arg)) {
+ case 1:
+ if (!CBB_add_u16(extensions, ext->value) ||
+ !CBB_add_u16_length_prefixed(extensions, &contents_cbb) ||
+ !CBB_add_bytes(&contents_cbb, contents, contents_len) ||
+ !CBB_flush(extensions)) {
+ OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
+ ERR_add_error_dataf("extension: %u", (unsigned) ext->value);
+ if (ext->free_callback && 0 < contents_len) {
+ ext->free_callback(ssl, ext->value, contents, ext->add_arg);
+ }
+ return 0;
+ }
+
+ if (ext->free_callback && 0 < contents_len) {
+ ext->free_callback(ssl, ext->value, contents, ext->add_arg);
+ }
+
+ if (!ssl->server) {
+ assert((ssl->s3->tmp.custom_extensions.sent & (1u << i)) == 0);
+ ssl->s3->tmp.custom_extensions.sent |= (1u << i);
+ }
+ break;
+
+ case 0:
+ break;
+
+ default:
+ ssl3_send_alert(ssl, SSL3_AL_FATAL, alert);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_CUSTOM_EXTENSION_ERROR);
+ ERR_add_error_dataf("extension: %u", (unsigned) ext->value);
+ return 0;
+ }
+ }
+
+ return 1;
+}
+
+int custom_ext_add_clienthello(SSL *ssl, CBB *extensions) {
+ return custom_ext_add_hello(ssl, extensions);
+}
+
+int custom_ext_parse_serverhello(SSL *ssl, int *out_alert, uint16_t value,
+ const CBS *extension) {
+ unsigned index;
+ const SSL_CUSTOM_EXTENSION *ext =
+ custom_ext_find(ssl->ctx->client_custom_extensions, &index, value);
+
+ if (/* Unknown extensions are not allowed in a ServerHello. */
+ ext == NULL ||
+ /* Also, if we didn't send the extension, that's also unacceptable. */
+ !(ssl->s3->tmp.custom_extensions.sent & (1u << index))) {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_EXTENSION);
+ ERR_add_error_dataf("extension: %u", (unsigned)value);
+ *out_alert = SSL_AD_DECODE_ERROR;
+ return 0;
+ }
+
+ if (ext->parse_callback != NULL &&
+ !ext->parse_callback(ssl, value, CBS_data(extension), CBS_len(extension),
+ out_alert, ext->parse_arg)) {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_CUSTOM_EXTENSION_ERROR);
+ ERR_add_error_dataf("extension: %u", (unsigned)ext->value);
+ return 0;
+ }
+
+ return 1;
+}
+
+int custom_ext_parse_clienthello(SSL *ssl, int *out_alert, uint16_t value,
+ const CBS *extension) {
+ unsigned index;
+ const SSL_CUSTOM_EXTENSION *ext =
+ custom_ext_find(ssl->ctx->server_custom_extensions, &index, value);
+
+ if (ext == NULL) {
+ return 1;
+ }
+
+ assert((ssl->s3->tmp.custom_extensions.received & (1u << index)) == 0);
+ ssl->s3->tmp.custom_extensions.received |= (1u << index);
+
+ if (ext->parse_callback &&
+ !ext->parse_callback(ssl, value, CBS_data(extension), CBS_len(extension),
+ out_alert, ext->parse_arg)) {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_CUSTOM_EXTENSION_ERROR);
+ ERR_add_error_dataf("extension: %u", (unsigned)ext->value);
+ return 0;
+ }
+
+ return 1;
+}
+
+int custom_ext_add_serverhello(SSL *ssl, CBB *extensions) {
+ return custom_ext_add_hello(ssl, extensions);
+}
+
+/* MAX_NUM_CUSTOM_EXTENSIONS is the maximum number of custom extensions that
+ * can be set on an |SSL_CTX|. It's determined by the size of the bitset used
+ * to track when an extension has been sent. */
+#define MAX_NUM_CUSTOM_EXTENSIONS \
+ (sizeof(((struct ssl3_state_st *)NULL)->tmp.custom_extensions.sent) * 8)
+
+static int custom_ext_append(STACK_OF(SSL_CUSTOM_EXTENSION) **stack,
+ unsigned extension_value,
+ SSL_custom_ext_add_cb add_cb,
+ SSL_custom_ext_free_cb free_cb, void *add_arg,
+ SSL_custom_ext_parse_cb parse_cb,
+ void *parse_arg) {
+ if (add_cb == NULL ||
+ 0xffff < extension_value ||
+ SSL_extension_supported(extension_value) ||
+ /* Specifying a free callback without an add callback is nonsensical
+ * and an error. */
+ (*stack != NULL &&
+ (MAX_NUM_CUSTOM_EXTENSIONS <= sk_SSL_CUSTOM_EXTENSION_num(*stack) ||
+ custom_ext_find(*stack, NULL, extension_value) != NULL))) {
+ return 0;
+ }
+
+ SSL_CUSTOM_EXTENSION *ext = OPENSSL_malloc(sizeof(SSL_CUSTOM_EXTENSION));
+ if (ext == NULL) {
+ return 0;
+ }
+ ext->add_callback = add_cb;
+ ext->add_arg = add_arg;
+ ext->free_callback = free_cb;
+ ext->parse_callback = parse_cb;
+ ext->parse_arg = parse_arg;
+ ext->value = extension_value;
+
+ if (*stack == NULL) {
+ *stack = sk_SSL_CUSTOM_EXTENSION_new_null();
+ if (*stack == NULL) {
+ SSL_CUSTOM_EXTENSION_free(ext);
+ return 0;
+ }
+ }
+
+ if (!sk_SSL_CUSTOM_EXTENSION_push(*stack, ext)) {
+ SSL_CUSTOM_EXTENSION_free(ext);
+ if (sk_SSL_CUSTOM_EXTENSION_num(*stack) == 0) {
+ sk_SSL_CUSTOM_EXTENSION_free(*stack);
+ *stack = NULL;
+ }
+ return 0;
+ }
+
+ return 1;
+}
+
+int SSL_CTX_add_client_custom_ext(SSL_CTX *ctx, unsigned extension_value,
+ SSL_custom_ext_add_cb add_cb,
+ SSL_custom_ext_free_cb free_cb, void *add_arg,
+ SSL_custom_ext_parse_cb parse_cb,
+ void *parse_arg) {
+ return custom_ext_append(&ctx->client_custom_extensions, extension_value,
+ add_cb ? add_cb : default_add_callback, free_cb,
+ add_arg, parse_cb, parse_arg);
+}
+
+int SSL_CTX_add_server_custom_ext(SSL_CTX *ctx, unsigned extension_value,
+ SSL_custom_ext_add_cb add_cb,
+ SSL_custom_ext_free_cb free_cb, void *add_arg,
+ SSL_custom_ext_parse_cb parse_cb,
+ void *parse_arg) {
+ return custom_ext_append(&ctx->server_custom_extensions, extension_value,
+ add_cb ? add_cb : default_add_callback, free_cb,
+ add_arg, parse_cb, parse_arg);
+}
diff --git a/src/ssl/d1_both.c b/src/ssl/d1_both.c
index ac35a66..1acb3ce 100644
--- a/src/ssl/d1_both.c
+++ b/src/ssl/d1_both.c
@@ -111,6 +111,8 @@
* copied and put under another distribution licence
* [including the GNU Public Licence.] */
+#include <openssl/ssl.h>
+
#include <assert.h>
#include <limits.h>
#include <stdio.h>
@@ -147,52 +149,44 @@ static void dtls1_fix_message_header(SSL *s, unsigned long frag_off,
unsigned long frag_len);
static unsigned char *dtls1_write_message_header(SSL *s, unsigned char *p);
-static hm_fragment *dtls1_hm_fragment_new(unsigned long frag_len,
- int reassembly) {
- hm_fragment *frag = NULL;
- uint8_t *buf = NULL;
- uint8_t *bitmask = NULL;
-
- frag = (hm_fragment *)OPENSSL_malloc(sizeof(hm_fragment));
+static hm_fragment *dtls1_hm_fragment_new(size_t frag_len, int reassembly) {
+ hm_fragment *frag = OPENSSL_malloc(sizeof(hm_fragment));
if (frag == NULL) {
- OPENSSL_PUT_ERROR(SSL, dtls1_hm_fragment_new, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
return NULL;
}
+ memset(frag, 0, sizeof(hm_fragment));
- if (frag_len) {
- buf = (uint8_t *)OPENSSL_malloc(frag_len);
- if (buf == NULL) {
- OPENSSL_PUT_ERROR(SSL, dtls1_hm_fragment_new, ERR_R_MALLOC_FAILURE);
- OPENSSL_free(frag);
- return NULL;
+ /* If the handshake message is empty, |frag->fragment| and |frag->reassembly|
+ * are NULL. */
+ if (frag_len > 0) {
+ frag->fragment = OPENSSL_malloc(frag_len);
+ if (frag->fragment == NULL) {
+ OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
+ goto err;
}
- }
-
- /* zero length fragment gets zero frag->fragment */
- frag->fragment = buf;
- /* Initialize reassembly bitmask if necessary */
- if (reassembly && frag_len > 0) {
- if (frag_len + 7 < frag_len) {
- OPENSSL_PUT_ERROR(SSL, dtls1_hm_fragment_new, ERR_R_OVERFLOW);
- return NULL;
- }
- size_t bitmask_len = (frag_len + 7) / 8;
- bitmask = (uint8_t *)OPENSSL_malloc(bitmask_len);
- if (bitmask == NULL) {
- OPENSSL_PUT_ERROR(SSL, dtls1_hm_fragment_new, ERR_R_MALLOC_FAILURE);
- if (buf != NULL) {
- OPENSSL_free(buf);
+ if (reassembly) {
+ /* Initialize reassembly bitmask. */
+ if (frag_len + 7 < frag_len) {
+ OPENSSL_PUT_ERROR(SSL, ERR_R_OVERFLOW);
+ goto err;
}
- OPENSSL_free(frag);
- return NULL;
+ size_t bitmask_len = (frag_len + 7) / 8;
+ frag->reassembly = OPENSSL_malloc(bitmask_len);
+ if (frag->reassembly == NULL) {
+ OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+ memset(frag->reassembly, 0, bitmask_len);
}
- memset(bitmask, 0, bitmask_len);
}
- frag->reassembly = bitmask;
-
return frag;
+
+err:
+ dtls1_hm_fragment_free(frag);
+ return NULL;
}
void dtls1_hm_fragment_free(hm_fragment *frag) {
@@ -326,7 +320,7 @@ int dtls1_do_write(SSL *s, int type, enum dtls1_use_epoch_t use_epoch) {
if (curr_mtu <= DTLS1_HM_HEADER_LENGTH) {
/* To make forward progress, the MTU must, at minimum, fit the handshake
* header and one byte of handshake body. */
- OPENSSL_PUT_ERROR(SSL, dtls1_do_write, SSL_R_MTU_TOO_SMALL);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_MTU_TOO_SMALL);
return -1;
}
@@ -344,7 +338,7 @@ int dtls1_do_write(SSL *s, int type, enum dtls1_use_epoch_t use_epoch) {
assert(type == SSL3_RT_CHANGE_CIPHER_SPEC);
/* ChangeCipherSpec cannot be fragmented. */
if (s->init_num > curr_mtu) {
- OPENSSL_PUT_ERROR(SSL, dtls1_do_write, SSL_R_MTU_TOO_SMALL);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_MTU_TOO_SMALL);
return -1;
}
len = s->init_num;
@@ -450,8 +444,7 @@ static hm_fragment *dtls1_get_buffered_message(
frag->msg_header.msg_len != msg_hdr->msg_len) {
/* The new fragment must be compatible with the previous fragments from
* this message. */
- OPENSSL_PUT_ERROR(SSL, dtls1_get_buffered_message,
- SSL_R_FRAGMENT_MISMATCH);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_FRAGMENT_MISMATCH);
ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER);
return NULL;
}
@@ -473,11 +466,7 @@ static size_t dtls1_max_handshake_message_len(const SSL *s) {
/* dtls1_process_fragment reads a handshake fragment and processes it. It
* returns one if a fragment was successfully processed and 0 or -1 on error. */
static int dtls1_process_fragment(SSL *s) {
- /* Read handshake message header.
- *
- * TODO(davidben): ssl_read_bytes allows splitting the fragment header and
- * body across two records. Change this interface to consume the fragment in
- * one pass. */
+ /* Read handshake message header. */
uint8_t header[DTLS1_HM_HEADER_LENGTH];
int ret = dtls1_read_bytes(s, SSL3_RT_HANDSHAKE, header,
DTLS1_HM_HEADER_LENGTH, 0);
@@ -485,7 +474,7 @@ static int dtls1_process_fragment(SSL *s) {
return ret;
}
if (ret != DTLS1_HM_HEADER_LENGTH) {
- OPENSSL_PUT_ERROR(SSL, dtls1_process_fragment, SSL_R_UNEXPECTED_MESSAGE);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_MESSAGE);
ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_UNEXPECTED_MESSAGE);
return -1;
}
@@ -494,14 +483,16 @@ static int dtls1_process_fragment(SSL *s) {
struct hm_header_st msg_hdr;
dtls1_get_message_header(header, &msg_hdr);
+ /* TODO(davidben): dtls1_read_bytes is the wrong abstraction for DTLS. There
+ * should be no need to reach into |s->s3->rrec.length|. */
const size_t frag_off = msg_hdr.frag_off;
const size_t frag_len = msg_hdr.frag_len;
const size_t msg_len = msg_hdr.msg_len;
if (frag_off > msg_len || frag_off + frag_len < frag_off ||
frag_off + frag_len > msg_len ||
- msg_len > dtls1_max_handshake_message_len(s)) {
- OPENSSL_PUT_ERROR(SSL, dtls1_process_fragment,
- SSL_R_EXCESSIVE_MESSAGE_SIZE);
+ msg_len > dtls1_max_handshake_message_len(s) ||
+ frag_len > s->s3->rrec.length) {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_EXCESSIVE_MESSAGE_SIZE);
ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER);
return -1;
}
@@ -535,8 +526,8 @@ static int dtls1_process_fragment(SSL *s) {
ret = dtls1_read_bytes(s, SSL3_RT_HANDSHAKE, frag->fragment + frag_off,
frag_len, 0);
if (ret != frag_len) {
- OPENSSL_PUT_ERROR(SSL, dtls1_process_fragment, SSL_R_UNEXPECTED_MESSAGE);
- ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_UNEXPECTED_MESSAGE);
+ OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
+ ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
return -1;
}
dtls1_hm_fragment_mark(frag, frag_off, frag_off + frag_len);
@@ -563,7 +554,7 @@ long dtls1_get_message(SSL *s, int st1, int stn, int msg_type, long max,
s->s3->tmp.reuse_message = 0;
if (msg_type >= 0 && s->s3->tmp.message_type != msg_type) {
al = SSL_AD_UNEXPECTED_MESSAGE;
- OPENSSL_PUT_ERROR(SSL, dtls1_get_message, SSL_R_UNEXPECTED_MESSAGE);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_MESSAGE);
goto f_err;
}
*ok = 1;
@@ -589,22 +580,19 @@ long dtls1_get_message(SSL *s, int st1, int stn, int msg_type, long max,
assert(frag->reassembly == NULL);
if (frag->msg_header.msg_len > (size_t)max) {
- OPENSSL_PUT_ERROR(SSL, dtls1_get_message, SSL_R_EXCESSIVE_MESSAGE_SIZE);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_EXCESSIVE_MESSAGE_SIZE);
goto err;
}
+ /* Reconstruct the assembled message. */
+ size_t len;
CBB cbb;
+ CBB_zero(&cbb);
if (!BUF_MEM_grow(s->init_buf,
(size_t)frag->msg_header.msg_len +
DTLS1_HM_HEADER_LENGTH) ||
- !CBB_init_fixed(&cbb, (uint8_t *)s->init_buf->data, s->init_buf->max)) {
- OPENSSL_PUT_ERROR(SSL, dtls1_get_message, ERR_R_MALLOC_FAILURE);
- goto err;
- }
-
- /* Reconstruct the assembled message. */
- size_t len;
- if (!CBB_add_u8(&cbb, frag->msg_header.type) ||
+ !CBB_init_fixed(&cbb, (uint8_t *)s->init_buf->data, s->init_buf->max) ||
+ !CBB_add_u8(&cbb, frag->msg_header.type) ||
!CBB_add_u24(&cbb, frag->msg_header.msg_len) ||
!CBB_add_u16(&cbb, frag->msg_header.seq) ||
!CBB_add_u24(&cbb, 0 /* frag_off */) ||
@@ -612,7 +600,7 @@ long dtls1_get_message(SSL *s, int st1, int stn, int msg_type, long max,
!CBB_add_bytes(&cbb, frag->fragment, frag->msg_header.msg_len) ||
!CBB_finish(&cbb, NULL, &len)) {
CBB_cleanup(&cbb);
- OPENSSL_PUT_ERROR(SSL, dtls1_get_message, ERR_R_INTERNAL_ERROR);
+ OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
goto err;
}
assert(len == (size_t)frag->msg_header.msg_len + DTLS1_HM_HEADER_LENGTH);
@@ -628,7 +616,7 @@ long dtls1_get_message(SSL *s, int st1, int stn, int msg_type, long max,
if (msg_type >= 0 && s->s3->tmp.message_type != msg_type) {
al = SSL_AD_UNEXPECTED_MESSAGE;
- OPENSSL_PUT_ERROR(SSL, dtls1_get_message, SSL_R_UNEXPECTED_MESSAGE);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_MESSAGE);
goto f_err;
}
if (hash_message == ssl_hash_message && !ssl3_hash_current_message(s)) {
diff --git a/src/ssl/d1_clnt.c b/src/ssl/d1_clnt.c
index 92fb8f6..73a3f8a 100644
--- a/src/ssl/d1_clnt.c
+++ b/src/ssl/d1_clnt.c
@@ -112,6 +112,8 @@
* [including the GNU Public Licence.]
*/
+#include <openssl/ssl.h>
+
#include <assert.h>
#include <stdio.h>
#include <string.h>
@@ -128,6 +130,7 @@
#include "internal.h"
+
static int dtls1_get_hello_verify(SSL *s);
int dtls1_connect(SSL *s) {
@@ -188,9 +191,8 @@ int dtls1_connect(SSL *s) {
case SSL3_ST_CW_CLNT_HELLO_B:
s->shutdown = 0;
- /* every DTLS ClientHello resets Finished MAC */
- if (!ssl3_init_finished_mac(s)) {
- OPENSSL_PUT_ERROR(SSL, dtls1_connect, ERR_R_INTERNAL_ERROR);
+ if (!ssl3_init_handshake_buffer(s)) {
+ OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
ret = -1;
goto end;
}
@@ -261,7 +263,7 @@ int dtls1_connect(SSL *s) {
if (s->s3->tmp.certificate_status_expected) {
s->state = SSL3_ST_CR_CERT_STATUS_A;
} else {
- s->state = SSL3_ST_CR_KEY_EXCH_A;
+ s->state = SSL3_ST_VERIFY_SERVER_CERT;
}
} else {
skip = 1;
@@ -270,6 +272,16 @@ int dtls1_connect(SSL *s) {
s->init_num = 0;
break;
+ case SSL3_ST_VERIFY_SERVER_CERT:
+ ret = ssl3_verify_server_cert(s);
+ if (ret <= 0) {
+ goto end;
+ }
+
+ s->state = SSL3_ST_CR_KEY_EXCH_A;
+ s->init_num = 0;
+ break;
+
case SSL3_ST_CR_KEY_EXCH_A:
case SSL3_ST_CR_KEY_EXCH_B:
ret = ssl3_get_server_key_exchange(s);
@@ -278,13 +290,6 @@ int dtls1_connect(SSL *s) {
}
s->state = SSL3_ST_CR_CERT_REQ_A;
s->init_num = 0;
-
- /* at this point we check that we have the
- * required stuff from the server */
- if (!ssl3_check_cert_and_algorithm(s)) {
- ret = -1;
- goto end;
- }
break;
case SSL3_ST_CR_CERT_REQ_A:
@@ -426,7 +431,7 @@ int dtls1_connect(SSL *s) {
if (ret <= 0) {
goto end;
}
- s->state = SSL3_ST_CR_KEY_EXCH_A;
+ s->state = SSL3_ST_VERIFY_SERVER_CERT;
s->init_num = 0;
break;
@@ -483,7 +488,7 @@ int dtls1_connect(SSL *s) {
goto end;
default:
- OPENSSL_PUT_ERROR(SSL, dtls1_connect, SSL_R_UNKNOWN_STATE);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_UNKNOWN_STATE);
ret = -1;
goto end;
}
@@ -538,7 +543,7 @@ static int dtls1_get_hello_verify(SSL *s) {
!CBS_get_u8_length_prefixed(&hello_verify_request, &cookie) ||
CBS_len(&hello_verify_request) != 0) {
al = SSL_AD_DECODE_ERROR;
- OPENSSL_PUT_ERROR(SSL, dtls1_get_hello_verify, SSL_R_DECODE_ERROR);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
goto f_err;
}
diff --git a/src/ssl/d1_lib.c b/src/ssl/d1_lib.c
index ef7a9c9..cb95585 100644
--- a/src/ssl/d1_lib.c
+++ b/src/ssl/d1_lib.c
@@ -54,12 +54,18 @@
* (eay@cryptsoft.com). This product includes software written by Tim
* Hudson (tjh@cryptsoft.com). */
-#include <openssl/base.h>
+#include <openssl/ssl.h>
#include <limits.h>
#include <stdio.h>
#include <string.h>
+#include <openssl/err.h>
+#include <openssl/mem.h>
+#include <openssl/obj.h>
+
+#include "internal.h"
+
#if defined(OPENSSL_WINDOWS)
#include <sys/timeb.h>
#else
@@ -67,11 +73,6 @@
#include <sys/time.h>
#endif
-#include <openssl/err.h>
-#include <openssl/mem.h>
-#include <openssl/obj.h>
-
-#include "internal.h"
/* DTLS1_MTU_TIMEOUTS is the maximum number of timeouts to expire
* before starting to decrease the MTU. */
@@ -152,8 +153,9 @@ void dtls1_free(SSL *s) {
}
int dtls1_supports_cipher(const SSL_CIPHER *cipher) {
- /* DTLS does not support stream ciphers. */
- return cipher->algorithm_enc != SSL_RC4;
+ /* DTLS does not support stream ciphers. The NULL cipher is rejected because
+ * it's not needed. */
+ return cipher->algorithm_enc != SSL_RC4 && cipher->algorithm_enc != SSL_eNULL;
}
void dtls1_start_timer(SSL *s) {
@@ -262,7 +264,7 @@ int dtls1_check_timeout_num(SSL *s) {
if (s->d1->num_timeouts > DTLS1_MAX_TIMEOUTS) {
/* fail the connection, enough alerts have been sent */
- OPENSSL_PUT_ERROR(SSL, dtls1_check_timeout_num, SSL_R_READ_TIMEOUT_EXPIRED);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_READ_TIMEOUT_EXPIRED);
return -1;
}
@@ -328,8 +330,9 @@ int dtls1_set_handshake_header(SSL *s, int htype, unsigned long len) {
s2n(msg_hdr->seq, p);
l2n3(0, p);
l2n3(msg_hdr->msg_len, p);
- return ssl3_finish_mac(s, serialised_header, sizeof(serialised_header)) &&
- ssl3_finish_mac(s, message + DTLS1_HM_HEADER_LENGTH, len);
+ return ssl3_update_handshake_hash(s, serialised_header,
+ sizeof(serialised_header)) &&
+ ssl3_update_handshake_hash(s, message + DTLS1_HM_HEADER_LENGTH, len);
}
int dtls1_handshake_write(SSL *s) {
diff --git a/src/ssl/d1_meth.c b/src/ssl/d1_meth.c
index d90f75b..d54a037 100644
--- a/src/ssl/d1_meth.c
+++ b/src/ssl/d1_meth.c
@@ -55,6 +55,8 @@
* (eay@cryptsoft.com). This product includes software written by Tim
* Hudson (tjh@cryptsoft.com). */
+#include <openssl/ssl.h>
+
#include "internal.h"
@@ -69,8 +71,6 @@ static const SSL_PROTOCOL_METHOD DTLS_protocol_method = {
dtls1_read_close_notify,
dtls1_write_app_data,
dtls1_dispatch_alert,
- ssl3_ctrl,
- ssl3_ctx_ctrl,
dtls1_supports_cipher,
DTLS1_HM_HEADER_LENGTH,
dtls1_set_handshake_header,
diff --git a/src/ssl/d1_pkt.c b/src/ssl/d1_pkt.c
index 553499f..e2d505c 100644
--- a/src/ssl/d1_pkt.c
+++ b/src/ssl/d1_pkt.c
@@ -109,6 +109,8 @@
* copied and put under another distribution licence
* [including the GNU Public Licence.] */
+#include <openssl/ssl.h>
+
#include <assert.h>
#include <stdio.h>
#include <string.h>
@@ -122,270 +124,66 @@
#include "internal.h"
-/* mod 128 saturating subtract of two 64-bit values in big-endian order */
-static int satsub64be(const uint8_t *v1, const uint8_t *v2) {
- int ret, sat, brw, i;
-
- if (sizeof(long) == 8) {
- do {
- const union {
- long one;
- char little;
- } is_endian = {1};
- long l;
-
- if (is_endian.little) {
- break;
- }
- /* not reached on little-endians */
- /* following test is redundant, because input is
- * always aligned, but I take no chances... */
- if (((size_t)v1 | (size_t)v2) & 0x7) {
- break;
- }
-
- l = *((long *)v1);
- l -= *((long *)v2);
- if (l > 128) {
- return 128;
- } else if (l < -128) {
- return -128;
- } else {
- return (int)l;
- }
- } while (0);
- }
-
- ret = (int)v1[7] - (int)v2[7];
- sat = 0;
- brw = ret >> 8; /* brw is either 0 or -1 */
- if (ret & 0x80) {
- for (i = 6; i >= 0; i--) {
- brw += (int)v1[i] - (int)v2[i];
- sat |= ~brw;
- brw >>= 8;
- }
- } else {
- for (i = 6; i >= 0; i--) {
- brw += (int)v1[i] - (int)v2[i];
- sat |= brw;
- brw >>= 8;
- }
- }
- brw <<= 8; /* brw is either 0 or -256 */
-
- if (sat & 0xff) {
- return brw | 0x80;
- } else {
- return brw + (ret & 0xFF);
- }
-}
-
-static int dtls1_record_replay_check(SSL *s, DTLS1_BITMAP *bitmap);
-static void dtls1_record_bitmap_update(SSL *s, DTLS1_BITMAP *bitmap);
-static int dtls1_process_record(SSL *s);
static int do_dtls1_write(SSL *s, int type, const uint8_t *buf,
unsigned int len, enum dtls1_use_epoch_t use_epoch);
-static int dtls1_process_record(SSL *s) {
- int al;
- SSL3_RECORD *rr = &s->s3->rrec;
-
- /* check is not needed I believe */
- if (rr->length > SSL3_RT_MAX_ENCRYPTED_LENGTH) {
- al = SSL_AD_RECORD_OVERFLOW;
- OPENSSL_PUT_ERROR(SSL, dtls1_process_record,
- SSL_R_ENCRYPTED_LENGTH_TOO_LONG);
- goto f_err;
- }
-
- /* |rr->data| points to |rr->length| bytes of ciphertext in |s->packet|. */
- rr->data = &s->packet[DTLS1_RT_HEADER_LENGTH];
-
- uint8_t seq[8];
- seq[0] = rr->epoch >> 8;
- seq[1] = rr->epoch & 0xff;
- memcpy(&seq[2], &rr->seq_num[2], 6);
-
- /* Decrypt the packet in-place. Note it is important that |SSL_AEAD_CTX_open|
- * not write beyond |rr->length|. There may be another record in the packet.
- *
- * TODO(davidben): This assumes |s->version| is the same as the record-layer
- * version which isn't always true, but it only differs with the NULL cipher
- * which ignores the parameter. */
- size_t plaintext_len;
- if (!SSL_AEAD_CTX_open(s->aead_read_ctx, rr->data, &plaintext_len, rr->length,
- rr->type, s->version, seq, rr->data, rr->length)) {
- /* Bad packets are silently dropped in DTLS. Clear the error queue of any
- * errors decryption may have added. */
- ERR_clear_error();
- rr->length = 0;
- s->packet_length = 0;
- goto err;
- }
-
- if (plaintext_len > SSL3_RT_MAX_PLAIN_LENGTH) {
- al = SSL_AD_RECORD_OVERFLOW;
- OPENSSL_PUT_ERROR(SSL, dtls1_process_record, SSL_R_DATA_LENGTH_TOO_LONG);
- goto f_err;
- }
- assert(plaintext_len < (1u << 16));
- rr->length = plaintext_len;
-
- rr->off = 0;
- /* So at this point the following is true
- * ssl->s3->rrec.type is the type of record
- * ssl->s3->rrec.length == number of bytes in record
- * ssl->s3->rrec.off == offset to first valid byte
- * ssl->s3->rrec.data == the first byte of the record body. */
-
- /* we have pulled in a full packet so zero things */
- s->packet_length = 0;
- return 1;
-
-f_err:
- ssl3_send_alert(s, SSL3_AL_FATAL, al);
-
-err:
- return 0;
-}
-
-/* Call this to get a new input record.
- * It will return <= 0 if more data is needed, normally due to an error
- * or non-blocking IO.
- * When it finishes, one packet has been decoded and can be found in
- * ssl->s3->rrec.type - is the type of record
- * ssl->s3->rrec.data, - data
- * ssl->s3->rrec.length, - number of bytes
- *
- * used only by dtls1_read_bytes */
-int dtls1_get_record(SSL *s) {
- uint8_t ssl_major, ssl_minor;
- int n;
- SSL3_RECORD *rr;
- uint8_t *p = NULL;
- uint16_t version;
-
- rr = &(s->s3->rrec);
-
- /* get something from the wire */
+/* dtls1_get_record reads a new input record. On success, it places it in
+ * |ssl->s3->rrec| and returns one. Otherwise it returns <= 0 on error or if
+ * more data is needed. */
+static int dtls1_get_record(SSL *ssl) {
again:
- /* check if we have the header */
- if ((s->rstate != SSL_ST_READ_BODY) ||
- (s->packet_length < DTLS1_RT_HEADER_LENGTH)) {
- n = ssl3_read_n(s, DTLS1_RT_HEADER_LENGTH, 0);
- /* read timeout is handled by dtls1_read_bytes */
- if (n <= 0) {
- return n; /* error or non-blocking */
- }
-
- /* this packet contained a partial record, dump it */
- if (s->packet_length != DTLS1_RT_HEADER_LENGTH) {
- s->packet_length = 0;
- goto again;
+ /* Read a new packet if there is no unconsumed one. */
+ if (ssl_read_buffer_len(ssl) == 0) {
+ int ret = ssl_read_buffer_extend_to(ssl, 0 /* unused */);
+ if (ret <= 0) {
+ return ret;
}
+ }
+ assert(ssl_read_buffer_len(ssl) > 0);
- s->rstate = SSL_ST_READ_BODY;
+ /* Ensure the packet is large enough to decrypt in-place. */
+ if (ssl_read_buffer_len(ssl) < ssl_record_prefix_len(ssl)) {
+ ssl_read_buffer_clear(ssl);
+ goto again;
+ }
- p = s->packet;
+ uint8_t *out = ssl_read_buffer(ssl) + ssl_record_prefix_len(ssl);
+ size_t max_out = ssl_read_buffer_len(ssl) - ssl_record_prefix_len(ssl);
+ uint8_t type, alert;
+ size_t len, consumed;
+ switch (dtls_open_record(ssl, &type, out, &len, &consumed, &alert, max_out,
+ ssl_read_buffer(ssl), ssl_read_buffer_len(ssl))) {
+ case ssl_open_record_success:
+ ssl_read_buffer_consume(ssl, consumed);
- if (s->msg_callback) {
- s->msg_callback(0, 0, SSL3_RT_HEADER, p, DTLS1_RT_HEADER_LENGTH, s,
- s->msg_callback_arg);
- }
-
- /* Pull apart the header into the DTLS1_RECORD */
- rr->type = *(p++);
- ssl_major = *(p++);
- ssl_minor = *(p++);
- version = (((uint16_t)ssl_major) << 8) | ssl_minor;
-
- /* sequence number is 64 bits, with top 2 bytes = epoch */
- n2s(p, rr->epoch);
-
- memcpy(&(s->s3->read_sequence[2]), p, 6);
- p += 6;
-
- n2s(p, rr->length);
-
- /* Lets check version */
- if (s->s3->have_version) {
- if (version != s->version) {
- /* The record's version doesn't match, so silently drop it.
- *
- * TODO(davidben): This doesn't work. The DTLS record layer is not
- * packet-based, so the remainder of the packet isn't dropped and we
- * get a framing error. It's also unclear what it means to silently
- * drop a record in a packet containing two records. */
- rr->length = 0;
- s->packet_length = 0;
- goto again;
+ if (len > 0xffff) {
+ OPENSSL_PUT_ERROR(SSL, ERR_R_OVERFLOW);
+ return -1;
}
- }
- if ((version & 0xff00) != (s->version & 0xff00)) {
- /* wrong version, silently discard record */
- rr->length = 0;
- s->packet_length = 0;
- goto again;
- }
+ SSL3_RECORD *rr = &ssl->s3->rrec;
+ rr->type = type;
+ rr->length = (uint16_t)len;
+ rr->off = 0;
+ rr->data = out;
+ return 1;
- if (rr->length > SSL3_RT_MAX_ENCRYPTED_LENGTH) {
- /* record too long, silently discard it */
- rr->length = 0;
- s->packet_length = 0;
- goto again;
- }
-
- /* now s->rstate == SSL_ST_READ_BODY */
- }
-
- /* s->rstate == SSL_ST_READ_BODY, get and decode the data */
-
- if (rr->length > s->packet_length - DTLS1_RT_HEADER_LENGTH) {
- /* now s->packet_length == DTLS1_RT_HEADER_LENGTH */
- n = ssl3_read_n(s, rr->length, 1);
- /* This packet contained a partial record, dump it. */
- if (n != rr->length) {
- rr->length = 0;
- s->packet_length = 0;
+ case ssl_open_record_discard:
+ ssl_read_buffer_consume(ssl, consumed);
goto again;
- }
-
- /* now n == rr->length,
- * and s->packet_length == DTLS1_RT_HEADER_LENGTH + rr->length */
- }
- s->rstate = SSL_ST_READ_HEADER; /* set state for later operations */
-
- if (rr->epoch != s->d1->r_epoch) {
- /* This record is from the wrong epoch. If it is the next epoch, it could be
- * buffered. For simplicity, drop it and expect retransmit to handle it
- * later; DTLS is supposed to handle packet loss. */
- rr->length = 0;
- s->packet_length = 0;
- goto again;
- }
-
- /* Check whether this is a repeat, or aged record. */
- if (!dtls1_record_replay_check(s, &s->d1->bitmap)) {
- rr->length = 0;
- s->packet_length = 0; /* dump this record */
- goto again; /* get another record */
- }
- /* just read a 0 length packet */
- if (rr->length == 0) {
- goto again;
- }
+ case ssl_open_record_error:
+ ssl3_send_alert(ssl, SSL3_AL_FATAL, alert);
+ return -1;
- if (!dtls1_process_record(s)) {
- rr->length = 0;
- s->packet_length = 0; /* dump this record */
- goto again; /* get another record */
+ case ssl_open_record_partial:
+ /* Impossible in DTLS. */
+ break;
}
- dtls1_record_bitmap_update(s, &s->d1->bitmap); /* Mark receipt of record. */
- return 1;
+ assert(0);
+ OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
+ return -1;
}
int dtls1_read_app_data(SSL *ssl, uint8_t *buf, int len, int peek) {
@@ -393,7 +191,11 @@ int dtls1_read_app_data(SSL *ssl, uint8_t *buf, int len, int peek) {
}
void dtls1_read_close_notify(SSL *ssl) {
- dtls1_read_bytes(ssl, 0, NULL, 0, 0);
+ /* Bidirectional shutdown doesn't make sense for an unordered transport. DTLS
+ * alerts also aren't delivered reliably, so we may even time out because the
+ * peer never received our close_notify. Report to the caller that the channel
+ * has fully shut down. */
+ ssl->shutdown |= SSL_RECEIVED_SHUTDOWN;
}
/* Return up to 'len' payload bytes received in 'type' records.
@@ -401,7 +203,6 @@ void dtls1_read_close_notify(SSL *ssl) {
*
* - SSL3_RT_HANDSHAKE (when ssl3_get_message calls us)
* - SSL3_RT_APPLICATION_DATA (when ssl3_read calls us)
- * - 0 (during a shutdown, no data has to be returned)
*
* If we don't have stored data to work from, read a SSL/TLS record first
* (possibly multiple records if we still don't have anything to return).
@@ -429,11 +230,9 @@ int dtls1_read_bytes(SSL *s, int type, unsigned char *buf, int len, int peek) {
SSL3_RECORD *rr;
void (*cb)(const SSL *ssl, int type2, int val) = NULL;
- /* XXX: check what the second '&& type' is about */
- if ((type && (type != SSL3_RT_APPLICATION_DATA) &&
- (type != SSL3_RT_HANDSHAKE) && type) ||
- (peek && (type != SSL3_RT_APPLICATION_DATA))) {
- OPENSSL_PUT_ERROR(SSL, dtls1_read_bytes, ERR_R_INTERNAL_ERROR);
+ if ((type != SSL3_RT_APPLICATION_DATA && type != SSL3_RT_HANDSHAKE) ||
+ (peek && type != SSL3_RT_APPLICATION_DATA)) {
+ OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
return -1;
}
@@ -444,7 +243,7 @@ int dtls1_read_bytes(SSL *s, int type, unsigned char *buf, int len, int peek) {
return i;
}
if (i == 0) {
- OPENSSL_PUT_ERROR(SSL, dtls1_read_bytes, SSL_R_SSL_HANDSHAKE_FAILURE);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_SSL_HANDSHAKE_FAILURE);
return -1;
}
}
@@ -464,7 +263,7 @@ start:
}
/* get new packet if necessary */
- if (rr->length == 0 || s->rstate == SSL_ST_READ_BODY) {
+ if (rr->length == 0) {
ret = dtls1_get_record(s);
if (ret <= 0) {
ret = dtls1_read_failed(s, ret);
@@ -507,10 +306,15 @@ start:
/* TODO(davidben): Is this check redundant with the handshake_func
* check? */
al = SSL_AD_UNEXPECTED_MESSAGE;
- OPENSSL_PUT_ERROR(SSL, dtls1_read_bytes, SSL_R_APP_DATA_IN_HANDSHAKE);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_APP_DATA_IN_HANDSHAKE);
goto f_err;
}
+ /* Discard empty records. */
+ if (rr->length == 0) {
+ goto start;
+ }
+
if (len <= 0) {
return len;
}
@@ -526,8 +330,9 @@ start:
rr->length -= n;
rr->off += n;
if (rr->length == 0) {
- s->rstate = SSL_ST_READ_HEADER;
rr->off = 0;
+ /* The record has been consumed, so we may now clear the buffer. */
+ ssl_read_buffer_discard(s);
}
}
@@ -542,7 +347,7 @@ start:
/* Alerts may not be fragmented. */
if (rr->length < 2) {
al = SSL_AD_DECODE_ERROR;
- OPENSSL_PUT_ERROR(SSL, dtls1_read_bytes, SSL_R_BAD_ALERT);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_ALERT);
goto f_err;
}
@@ -576,8 +381,7 @@ start:
s->rwstate = SSL_NOTHING;
s->s3->fatal_alert = alert_descr;
- OPENSSL_PUT_ERROR(SSL, dtls1_read_bytes,
- SSL_AD_REASON_OFFSET + alert_descr);
+ OPENSSL_PUT_ERROR(SSL, SSL_AD_REASON_OFFSET + alert_descr);
BIO_snprintf(tmp, sizeof tmp, "%d", alert_descr);
ERR_add_error_data(2, "SSL alert number ", tmp);
s->shutdown |= SSL_RECEIVED_SHUTDOWN;
@@ -585,26 +389,19 @@ start:
return 0;
} else {
al = SSL_AD_ILLEGAL_PARAMETER;
- OPENSSL_PUT_ERROR(SSL, dtls1_read_bytes, SSL_R_UNKNOWN_ALERT_TYPE);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_UNKNOWN_ALERT_TYPE);
goto f_err;
}
goto start;
}
- if (s->shutdown & SSL_SENT_SHUTDOWN) {
- /* but we have not received a shutdown */
- s->rwstate = SSL_NOTHING;
- rr->length = 0;
- return 0;
- }
-
if (rr->type == SSL3_RT_CHANGE_CIPHER_SPEC) {
/* 'Change Cipher Spec' is just a single byte, so we know exactly what the
* record payload has to look like */
if (rr->length != 1 || rr->off != 0 || rr->data[0] != SSL3_MT_CCS) {
al = SSL_AD_ILLEGAL_PARAMETER;
- OPENSSL_PUT_ERROR(SSL, dtls1_read_bytes, SSL_R_BAD_CHANGE_CIPHER_SPEC);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_CHANGE_CIPHER_SPEC);
goto f_err;
}
@@ -641,7 +438,7 @@ start:
if (rr->type == SSL3_RT_HANDSHAKE && !s->in_handshake) {
if (rr->length < DTLS1_HM_HEADER_LENGTH) {
al = SSL_AD_DECODE_ERROR;
- OPENSSL_PUT_ERROR(SSL, dtls1_read_bytes, SSL_R_BAD_HANDSHAKE_RECORD);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_HANDSHAKE_RECORD);
goto f_err;
}
struct hm_header_st msg_hdr;
@@ -669,7 +466,7 @@ start:
assert(rr->type != SSL3_RT_CHANGE_CIPHER_SPEC && rr->type != SSL3_RT_ALERT);
al = SSL_AD_UNEXPECTED_MESSAGE;
- OPENSSL_PUT_ERROR(SSL, dtls1_read_bytes, SSL_R_UNEXPECTED_RECORD);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_RECORD);
f_err:
ssl3_send_alert(s, SSL3_AL_FATAL, al);
@@ -686,13 +483,13 @@ int dtls1_write_app_data(SSL *s, const void *buf_, int len) {
return i;
}
if (i == 0) {
- OPENSSL_PUT_ERROR(SSL, dtls1_write_app_data, SSL_R_SSL_HANDSHAKE_FAILURE);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_SSL_HANDSHAKE_FAILURE);
return -1;
}
}
if (len > SSL3_RT_MAX_PLAIN_LENGTH) {
- OPENSSL_PUT_ERROR(SSL, dtls1_write_app_data, SSL_R_DTLS_MESSAGE_TOO_BIG);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_DTLS_MESSAGE_TOO_BIG);
return -1;
}
@@ -713,73 +510,11 @@ int dtls1_write_bytes(SSL *s, int type, const void *buf, int len,
return i;
}
-/* dtls1_seal_record seals a new record of type |type| and plaintext |in| and
- * writes it to |out|. At most |max_out| bytes will be written. It returns one
- * on success and zero on error. On success, it updates the write sequence
- * number. */
-static int dtls1_seal_record(SSL *s, uint8_t *out, size_t *out_len,
- size_t max_out, uint8_t type, const uint8_t *in,
- size_t in_len, enum dtls1_use_epoch_t use_epoch) {
- if (max_out < DTLS1_RT_HEADER_LENGTH) {
- OPENSSL_PUT_ERROR(SSL, dtls1_seal_record, SSL_R_BUFFER_TOO_SMALL);
- return 0;
- }
-
- /* Determine the parameters for the current epoch. */
- uint16_t epoch = s->d1->w_epoch;
- SSL_AEAD_CTX *aead = s->aead_write_ctx;
- uint8_t *seq = s->s3->write_sequence;
- if (use_epoch == dtls1_use_previous_epoch) {
- /* DTLS renegotiation is unsupported, so only epochs 0 (NULL cipher) and 1
- * (negotiated cipher) exist. */
- assert(s->d1->w_epoch == 1);
- epoch = s->d1->w_epoch - 1;
- aead = NULL;
- seq = s->d1->last_write_sequence;
- }
-
- out[0] = type;
-
- uint16_t wire_version = s->s3->have_version ? s->version : DTLS1_VERSION;
- out[1] = wire_version >> 8;
- out[2] = wire_version & 0xff;
-
- out[3] = epoch >> 8;
- out[4] = epoch & 0xff;
- memcpy(&out[5], &seq[2], 6);
-
- size_t ciphertext_len;
- if (!SSL_AEAD_CTX_seal(aead, out + DTLS1_RT_HEADER_LENGTH, &ciphertext_len,
- max_out - DTLS1_RT_HEADER_LENGTH, type, wire_version,
- &out[3] /* seq */, in, in_len) ||
- !ssl3_record_sequence_update(&seq[2], 6)) {
- return 0;
- }
-
- if (ciphertext_len >= 1 << 16) {
- OPENSSL_PUT_ERROR(SSL, dtls1_seal_record, ERR_R_OVERFLOW);
- return 0;
- }
- out[11] = ciphertext_len >> 8;
- out[12] = ciphertext_len & 0xff;
-
- *out_len = DTLS1_RT_HEADER_LENGTH + ciphertext_len;
-
- if (s->msg_callback) {
- s->msg_callback(1 /* write */, 0, SSL3_RT_HEADER, out,
- DTLS1_RT_HEADER_LENGTH, s, s->msg_callback_arg);
- }
-
- return 1;
-}
-
static int do_dtls1_write(SSL *s, int type, const uint8_t *buf,
unsigned int len, enum dtls1_use_epoch_t use_epoch) {
- SSL3_BUFFER *wb = &s->s3->wbuf;
-
/* ssl3_write_pending drops the write if |BIO_write| fails in DTLS, so there
* is never pending data. */
- assert(s->s3->wbuf.left == 0);
+ assert(!ssl_write_buffer_is_pending(s));
/* If we have an alert to send, lets send it */
if (s->s3->alert_dispatch) {
@@ -790,7 +525,8 @@ static int do_dtls1_write(SSL *s, int type, const uint8_t *buf,
/* if it went, fall through and send more stuff */
}
- if (wb->buf == NULL && !ssl3_setup_write_buffer(s)) {
+ if (len > SSL3_RT_MAX_PLAIN_LENGTH) {
+ OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
return -1;
}
@@ -798,21 +534,15 @@ static int do_dtls1_write(SSL *s, int type, const uint8_t *buf,
return 0;
}
- /* Align the output so the ciphertext is aligned to |SSL3_ALIGN_PAYLOAD|. */
- uintptr_t align = (uintptr_t)wb->buf + DTLS1_RT_HEADER_LENGTH;
- align = (0 - align) & (SSL3_ALIGN_PAYLOAD - 1);
- uint8_t *out = wb->buf + align;
- wb->offset = align;
- size_t max_out = wb->len - wb->offset;
-
+ size_t max_out = len + ssl_max_seal_overhead(s);
+ uint8_t *out;
size_t ciphertext_len;
- if (!dtls1_seal_record(s, out, &ciphertext_len, max_out, type, buf, len,
- use_epoch)) {
+ if (!ssl_write_buffer_init(s, &out, max_out) ||
+ !dtls_seal_record(s, out, &ciphertext_len, max_out, type, buf, len,
+ use_epoch)) {
return -1;
}
-
- /* now let's set up wb */
- wb->left = ciphertext_len;
+ ssl_write_buffer_set_len(s, ciphertext_len);
/* memorize arguments so that ssl3_write_pending can detect bad write retries
* later */
@@ -825,49 +555,6 @@ static int do_dtls1_write(SSL *s, int type, const uint8_t *buf,
return ssl3_write_pending(s, type, buf, len);
}
-static int dtls1_record_replay_check(SSL *s, DTLS1_BITMAP *bitmap) {
- int cmp;
- unsigned int shift;
- const uint8_t *seq = s->s3->read_sequence;
-
- cmp = satsub64be(seq, bitmap->max_seq_num);
- if (cmp > 0) {
- memcpy(s->s3->rrec.seq_num, seq, 8);
- return 1; /* this record in new */
- }
- shift = -cmp;
- if (shift >= sizeof(bitmap->map) * 8) {
- return 0; /* stale, outside the window */
- } else if (bitmap->map & (((uint64_t)1) << shift)) {
- return 0; /* record previously received */
- }
-
- memcpy(s->s3->rrec.seq_num, seq, 8);
- return 1;
-}
-
-static void dtls1_record_bitmap_update(SSL *s, DTLS1_BITMAP *bitmap) {
- int cmp;
- unsigned int shift;
- const uint8_t *seq = s->s3->read_sequence;
-
- cmp = satsub64be(seq, bitmap->max_seq_num);
- if (cmp > 0) {
- shift = cmp;
- if (shift < sizeof(bitmap->map) * 8) {
- bitmap->map <<= shift, bitmap->map |= 1UL;
- } else {
- bitmap->map = 1UL;
- }
- memcpy(bitmap->max_seq_num, seq, 8);
- } else {
- shift = -cmp;
- if (shift < sizeof(bitmap->map) * 8) {
- bitmap->map |= ((uint64_t)1) << shift;
- }
- }
-}
-
int dtls1_dispatch_alert(SSL *s) {
int i, j;
void (*cb)(const SSL *ssl, int type, int val) = NULL;
diff --git a/src/ssl/d1_srtp.c b/src/ssl/d1_srtp.c
index 5928fc8..2fcc1ea 100644
--- a/src/ssl/d1_srtp.c
+++ b/src/ssl/d1_srtp.c
@@ -114,6 +114,8 @@
Copyright (C) 2011, RTFM, Inc.
*/
+#include <openssl/ssl.h>
+
#include <stdio.h>
#include <string.h>
@@ -122,15 +124,14 @@
#include <openssl/obj.h>
#include "internal.h"
-#include <openssl/srtp.h>
-static const SRTP_PROTECTION_PROFILE srtp_known_profiles[] = {
+const SRTP_PROTECTION_PROFILE kSRTPProfiles[] = {
{
- "SRTP_AES128_CM_SHA1_80", SRTP_AES128_CM_SHA1_80,
+ "SRTP_AES128_CM_SHA1_80", SRTP_AES128_CM_SHA1_80,
},
{
- "SRTP_AES128_CM_SHA1_32", SRTP_AES128_CM_SHA1_32,
+ "SRTP_AES128_CM_SHA1_32", SRTP_AES128_CM_SHA1_32,
},
{0},
};
@@ -140,7 +141,7 @@ static int find_profile_by_name(const char *profile_name,
size_t len) {
const SRTP_PROTECTION_PROFILE *p;
- p = srtp_known_profiles;
+ p = kSRTPProfiles;
while (p->name) {
if (len == strlen(p->name) && !strncmp(p->name, profile_name, len)) {
*pptr = p;
@@ -153,22 +154,6 @@ static int find_profile_by_name(const char *profile_name,
return 0;
}
-static int find_profile_by_num(unsigned profile_num,
- const SRTP_PROTECTION_PROFILE **pptr) {
- const SRTP_PROTECTION_PROFILE *p;
-
- p = srtp_known_profiles;
- while (p->name) {
- if (p->id == profile_num) {
- *pptr = p;
- return 1;
- }
- p++;
- }
-
- return 0;
-}
-
static int ssl_ctx_make_profiles(const char *profiles_string,
STACK_OF(SRTP_PROTECTION_PROFILE) **out) {
STACK_OF(SRTP_PROTECTION_PROFILE) *profiles;
@@ -178,8 +163,7 @@ static int ssl_ctx_make_profiles(const char *profiles_string,
profiles = sk_SRTP_PROTECTION_PROFILE_new_null();
if (profiles == NULL) {
- OPENSSL_PUT_ERROR(SSL, ssl_ctx_make_profiles,
- SSL_R_SRTP_COULD_NOT_ALLOCATE_PROFILES);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_SRTP_COULD_NOT_ALLOCATE_PROFILES);
return 0;
}
@@ -190,8 +174,7 @@ static int ssl_ctx_make_profiles(const char *profiles_string,
if (find_profile_by_name(ptr, &p, col ? col - ptr : strlen(ptr))) {
sk_SRTP_PROTECTION_PROFILE_push(profiles, p);
} else {
- OPENSSL_PUT_ERROR(SSL, ssl_ctx_make_profiles,
- SSL_R_SRTP_UNKNOWN_PROTECTION_PROFILE);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_SRTP_UNKNOWN_PROTECTION_PROFILE);
return 0;
}
@@ -209,28 +192,28 @@ int SSL_CTX_set_srtp_profiles(SSL_CTX *ctx, const char *profiles) {
return ssl_ctx_make_profiles(profiles, &ctx->srtp_profiles);
}
-int SSL_set_srtp_profiles(SSL *s, const char *profiles) {
- return ssl_ctx_make_profiles(profiles, &s->srtp_profiles);
+int SSL_set_srtp_profiles(SSL *ssl, const char *profiles) {
+ return ssl_ctx_make_profiles(profiles, &ssl->srtp_profiles);
}
-STACK_OF(SRTP_PROTECTION_PROFILE) *SSL_get_srtp_profiles(SSL *s) {
- if (s == NULL) {
+STACK_OF(SRTP_PROTECTION_PROFILE) *SSL_get_srtp_profiles(SSL *ssl) {
+ if (ssl == NULL) {
return NULL;
}
- if (s->srtp_profiles != NULL) {
- return s->srtp_profiles;
+ if (ssl->srtp_profiles != NULL) {
+ return ssl->srtp_profiles;
}
- if (s->ctx != NULL && s->ctx->srtp_profiles != NULL) {
- return s->ctx->srtp_profiles;
+ if (ssl->ctx != NULL && ssl->ctx->srtp_profiles != NULL) {
+ return ssl->ctx->srtp_profiles;
}
return NULL;
}
-const SRTP_PROTECTION_PROFILE *SSL_get_selected_srtp_profile(SSL *s) {
- return s->srtp_profile;
+const SRTP_PROTECTION_PROFILE *SSL_get_selected_srtp_profile(SSL *ssl) {
+ return ssl->srtp_profile;
}
int SSL_CTX_set_tlsext_use_srtp(SSL_CTX *ctx, const char *profiles) {
@@ -238,195 +221,7 @@ int SSL_CTX_set_tlsext_use_srtp(SSL_CTX *ctx, const char *profiles) {
return !SSL_CTX_set_srtp_profiles(ctx, profiles);
}
-int SSL_set_tlsext_use_srtp(SSL *s, const char *profiles) {
+int SSL_set_tlsext_use_srtp(SSL *ssl, const char *profiles) {
/* This API inverts its return value. */
- return !SSL_set_srtp_profiles(s, profiles);
-}
-
-/* Note: this function returns 0 length if there are no profiles specified */
-int ssl_add_clienthello_use_srtp_ext(SSL *s, uint8_t *p, int *len, int maxlen) {
- int ct = 0;
- int i;
- STACK_OF(SRTP_PROTECTION_PROFILE) *clnt = 0;
- const SRTP_PROTECTION_PROFILE *prof;
-
- clnt = SSL_get_srtp_profiles(s);
- ct = sk_SRTP_PROTECTION_PROFILE_num(clnt); /* -1 if clnt == 0 */
-
- if (p) {
- if (ct == 0) {
- OPENSSL_PUT_ERROR(SSL, ssl_add_clienthello_use_srtp_ext,
- SSL_R_EMPTY_SRTP_PROTECTION_PROFILE_LIST);
- return 0;
- }
-
- if (2 + ct * 2 + 1 > maxlen) {
- OPENSSL_PUT_ERROR(SSL, ssl_add_clienthello_use_srtp_ext,
- SSL_R_SRTP_PROTECTION_PROFILE_LIST_TOO_LONG);
- return 0;
- }
-
- /* Add the length */
- s2n(ct * 2, p);
- for (i = 0; i < ct; i++) {
- prof = sk_SRTP_PROTECTION_PROFILE_value(clnt, i);
- s2n(prof->id, p);
- }
-
- /* Add an empty use_mki value */
- *p++ = 0;
- }
-
- *len = 2 + ct * 2 + 1;
-
- return 1;
-}
-
-int ssl_parse_clienthello_use_srtp_ext(SSL *s, CBS *cbs, int *out_alert) {
- CBS profile_ids, srtp_mki;
- const SRTP_PROTECTION_PROFILE *cprof, *sprof;
- STACK_OF(SRTP_PROTECTION_PROFILE) *client_profiles = 0, *server_profiles;
- size_t i, j;
- int ret = 0;
-
- if (!CBS_get_u16_length_prefixed(cbs, &profile_ids) ||
- CBS_len(&profile_ids) < 2 ||
- !CBS_get_u8_length_prefixed(cbs, &srtp_mki) ||
- CBS_len(cbs) != 0) {
- OPENSSL_PUT_ERROR(SSL, ssl_parse_clienthello_use_srtp_ext,
- SSL_R_BAD_SRTP_PROTECTION_PROFILE_LIST);
- *out_alert = SSL_AD_DECODE_ERROR;
- goto done;
- }
-
- client_profiles = sk_SRTP_PROTECTION_PROFILE_new_null();
- if (client_profiles == NULL) {
- OPENSSL_PUT_ERROR(SSL, ssl_parse_clienthello_use_srtp_ext,
- ERR_R_MALLOC_FAILURE);
- *out_alert = SSL_AD_INTERNAL_ERROR;
- goto done;
- }
-
- while (CBS_len(&profile_ids) > 0) {
- uint16_t profile_id;
-
- if (!CBS_get_u16(&profile_ids, &profile_id)) {
- *out_alert = SSL_AD_DECODE_ERROR;
- goto done;
- }
-
- if (find_profile_by_num(profile_id, &cprof)) {
- sk_SRTP_PROTECTION_PROFILE_push(client_profiles, cprof);
- }
- }
-
- /* Discard the MKI value for now. */
-
- server_profiles = SSL_get_srtp_profiles(s);
-
- /* Pick the server's most preferred profile. */
- for (i = 0; i < sk_SRTP_PROTECTION_PROFILE_num(server_profiles); i++) {
- sprof = sk_SRTP_PROTECTION_PROFILE_value(server_profiles, i);
-
- for (j = 0; j < sk_SRTP_PROTECTION_PROFILE_num(client_profiles); j++) {
- cprof = sk_SRTP_PROTECTION_PROFILE_value(client_profiles, j);
-
- if (cprof->id == sprof->id) {
- s->srtp_profile = sprof;
- ret = 1;
- goto done;
- }
- }
- }
-
- ret = 1;
-
-done:
- if (client_profiles) {
- sk_SRTP_PROTECTION_PROFILE_free(client_profiles);
- }
-
- return ret;
-}
-
-int ssl_add_serverhello_use_srtp_ext(SSL *s, unsigned char *p, int *len,
- int maxlen) {
- if (p) {
- if (maxlen < 5) {
- OPENSSL_PUT_ERROR(SSL, ssl_add_serverhello_use_srtp_ext,
- SSL_R_SRTP_PROTECTION_PROFILE_LIST_TOO_LONG);
- return 0;
- }
-
- if (s->srtp_profile == 0) {
- OPENSSL_PUT_ERROR(SSL, ssl_add_serverhello_use_srtp_ext,
- SSL_R_USE_SRTP_NOT_NEGOTIATED);
- return 0;
- }
-
- s2n(2, p);
- s2n(s->srtp_profile->id, p);
- *p++ = 0;
- }
-
- *len = 5;
-
- return 1;
-}
-
-int ssl_parse_serverhello_use_srtp_ext(SSL *s, CBS *cbs, int *out_alert) {
- CBS profile_ids, srtp_mki;
- uint16_t profile_id;
- size_t i;
-
- STACK_OF(SRTP_PROTECTION_PROFILE) *client_profiles;
- const SRTP_PROTECTION_PROFILE *prof;
-
- /* The extension consists of a u16-prefixed profile ID list containing a
- * single uint16_t profile ID, then followed by a u8-prefixed srtp_mki field.
- *
- * See https://tools.ietf.org/html/rfc5764#section-4.1.1 */
- if (!CBS_get_u16_length_prefixed(cbs, &profile_ids) ||
- !CBS_get_u16(&profile_ids, &profile_id) || CBS_len(&profile_ids) != 0 ||
- !CBS_get_u8_length_prefixed(cbs, &srtp_mki) || CBS_len(cbs) != 0) {
- OPENSSL_PUT_ERROR(SSL, ssl_parse_serverhello_use_srtp_ext,
- SSL_R_BAD_SRTP_PROTECTION_PROFILE_LIST);
- *out_alert = SSL_AD_DECODE_ERROR;
- return 0;
- }
-
- if (CBS_len(&srtp_mki) != 0) {
- /* Must be no MKI, since we never offer one. */
- OPENSSL_PUT_ERROR(SSL, ssl_parse_serverhello_use_srtp_ext,
- SSL_R_BAD_SRTP_MKI_VALUE);
- *out_alert = SSL_AD_ILLEGAL_PARAMETER;
- return 0;
- }
-
- client_profiles = SSL_get_srtp_profiles(s);
-
- /* Throw an error if the server gave us an unsolicited extension */
- if (client_profiles == NULL) {
- OPENSSL_PUT_ERROR(SSL, ssl_parse_serverhello_use_srtp_ext,
- SSL_R_NO_SRTP_PROFILES);
- *out_alert = SSL_AD_DECODE_ERROR;
- return 0;
- }
-
- /* Check to see if the server gave us something we support
- (and presumably offered). */
- for (i = 0; i < sk_SRTP_PROTECTION_PROFILE_num(client_profiles); i++) {
- prof = sk_SRTP_PROTECTION_PROFILE_value(client_profiles, i);
-
- if (prof->id == profile_id) {
- s->srtp_profile = prof;
- *out_alert = 0;
- return 1;
- }
- }
-
- OPENSSL_PUT_ERROR(SSL, ssl_parse_serverhello_use_srtp_ext,
- SSL_R_BAD_SRTP_PROTECTION_PROFILE_LIST);
- *out_alert = SSL_AD_ILLEGAL_PARAMETER;
- return 0;
+ return !SSL_set_srtp_profiles(ssl, profiles);
}
diff --git a/src/ssl/d1_srvr.c b/src/ssl/d1_srvr.c
index e49a3f0..89c26aa 100644
--- a/src/ssl/d1_srvr.c
+++ b/src/ssl/d1_srvr.c
@@ -112,6 +112,8 @@
* [including the GNU Public Licence.]
*/
+#include <openssl/ssl.h>
+
#include <assert.h>
#include <stdio.h>
@@ -150,11 +152,6 @@ int dtls1_accept(SSL *s) {
s->in_handshake++;
- if (s->cert == NULL) {
- OPENSSL_PUT_ERROR(SSL, dtls1_accept, SSL_R_NO_CERTIFICATE_SET);
- return -1;
- }
-
for (;;) {
state = s->state;
@@ -181,8 +178,8 @@ int dtls1_accept(SSL *s) {
goto end;
}
- if (!ssl3_init_finished_mac(s)) {
- OPENSSL_PUT_ERROR(SSL, dtls1_accept, ERR_R_INTERNAL_ERROR);
+ if (!ssl3_init_handshake_buffer(s)) {
+ OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
ret = -1;
goto end;
}
@@ -244,8 +241,19 @@ int dtls1_accept(SSL *s) {
s->init_num = 0;
break;
+ case SSL3_ST_SW_CERT_STATUS_A:
+ case SSL3_ST_SW_CERT_STATUS_B:
+ ret = ssl3_send_certificate_status(s);
+ if (ret <= 0) {
+ goto end;
+ }
+ s->state = SSL3_ST_SW_KEY_EXCH_A;
+ s->init_num = 0;
+ break;
+
case SSL3_ST_SW_KEY_EXCH_A:
case SSL3_ST_SW_KEY_EXCH_B:
+ case SSL3_ST_SW_KEY_EXCH_C:
alg_a = s->s3->tmp.new_cipher->algorithm_auth;
/* Send a ServerKeyExchange message if:
@@ -439,7 +447,7 @@ int dtls1_accept(SSL *s) {
goto end;
default:
- OPENSSL_PUT_ERROR(SSL, dtls1_accept, SSL_R_UNKNOWN_STATE);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_UNKNOWN_STATE);
ret = -1;
goto end;
}
diff --git a/src/ssl/dtls_record.c b/src/ssl/dtls_record.c
new file mode 100644
index 0000000..940494a
--- /dev/null
+++ b/src/ssl/dtls_record.c
@@ -0,0 +1,308 @@
+/* DTLS implementation written by Nagendra Modadugu
+ * (nagendra@cs.stanford.edu) for the OpenSSL project 2005. */
+/* ====================================================================
+ * Copyright (c) 1998-2005 The OpenSSL Project. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ * software must display the following acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ * endorse or promote products derived from this software without
+ * prior written permission. For written permission, please contact
+ * openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ * nor may "OpenSSL" appear in their names without prior written
+ * permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ * acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com). This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.] */
+
+#include <openssl/ssl.h>
+
+#include <assert.h>
+#include <string.h>
+
+#include <openssl/bytestring.h>
+#include <openssl/err.h>
+
+#include "internal.h"
+
+
+/* to_u64_be treats |in| as a 8-byte big-endian integer and returns the value as
+ * a |uint64_t|. */
+static uint64_t to_u64_be(const uint8_t in[8]) {
+ uint64_t ret = 0;
+ unsigned i;
+ for (i = 0; i < 8; i++) {
+ ret <<= 8;
+ ret |= in[i];
+ }
+ return ret;
+}
+
+/* dtls1_bitmap_should_discard returns one if |seq_num| has been seen in |bitmap|
+ * or is stale. Otherwise it returns zero. */
+static int dtls1_bitmap_should_discard(DTLS1_BITMAP *bitmap,
+ const uint8_t seq_num[8]) {
+ const unsigned kWindowSize = sizeof(bitmap->map) * 8;
+
+ uint64_t seq_num_u = to_u64_be(seq_num);
+ if (seq_num_u > bitmap->max_seq_num) {
+ return 0;
+ }
+ uint64_t idx = bitmap->max_seq_num - seq_num_u;
+ return idx >= kWindowSize || (bitmap->map & (((uint64_t)1) << idx));
+}
+
+/* dtls1_bitmap_record updates |bitmap| to record receipt of sequence number
+ * |seq_num|. It slides the window forward if needed. It is an error to call
+ * this function on a stale sequence number. */
+static void dtls1_bitmap_record(DTLS1_BITMAP *bitmap,
+ const uint8_t seq_num[8]) {
+ const unsigned kWindowSize = sizeof(bitmap->map) * 8;
+
+ uint64_t seq_num_u = to_u64_be(seq_num);
+ /* Shift the window if necessary. */
+ if (seq_num_u > bitmap->max_seq_num) {
+ uint64_t shift = seq_num_u - bitmap->max_seq_num;
+ if (shift >= kWindowSize) {
+ bitmap->map = 0;
+ } else {
+ bitmap->map <<= shift;
+ }
+ bitmap->max_seq_num = seq_num_u;
+ }
+
+ uint64_t idx = bitmap->max_seq_num - seq_num_u;
+ if (idx < kWindowSize) {
+ bitmap->map |= ((uint64_t)1) << idx;
+ }
+}
+
+enum ssl_open_record_t dtls_open_record(
+ SSL *ssl, uint8_t *out_type, uint8_t *out, size_t *out_len,
+ size_t *out_consumed, uint8_t *out_alert, size_t max_out, const uint8_t *in,
+ size_t in_len) {
+ CBS cbs;
+ CBS_init(&cbs, in, in_len);
+
+ /* Decode the record. */
+ uint8_t type;
+ uint16_t version;
+ uint8_t sequence[8];
+ CBS body;
+ if (!CBS_get_u8(&cbs, &type) ||
+ !CBS_get_u16(&cbs, &version) ||
+ !CBS_copy_bytes(&cbs, sequence, 8) ||
+ !CBS_get_u16_length_prefixed(&cbs, &body) ||
+ (ssl->s3->have_version && version != ssl->version) ||
+ (version >> 8) != DTLS1_VERSION_MAJOR ||
+ CBS_len(&body) > SSL3_RT_MAX_ENCRYPTED_LENGTH) {
+ /* The record header was incomplete or malformed. Drop the entire packet. */
+ *out_consumed = in_len;
+ return ssl_open_record_discard;
+ }
+
+ if (ssl->msg_callback != NULL) {
+ ssl->msg_callback(0 /* read */, 0, SSL3_RT_HEADER, in,
+ DTLS1_RT_HEADER_LENGTH, ssl, ssl->msg_callback_arg);
+ }
+
+ uint16_t epoch = (((uint16_t)sequence[0]) << 8) | sequence[1];
+ if (epoch != ssl->d1->r_epoch ||
+ dtls1_bitmap_should_discard(&ssl->d1->bitmap, sequence)) {
+ /* Drop this record. It's from the wrong epoch or is a replay. Note that if
+ * |epoch| is the next epoch, the record could be buffered for later. For
+ * simplicity, drop it and expect retransmit to handle it later; DTLS must
+ * handle packet loss anyway. */
+ *out_consumed = in_len - CBS_len(&cbs);
+ return ssl_open_record_discard;
+ }
+
+ /* Decrypt the body. */
+ size_t plaintext_len;
+ if (!SSL_AEAD_CTX_open(ssl->aead_read_ctx, out, &plaintext_len, max_out,
+ type, version, sequence, CBS_data(&body),
+ CBS_len(&body))) {
+ /* Bad packets are silently dropped in DTLS. See section 4.2.1 of RFC 6347.
+ * Clear the error queue of any errors decryption may have added. Drop the
+ * entire packet as it must not have come from the peer.
+ *
+ * TODO(davidben): This doesn't distinguish malloc failures from encryption
+ * failures. */
+ ERR_clear_error();
+ *out_consumed = in_len - CBS_len(&cbs);
+ return ssl_open_record_discard;
+ }
+
+ /* Check the plaintext length. */
+ if (plaintext_len > SSL3_RT_MAX_PLAIN_LENGTH) {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_DATA_LENGTH_TOO_LONG);
+ *out_alert = SSL_AD_RECORD_OVERFLOW;
+ return ssl_open_record_error;
+ }
+
+ dtls1_bitmap_record(&ssl->d1->bitmap, sequence);
+
+ /* TODO(davidben): Limit the number of empty records as in TLS? This is only
+ * useful if we also limit discarded packets. */
+
+ *out_type = type;
+ *out_len = plaintext_len;
+ *out_consumed = in_len - CBS_len(&cbs);
+ return ssl_open_record_success;
+}
+
+int dtls_seal_record(SSL *ssl, uint8_t *out, size_t *out_len, size_t max_out,
+ uint8_t type, const uint8_t *in, size_t in_len,
+ enum dtls1_use_epoch_t use_epoch) {
+ /* Determine the parameters for the current epoch. */
+ uint16_t epoch = ssl->d1->w_epoch;
+ SSL_AEAD_CTX *aead = ssl->aead_write_ctx;
+ uint8_t *seq = ssl->s3->write_sequence;
+ if (use_epoch == dtls1_use_previous_epoch) {
+ /* DTLS renegotiation is unsupported, so only epochs 0 (NULL cipher) and 1
+ * (negotiated cipher) exist. */
+ assert(ssl->d1->w_epoch == 1);
+ epoch = ssl->d1->w_epoch - 1;
+ aead = NULL;
+ seq = ssl->d1->last_write_sequence;
+ }
+
+ if (max_out < DTLS1_RT_HEADER_LENGTH) {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_BUFFER_TOO_SMALL);
+ return 0;
+ }
+ /* Check the record header does not alias any part of the input.
+ * |SSL_AEAD_CTX_seal| will internally enforce other aliasing requirements. */
+ if (in < out + DTLS1_RT_HEADER_LENGTH && out < in + in_len) {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_OUTPUT_ALIASES_INPUT);
+ return 0;
+ }
+
+ out[0] = type;
+
+ uint16_t wire_version = ssl->s3->have_version ? ssl->version : DTLS1_VERSION;
+ out[1] = wire_version >> 8;
+ out[2] = wire_version & 0xff;
+
+ out[3] = epoch >> 8;
+ out[4] = epoch & 0xff;
+ memcpy(&out[5], &seq[2], 6);
+
+ size_t ciphertext_len;
+ if (!SSL_AEAD_CTX_seal(aead, out + DTLS1_RT_HEADER_LENGTH, &ciphertext_len,
+ max_out - DTLS1_RT_HEADER_LENGTH, type, wire_version,
+ &out[3] /* seq */, in, in_len) ||
+ !ssl3_record_sequence_update(&seq[2], 6)) {
+ return 0;
+ }
+
+ if (ciphertext_len >= 1 << 16) {
+ OPENSSL_PUT_ERROR(SSL, ERR_R_OVERFLOW);
+ return 0;
+ }
+ out[11] = ciphertext_len >> 8;
+ out[12] = ciphertext_len & 0xff;
+
+ *out_len = DTLS1_RT_HEADER_LENGTH + ciphertext_len;
+
+ if (ssl->msg_callback) {
+ ssl->msg_callback(1 /* write */, 0, SSL3_RT_HEADER, out,
+ DTLS1_RT_HEADER_LENGTH, ssl, ssl->msg_callback_arg);
+ }
+
+ return 1;
+}
diff --git a/src/ssl/internal.h b/src/ssl/internal.h
index 4d70431..6fb8dbe 100644
--- a/src/ssl/internal.h
+++ b/src/ssl/internal.h
@@ -182,6 +182,7 @@
#define SSL_AES128GCM 0x00000010L
#define SSL_AES256GCM 0x00000020L
#define SSL_CHACHA20POLY1305 0x00000040L
+#define SSL_eNULL 0x00000080L
#define SSL_AES (SSL_AES128 | SSL_AES256 | SSL_AES128GCM | SSL_AES256GCM)
@@ -202,25 +203,15 @@
#define SSL_TLSV1 SSL_SSLV3
#define SSL_TLSV1_2 0x00000004L
-/* Bits for |algorithm2| (handshake digests and other extra flags). */
-
-#define SSL_HANDSHAKE_MAC_MD5 0x10
-#define SSL_HANDSHAKE_MAC_SHA 0x20
-#define SSL_HANDSHAKE_MAC_SHA256 0x40
-#define SSL_HANDSHAKE_MAC_SHA384 0x80
-#define SSL_HANDSHAKE_MAC_DEFAULT \
- (SSL_HANDSHAKE_MAC_MD5 | SSL_HANDSHAKE_MAC_SHA)
+/* Bits for |algorithm_prf| (handshake digest). */
+#define SSL_HANDSHAKE_MAC_DEFAULT 0x1
+#define SSL_HANDSHAKE_MAC_SHA256 0x2
+#define SSL_HANDSHAKE_MAC_SHA384 0x4
/* SSL_MAX_DIGEST is the number of digest types which exist. When adding a new
* one, update the table in ssl_cipher.c. */
#define SSL_MAX_DIGEST 4
-/* SSL_CIPHER_ALGORITHM2_VARIABLE_NONCE_INCLUDED_IN_RECORD is a flag in
- * SSL_CIPHER.algorithm2 which indicates that the variable part of the nonce is
- * included as a prefix of the record. (AES-GCM, for example, does with with an
- * 8-byte variable nonce.) */
-#define SSL_CIPHER_ALGORITHM2_VARIABLE_NONCE_INCLUDED_IN_RECORD (1<<22)
-
/* Bits for |algo_strength|, cipher strength information. */
#define SSL_MEDIUM 0x00000001L
#define SSL_HIGH 0x00000002L
@@ -236,11 +227,11 @@ int ssl_cipher_get_evp_aead(const EVP_AEAD **out_aead,
size_t *out_fixed_iv_len,
const SSL_CIPHER *cipher, uint16_t version);
-/* ssl_get_handshake_digest looks up the |i|th handshake digest type and sets
- * |*out_mask| to the |SSL_HANDSHAKE_MAC_*| mask and |*out_md| to the
- * |EVP_MD|. It returns one on successs and zero if |i| >= |SSL_MAX_DIGEST|. */
-int ssl_get_handshake_digest(uint32_t *out_mask, const EVP_MD **out_md,
- size_t i);
+/* ssl_get_handshake_digest returns the |EVP_MD| corresponding to
+ * |algorithm_prf|. It returns SHA-1 for |SSL_HANDSHAKE_DEFAULT|. The caller is
+ * responsible for maintaining the additional MD5 digest and switching to
+ * SHA-256 in TLS 1.2. */
+const EVP_MD *ssl_get_handshake_digest(uint32_t algorithm_prf);
/* ssl_create_cipher_list evaluates |rule_str| according to the ciphers in
* |ssl_method|. It sets |*out_cipher_list| to a newly-allocated
@@ -254,18 +245,12 @@ ssl_create_cipher_list(const SSL_PROTOCOL_METHOD *ssl_method,
STACK_OF(SSL_CIPHER) **out_cipher_list_by_id,
const char *rule_str);
-/* SSL_PKEY_* denote certificate types. */
-#define SSL_PKEY_RSA_ENC 0
-#define SSL_PKEY_RSA_SIGN 1
-#define SSL_PKEY_ECC 2
-#define SSL_PKEY_NUM 3
-
/* ssl_cipher_get_value returns the cipher suite id of |cipher|. */
uint16_t ssl_cipher_get_value(const SSL_CIPHER *cipher);
-/* ssl_cipher_get_cert_index returns the |SSL_PKEY_*| value corresponding to the
- * certificate type of |cipher| or -1 if there is none. */
-int ssl_cipher_get_cert_index(const SSL_CIPHER *cipher);
+/* ssl_cipher_get_key_type returns the |EVP_PKEY_*| value corresponding to the
+ * server key used in |cipher| or |EVP_PKEY_NONE| if there is none. */
+int ssl_cipher_get_key_type(const SSL_CIPHER *cipher);
/* ssl_cipher_has_server_public_key returns 1 if |cipher| involves a server
* public key in the key exchange, sent in a server Certificate message.
@@ -275,11 +260,16 @@ int ssl_cipher_has_server_public_key(const SSL_CIPHER *cipher);
/* ssl_cipher_requires_server_key_exchange returns 1 if |cipher| requires a
* ServerKeyExchange message. Otherwise it returns 0.
*
- * Unlike ssl_cipher_has_server_public_key, some ciphers take optional
- * ServerKeyExchanges. PSK and RSA_PSK only use the ServerKeyExchange to
- * communicate a psk_identity_hint, so it is optional. */
+ * Unlike |ssl_cipher_has_server_public_key|, this function may return zero
+ * while still allowing |cipher| an optional ServerKeyExchange. This is the
+ * case for plain PSK ciphers. */
int ssl_cipher_requires_server_key_exchange(const SSL_CIPHER *cipher);
+/* ssl_cipher_get_record_split_len, for TLS 1.0 CBC mode ciphers, returns the
+ * length of an encrypted 1-byte record, for use in record-splitting. Otherwise
+ * it returns zero. */
+size_t ssl_cipher_get_record_split_len(const SSL_CIPHER *cipher);
+
/* Encryption layer. */
@@ -350,6 +340,238 @@ int SSL_AEAD_CTX_seal(SSL_AEAD_CTX *ctx, uint8_t *out, size_t *out_len,
size_t in_len);
+/* DTLS replay bitmap. */
+
+/* DTLS1_BITMAP maintains a sliding window of 64 sequence numbers to detect
+ * replayed packets. It should be initialized by zeroing every field. */
+typedef struct dtls1_bitmap_st {
+ /* map is a bit mask of the last 64 sequence numbers. Bit
+ * |1<<i| corresponds to |max_seq_num - i|. */
+ uint64_t map;
+ /* max_seq_num is the largest sequence number seen so far as a 64-bit
+ * integer. */
+ uint64_t max_seq_num;
+} DTLS1_BITMAP;
+
+
+/* Record layer. */
+
+/* ssl_record_prefix_len returns the length of the prefix before the ciphertext
+ * of a record for |ssl|.
+ *
+ * TODO(davidben): Expose this as part of public API once the high-level
+ * buffer-free APIs are available. */
+size_t ssl_record_prefix_len(const SSL *ssl);
+
+enum ssl_open_record_t {
+ ssl_open_record_success,
+ ssl_open_record_discard,
+ ssl_open_record_partial,
+ ssl_open_record_error,
+};
+
+/* tls_open_record decrypts a record from |in|.
+ *
+ * On success, it returns |ssl_open_record_success|. It sets |*out_type| to the
+ * record type, |*out_len| to the plaintext length, and writes the record body
+ * to |out|. It sets |*out_consumed| to the number of bytes of |in| consumed.
+ * Note that |*out_len| may be zero.
+ *
+ * If a record was successfully processed but should be discarded, it returns
+ * |ssl_open_record_discard| and sets |*out_consumed| to the number of bytes
+ * consumed.
+ *
+ * If the input did not contain a complete record, it returns
+ * |ssl_open_record_partial|. It sets |*out_consumed| to the total number of
+ * bytes necessary. It is guaranteed that a successful call to |tls_open_record|
+ * will consume at least that many bytes.
+ *
+ * On failure, it returns |ssl_open_record_error| and sets |*out_alert| to an
+ * alert to emit.
+ *
+ * If |in| and |out| alias, |out| must be <= |in| + |ssl_record_prefix_len|. */
+enum ssl_open_record_t tls_open_record(
+ SSL *ssl, uint8_t *out_type, uint8_t *out, size_t *out_len,
+ size_t *out_consumed, uint8_t *out_alert, size_t max_out, const uint8_t *in,
+ size_t in_len);
+
+/* dtls_open_record implements |tls_open_record| for DTLS. It never returns
+ * |ssl_open_record_partial| but otherwise behaves analogously. */
+enum ssl_open_record_t dtls_open_record(
+ SSL *ssl, uint8_t *out_type, uint8_t *out, size_t *out_len,
+ size_t *out_consumed, uint8_t *out_alert, size_t max_out, const uint8_t *in,
+ size_t in_len);
+
+/* ssl_seal_prefix_len returns the length of the prefix before the ciphertext
+ * when sealing a record with |ssl|. Note that this value may differ from
+ * |ssl_record_prefix_len| when TLS 1.0 CBC record-splitting is enabled. Sealing
+ * a small record may also result in a smaller output than this value.
+ *
+ * TODO(davidben): Expose this as part of public API once the high-level
+ * buffer-free APIs are available. */
+size_t ssl_seal_prefix_len(const SSL *ssl);
+
+/* ssl_max_seal_overhead returns the maximum overhead of sealing a record with
+ * |ssl|. This includes |ssl_seal_prefix_len|.
+ *
+ * TODO(davidben): Expose this as part of public API once the high-level
+ * buffer-free APIs are available. */
+size_t ssl_max_seal_overhead(const SSL *ssl);
+
+/* tls_seal_record seals a new record of type |type| and body |in| and writes it
+ * to |out|. At most |max_out| bytes will be written. It returns one on success
+ * and zero on error. If enabled, |tls_seal_record| implements TLS 1.0 CBC 1/n-1
+ * record splitting and may write two records concatenated.
+ *
+ * For a large record, the ciphertext will begin |ssl_seal_prefix_len| bytes
+ * into out. Aligning |out| appropriately may improve performance. It writes at
+ * most |in_len| + |ssl_max_seal_overhead| bytes to |out|.
+ *
+ * If |in| and |out| alias, |out| + |ssl_seal_prefix_len| must be <= |in|. */
+int tls_seal_record(SSL *ssl, uint8_t *out, size_t *out_len, size_t max_out,
+ uint8_t type, const uint8_t *in, size_t in_len);
+
+enum dtls1_use_epoch_t {
+ dtls1_use_previous_epoch,
+ dtls1_use_current_epoch,
+};
+
+/* dtls_seal_record implements |tls_seal_record| for DTLS. |use_epoch| selects
+ * which epoch's cipher state to use. */
+int dtls_seal_record(SSL *ssl, uint8_t *out, size_t *out_len, size_t max_out,
+ uint8_t type, const uint8_t *in, size_t in_len,
+ enum dtls1_use_epoch_t use_epoch);
+
+
+/* Private key operations. */
+
+/* ssl_has_private_key returns one if |ssl| has a private key
+ * configured and zero otherwise. */
+int ssl_has_private_key(SSL *ssl);
+
+/* ssl_private_key_* call the corresponding function on the
+ * |SSL_PRIVATE_KEY_METHOD| for |ssl|, if configured. Otherwise, they implement
+ * the operation with |EVP_PKEY|. */
+
+int ssl_private_key_type(SSL *ssl);
+
+size_t ssl_private_key_max_signature_len(SSL *ssl);
+
+enum ssl_private_key_result_t ssl_private_key_sign(
+ SSL *ssl, uint8_t *out, size_t *out_len, size_t max_out, const EVP_MD *md,
+ const uint8_t *in, size_t in_len);
+
+enum ssl_private_key_result_t ssl_private_key_sign_complete(
+ SSL *ssl, uint8_t *out, size_t *out_len, size_t max_out);
+
+
+/* Custom extensions */
+
+/* ssl_custom_extension (a.k.a. SSL_CUSTOM_EXTENSION) is a structure that
+ * contains information about custom-extension callbacks. */
+struct ssl_custom_extension {
+ SSL_custom_ext_add_cb add_callback;
+ void *add_arg;
+ SSL_custom_ext_free_cb free_callback;
+ SSL_custom_ext_parse_cb parse_callback;
+ void *parse_arg;
+ uint16_t value;
+};
+
+void SSL_CUSTOM_EXTENSION_free(SSL_CUSTOM_EXTENSION *custom_extension);
+
+int custom_ext_add_clienthello(SSL *ssl, CBB *extensions);
+int custom_ext_parse_serverhello(SSL *ssl, int *out_alert, uint16_t value,
+ const CBS *extension);
+int custom_ext_parse_clienthello(SSL *ssl, int *out_alert, uint16_t value,
+ const CBS *extension);
+int custom_ext_add_serverhello(SSL *ssl, CBB *extensions);
+
+
+/* Handshake hash.
+ *
+ * The TLS handshake maintains a transcript of all handshake messages. At
+ * various points in the protocol, this is either a handshake buffer, a rolling
+ * hash (selected by cipher suite) or both. */
+
+/* ssl3_init_handshake_buffer initializes the handshake buffer and resets the
+ * handshake hash. It returns one success and zero on failure. */
+int ssl3_init_handshake_buffer(SSL *ssl);
+
+/* ssl3_init_handshake_hash initializes the handshake hash based on the pending
+ * cipher and the contents of the handshake buffer. Subsequent calls to
+ * |ssl3_update_handshake_hash| will update the rolling hash. It returns one on
+ * success and zero on failure. It is an error to call this function after the
+ * handshake buffer is released. */
+int ssl3_init_handshake_hash(SSL *ssl);
+
+/* ssl3_free_handshake_buffer releases the handshake buffer. Subsequent calls
+ * to |ssl3_update_handshake_hash| will not update the handshake buffer. */
+void ssl3_free_handshake_buffer(SSL *ssl);
+
+/* ssl3_free_handshake_hash releases the handshake hash. */
+void ssl3_free_handshake_hash(SSL *s);
+
+/* ssl3_update_handshake_hash adds |in| to the handshake buffer and handshake
+ * hash, whichever is enabled. It returns one on success and zero on failure. */
+int ssl3_update_handshake_hash(SSL *ssl, const uint8_t *in, size_t in_len);
+
+
+/* Transport buffers. */
+
+/* ssl_read_buffer returns a pointer to contents of the read buffer. */
+uint8_t *ssl_read_buffer(SSL *ssl);
+
+/* ssl_read_buffer_len returns the length of the read buffer. */
+size_t ssl_read_buffer_len(const SSL *ssl);
+
+/* ssl_read_buffer_extend_to extends the read buffer to the desired length. For
+ * TLS, it reads to the end of the buffer until the buffer is |len| bytes
+ * long. For DTLS, it reads a new packet and ignores |len|. It returns one on
+ * success, zero on EOF, and a negative number on error.
+ *
+ * It is an error to call |ssl_read_buffer_extend_to| in DTLS when the buffer is
+ * non-empty. */
+int ssl_read_buffer_extend_to(SSL *ssl, size_t len);
+
+/* ssl_read_buffer_consume consumes |len| bytes from the read buffer. It
+ * advances the data pointer and decrements the length. The memory consumed will
+ * remain valid until the next call to |ssl_read_buffer_extend| or it is
+ * discarded with |ssl_read_buffer_discard|. */
+void ssl_read_buffer_consume(SSL *ssl, size_t len);
+
+/* ssl_read_buffer_discard discards the consumed bytes from the read buffer. If
+ * the buffer is now empty, it releases memory used by it. */
+void ssl_read_buffer_discard(SSL *ssl);
+
+/* ssl_read_buffer_clear releases all memory associated with the read buffer and
+ * zero-initializes it. */
+void ssl_read_buffer_clear(SSL *ssl);
+
+/* ssl_write_buffer_is_pending returns one if the write buffer has pending data
+ * and zero if is empty. */
+int ssl_write_buffer_is_pending(const SSL *ssl);
+
+/* ssl_write_buffer_init initializes the write buffer. On success, it sets
+ * |*out_ptr| to the start of the write buffer with space for up to |max_len|
+ * bytes. It returns one on success and zero on failure. Call
+ * |ssl_write_buffer_set_len| to complete initialization. */
+int ssl_write_buffer_init(SSL *ssl, uint8_t **out_ptr, size_t max_len);
+
+/* ssl_write_buffer_set_len is called after |ssl_write_buffer_init| to complete
+ * initialization after |len| bytes are written to the buffer. */
+void ssl_write_buffer_set_len(SSL *ssl, size_t len);
+
+/* ssl_write_buffer_flush flushes the write buffer to the transport. It returns
+ * one on success and <= 0 on error. For DTLS, whether or not the write
+ * succeeds, the write buffer will be cleared. */
+int ssl_write_buffer_flush(SSL *ssl);
+
+/* ssl_write_buffer_clear releases all memory associated with the write buffer
+ * and zero-initializes it. */
+void ssl_write_buffer_clear(SSL *ssl);
+
+
/* Underdocumented functions.
*
* Functions below here haven't been touched up and may be underdocumented. */
@@ -483,8 +705,6 @@ int SSL_AEAD_CTX_seal(SSL_AEAD_CTX *ctx, uint8_t *out, size_t *out_len,
* SSL_aRSA <- RSA_ENC | RSA_SIGN
* SSL_aDSS <- DSA_SIGN */
-#define PENDING_SESSION -10000
-
/* From RFC4492, used in encoding the curve type in ECParameters */
#define EXPLICIT_PRIME_CURVE_TYPE 1
#define EXPLICIT_CHAR2_CURVE_TYPE 2
@@ -495,18 +715,21 @@ enum ssl_hash_message_t {
ssl_hash_message,
};
-typedef struct cert_pkey_st {
+/* Structure containing decoded values of signature algorithms extension */
+typedef struct tls_sigalgs_st {
+ uint8_t rsign;
+ uint8_t rhash;
+} TLS_SIGALGS;
+
+typedef struct cert_st {
X509 *x509;
EVP_PKEY *privatekey;
/* Chain for this certificate */
STACK_OF(X509) *chain;
-} CERT_PKEY;
-typedef struct cert_st {
- /* Current active set */
- CERT_PKEY *key; /* ALWAYS points to an element of the pkeys array
- * Probably it would make more sense to store
- * an index, not a pointer. */
+ /* key_method, if non-NULL, is a set of callbacks to call for private key
+ * operations. */
+ const SSL_PRIVATE_KEY_METHOD *key_method;
/* For clients the following masks are of *disabled* key and auth algorithms
* based on the current session.
@@ -531,39 +754,18 @@ typedef struct cert_st {
* keys. If NULL, a curve is selected automatically. See
* |SSL_CTX_set_tmp_ecdh_callback|. */
EC_KEY *(*ecdh_tmp_cb)(SSL *ssl, int is_export, int keysize);
- CERT_PKEY pkeys[SSL_PKEY_NUM];
-
- /* Server-only: client_certificate_types is list of certificate types to
- * include in the CertificateRequest message.
- */
- uint8_t *client_certificate_types;
- size_t num_client_certificate_types;
-
- /* signature algorithms peer reports: e.g. supported signature
- * algorithms extension for server or as part of a certificate
- * request for client. */
- uint8_t *peer_sigalgs;
- /* Size of above array */
+
+ /* peer_sigalgs are the algorithm/hash pairs that the peer supports. These
+ * are taken from the contents of signature algorithms extension for a server
+ * or from the CertificateRequest for a client. */
+ TLS_SIGALGS *peer_sigalgs;
+ /* peer_sigalgslen is the number of entries in |peer_sigalgs|. */
size_t peer_sigalgslen;
- /* suppported signature algorithms.
- * When set on a client this is sent in the client hello as the
- * supported signature algorithms extension. For servers
- * it represents the signature algorithms we are willing to use. */
- uint8_t *conf_sigalgs;
- /* Size of above array */
- size_t conf_sigalgslen;
- /* Client authentication signature algorithms, if not set then
- * uses conf_sigalgs. On servers these will be the signature
- * algorithms sent to the client in a cerificate request for TLS 1.2.
- * On a client this represents the signature algortithms we are
- * willing to use for client authentication. */
- uint8_t *client_sigalgs;
- /* Size of above array */
- size_t client_sigalgslen;
- /* Signature algorithms shared by client and server: cached
- * because these are used most often. */
- TLS_SIGALGS *shared_sigalgs;
- size_t shared_sigalgslen;
+
+ /* digest_nids, if non-NULL, is the set of digests supported by |privatekey|
+ * in decreasing order of preference. */
+ int *digest_nids;
+ size_t num_digest_nids;
/* Certificate setup callback: if set is called whenever a
* certificate may be required (client or server). the callback
@@ -573,39 +775,8 @@ typedef struct cert_st {
* supported signature algorithms or curves. */
int (*cert_cb)(SSL *ssl, void *arg);
void *cert_cb_arg;
-
- /* Optional X509_STORE for chain building or certificate validation
- * If NULL the parent SSL_CTX store is used instead. */
- X509_STORE *chain_store;
- X509_STORE *verify_store;
} CERT;
-typedef struct sess_cert_st {
- /* cert_chain is the certificate chain sent by the peer. NOTE: for a client,
- * this does includes the server's leaf certificate, but, for a server, this
- * does NOT include the client's leaf. */
- STACK_OF(X509) *cert_chain;
-
- /* peer_cert, on a client, is the leaf certificate of the peer. */
- X509 *peer_cert;
-
- DH *peer_dh_tmp;
- EC_KEY *peer_ecdh_tmp;
-} SESS_CERT;
-
-/* Structure containing decoded values of signature algorithms extension */
-struct tls_sigalgs_st {
- /* NID of hash algorithm */
- int hash_nid;
- /* NID of signature algorithm */
- int sign_nid;
- /* Combined hash and signature NID */
- int signandhash_nid;
- /* Raw values used in extension */
- uint8_t rsign;
- uint8_t rhash;
-};
-
/* SSL_METHOD is a compatibility structure to support the legacy version-locked
* methods. */
struct ssl_method_st {
@@ -632,8 +803,6 @@ struct ssl_protocol_method_st {
void (*ssl_read_close_notify)(SSL *s);
int (*ssl_write_app_data)(SSL *s, const void *buf_, int len);
int (*ssl_dispatch_alert)(SSL *s);
- long (*ssl_ctrl)(SSL *s, int cmd, long larg, void *parg);
- long (*ssl_ctx_ctrl)(SSL_CTX *ctx, int cmd, long larg, void *parg);
/* supports_cipher returns one if |cipher| is supported by this protocol and
* zero otherwise. */
int (*supports_cipher)(const SSL_CIPHER *cipher);
@@ -696,15 +865,6 @@ struct ssl3_enc_method {
#define DTLS1_AL_HEADER_LENGTH 2
-typedef struct dtls1_bitmap_st {
- /* map is a bit mask of the last 64 sequence numbers. Bit
- * |1<<i| corresponds to |max_seq_num - i|. */
- uint64_t map;
- /* max_seq_num is the largest sequence number seen so far. It
- * is a 64-bit value in big-endian encoding. */
- uint8_t max_seq_num[8];
-} DTLS1_BITMAP;
-
/* TODO(davidben): This structure is used for both incoming messages and
* outgoing messages. |is_ccs| and |epoch| are only used in the latter and
* should be moved elsewhere. */
@@ -789,6 +949,7 @@ extern const SSL3_ENC_METHOD TLSv1_enc_data;
extern const SSL3_ENC_METHOD TLSv1_1_enc_data;
extern const SSL3_ENC_METHOD TLSv1_2_enc_data;
extern const SSL3_ENC_METHOD SSLv3_enc_data;
+extern const SRTP_PROTECTION_PROFILE kSRTPProfiles[];
void ssl_clear_cipher_ctx(SSL *s);
int ssl_clear_bad_session(SSL *s);
@@ -796,11 +957,24 @@ CERT *ssl_cert_new(void);
CERT *ssl_cert_dup(CERT *cert);
void ssl_cert_clear_certs(CERT *c);
void ssl_cert_free(CERT *c);
-SESS_CERT *ssl_sess_cert_new(void);
-SESS_CERT *ssl_sess_cert_dup(const SESS_CERT *sess_cert);
-void ssl_sess_cert_free(SESS_CERT *sess_cert);
int ssl_get_new_session(SSL *s, int session);
-int ssl_get_prev_session(SSL *s, const struct ssl_early_callback_ctx *ctx);
+
+enum ssl_session_result_t {
+ ssl_session_success,
+ ssl_session_error,
+ ssl_session_retry,
+};
+
+/* ssl_get_prev_session looks up the previous session based on |ctx|. On
+ * success, it sets |*out_session| to the session or NULL if none was found. It
+ * sets |*out_send_ticket| to whether a ticket should be sent at the end of the
+ * handshake. If the session could not be looked up synchronously, it returns
+ * |ssl_session_retry| and should be called again. Otherwise, it returns
+ * |ssl_session_error|. */
+enum ssl_session_result_t ssl_get_prev_session(
+ SSL *ssl, SSL_SESSION **out_session, int *out_send_ticket,
+ const struct ssl_early_callback_ctx *ctx);
+
STACK_OF(SSL_CIPHER) *ssl_bytes_to_cipher_list(SSL *s, const CBS *cbs);
int ssl_cipher_list_to_bytes(SSL *s, STACK_OF(SSL_CIPHER) *sk, uint8_t *p);
struct ssl_cipher_preference_list_st *ssl_cipher_preference_list_dup(
@@ -811,21 +985,16 @@ struct ssl_cipher_preference_list_st *ssl_cipher_preference_list_from_ciphers(
STACK_OF(SSL_CIPHER) *ciphers);
struct ssl_cipher_preference_list_st *ssl_get_cipher_preferences(SSL *s);
-int ssl_cert_set0_chain(CERT *c, STACK_OF(X509) *chain);
-int ssl_cert_set1_chain(CERT *c, STACK_OF(X509) *chain);
-int ssl_cert_add0_chain_cert(CERT *c, X509 *x);
-int ssl_cert_add1_chain_cert(CERT *c, X509 *x);
-int ssl_cert_select_current(CERT *c, X509 *x);
-void ssl_cert_set_cert_cb(CERT *c, int (*cb)(SSL *ssl, void *arg), void *arg);
-
-int ssl_verify_cert_chain(SSL *s, STACK_OF(X509) *sk);
-int ssl_add_cert_chain(SSL *s, CERT_PKEY *cpk, unsigned long *l);
-int ssl_build_cert_chain(CERT *c, X509_STORE *chain_store, int flags);
-int ssl_cert_set_cert_store(CERT *c, X509_STORE *store, int chain, int ref);
-CERT_PKEY *ssl_get_server_send_pkey(const SSL *s);
-EVP_PKEY *ssl_get_sign_pkey(SSL *s, const SSL_CIPHER *c);
+int ssl_cert_set0_chain(CERT *cert, STACK_OF(X509) *chain);
+int ssl_cert_set1_chain(CERT *cert, STACK_OF(X509) *chain);
+int ssl_cert_add0_chain_cert(CERT *cert, X509 *x509);
+int ssl_cert_add1_chain_cert(CERT *cert, X509 *x509);
+void ssl_cert_set_cert_cb(CERT *cert,
+ int (*cb)(SSL *ssl, void *arg), void *arg);
+
+int ssl_verify_cert_chain(SSL *ssl, STACK_OF(X509) *cert_chain);
+int ssl_add_cert_chain(SSL *s, unsigned long *l);
void ssl_update_cache(SSL *s, int mode);
-int ssl_cert_type(EVP_PKEY *pkey);
/* ssl_get_compatible_server_ciphers determines the key exchange and
* authentication cipher suite masks compatible with the server configuration
@@ -841,10 +1010,9 @@ int ssl_verify_alarm_type(long type);
* |len|. It returns one on success and zero on failure. */
int ssl_fill_hello_random(uint8_t *out, size_t len, int is_server);
-int ssl3_init_finished_mac(SSL *s);
int ssl3_send_server_certificate(SSL *s);
int ssl3_send_new_session_ticket(SSL *s);
-int ssl3_send_cert_status(SSL *s);
+int ssl3_send_certificate_status(SSL *s);
int ssl3_get_finished(SSL *s, int state_a, int state_b);
int ssl3_send_change_cipher_spec(SSL *s, int state_a, int state_b);
int ssl3_prf(SSL *s, uint8_t *out, size_t out_len, const uint8_t *secret,
@@ -865,11 +1033,11 @@ int ssl3_hash_current_message(SSL *s);
/* ssl3_cert_verify_hash writes the CertificateVerify hash into the bytes
* pointed to by |out| and writes the number of bytes to |*out_len|. |out| must
* have room for EVP_MAX_MD_SIZE bytes. For TLS 1.2 and up, |*out_md| is used
- * for the hash function, otherwise the hash function depends on the type of
- * |pkey| and is written to |*out_md|. It returns one on success and zero on
+ * for the hash function, otherwise the hash function depends on |pkey_type|
+ * and is written to |*out_md|. It returns one on success and zero on
* failure. */
int ssl3_cert_verify_hash(SSL *s, uint8_t *out, size_t *out_len,
- const EVP_MD **out_md, EVP_PKEY *pkey);
+ const EVP_MD **out_md, int pkey_type);
int ssl3_send_finished(SSL *s, int a, int b, const char *sender, int slen);
int ssl3_supports_cipher(const SSL_CIPHER *cipher);
@@ -882,29 +1050,15 @@ int ssl3_write_app_data(SSL *ssl, const void *buf, int len);
int ssl3_write_bytes(SSL *s, int type, const void *buf, int len);
int ssl3_final_finish_mac(SSL *s, const char *sender, int slen, uint8_t *p);
int ssl3_cert_verify_mac(SSL *s, int md_nid, uint8_t *p);
-int ssl3_finish_mac(SSL *s, const uint8_t *buf, int len);
-void ssl3_free_digest_list(SSL *s);
-int ssl3_output_cert_chain(SSL *s, CERT_PKEY *cpk);
+int ssl3_output_cert_chain(SSL *s);
const SSL_CIPHER *ssl3_choose_cipher(
SSL *ssl, STACK_OF(SSL_CIPHER) *clnt,
struct ssl_cipher_preference_list_st *srvr);
-int ssl3_setup_read_buffer(SSL *s);
-int ssl3_setup_write_buffer(SSL *s);
-int ssl3_release_read_buffer(SSL *s);
-int ssl3_release_write_buffer(SSL *s);
-
-enum should_free_handshake_buffer_t {
- free_handshake_buffer,
- dont_free_handshake_buffer,
-};
-int ssl3_digest_cached_records(SSL *s, enum should_free_handshake_buffer_t);
int ssl3_new(SSL *s);
void ssl3_free(SSL *s);
int ssl3_accept(SSL *s);
int ssl3_connect(SSL *s);
-long ssl3_ctrl(SSL *s, int cmd, long larg, void *parg);
-long ssl3_ctx_ctrl(SSL_CTX *s, int cmd, long larg, void *parg);
/* ssl3_record_sequence_update increments the sequence number in |seq|. It
* returns one on success and zero on wraparound. */
@@ -915,13 +1069,7 @@ int ssl3_do_change_cipher_spec(SSL *ssl);
int ssl3_set_handshake_header(SSL *s, int htype, unsigned long len);
int ssl3_handshake_write(SSL *s);
-enum dtls1_use_epoch_t {
- dtls1_use_previous_epoch,
- dtls1_use_current_epoch,
-};
-
int dtls1_do_write(SSL *s, int type, enum dtls1_use_epoch_t use_epoch);
-int ssl3_read_n(SSL *s, int n, int extend);
int dtls1_read_app_data(SSL *ssl, uint8_t *buf, int len, int peek);
void dtls1_read_close_notify(SSL *ssl);
int dtls1_read_bytes(SSL *s, int type, uint8_t *buf, int len, int peek);
@@ -968,11 +1116,9 @@ int ssl_do_client_cert_cb(SSL *s, X509 **px509, EVP_PKEY **ppkey);
int ssl3_send_client_key_exchange(SSL *s);
int ssl3_get_server_key_exchange(SSL *s);
int ssl3_get_server_certificate(SSL *s);
-int ssl3_check_cert_and_algorithm(SSL *s);
int ssl3_send_next_proto(SSL *s);
int ssl3_send_channel_id(SSL *s);
-
-int dtls1_client_hello(SSL *s);
+int ssl3_verify_server_cert(SSL *s);
/* some server-only functions */
int ssl3_get_initial_bytes(SSL *s);
@@ -995,7 +1141,6 @@ void dtls1_free(SSL *s);
long dtls1_get_message(SSL *s, int st1, int stn, int mt, long max,
enum ssl_hash_message_t hash_message, int *ok);
-int dtls1_get_record(SSL *s);
int dtls1_dispatch_alert(SSL *s);
int ssl_init_wbio_buffer(SSL *s, int push);
@@ -1025,12 +1170,15 @@ int tls1_export_keying_material(SSL *s, uint8_t *out, size_t out_len,
int tls1_alert_code(int code);
int ssl3_alert_code(int code);
-int ssl_check_srvr_ecc_cert_and_alg(X509 *x, SSL *s);
-
char ssl_early_callback_init(struct ssl_early_callback_ctx *ctx);
int tls1_ec_curve_id2nid(uint16_t curve_id);
int tls1_ec_nid2curve_id(uint16_t *out_curve_id, int nid);
+/* tls1_ec_curve_id2name returns a human-readable name for the
+ * curve specified by the TLS curve id in |curve_id|. If the
+ * curve is unknown, it returns NULL. */
+const char* tls1_ec_curve_id2name(uint16_t curve_id);
+
/* tls1_check_curve parses ECParameters out of |cbs|, modifying it. It
* checks the curve is one of our preferences and writes the
* NamedCurve value to |*out_curve_id|. It returns one on success and
@@ -1060,27 +1208,38 @@ int tls1_check_ec_tmp_key(SSL *s);
int tls1_shared_list(SSL *s, const uint8_t *l1, size_t l1len, const uint8_t *l2,
size_t l2len, int nmatch);
-uint8_t *ssl_add_clienthello_tlsext(SSL *s, uint8_t *buf, uint8_t *limit,
- size_t header_len);
-uint8_t *ssl_add_serverhello_tlsext(SSL *s, uint8_t *buf, uint8_t *limit);
+uint8_t *ssl_add_clienthello_tlsext(SSL *s, uint8_t *const buf,
+ uint8_t *const limit, size_t header_len);
+uint8_t *ssl_add_serverhello_tlsext(SSL *s, uint8_t *const buf,
+ uint8_t *const limit);
int ssl_parse_clienthello_tlsext(SSL *s, CBS *cbs);
int ssl_parse_serverhello_tlsext(SSL *s, CBS *cbs);
-int ssl_prepare_clienthello_tlsext(SSL *s);
-int ssl_prepare_serverhello_tlsext(SSL *s);
#define tlsext_tick_md EVP_sha256
-int tls1_process_ticket(SSL *s, const struct ssl_early_callback_ctx *ctx,
- SSL_SESSION **ret);
-int tls12_get_sigandhash(uint8_t *p, const EVP_PKEY *pk, const EVP_MD *md);
-int tls12_get_sigid(const EVP_PKEY *pk);
+/* tls_process_ticket processes the session ticket extension. On success, it
+ * sets |*out_session| to the decrypted session or NULL if the ticket was
+ * rejected. It sets |*out_send_ticket| to whether a new ticket should be sent
+ * at the end of the handshake. It returns one on success and zero on fatal
+ * error. */
+int tls_process_ticket(SSL *ssl, SSL_SESSION **out_session,
+ int *out_send_ticket, const uint8_t *ticket,
+ size_t ticket_len, const uint8_t *session_id,
+ size_t session_id_len);
+
+/* tls12_get_sigandhash assembles the SignatureAndHashAlgorithm corresponding to
+ * |ssl|'s private key and |md|. The two-byte value is written to |p|. It
+ * returns one on success and zero on failure. */
+int tls12_get_sigandhash(SSL *ssl, uint8_t *p, const EVP_MD *md);
+int tls12_get_sigid(int pkey_type);
const EVP_MD *tls12_get_hash(uint8_t hash_alg);
-int tls1_channel_id_hash(EVP_MD_CTX *ctx, SSL *s);
-int tls1_record_handshake_hashes_for_channel_id(SSL *s);
+/* tls1_channel_id_hash computes the hash to be signed by Channel ID and writes
+ * it to |out|, which must contain at least |EVP_MAX_MD_SIZE| bytes. It returns
+ * one on success and zero on failure. */
+int tls1_channel_id_hash(SSL *ssl, uint8_t *out, size_t *out_len);
-int tls1_set_sigalgs_list(CERT *c, const char *str, int client);
-int tls1_set_sigalgs(CERT *c, const int *salg, size_t salglen, int client);
+int tls1_record_handshake_hashes_for_channel_id(SSL *s);
/* ssl_ctx_log_rsa_client_key_exchange logs |premaster| to |ctx|, if logging is
* enabled. It returns one on success and zero on failure. The entry is
@@ -1134,27 +1293,16 @@ int ssl3_is_version_enabled(SSL *s, uint16_t version);
* the wire version except at API boundaries. */
uint16_t ssl3_version_from_wire(SSL *s, uint16_t wire_version);
-int ssl_add_serverhello_renegotiate_ext(SSL *s, uint8_t *p, int *len,
- int maxlen);
-int ssl_parse_serverhello_renegotiate_ext(SSL *s, CBS *cbs, int *out_alert);
-int ssl_add_clienthello_renegotiate_ext(SSL *s, uint8_t *p, int *len,
- int maxlen);
-int ssl_parse_clienthello_renegotiate_ext(SSL *s, CBS *cbs, int *out_alert);
-uint32_t ssl_get_algorithm2(SSL *s);
-int tls1_process_sigalgs(SSL *s, const CBS *sigalgs);
+uint32_t ssl_get_algorithm_prf(SSL *s);
+int tls1_parse_peer_sigalgs(SSL *s, const CBS *sigalgs);
-/* tls1_choose_signing_digest returns a digest for use with |pkey| based on the
- * peer's preferences recorded for |s| and the digests supported by |pkey|. */
-const EVP_MD *tls1_choose_signing_digest(SSL *s, EVP_PKEY *pkey);
+/* tls1_choose_signing_digest returns a digest for use with |ssl|'s private key
+ * based on the peer's preferences the digests supported. */
+const EVP_MD *tls1_choose_signing_digest(SSL *ssl);
size_t tls12_get_psigalgs(SSL *s, const uint8_t **psigs);
int tls12_check_peer_sigalg(const EVP_MD **out_md, int *out_alert, SSL *s,
CBS *cbs, EVP_PKEY *pkey);
void ssl_set_client_disabled(SSL *s);
-int ssl_add_clienthello_use_srtp_ext(SSL *s, uint8_t *p, int *len, int maxlen);
-int ssl_parse_clienthello_use_srtp_ext(SSL *s, CBS *cbs, int *out_alert);
-int ssl_add_serverhello_use_srtp_ext(SSL *s, uint8_t *p, int *len, int maxlen);
-int ssl_parse_serverhello_use_srtp_ext(SSL *s, CBS *cbs, int *out_alert);
-
#endif /* OPENSSL_HEADER_SSL_INTERNAL_H */
diff --git a/src/ssl/s3_both.c b/src/ssl/s3_both.c
index 06338b7..31e36c7 100644
--- a/src/ssl/s3_both.c
+++ b/src/ssl/s3_both.c
@@ -110,6 +110,8 @@
* ECC cipher suite support in OpenSSL originally developed by
* SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project. */
+#include <openssl/ssl.h>
+
#include <assert.h>
#include <limits.h>
#include <stdio.h>
@@ -242,7 +244,7 @@ int ssl3_get_finished(SSL *s, int a, int b) {
* TODO(davidben): Is this check now redundant with SSL3_FLAGS_EXPECT_CCS? */
if (!s->s3->change_cipher_spec) {
al = SSL_AD_UNEXPECTED_MESSAGE;
- OPENSSL_PUT_ERROR(SSL, ssl3_get_finished, SSL_R_GOT_A_FIN_BEFORE_A_CCS);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_GOT_A_FIN_BEFORE_A_CCS);
goto f_err;
}
s->s3->change_cipher_spec = 0;
@@ -252,13 +254,13 @@ int ssl3_get_finished(SSL *s, int a, int b) {
if (finished_len != message_len) {
al = SSL_AD_DECODE_ERROR;
- OPENSSL_PUT_ERROR(SSL, ssl3_get_finished, SSL_R_BAD_DIGEST_LENGTH);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_DIGEST_LENGTH);
goto f_err;
}
if (CRYPTO_memcmp(p, s->s3->tmp.peer_finish_md, finished_len) != 0) {
al = SSL_AD_DECRYPT_ERROR;
- OPENSSL_PUT_ERROR(SSL, ssl3_get_finished, SSL_R_DIGEST_CHECK_FAILED);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_DIGEST_CHECK_FAILED);
goto f_err;
}
@@ -301,17 +303,11 @@ int ssl3_send_change_cipher_spec(SSL *s, int a, int b) {
return ssl3_do_write(s, SSL3_RT_CHANGE_CIPHER_SPEC);
}
-int ssl3_output_cert_chain(SSL *s, CERT_PKEY *cpk) {
+int ssl3_output_cert_chain(SSL *s) {
uint8_t *p;
unsigned long l = 3 + SSL_HM_HEADER_LENGTH(s);
- if (cpk == NULL) {
- /* TLSv1 sends a chain with nothing in it, instead of an alert. */
- if (!BUF_MEM_grow_clean(s->init_buf, l)) {
- OPENSSL_PUT_ERROR(SSL, ssl3_output_cert_chain, ERR_R_BUF_LIB);
- return 0;
- }
- } else if (!ssl_add_cert_chain(s, cpk, &l)) {
+ if (!ssl_add_cert_chain(s, &l)) {
return 0;
}
@@ -340,7 +336,7 @@ long ssl3_get_message(SSL *s, int header_state, int body_state, int msg_type,
s->s3->tmp.reuse_message = 0;
if (msg_type >= 0 && s->s3->tmp.message_type != msg_type) {
al = SSL_AD_UNEXPECTED_MESSAGE;
- OPENSSL_PUT_ERROR(SSL, ssl3_get_message, SSL_R_UNEXPECTED_MESSAGE);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_MESSAGE);
goto f_err;
}
*ok = 1;
@@ -386,7 +382,7 @@ long ssl3_get_message(SSL *s, int header_state, int body_state, int msg_type,
if (msg_type >= 0 && *p != msg_type) {
al = SSL_AD_UNEXPECTED_MESSAGE;
- OPENSSL_PUT_ERROR(SSL, ssl3_get_message, SSL_R_UNEXPECTED_MESSAGE);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_MESSAGE);
goto f_err;
}
s->s3->tmp.message_type = *(p++);
@@ -394,12 +390,12 @@ long ssl3_get_message(SSL *s, int header_state, int body_state, int msg_type,
n2l3(p, l);
if (l > (unsigned long)max) {
al = SSL_AD_ILLEGAL_PARAMETER;
- OPENSSL_PUT_ERROR(SSL, ssl3_get_message, SSL_R_EXCESSIVE_MESSAGE_SIZE);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_EXCESSIVE_MESSAGE_SIZE);
goto f_err;
}
if (l && !BUF_MEM_grow_clean(s->init_buf, l + 4)) {
- OPENSSL_PUT_ERROR(SSL, ssl3_get_message, ERR_R_BUF_LIB);
+ OPENSSL_PUT_ERROR(SSL, ERR_R_BUF_LIB);
goto err;
}
s->s3->tmp.message_size = l;
@@ -447,8 +443,8 @@ int ssl3_hash_current_message(SSL *s) {
/* The handshake header (different size between DTLS and TLS) is included in
* the hash. */
size_t header_len = s->init_msg - (uint8_t *)s->init_buf->data;
- return ssl3_finish_mac(s, (uint8_t *)s->init_buf->data,
- s->init_num + header_len);
+ return ssl3_update_handshake_hash(s, (uint8_t *)s->init_buf->data,
+ s->init_num + header_len);
}
/* ssl3_cert_verify_hash is documented as needing EVP_MAX_MD_SIZE because that
@@ -457,30 +453,25 @@ OPENSSL_COMPILE_ASSERT(EVP_MAX_MD_SIZE > MD5_DIGEST_LENGTH + SHA_DIGEST_LENGTH,
combined_tls_hash_fits_in_max);
int ssl3_cert_verify_hash(SSL *s, uint8_t *out, size_t *out_len,
- const EVP_MD **out_md, EVP_PKEY *pkey) {
+ const EVP_MD **out_md, int pkey_type) {
/* For TLS v1.2 send signature algorithm and signature using
* agreed digest and cached handshake records. Otherwise, use
* SHA1 or MD5 + SHA1 depending on key type. */
if (SSL_USE_SIGALGS(s)) {
- const uint8_t *hdata;
- size_t hdatalen;
EVP_MD_CTX mctx;
unsigned len;
- if (!BIO_mem_contents(s->s3->handshake_buffer, &hdata, &hdatalen)) {
- OPENSSL_PUT_ERROR(SSL, ssl3_cert_verify_hash, ERR_R_INTERNAL_ERROR);
- return 0;
- }
EVP_MD_CTX_init(&mctx);
if (!EVP_DigestInit_ex(&mctx, *out_md, NULL) ||
- !EVP_DigestUpdate(&mctx, hdata, hdatalen) ||
+ !EVP_DigestUpdate(&mctx, s->s3->handshake_buffer->data,
+ s->s3->handshake_buffer->length) ||
!EVP_DigestFinal(&mctx, out, &len)) {
- OPENSSL_PUT_ERROR(SSL, ssl3_cert_verify_hash, ERR_R_EVP_LIB);
+ OPENSSL_PUT_ERROR(SSL, ERR_R_EVP_LIB);
EVP_MD_CTX_cleanup(&mctx);
return 0;
}
*out_len = len;
- } else if (pkey->type == EVP_PKEY_RSA) {
+ } else if (pkey_type == EVP_PKEY_RSA) {
if (s->enc_method->cert_verify_mac(s, NID_md5, out) == 0 ||
s->enc_method->cert_verify_mac(s, NID_sha1, out + MD5_DIGEST_LENGTH) ==
0) {
@@ -488,31 +479,20 @@ int ssl3_cert_verify_hash(SSL *s, uint8_t *out, size_t *out_len,
}
*out_len = MD5_DIGEST_LENGTH + SHA_DIGEST_LENGTH;
*out_md = EVP_md5_sha1();
- } else if (pkey->type == EVP_PKEY_EC) {
+ } else if (pkey_type == EVP_PKEY_EC) {
if (s->enc_method->cert_verify_mac(s, NID_sha1, out) == 0) {
return 0;
}
*out_len = SHA_DIGEST_LENGTH;
*out_md = EVP_sha1();
} else {
- OPENSSL_PUT_ERROR(SSL, ssl3_cert_verify_hash, ERR_R_INTERNAL_ERROR);
+ OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
return 0;
}
return 1;
}
-int ssl_cert_type(EVP_PKEY *pkey) {
- switch (pkey->type) {
- case EVP_PKEY_RSA:
- return SSL_PKEY_RSA_ENC;
- case EVP_PKEY_EC:
- return SSL_PKEY_ECC;
- default:
- return -1;
- }
-}
-
int ssl_verify_alarm_type(long type) {
int al;
@@ -581,92 +561,6 @@ int ssl_verify_alarm_type(long type) {
return al;
}
-int ssl3_setup_read_buffer(SSL *s) {
- uint8_t *p;
- size_t len, align = 0, headerlen;
-
- if (SSL_IS_DTLS(s)) {
- headerlen = DTLS1_RT_HEADER_LENGTH;
- } else {
- headerlen = SSL3_RT_HEADER_LENGTH;
- }
-
-#if defined(SSL3_ALIGN_PAYLOAD) && SSL3_ALIGN_PAYLOAD != 0
- align = (-SSL3_RT_HEADER_LENGTH) & (SSL3_ALIGN_PAYLOAD - 1);
-#endif
-
- if (s->s3->rbuf.buf == NULL) {
- len = SSL3_RT_MAX_ENCRYPTED_LENGTH + headerlen + align;
- if (s->options & SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER) {
- s->s3->init_extra = 1;
- len += SSL3_RT_MAX_EXTRA;
- }
- p = OPENSSL_malloc(len);
- if (p == NULL) {
- goto err;
- }
- s->s3->rbuf.buf = p;
- s->s3->rbuf.len = len;
- }
-
- s->packet = &s->s3->rbuf.buf[0];
- return 1;
-
-err:
- OPENSSL_PUT_ERROR(SSL, ssl3_setup_read_buffer, ERR_R_MALLOC_FAILURE);
- return 0;
-}
-
-int ssl3_setup_write_buffer(SSL *s) {
- uint8_t *p;
- size_t len, align = 0, headerlen;
-
- if (SSL_IS_DTLS(s)) {
- headerlen = DTLS1_RT_HEADER_LENGTH + 1;
- } else {
- headerlen = SSL3_RT_HEADER_LENGTH;
- }
-
-#if defined(SSL3_ALIGN_PAYLOAD) && SSL3_ALIGN_PAYLOAD != 0
- align = (-SSL3_RT_HEADER_LENGTH) & (SSL3_ALIGN_PAYLOAD - 1);
-#endif
-
- if (s->s3->wbuf.buf == NULL) {
- len = s->max_send_fragment + SSL3_RT_SEND_MAX_ENCRYPTED_OVERHEAD +
- headerlen + align;
- /* Account for 1/n-1 record splitting. */
- if (s->mode & SSL_MODE_CBC_RECORD_SPLITTING) {
- len += headerlen + align + 1 + SSL3_RT_SEND_MAX_ENCRYPTED_OVERHEAD;
- }
-
- p = OPENSSL_malloc(len);
- if (p == NULL) {
- goto err;
- }
- s->s3->wbuf.buf = p;
- s->s3->wbuf.len = len;
- }
-
- return 1;
-
-err:
- OPENSSL_PUT_ERROR(SSL, ssl3_setup_write_buffer, ERR_R_MALLOC_FAILURE);
- return 0;
-}
-
-int ssl3_release_write_buffer(SSL *s) {
- OPENSSL_free(s->s3->wbuf.buf);
- s->s3->wbuf.buf = NULL;
- return 1;
-}
-
-int ssl3_release_read_buffer(SSL *s) {
- OPENSSL_free(s->s3->rbuf.buf);
- s->s3->rbuf.buf = NULL;
- s->packet = NULL;
- return 1;
-}
-
int ssl_fill_hello_random(uint8_t *out, size_t len, int is_server) {
if (is_server) {
const uint32_t current_time = time(NULL);
diff --git a/src/ssl/s3_clnt.c b/src/ssl/s3_clnt.c
index d334e1d..559db72 100644
--- a/src/ssl/s3_clnt.c
+++ b/src/ssl/s3_clnt.c
@@ -148,21 +148,26 @@
* OTHERWISE.
*/
+#include <openssl/ssl.h>
+
#include <assert.h>
#include <stdio.h>
#include <string.h>
+#include <openssl/bn.h>
#include <openssl/buf.h>
#include <openssl/bytestring.h>
-#include <openssl/rand.h>
-#include <openssl/obj.h>
+#include <openssl/dh.h>
+#include <openssl/ec_key.h>
+#include <openssl/ecdsa.h>
#include <openssl/err.h>
#include <openssl/evp.h>
-#include <openssl/mem.h>
#include <openssl/md5.h>
-#include <openssl/dh.h>
-#include <openssl/bn.h>
+#include <openssl/mem.h>
+#include <openssl/obj.h>
+#include <openssl/rand.h>
#include <openssl/x509.h>
+#include <openssl/x509v3.h>
#include "internal.h"
#include "../crypto/dh/internal.h"
@@ -217,8 +222,8 @@ int ssl3_connect(SSL *s) {
/* don't push the buffering BIO quite yet */
- if (!ssl3_init_finished_mac(s)) {
- OPENSSL_PUT_ERROR(SSL, ssl3_connect, ERR_R_INTERNAL_ERROR);
+ if (!ssl3_init_handshake_buffer(s)) {
+ OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
ret = -1;
goto end;
}
@@ -273,7 +278,7 @@ int ssl3_connect(SSL *s) {
if (s->s3->tmp.certificate_status_expected) {
s->state = SSL3_ST_CR_CERT_STATUS_A;
} else {
- s->state = SSL3_ST_CR_KEY_EXCH_A;
+ s->state = SSL3_ST_VERIFY_SERVER_CERT;
}
} else {
skip = 1;
@@ -282,6 +287,16 @@ int ssl3_connect(SSL *s) {
s->init_num = 0;
break;
+ case SSL3_ST_VERIFY_SERVER_CERT:
+ ret = ssl3_verify_server_cert(s);
+ if (ret <= 0) {
+ goto end;
+ }
+
+ s->state = SSL3_ST_CR_KEY_EXCH_A;
+ s->init_num = 0;
+ break;
+
case SSL3_ST_CR_KEY_EXCH_A:
case SSL3_ST_CR_KEY_EXCH_B:
ret = ssl3_get_server_key_exchange(s);
@@ -290,13 +305,6 @@ int ssl3_connect(SSL *s) {
}
s->state = SSL3_ST_CR_CERT_REQ_A;
s->init_num = 0;
-
- /* at this point we check that we have the
- * required stuff from the server */
- if (!ssl3_check_cert_and_algorithm(s)) {
- ret = -1;
- goto end;
- }
break;
case SSL3_ST_CR_CERT_REQ_A:
@@ -356,6 +364,7 @@ int ssl3_connect(SSL *s) {
case SSL3_ST_CW_CERT_VRFY_A:
case SSL3_ST_CW_CERT_VRFY_B:
+ case SSL3_ST_CW_CERT_VRFY_C:
ret = ssl3_send_cert_verify(s);
if (ret <= 0) {
goto end;
@@ -433,11 +442,9 @@ int ssl3_connect(SSL *s) {
* record the handshake hashes at this point in the session so that
* any resumption of this session with ChannelID can sign those
* hashes. */
- if (s->s3->tlsext_channel_id_new) {
- ret = tls1_record_handshake_hashes_for_channel_id(s);
- if (ret <= 0) {
- goto end;
- }
+ ret = tls1_record_handshake_hashes_for_channel_id(s);
+ if (ret <= 0) {
+ goto end;
}
if ((SSL_get_mode(s) & SSL_MODE_ENABLE_FALSE_START) &&
ssl3_can_false_start(s) &&
@@ -473,7 +480,7 @@ int ssl3_connect(SSL *s) {
if (ret <= 0) {
goto end;
}
- s->state = SSL3_ST_CR_KEY_EXCH_A;
+ s->state = SSL3_ST_VERIFY_SERVER_CERT;
s->init_num = 0;
break;
@@ -536,11 +543,16 @@ int ssl3_connect(SSL *s) {
/* Remove write buffering now. */
ssl_free_wbio_buffer(s);
+ const int is_initial_handshake = !s->s3->initial_handshake_complete;
+
s->init_num = 0;
s->s3->tmp.in_false_start = 0;
s->s3->initial_handshake_complete = 1;
- ssl_update_cache(s, SSL_SESS_CACHE_CLIENT);
+ if (is_initial_handshake) {
+ /* Renegotiations do not participate in session resumption. */
+ ssl_update_cache(s, SSL_SESS_CACHE_CLIENT);
+ }
ret = 1;
/* s->server=0; */
@@ -552,7 +564,7 @@ int ssl3_connect(SSL *s) {
goto end;
default:
- OPENSSL_PUT_ERROR(SSL, ssl3_connect, SSL_R_UNKNOWN_STATE);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_UNKNOWN_STATE);
ret = -1;
goto end;
}
@@ -588,7 +600,7 @@ int ssl3_send_client_hello(SSL *s) {
uint16_t max_version = ssl3_get_max_client_version(s);
/* Disabling all versions is silly: return an error. */
if (max_version == 0) {
- OPENSSL_PUT_ERROR(SSL, ssl3_send_client_hello, SSL_R_WRONG_SSL_VERSION);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_WRONG_SSL_VERSION);
goto err;
}
s->version = max_version;
@@ -661,7 +673,7 @@ int ssl3_send_client_hello(SSL *s) {
*(p++) = i;
if (i != 0) {
if (i > (int)sizeof(s->session->session_id)) {
- OPENSSL_PUT_ERROR(SSL, ssl3_send_client_hello, ERR_R_INTERNAL_ERROR);
+ OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
goto err;
}
memcpy(p, s->session->session_id, i);
@@ -671,7 +683,7 @@ int ssl3_send_client_hello(SSL *s) {
/* cookie stuff for DTLS */
if (SSL_IS_DTLS(s)) {
if (s->d1->cookie_len > sizeof(s->d1->cookie)) {
- OPENSSL_PUT_ERROR(SSL, ssl3_send_client_hello, ERR_R_INTERNAL_ERROR);
+ OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
goto err;
}
*(p++) = s->d1->cookie_len;
@@ -682,8 +694,7 @@ int ssl3_send_client_hello(SSL *s) {
/* Ciphers supported */
i = ssl_cipher_list_to_bytes(s, SSL_get_ciphers(s), &p[2]);
if (i == 0) {
- OPENSSL_PUT_ERROR(SSL, ssl3_send_client_hello,
- SSL_R_NO_CIPHERS_AVAILABLE);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_NO_CIPHERS_AVAILABLE);
goto err;
}
s2n(i, p);
@@ -694,15 +705,10 @@ int ssl3_send_client_hello(SSL *s) {
*(p++) = 0; /* Add the NULL method */
/* TLS extensions*/
- if (ssl_prepare_clienthello_tlsext(s) <= 0) {
- OPENSSL_PUT_ERROR(SSL, ssl3_send_client_hello, SSL_R_CLIENTHELLO_TLSEXT);
- goto err;
- }
-
p = ssl_add_clienthello_tlsext(s, p, buf + SSL3_RT_MAX_PLAIN_LENGTH,
p - buf);
if (p == NULL) {
- OPENSSL_PUT_ERROR(SSL, ssl3_send_client_hello, ERR_R_INTERNAL_ERROR);
+ OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
goto err;
}
@@ -746,8 +752,7 @@ int ssl3_get_server_hello(SSL *s) {
* parameters. Note: this error code comes after the original one.
*
* See https://crbug.com/446505. */
- OPENSSL_PUT_ERROR(SSL, ssl3_get_server_hello,
- SSL_R_HANDSHAKE_FAILURE_ON_CLIENT_HELLO);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_HANDSHAKE_FAILURE_ON_CLIENT_HELLO);
}
return n;
}
@@ -761,14 +766,14 @@ int ssl3_get_server_hello(SSL *s) {
!CBS_get_u16(&server_hello, &cipher_suite) ||
!CBS_get_u8(&server_hello, &compression_method)) {
al = SSL_AD_DECODE_ERROR;
- OPENSSL_PUT_ERROR(SSL, ssl3_get_server_hello, SSL_R_DECODE_ERROR);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
goto f_err;
}
assert(s->s3->have_version == s->s3->initial_handshake_complete);
if (!s->s3->have_version) {
if (!ssl3_is_version_enabled(s, server_version)) {
- OPENSSL_PUT_ERROR(SSL, ssl3_get_server_hello, SSL_R_UNSUPPORTED_PROTOCOL);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_UNSUPPORTED_PROTOCOL);
s->version = server_version;
/* Mark the version as fixed so the record-layer version is not clamped
* to TLS 1.0. */
@@ -783,7 +788,7 @@ int ssl3_get_server_hello(SSL *s) {
* fixed. Begin enforcing the record-layer version. */
s->s3->have_version = 1;
} else if (server_version != s->version) {
- OPENSSL_PUT_ERROR(SSL, ssl3_get_server_hello, SSL_R_WRONG_SSL_VERSION);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_WRONG_SSL_VERSION);
al = SSL_AD_PROTOCOL_VERSION;
goto f_err;
}
@@ -799,7 +804,7 @@ int ssl3_get_server_hello(SSL *s) {
memcmp(s->session->sid_ctx, s->sid_ctx, s->sid_ctx_length)) {
/* actually a client application bug */
al = SSL_AD_ILLEGAL_PARAMETER;
- OPENSSL_PUT_ERROR(SSL, ssl3_get_server_hello,
+ OPENSSL_PUT_ERROR(SSL,
SSL_R_ATTEMPT_TO_REUSE_SESSION_IN_DIFFERENT_CONTEXT);
goto f_err;
}
@@ -820,8 +825,7 @@ int ssl3_get_server_hello(SSL *s) {
if (c == NULL) {
/* unknown cipher */
al = SSL_AD_ILLEGAL_PARAMETER;
- OPENSSL_PUT_ERROR(SSL, ssl3_get_server_hello,
- SSL_R_UNKNOWN_CIPHER_RETURNED);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_UNKNOWN_CIPHER_RETURNED);
goto f_err;
}
/* ct->mask_ssl was computed from client capabilities. Now
@@ -837,7 +841,7 @@ int ssl3_get_server_hello(SSL *s) {
(c->algorithm_mkey & ct->mask_k) ||
(c->algorithm_auth & ct->mask_a)) {
al = SSL_AD_ILLEGAL_PARAMETER;
- OPENSSL_PUT_ERROR(SSL, ssl3_get_server_hello, SSL_R_WRONG_CIPHER_RETURNED);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_WRONG_CIPHER_RETURNED);
goto f_err;
}
@@ -845,45 +849,46 @@ int ssl3_get_server_hello(SSL *s) {
if (!sk_SSL_CIPHER_find(sk, NULL, c)) {
/* we did not say we would use this cipher */
al = SSL_AD_ILLEGAL_PARAMETER;
- OPENSSL_PUT_ERROR(SSL, ssl3_get_server_hello, SSL_R_WRONG_CIPHER_RETURNED);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_WRONG_CIPHER_RETURNED);
goto f_err;
}
if (s->hit) {
if (s->session->cipher != c) {
al = SSL_AD_ILLEGAL_PARAMETER;
- OPENSSL_PUT_ERROR(SSL, ssl3_get_server_hello,
- SSL_R_OLD_SESSION_CIPHER_NOT_RETURNED);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_OLD_SESSION_CIPHER_NOT_RETURNED);
goto f_err;
}
if (s->session->ssl_version != s->version) {
al = SSL_AD_ILLEGAL_PARAMETER;
- OPENSSL_PUT_ERROR(SSL, ssl3_get_server_hello,
- SSL_R_OLD_SESSION_VERSION_NOT_RETURNED);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_OLD_SESSION_VERSION_NOT_RETURNED);
goto f_err;
}
}
s->s3->tmp.new_cipher = c;
+ /* Now that the cipher is known, initialize the handshake hash. */
+ if (!ssl3_init_handshake_hash(s)) {
+ goto f_err;
+ }
+
/* If doing a full handshake with TLS 1.2, the server may request a client
* certificate which requires hashing the handshake transcript under a
- * different hash. Otherwise, release the handshake buffer. */
- if ((!SSL_USE_SIGALGS(s) || s->hit) &&
- !ssl3_digest_cached_records(s, free_handshake_buffer)) {
- goto f_err;
+ * different hash. Otherwise, the handshake buffer may be released. */
+ if (!SSL_USE_SIGALGS(s) || s->hit) {
+ ssl3_free_handshake_buffer(s);
}
/* Only the NULL compression algorithm is supported. */
if (compression_method != 0) {
al = SSL_AD_ILLEGAL_PARAMETER;
- OPENSSL_PUT_ERROR(SSL, ssl3_get_server_hello,
- SSL_R_UNSUPPORTED_COMPRESSION_ALGORITHM);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_UNSUPPORTED_COMPRESSION_ALGORITHM);
goto f_err;
}
/* TLS extensions */
if (!ssl_parse_serverhello_tlsext(s, &server_hello)) {
- OPENSSL_PUT_ERROR(SSL, ssl3_get_server_hello, SSL_R_PARSE_TLSEXT);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_PARSE_TLSEXT);
goto err;
}
@@ -891,7 +896,7 @@ int ssl3_get_server_hello(SSL *s) {
if (CBS_len(&server_hello) != 0) {
/* wrong packet length */
al = SSL_AD_DECODE_ERROR;
- OPENSSL_PUT_ERROR(SSL, ssl3_get_server_hello, SSL_R_BAD_PACKET_LENGTH);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_PACKET_LENGTH);
goto f_err;
}
@@ -899,11 +904,9 @@ int ssl3_get_server_hello(SSL *s) {
s->s3->tmp.extended_master_secret != s->session->extended_master_secret) {
al = SSL_AD_HANDSHAKE_FAILURE;
if (s->session->extended_master_secret) {
- OPENSSL_PUT_ERROR(SSL, ssl3_get_server_hello,
- SSL_R_RESUMED_EMS_SESSION_WITHOUT_EMS_EXTENSION);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_RESUMED_EMS_SESSION_WITHOUT_EMS_EXTENSION);
} else {
- OPENSSL_PUT_ERROR(SSL, ssl3_get_server_hello,
- SSL_R_RESUMED_NON_EMS_SESSION_WITH_EMS_EXTENSION);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_RESUMED_NON_EMS_SESSION_WITH_EMS_EXTENSION);
}
goto f_err;
}
@@ -916,12 +919,49 @@ err:
return -1;
}
+/* ssl3_check_certificate_for_cipher returns one if |leaf| is a suitable server
+ * certificate type for |cipher|. Otherwise, it returns zero and pushes an error
+ * on the error queue. */
+static int ssl3_check_certificate_for_cipher(X509 *leaf,
+ const SSL_CIPHER *cipher) {
+ int ret = 0;
+ EVP_PKEY *pkey = X509_get_pubkey(leaf);
+ if (pkey == NULL) {
+ goto err;
+ }
+
+ /* Check the certificate's type matches the cipher. */
+ int expected_type = ssl_cipher_get_key_type(cipher);
+ assert(expected_type != EVP_PKEY_NONE);
+ if (pkey->type != expected_type) {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_WRONG_CERTIFICATE_TYPE);
+ goto err;
+ }
+
+ /* TODO(davidben): This behavior is preserved from upstream. Should key usages
+ * be checked in other cases as well? */
+ if (cipher->algorithm_auth & SSL_aECDSA) {
+ /* This call populates the ex_flags field correctly */
+ X509_check_purpose(leaf, -1, 0);
+ if ((leaf->ex_flags & EXFLAG_KUSAGE) &&
+ !(leaf->ex_kusage & X509v3_KU_DIGITAL_SIGNATURE)) {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_ECC_CERT_NOT_FOR_SIGNING);
+ goto err;
+ }
+ }
+
+ ret = 1;
+
+err:
+ EVP_PKEY_free(pkey);
+ return ret;
+}
+
int ssl3_get_server_certificate(SSL *s) {
- int al, i, ok, ret = -1;
+ int al, ok, ret = -1;
unsigned long n;
X509 *x = NULL;
STACK_OF(X509) *sk = NULL;
- SESS_CERT *sc;
EVP_PKEY *pkey = NULL;
CBS cbs, certificate_list;
const uint8_t *data;
@@ -938,14 +978,15 @@ int ssl3_get_server_certificate(SSL *s) {
sk = sk_X509_new_null();
if (sk == NULL) {
- OPENSSL_PUT_ERROR(SSL, ssl3_get_server_certificate, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
goto err;
}
if (!CBS_get_u24_length_prefixed(&cbs, &certificate_list) ||
+ CBS_len(&certificate_list) == 0 ||
CBS_len(&cbs) != 0) {
al = SSL_AD_DECODE_ERROR;
- OPENSSL_PUT_ERROR(SSL, ssl3_get_server_certificate, SSL_R_LENGTH_MISMATCH);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
goto f_err;
}
@@ -953,90 +994,45 @@ int ssl3_get_server_certificate(SSL *s) {
CBS certificate;
if (!CBS_get_u24_length_prefixed(&certificate_list, &certificate)) {
al = SSL_AD_DECODE_ERROR;
- OPENSSL_PUT_ERROR(SSL, ssl3_get_server_certificate,
- SSL_R_CERT_LENGTH_MISMATCH);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_CERT_LENGTH_MISMATCH);
goto f_err;
}
data = CBS_data(&certificate);
x = d2i_X509(NULL, &data, CBS_len(&certificate));
if (x == NULL) {
al = SSL_AD_BAD_CERTIFICATE;
- OPENSSL_PUT_ERROR(SSL, ssl3_get_server_certificate, ERR_R_ASN1_LIB);
+ OPENSSL_PUT_ERROR(SSL, ERR_R_ASN1_LIB);
goto f_err;
}
if (data != CBS_data(&certificate) + CBS_len(&certificate)) {
al = SSL_AD_DECODE_ERROR;
- OPENSSL_PUT_ERROR(SSL, ssl3_get_server_certificate,
- SSL_R_CERT_LENGTH_MISMATCH);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_CERT_LENGTH_MISMATCH);
goto f_err;
}
if (!sk_X509_push(sk, x)) {
- OPENSSL_PUT_ERROR(SSL, ssl3_get_server_certificate, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
goto err;
}
x = NULL;
}
- i = ssl_verify_cert_chain(s, sk);
- if (s->verify_mode != SSL_VERIFY_NONE && i <= 0) {
- al = ssl_verify_alarm_type(s->verify_result);
- OPENSSL_PUT_ERROR(SSL, ssl3_get_server_certificate,
- SSL_R_CERTIFICATE_VERIFY_FAILED);
+ X509 *leaf = sk_X509_value(sk, 0);
+ if (!ssl3_check_certificate_for_cipher(leaf, s->s3->tmp.new_cipher)) {
+ al = SSL_AD_ILLEGAL_PARAMETER;
goto f_err;
}
- ERR_clear_error(); /* but we keep s->verify_result */
-
- sc = ssl_sess_cert_new();
- if (sc == NULL) {
- goto err;
- }
- ssl_sess_cert_free(s->session->sess_cert);
- s->session->sess_cert = sc;
-
- sc->cert_chain = sk;
- /* Inconsistency alert: cert_chain does include the peer's certificate, which
- * we don't include in s3_srvr.c */
- x = sk_X509_value(sk, 0);
+ /* NOTE: Unlike the server half, the client's copy of |cert_chain| includes
+ * the leaf. */
+ sk_X509_pop_free(s->session->cert_chain, X509_free);
+ s->session->cert_chain = sk;
sk = NULL;
- /* VRS 19990621: possible memory leak; sk=null ==> !sk_pop_free() @end*/
-
- pkey = X509_get_pubkey(x);
-
- if (pkey == NULL || EVP_PKEY_missing_parameters(pkey)) {
- x = NULL;
- al = SSL3_AL_FATAL;
- OPENSSL_PUT_ERROR(SSL, ssl3_get_server_certificate,
- SSL_R_UNABLE_TO_FIND_PUBLIC_KEY_PARAMETERS);
- goto f_err;
- }
-
- i = ssl_cert_type(pkey);
- if (i < 0) {
- x = NULL;
- al = SSL3_AL_FATAL;
- OPENSSL_PUT_ERROR(SSL, ssl3_get_server_certificate,
- SSL_R_UNKNOWN_CERTIFICATE_TYPE);
- goto f_err;
- }
-
- int exp_idx = ssl_cipher_get_cert_index(s->s3->tmp.new_cipher);
- if (exp_idx >= 0 && i != exp_idx) {
- x = NULL;
- al = SSL_AD_ILLEGAL_PARAMETER;
- OPENSSL_PUT_ERROR(SSL, ssl3_get_server_certificate,
- SSL_R_WRONG_CERTIFICATE_TYPE);
- goto f_err;
- }
- X509_free(sc->peer_cert);
- sc->peer_cert = X509_up_ref(x);
X509_free(s->session->peer);
- s->session->peer = X509_up_ref(x);
+ s->session->peer = X509_up_ref(leaf);
s->session->verify_result = s->verify_result;
- x = NULL;
ret = 1;
if (0) {
@@ -1075,25 +1071,14 @@ int ssl3_get_server_key_exchange(SSL *s) {
if (s->s3->tmp.message_type != SSL3_MT_SERVER_KEY_EXCHANGE) {
if (ssl_cipher_requires_server_key_exchange(s->s3->tmp.new_cipher)) {
- OPENSSL_PUT_ERROR(SSL, ssl3_get_server_key_exchange,
- SSL_R_UNEXPECTED_MESSAGE);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_MESSAGE);
ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_UNEXPECTED_MESSAGE);
return -1;
}
- /* In plain PSK ciphersuite, ServerKeyExchange can be
- omitted if no identity hint is sent. Set session->sess_cert anyway to
- avoid problems later.*/
+ /* In plain PSK ciphersuite, ServerKeyExchange may be omitted to send no
+ * identity hint. */
if (s->s3->tmp.new_cipher->algorithm_auth & SSL_aPSK) {
- /* PSK ciphersuites that also send a Certificate would have already
- * initialized |sess_cert|. */
- if (s->session->sess_cert == NULL) {
- s->session->sess_cert = ssl_sess_cert_new();
- if (s->session->sess_cert == NULL) {
- return -1;
- }
- }
-
/* TODO(davidben): This should be reset in one place with the rest of the
* handshake state. */
OPENSSL_free(s->s3->tmp.peer_psk_identity_hint);
@@ -1107,18 +1092,6 @@ int ssl3_get_server_key_exchange(SSL *s) {
CBS_init(&server_key_exchange, s->init_msg, n);
server_key_exchange_orig = server_key_exchange;
- if (s->session->sess_cert != NULL) {
- DH_free(s->session->sess_cert->peer_dh_tmp);
- s->session->sess_cert->peer_dh_tmp = NULL;
- EC_KEY_free(s->session->sess_cert->peer_ecdh_tmp);
- s->session->sess_cert->peer_ecdh_tmp = NULL;
- } else {
- s->session->sess_cert = ssl_sess_cert_new();
- if (s->session->sess_cert == NULL) {
- return -1;
- }
- }
-
alg_k = s->s3->tmp.new_cipher->algorithm_mkey;
alg_a = s->s3->tmp.new_cipher->algorithm_auth;
EVP_MD_CTX_init(&md_ctx);
@@ -1130,7 +1103,7 @@ int ssl3_get_server_key_exchange(SSL *s) {
if (!CBS_get_u16_length_prefixed(&server_key_exchange,
&psk_identity_hint)) {
al = SSL_AD_DECODE_ERROR;
- OPENSSL_PUT_ERROR(SSL, ssl3_get_server_key_exchange, SSL_R_DECODE_ERROR);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
goto f_err;
}
@@ -1144,16 +1117,14 @@ int ssl3_get_server_key_exchange(SSL *s) {
if (CBS_len(&psk_identity_hint) > PSK_MAX_IDENTITY_LEN ||
CBS_contains_zero_byte(&psk_identity_hint)) {
al = SSL_AD_HANDSHAKE_FAILURE;
- OPENSSL_PUT_ERROR(SSL, ssl3_get_server_key_exchange,
- SSL_R_DATA_LENGTH_TOO_LONG);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_DATA_LENGTH_TOO_LONG);
goto f_err;
}
/* Save the identity hint as a C string. */
if (!CBS_strdup(&psk_identity_hint, &s->s3->tmp.peer_psk_identity_hint)) {
al = SSL_AD_INTERNAL_ERROR;
- OPENSSL_PUT_ERROR(SSL, ssl3_get_server_key_exchange,
- ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
goto f_err;
}
}
@@ -1168,13 +1139,13 @@ int ssl3_get_server_key_exchange(SSL *s) {
!CBS_get_u16_length_prefixed(&server_key_exchange, &dh_Ys) ||
CBS_len(&dh_Ys) == 0) {
al = SSL_AD_DECODE_ERROR;
- OPENSSL_PUT_ERROR(SSL, ssl3_get_server_key_exchange, SSL_R_DECODE_ERROR);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
goto f_err;
}
dh = DH_new();
if (dh == NULL) {
- OPENSSL_PUT_ERROR(SSL, ssl3_get_server_key_exchange, ERR_R_DH_LIB);
+ OPENSSL_PUT_ERROR(SSL, ERR_R_DH_LIB);
goto err;
}
@@ -1182,22 +1153,17 @@ int ssl3_get_server_key_exchange(SSL *s) {
(dh->g = BN_bin2bn(CBS_data(&dh_g), CBS_len(&dh_g), NULL)) == NULL ||
(dh->pub_key = BN_bin2bn(CBS_data(&dh_Ys), CBS_len(&dh_Ys), NULL)) ==
NULL) {
- OPENSSL_PUT_ERROR(SSL, ssl3_get_server_key_exchange, ERR_R_BN_LIB);
+ OPENSSL_PUT_ERROR(SSL, ERR_R_BN_LIB);
goto err;
}
- if (DH_num_bits(dh) < 1024) {
- OPENSSL_PUT_ERROR(SSL, ssl3_get_server_key_exchange,
- SSL_R_BAD_DH_P_LENGTH);
+ s->session->key_exchange_info = DH_num_bits(dh);
+ if (s->session->key_exchange_info < 1024) {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_DH_P_LENGTH);
goto err;
}
-
- if (alg_a & SSL_aRSA) {
- pkey = X509_get_pubkey(s->session->sess_cert->peer_cert);
- }
- /* else anonymous DH, so no certificate or pkey. */
-
- s->session->sess_cert->peer_dh_tmp = dh;
+ DH_free(s->s3->tmp.peer_dh_tmp);
+ s->s3->tmp.peer_dh_tmp = dh;
dh = NULL;
} else if (alg_k & SSL_kECDHE) {
uint16_t curve_id;
@@ -1210,22 +1176,21 @@ int ssl3_get_server_key_exchange(SSL *s) {
* invalid curve. */
if (!tls1_check_curve(s, &server_key_exchange, &curve_id)) {
al = SSL_AD_DECODE_ERROR;
- OPENSSL_PUT_ERROR(SSL, ssl3_get_server_key_exchange, SSL_R_WRONG_CURVE);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_WRONG_CURVE);
goto f_err;
}
curve_nid = tls1_ec_curve_id2nid(curve_id);
if (curve_nid == 0) {
al = SSL_AD_INTERNAL_ERROR;
- OPENSSL_PUT_ERROR(SSL, ssl3_get_server_key_exchange,
- SSL_R_UNABLE_TO_FIND_ECDH_PARAMETERS);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_UNABLE_TO_FIND_ECDH_PARAMETERS);
goto f_err;
}
ecdh = EC_KEY_new_by_curve_name(curve_nid);
+ s->session->key_exchange_info = curve_id;
if (ecdh == NULL) {
- OPENSSL_PUT_ERROR(SSL, ssl3_get_server_key_exchange,
- ERR_R_EC_LIB);
+ OPENSSL_PUT_ERROR(SSL, ERR_R_EC_LIB);
goto err;
}
@@ -1234,35 +1199,25 @@ int ssl3_get_server_key_exchange(SSL *s) {
/* Next, get the encoded ECPoint */
if (!CBS_get_u8_length_prefixed(&server_key_exchange, &point)) {
al = SSL_AD_DECODE_ERROR;
- OPENSSL_PUT_ERROR(SSL, ssl3_get_server_key_exchange, SSL_R_DECODE_ERROR);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
goto f_err;
}
if (((srvr_ecpoint = EC_POINT_new(group)) == NULL) ||
((bn_ctx = BN_CTX_new()) == NULL)) {
- OPENSSL_PUT_ERROR(SSL, ssl3_get_server_key_exchange,
- ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
goto err;
}
if (!EC_POINT_oct2point(group, srvr_ecpoint, CBS_data(&point),
CBS_len(&point), bn_ctx)) {
al = SSL_AD_DECODE_ERROR;
- OPENSSL_PUT_ERROR(SSL, ssl3_get_server_key_exchange, SSL_R_BAD_ECPOINT);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_ECPOINT);
goto f_err;
}
-
- /* The ECC/TLS specification does not mention the use of DSA to sign
- * ECParameters in the server key exchange message. We do support RSA and
- * ECDSA. */
- if (alg_a & (SSL_aRSA|SSL_aECDSA)) {
- pkey = X509_get_pubkey(s->session->sess_cert->peer_cert);
- } else {
- /* Otherwise this is ECDHE_PSK, so no public key. */
- assert(alg_a == SSL_aPSK);
- }
EC_KEY_set_public_key(ecdh, srvr_ecpoint);
- s->session->sess_cert->peer_ecdh_tmp = ecdh;
+ EC_KEY_free(s->s3->tmp.peer_ecdh_tmp);
+ s->s3->tmp.peer_ecdh_tmp = ecdh;
ecdh = NULL;
BN_CTX_free(bn_ctx);
bn_ctx = NULL;
@@ -1270,8 +1225,7 @@ int ssl3_get_server_key_exchange(SSL *s) {
srvr_ecpoint = NULL;
} else if (!(alg_k & SSL_kPSK)) {
al = SSL_AD_UNEXPECTED_MESSAGE;
- OPENSSL_PUT_ERROR(SSL, ssl3_get_server_key_exchange,
- SSL_R_UNEXPECTED_MESSAGE);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_MESSAGE);
goto f_err;
}
@@ -1281,9 +1235,12 @@ int ssl3_get_server_key_exchange(SSL *s) {
CBS_init(&parameter, CBS_data(&server_key_exchange_orig),
CBS_len(&server_key_exchange_orig) - CBS_len(&server_key_exchange));
- /* if it was signed, check the signature */
- if (pkey != NULL) {
- CBS signature;
+ /* ServerKeyExchange should be signed by the server's public key. */
+ if (ssl_cipher_has_server_public_key(s->s3->tmp.new_cipher)) {
+ pkey = X509_get_pubkey(s->session->peer);
+ if (pkey == NULL) {
+ goto err;
+ }
if (SSL_USE_SIGALGS(s)) {
if (!tls12_check_peer_sigalg(&md, &al, s, &server_key_exchange, pkey)) {
@@ -1296,10 +1253,11 @@ int ssl3_get_server_key_exchange(SSL *s) {
}
/* The last field in |server_key_exchange| is the signature. */
+ CBS signature;
if (!CBS_get_u16_length_prefixed(&server_key_exchange, &signature) ||
CBS_len(&server_key_exchange) != 0) {
al = SSL_AD_DECODE_ERROR;
- OPENSSL_PUT_ERROR(SSL, ssl3_get_server_key_exchange, SSL_R_DECODE_ERROR);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
goto f_err;
}
@@ -1314,24 +1272,16 @@ int ssl3_get_server_key_exchange(SSL *s) {
CBS_len(&signature))) {
/* bad signature */
al = SSL_AD_DECRYPT_ERROR;
- OPENSSL_PUT_ERROR(SSL, ssl3_get_server_key_exchange, SSL_R_BAD_SIGNATURE);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_SIGNATURE);
goto f_err;
}
} else {
- if (ssl_cipher_has_server_public_key(s->s3->tmp.new_cipher)) {
- /* Might be wrong key type, check it */
- if (ssl3_check_cert_and_algorithm(s)) {
- /* Otherwise this shouldn't happen */
- OPENSSL_PUT_ERROR(SSL, ssl3_get_server_key_exchange,
- ERR_R_INTERNAL_ERROR);
- }
- goto err;
- }
- /* still data left over */
+ /* PSK ciphers are the only supported certificate-less ciphers. */
+ assert(alg_a == SSL_aPSK);
+
if (CBS_len(&server_key_exchange) > 0) {
al = SSL_AD_DECODE_ERROR;
- OPENSSL_PUT_ERROR(SSL, ssl3_get_server_key_exchange,
- SSL_R_EXTRA_DATA_IN_MESSAGE);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_EXTRA_DATA_IN_MESSAGE);
goto f_err;
}
}
@@ -1378,19 +1328,15 @@ int ssl3_get_certificate_request(SSL *s) {
if (s->s3->tmp.message_type == SSL3_MT_SERVER_DONE) {
s->s3->tmp.reuse_message = 1;
- /* If we get here we don't need any cached handshake records as we wont be
- * doing client auth. */
- if (s->s3->handshake_buffer &&
- !ssl3_digest_cached_records(s, free_handshake_buffer)) {
- goto err;
- }
+ /* If we get here we don't need the handshake buffer as we won't be doing
+ * client auth. */
+ ssl3_free_handshake_buffer(s);
return 1;
}
if (s->s3->tmp.message_type != SSL3_MT_CERTIFICATE_REQUEST) {
ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_UNEXPECTED_MESSAGE);
- OPENSSL_PUT_ERROR(SSL, ssl3_get_certificate_request,
- SSL_R_WRONG_MESSAGE_TYPE);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_WRONG_MESSAGE_TYPE);
goto err;
}
@@ -1398,14 +1344,14 @@ int ssl3_get_certificate_request(SSL *s) {
ca_sk = sk_X509_NAME_new(ca_dn_cmp);
if (ca_sk == NULL) {
- OPENSSL_PUT_ERROR(SSL, ssl3_get_certificate_request, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
goto err;
}
/* get the certificate types */
if (!CBS_get_u8_length_prefixed(&cbs, &certificate_types)) {
ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
- OPENSSL_PUT_ERROR(SSL, ssl3_get_certificate_request, SSL_R_DECODE_ERROR);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
goto err;
}
@@ -1417,16 +1363,10 @@ int ssl3_get_certificate_request(SSL *s) {
if (SSL_USE_SIGALGS(s)) {
CBS supported_signature_algorithms;
- if (!CBS_get_u16_length_prefixed(&cbs, &supported_signature_algorithms)) {
+ if (!CBS_get_u16_length_prefixed(&cbs, &supported_signature_algorithms) ||
+ !tls1_parse_peer_sigalgs(s, &supported_signature_algorithms)) {
ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
- OPENSSL_PUT_ERROR(SSL, ssl3_get_certificate_request, SSL_R_DECODE_ERROR);
- goto err;
- }
-
- if (!tls1_process_sigalgs(s, &supported_signature_algorithms)) {
- ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
- OPENSSL_PUT_ERROR(SSL, ssl3_get_certificate_request,
- SSL_R_SIGNATURE_ALGORITHMS_ERROR);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
goto err;
}
}
@@ -1434,7 +1374,7 @@ int ssl3_get_certificate_request(SSL *s) {
/* get the CA RDNs */
if (!CBS_get_u16_length_prefixed(&cbs, &certificate_authorities)) {
ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
- OPENSSL_PUT_ERROR(SSL, ssl3_get_certificate_request, SSL_R_LENGTH_MISMATCH);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_LENGTH_MISMATCH);
goto err;
}
@@ -1443,8 +1383,7 @@ int ssl3_get_certificate_request(SSL *s) {
if (!CBS_get_u16_length_prefixed(&certificate_authorities,
&distinguished_name)) {
ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
- OPENSSL_PUT_ERROR(SSL, ssl3_get_certificate_request,
- SSL_R_CA_DN_TOO_LONG);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_CA_DN_TOO_LONG);
goto err;
}
@@ -1453,26 +1392,24 @@ int ssl3_get_certificate_request(SSL *s) {
xn = d2i_X509_NAME(NULL, &data, CBS_len(&distinguished_name));
if (xn == NULL) {
ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
- OPENSSL_PUT_ERROR(SSL, ssl3_get_certificate_request, ERR_R_ASN1_LIB);
+ OPENSSL_PUT_ERROR(SSL, ERR_R_ASN1_LIB);
goto err;
}
if (!CBS_skip(&distinguished_name, data - CBS_data(&distinguished_name))) {
ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
- OPENSSL_PUT_ERROR(SSL, ssl3_get_certificate_request, ERR_R_INTERNAL_ERROR);
+ OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
goto err;
}
if (CBS_len(&distinguished_name) != 0) {
ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
- OPENSSL_PUT_ERROR(SSL, ssl3_get_certificate_request,
- SSL_R_CA_DN_LENGTH_MISMATCH);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_CA_DN_LENGTH_MISMATCH);
goto err;
}
if (!sk_X509_NAME_push(ca_sk, xn)) {
- OPENSSL_PUT_ERROR(SSL, ssl3_get_certificate_request,
- ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
goto err;
}
}
@@ -1516,18 +1453,9 @@ int ssl3_get_new_session_ticket(SSL *s) {
OPENSSL_free(bytes);
if (new_session == NULL) {
/* This should never happen. */
- OPENSSL_PUT_ERROR(SSL, ssl3_get_new_session_ticket, ERR_R_INTERNAL_ERROR);
+ OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
goto err;
}
- if (s->session->sess_cert != NULL) {
- /* |sess_cert| is not serialized and must be duplicated explicitly. */
- assert(new_session->sess_cert == NULL);
- new_session->sess_cert = ssl_sess_cert_dup(s->session->sess_cert);
- if (new_session->sess_cert == NULL) {
- SSL_SESSION_free(new_session);
- goto err;
- }
- }
SSL_SESSION_free(s->session);
s->session = new_session;
@@ -1540,13 +1468,13 @@ int ssl3_get_new_session_ticket(SSL *s) {
!CBS_get_u16_length_prefixed(&new_session_ticket, &ticket) ||
CBS_len(&new_session_ticket) != 0) {
al = SSL_AD_DECODE_ERROR;
- OPENSSL_PUT_ERROR(SSL, ssl3_get_new_session_ticket, SSL_R_DECODE_ERROR);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
goto f_err;
}
if (!CBS_stow(&ticket, &s->session->tlsext_tick,
&s->session->tlsext_ticklen)) {
- OPENSSL_PUT_ERROR(SSL, ssl3_get_new_session_ticket, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
goto err;
}
@@ -1594,14 +1522,14 @@ int ssl3_get_cert_status(SSL *s) {
CBS_len(&ocsp_response) == 0 ||
CBS_len(&certificate_status) != 0) {
al = SSL_AD_DECODE_ERROR;
- OPENSSL_PUT_ERROR(SSL, ssl3_get_cert_status, SSL_R_DECODE_ERROR);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
goto f_err;
}
if (!CBS_stow(&ocsp_response, &s->session->ocsp_response,
&s->session->ocsp_response_length)) {
al = SSL_AD_INTERNAL_ERROR;
- OPENSSL_PUT_ERROR(SSL, ssl3_get_cert_status, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
goto f_err;
}
return 1;
@@ -1627,7 +1555,7 @@ int ssl3_get_server_done(SSL *s) {
if (n > 0) {
/* should contain no data */
ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR);
- OPENSSL_PUT_ERROR(SSL, ssl3_get_server_done, SSL_R_LENGTH_MISMATCH);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_LENGTH_MISMATCH);
return -1;
}
@@ -1665,8 +1593,7 @@ int ssl3_send_client_key_exchange(SSL *s) {
size_t identity_len;
if (s->psk_client_callback == NULL) {
- OPENSSL_PUT_ERROR(SSL, ssl3_send_client_key_exchange,
- SSL_R_PSK_NO_CLIENT_CB);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_PSK_NO_CLIENT_CB);
goto err;
}
@@ -1675,28 +1602,24 @@ int ssl3_send_client_key_exchange(SSL *s) {
s->psk_client_callback(s, s->s3->tmp.peer_psk_identity_hint, identity,
sizeof(identity), psk, sizeof(psk));
if (psk_len > PSK_MAX_PSK_LEN) {
- OPENSSL_PUT_ERROR(SSL, ssl3_send_client_key_exchange,
- ERR_R_INTERNAL_ERROR);
+ OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
goto err;
} else if (psk_len == 0) {
- OPENSSL_PUT_ERROR(SSL, ssl3_send_client_key_exchange,
- SSL_R_PSK_IDENTITY_NOT_FOUND);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_PSK_IDENTITY_NOT_FOUND);
ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE);
goto err;
}
identity_len = OPENSSL_strnlen(identity, sizeof(identity));
if (identity_len > PSK_MAX_IDENTITY_LEN) {
- OPENSSL_PUT_ERROR(SSL, ssl3_send_client_key_exchange,
- ERR_R_INTERNAL_ERROR);
+ OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
goto err;
}
OPENSSL_free(s->session->psk_identity);
s->session->psk_identity = BUF_strdup(identity);
if (s->session->psk_identity == NULL) {
- OPENSSL_PUT_ERROR(SSL, ssl3_send_client_key_exchange,
- ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
goto err;
}
@@ -1715,28 +1638,20 @@ int ssl3_send_client_key_exchange(SSL *s) {
pms_len = SSL_MAX_MASTER_KEY_LENGTH;
pms = OPENSSL_malloc(pms_len);
if (pms == NULL) {
- OPENSSL_PUT_ERROR(SSL, ssl3_send_client_key_exchange,
- ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
goto err;
}
- if (s->session->sess_cert == NULL) {
- /* We should always have a server certificate with SSL_kRSA. */
- OPENSSL_PUT_ERROR(SSL, ssl3_send_client_key_exchange,
- ERR_R_INTERNAL_ERROR);
- goto err;
- }
-
- pkey = X509_get_pubkey(s->session->sess_cert->peer_cert);
+ pkey = X509_get_pubkey(s->session->peer);
if (pkey == NULL ||
pkey->type != EVP_PKEY_RSA ||
pkey->pkey.rsa == NULL) {
- OPENSSL_PUT_ERROR(SSL, ssl3_send_client_key_exchange,
- ERR_R_INTERNAL_ERROR);
+ OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
EVP_PKEY_free(pkey);
goto err;
}
+ s->session->key_exchange_info = EVP_PKEY_bits(pkey);
rsa = pkey->pkey.rsa;
EVP_PKEY_free(pkey);
@@ -1756,8 +1671,7 @@ int ssl3_send_client_key_exchange(SSL *s) {
}
if (!RSA_encrypt(rsa, &enc_pms_len, p, RSA_size(rsa), pms, pms_len,
RSA_PKCS1_PADDING)) {
- OPENSSL_PUT_ERROR(SSL, ssl3_send_client_key_exchange,
- SSL_R_BAD_RSA_ENCRYPT);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_RSA_ENCRYPT);
goto err;
}
n += enc_pms_len;
@@ -1774,32 +1688,23 @@ int ssl3_send_client_key_exchange(SSL *s) {
}
} else if (alg_k & SSL_kDHE) {
DH *dh_srvr, *dh_clnt;
- SESS_CERT *scert = s->session->sess_cert;
int dh_len;
size_t pub_len;
- if (scert == NULL) {
- ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_UNEXPECTED_MESSAGE);
- OPENSSL_PUT_ERROR(SSL, ssl3_send_client_key_exchange,
- SSL_R_UNEXPECTED_MESSAGE);
- goto err;
- }
-
- if (scert->peer_dh_tmp == NULL) {
- OPENSSL_PUT_ERROR(SSL, ssl3_send_client_key_exchange,
- ERR_R_INTERNAL_ERROR);
+ if (s->s3->tmp.peer_dh_tmp == NULL) {
+ OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
goto err;
}
- dh_srvr = scert->peer_dh_tmp;
+ dh_srvr = s->s3->tmp.peer_dh_tmp;
/* generate a new random key */
dh_clnt = DHparams_dup(dh_srvr);
if (dh_clnt == NULL) {
- OPENSSL_PUT_ERROR(SSL, ssl3_send_client_key_exchange, ERR_R_DH_LIB);
+ OPENSSL_PUT_ERROR(SSL, ERR_R_DH_LIB);
goto err;
}
if (!DH_generate_key(dh_clnt)) {
- OPENSSL_PUT_ERROR(SSL, ssl3_send_client_key_exchange, ERR_R_DH_LIB);
+ OPENSSL_PUT_ERROR(SSL, ERR_R_DH_LIB);
DH_free(dh_clnt);
goto err;
}
@@ -1807,15 +1712,14 @@ int ssl3_send_client_key_exchange(SSL *s) {
pms_len = DH_size(dh_clnt);
pms = OPENSSL_malloc(pms_len);
if (pms == NULL) {
- OPENSSL_PUT_ERROR(SSL, ssl3_send_client_key_exchange,
- ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
DH_free(dh_clnt);
goto err;
}
dh_len = DH_compute_key(pms, dh_srvr->pub_key, dh_clnt);
if (dh_len <= 0) {
- OPENSSL_PUT_ERROR(SSL, ssl3_send_client_key_exchange, ERR_R_DH_LIB);
+ OPENSSL_PUT_ERROR(SSL, ERR_R_DH_LIB);
DH_free(dh_clnt);
goto err;
}
@@ -1833,64 +1737,53 @@ int ssl3_send_client_key_exchange(SSL *s) {
EC_KEY *tkey;
int field_size = 0, ecdh_len;
- if (s->session->sess_cert == NULL) {
- ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_UNEXPECTED_MESSAGE);
- OPENSSL_PUT_ERROR(SSL, ssl3_send_client_key_exchange,
- SSL_R_UNEXPECTED_MESSAGE);
+ if (s->s3->tmp.peer_ecdh_tmp == NULL) {
+ OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
goto err;
}
- if (s->session->sess_cert->peer_ecdh_tmp == NULL) {
- OPENSSL_PUT_ERROR(SSL, ssl3_send_client_key_exchange,
- ERR_R_INTERNAL_ERROR);
- goto err;
- }
-
- tkey = s->session->sess_cert->peer_ecdh_tmp;
+ tkey = s->s3->tmp.peer_ecdh_tmp;
srvr_group = EC_KEY_get0_group(tkey);
srvr_ecpoint = EC_KEY_get0_public_key(tkey);
if (srvr_group == NULL || srvr_ecpoint == NULL) {
- OPENSSL_PUT_ERROR(SSL, ssl3_send_client_key_exchange,
- ERR_R_INTERNAL_ERROR);
+ OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
goto err;
}
clnt_ecdh = EC_KEY_new();
if (clnt_ecdh == NULL) {
- OPENSSL_PUT_ERROR(SSL, ssl3_send_client_key_exchange,
- ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
goto err;
}
if (!EC_KEY_set_group(clnt_ecdh, srvr_group)) {
- OPENSSL_PUT_ERROR(SSL, ssl3_send_client_key_exchange, ERR_R_EC_LIB);
+ OPENSSL_PUT_ERROR(SSL, ERR_R_EC_LIB);
goto err;
}
/* Generate a new ECDH key pair */
if (!EC_KEY_generate_key(clnt_ecdh)) {
- OPENSSL_PUT_ERROR(SSL, ssl3_send_client_key_exchange, ERR_R_ECDH_LIB);
+ OPENSSL_PUT_ERROR(SSL, ERR_R_ECDH_LIB);
goto err;
}
field_size = EC_GROUP_get_degree(srvr_group);
if (field_size <= 0) {
- OPENSSL_PUT_ERROR(SSL, ssl3_send_client_key_exchange, ERR_R_ECDH_LIB);
+ OPENSSL_PUT_ERROR(SSL, ERR_R_ECDH_LIB);
goto err;
}
pms_len = (field_size + 7) / 8;
pms = OPENSSL_malloc(pms_len);
if (pms == NULL) {
- OPENSSL_PUT_ERROR(SSL, ssl3_send_client_key_exchange,
- ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
goto err;
}
ecdh_len = ECDH_compute_key(pms, pms_len, srvr_ecpoint, clnt_ecdh, NULL);
if (ecdh_len <= 0) {
- OPENSSL_PUT_ERROR(SSL, ssl3_send_client_key_exchange, ERR_R_ECDH_LIB);
+ OPENSSL_PUT_ERROR(SSL, ERR_R_ECDH_LIB);
goto err;
}
pms_len = ecdh_len;
@@ -1904,8 +1797,7 @@ int ssl3_send_client_key_exchange(SSL *s) {
(uint8_t *)OPENSSL_malloc(encoded_pt_len * sizeof(uint8_t));
bn_ctx = BN_CTX_new();
if (encodedPoint == NULL || bn_ctx == NULL) {
- OPENSSL_PUT_ERROR(SSL, ssl3_send_client_key_exchange,
- ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
goto err;
}
@@ -1938,15 +1830,13 @@ int ssl3_send_client_key_exchange(SSL *s) {
pms_len = psk_len;
pms = OPENSSL_malloc(pms_len);
if (pms == NULL) {
- OPENSSL_PUT_ERROR(SSL, ssl3_send_client_key_exchange,
- ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
goto err;
}
memset(pms, 0, pms_len);
} else {
ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE);
- OPENSSL_PUT_ERROR(SSL, ssl3_send_client_key_exchange,
- ERR_R_INTERNAL_ERROR);
+ OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
goto err;
}
@@ -1957,19 +1847,15 @@ int ssl3_send_client_key_exchange(SSL *s) {
uint8_t *new_pms;
size_t new_pms_len;
- if (!CBB_init(&cbb, 2 + psk_len + 2 + pms_len)) {
- OPENSSL_PUT_ERROR(SSL, ssl3_send_client_key_exchange,
- ERR_R_MALLOC_FAILURE);
- goto err;
- }
- if (!CBB_add_u16_length_prefixed(&cbb, &child) ||
+ CBB_zero(&cbb);
+ if (!CBB_init(&cbb, 2 + psk_len + 2 + pms_len) ||
+ !CBB_add_u16_length_prefixed(&cbb, &child) ||
!CBB_add_bytes(&child, pms, pms_len) ||
!CBB_add_u16_length_prefixed(&cbb, &child) ||
!CBB_add_bytes(&child, psk, psk_len) ||
!CBB_finish(&cbb, &new_pms, &new_pms_len)) {
CBB_cleanup(&cbb);
- OPENSSL_PUT_ERROR(SSL, ssl3_send_client_key_exchange,
- ERR_R_INTERNAL_ERROR);
+ OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
goto err;
}
OPENSSL_cleanse(pms, pms_len);
@@ -2011,87 +1897,87 @@ err:
}
int ssl3_send_cert_verify(SSL *s) {
- uint8_t *buf, *p;
- const EVP_MD *md = NULL;
- uint8_t digest[EVP_MAX_MD_SIZE];
- size_t digest_length;
- EVP_PKEY *pkey;
- EVP_PKEY_CTX *pctx = NULL;
- size_t signature_length = 0;
- unsigned long n = 0;
-
- buf = (uint8_t *)s->init_buf->data;
-
- if (s->state == SSL3_ST_CW_CERT_VRFY_A) {
- p = ssl_handshake_start(s);
- pkey = s->cert->key->privatekey;
-
- /* Write out the digest type if needbe. */
- if (SSL_USE_SIGALGS(s)) {
- md = tls1_choose_signing_digest(s, pkey);
- if (!tls12_get_sigandhash(p, pkey, md)) {
- OPENSSL_PUT_ERROR(SSL, ssl3_send_cert_verify, ERR_R_INTERNAL_ERROR);
- goto err;
+ if (s->state == SSL3_ST_CW_CERT_VRFY_A ||
+ s->state == SSL3_ST_CW_CERT_VRFY_B) {
+ enum ssl_private_key_result_t sign_result;
+ uint8_t *p = ssl_handshake_start(s);
+ size_t signature_length = 0;
+ unsigned long n = 0;
+ assert(ssl_has_private_key(s));
+
+ if (s->state == SSL3_ST_CW_CERT_VRFY_A) {
+ uint8_t *buf = (uint8_t *)s->init_buf->data;
+ const EVP_MD *md = NULL;
+ uint8_t digest[EVP_MAX_MD_SIZE];
+ size_t digest_length;
+
+ /* Write out the digest type if need be. */
+ if (SSL_USE_SIGALGS(s)) {
+ md = tls1_choose_signing_digest(s);
+ if (!tls12_get_sigandhash(s, p, md)) {
+ OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
+ return -1;
+ }
+ p += 2;
+ n += 2;
}
- p += 2;
- n += 2;
- }
- /* Compute the digest. */
- if (!ssl3_cert_verify_hash(s, digest, &digest_length, &md, pkey)) {
- goto err;
- }
+ /* Compute the digest. */
+ const int pkey_type = ssl_private_key_type(s);
+ if (!ssl3_cert_verify_hash(s, digest, &digest_length, &md, pkey_type)) {
+ return -1;
+ }
- /* The handshake buffer is no longer necessary. */
- if (s->s3->handshake_buffer &&
- !ssl3_digest_cached_records(s, free_handshake_buffer)) {
- goto err;
- }
+ /* The handshake buffer is no longer necessary. */
+ ssl3_free_handshake_buffer(s);
- /* Sign the digest. */
- pctx = EVP_PKEY_CTX_new(pkey, NULL);
- if (pctx == NULL) {
- goto err;
- }
+ /* Sign the digest. */
+ signature_length = ssl_private_key_max_signature_len(s);
+ if (p + 2 + signature_length > buf + SSL3_RT_MAX_PLAIN_LENGTH) {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_DATA_LENGTH_TOO_LONG);
+ return -1;
+ }
- /* Initialize the EVP_PKEY_CTX and determine the size of the signature. */
- if (!EVP_PKEY_sign_init(pctx) || !EVP_PKEY_CTX_set_signature_md(pctx, md) ||
- !EVP_PKEY_sign(pctx, NULL, &signature_length, digest, digest_length)) {
- OPENSSL_PUT_ERROR(SSL, ssl3_send_cert_verify, ERR_R_EVP_LIB);
- goto err;
+ s->rwstate = SSL_PRIVATE_KEY_OPERATION;
+ sign_result = ssl_private_key_sign(s, &p[2], &signature_length,
+ signature_length, md, digest,
+ digest_length);
+ } else {
+ if (SSL_USE_SIGALGS(s)) {
+ /* The digest has already been selected and written. */
+ p += 2;
+ n += 2;
+ }
+ signature_length = ssl_private_key_max_signature_len(s);
+ s->rwstate = SSL_PRIVATE_KEY_OPERATION;
+ sign_result = ssl_private_key_sign_complete(s, &p[2], &signature_length,
+ signature_length);
}
- if (p + 2 + signature_length > buf + SSL3_RT_MAX_PLAIN_LENGTH) {
- OPENSSL_PUT_ERROR(SSL, ssl3_send_cert_verify, SSL_R_DATA_LENGTH_TOO_LONG);
- goto err;
+ if (sign_result == ssl_private_key_retry) {
+ s->state = SSL3_ST_CW_CERT_VRFY_B;
+ return -1;
}
-
- if (!EVP_PKEY_sign(pctx, &p[2], &signature_length, digest, digest_length)) {
- OPENSSL_PUT_ERROR(SSL, ssl3_send_cert_verify, ERR_R_EVP_LIB);
- goto err;
+ s->rwstate = SSL_NOTHING;
+ if (sign_result != ssl_private_key_success) {
+ return -1;
}
s2n(signature_length, p);
n += signature_length + 2;
-
if (!ssl_set_handshake_header(s, SSL3_MT_CERTIFICATE_VERIFY, n)) {
- goto err;
+ return -1;
}
- s->state = SSL3_ST_CW_CERT_VRFY_B;
+ s->state = SSL3_ST_CW_CERT_VRFY_C;
}
- EVP_PKEY_CTX_free(pctx);
return ssl_do_write(s);
-
-err:
- EVP_PKEY_CTX_free(pctx);
- return -1;
}
/* ssl3_has_client_certificate returns true if a client certificate is
* configured. */
-static int ssl3_has_client_certificate(SSL *s) {
- return s->cert && s->cert->key->x509 && s->cert->key->privatekey;
+static int ssl3_has_client_certificate(SSL *ssl) {
+ return ssl->cert && ssl->cert->x509 && ssl_has_private_key(ssl);
}
int ssl3_send_client_certificate(SSL *s) {
@@ -2139,8 +2025,7 @@ int ssl3_send_client_certificate(SSL *s) {
}
} else if (i == 1) {
i = 0;
- OPENSSL_PUT_ERROR(SSL, ssl3_send_client_certificate,
- SSL_R_BAD_DATA_RETURNED_BY_CALLBACK);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_DATA_RETURNED_BY_CALLBACK);
}
X509_free(x509);
@@ -2157,11 +2042,7 @@ int ssl3_send_client_certificate(SSL *s) {
s->s3->tmp.cert_req = 2;
/* There is no client certificate, so the handshake buffer may be
* released. */
- if (s->s3->handshake_buffer &&
- !ssl3_digest_cached_records(s, free_handshake_buffer)) {
- ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR);
- return -1;
- }
+ ssl3_free_handshake_buffer(s);
}
}
@@ -2170,80 +2051,23 @@ int ssl3_send_client_certificate(SSL *s) {
}
if (s->state == SSL3_ST_CW_CERT_C) {
- CERT_PKEY *cert_pkey = (s->s3->tmp.cert_req == 2) ? NULL : s->cert->key;
- if (!ssl3_output_cert_chain(s, cert_pkey)) {
+ if (s->s3->tmp.cert_req == 2) {
+ /* Send an empty Certificate message. */
+ uint8_t *p = ssl_handshake_start(s);
+ l2n3(0, p);
+ if (!ssl_set_handshake_header(s, SSL3_MT_CERTIFICATE, 3)) {
+ return -1;
+ }
+ } else if (!ssl3_output_cert_chain(s)) {
return -1;
}
+ s->state = SSL3_ST_CW_CERT_D;
}
/* SSL3_ST_CW_CERT_D */
return ssl_do_write(s);
}
-#define has_bits(i, m) (((i) & (m)) == (m))
-
-int ssl3_check_cert_and_algorithm(SSL *s) {
- long alg_k, alg_a;
- SESS_CERT *sc;
- DH *dh;
-
- /* we don't have a certificate */
- if (!ssl_cipher_has_server_public_key(s->s3->tmp.new_cipher)) {
- return 1;
- }
-
- alg_k = s->s3->tmp.new_cipher->algorithm_mkey;
- alg_a = s->s3->tmp.new_cipher->algorithm_auth;
-
- sc = s->session->sess_cert;
- if (sc == NULL) {
- OPENSSL_PUT_ERROR(SSL, ssl3_check_cert_and_algorithm, ERR_R_INTERNAL_ERROR);
- goto err;
- }
-
- dh = s->session->sess_cert->peer_dh_tmp;
-
- int cert_type = X509_certificate_type(sc->peer_cert, NULL);
- if (cert_type & EVP_PK_EC) {
- if (ssl_check_srvr_ecc_cert_and_alg(sc->peer_cert, s) == 0) {
- /* check failed */
- OPENSSL_PUT_ERROR(SSL, ssl3_check_cert_and_algorithm, SSL_R_BAD_ECC_CERT);
- goto f_err;
- } else {
- return 1;
- }
- } else if (alg_a & SSL_aECDSA) {
- OPENSSL_PUT_ERROR(SSL, ssl3_check_cert_and_algorithm,
- SSL_R_MISSING_ECDSA_SIGNING_CERT);
- goto f_err;
- }
-
- /* Check that we have a certificate if we require one */
- if ((alg_a & SSL_aRSA) && !has_bits(cert_type, EVP_PK_RSA | EVP_PKT_SIGN)) {
- OPENSSL_PUT_ERROR(SSL, ssl3_check_cert_and_algorithm,
- SSL_R_MISSING_RSA_SIGNING_CERT);
- goto f_err;
- }
-
- if ((alg_k & SSL_kRSA) && !has_bits(cert_type, EVP_PK_RSA | EVP_PKT_ENC)) {
- OPENSSL_PUT_ERROR(SSL, ssl3_check_cert_and_algorithm,
- SSL_R_MISSING_RSA_ENCRYPTING_CERT);
- goto f_err;
- }
-
- if ((alg_k & SSL_kDHE) && dh == NULL) {
- OPENSSL_PUT_ERROR(SSL, ssl3_check_cert_and_algorithm, SSL_R_MISSING_DH_KEY);
- goto f_err;
- }
-
- return 1;
-
-f_err:
- ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE);
-err:
- return 0;
-}
-
int ssl3_send_next_proto(SSL *s) {
unsigned int len, padding_len;
uint8_t *d, *p;
@@ -2273,7 +2097,6 @@ int ssl3_send_channel_id(SSL *s) {
uint8_t *d;
int ret = -1, public_key_len;
EVP_MD_CTX md_ctx;
- size_t sig_len;
ECDSA_SIG *sig = NULL;
uint8_t *public_key = NULL, *derp, *der_sig = NULL;
@@ -2295,72 +2118,48 @@ int ssl3_send_channel_id(SSL *s) {
}
s->rwstate = SSL_NOTHING;
- d = ssl_handshake_start(s);
- if (s->s3->tlsext_channel_id_new) {
- s2n(TLSEXT_TYPE_channel_id_new, d);
- } else {
- s2n(TLSEXT_TYPE_channel_id, d);
+ if (EVP_PKEY_id(s->tlsext_channel_id_private) != EVP_PKEY_EC) {
+ OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
+ return -1;
}
+ EC_KEY *ec_key = s->tlsext_channel_id_private->pkey.ec;
+
+ d = ssl_handshake_start(s);
+ s2n(TLSEXT_TYPE_channel_id, d);
s2n(TLSEXT_CHANNEL_ID_SIZE, d);
EVP_MD_CTX_init(&md_ctx);
- public_key_len = i2d_PublicKey(s->tlsext_channel_id_private, NULL);
+ public_key_len = i2o_ECPublicKey(ec_key, NULL);
if (public_key_len <= 0) {
- OPENSSL_PUT_ERROR(SSL, ssl3_send_channel_id,
- SSL_R_CANNOT_SERIALIZE_PUBLIC_KEY);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_CANNOT_SERIALIZE_PUBLIC_KEY);
goto err;
}
- /* i2d_PublicKey will produce an ANSI X9.62 public key which, for a
+ /* i2o_ECPublicKey will produce an ANSI X9.62 public key which, for a
* P-256 key, is 0x04 (meaning uncompressed) followed by the x and y
* field elements as 32-byte, big-endian numbers. */
if (public_key_len != 65) {
- OPENSSL_PUT_ERROR(SSL, ssl3_send_channel_id, SSL_R_CHANNEL_ID_NOT_P256);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_CHANNEL_ID_NOT_P256);
goto err;
}
public_key = OPENSSL_malloc(public_key_len);
if (!public_key) {
- OPENSSL_PUT_ERROR(SSL, ssl3_send_channel_id, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
goto err;
}
derp = public_key;
- i2d_PublicKey(s->tlsext_channel_id_private, &derp);
+ i2o_ECPublicKey(ec_key, &derp);
- if (EVP_DigestSignInit(&md_ctx, NULL, EVP_sha256(), NULL,
- s->tlsext_channel_id_private) != 1) {
- OPENSSL_PUT_ERROR(SSL, ssl3_send_channel_id,
- SSL_R_EVP_DIGESTSIGNINIT_FAILED);
- goto err;
- }
-
- if (!tls1_channel_id_hash(&md_ctx, s)) {
- goto err;
- }
-
- if (!EVP_DigestSignFinal(&md_ctx, NULL, &sig_len)) {
- OPENSSL_PUT_ERROR(SSL, ssl3_send_channel_id,
- SSL_R_EVP_DIGESTSIGNFINAL_FAILED);
- goto err;
- }
-
- der_sig = OPENSSL_malloc(sig_len);
- if (!der_sig) {
- OPENSSL_PUT_ERROR(SSL, ssl3_send_channel_id, ERR_R_MALLOC_FAILURE);
- goto err;
- }
-
- if (!EVP_DigestSignFinal(&md_ctx, der_sig, &sig_len)) {
- OPENSSL_PUT_ERROR(SSL, ssl3_send_channel_id,
- SSL_R_EVP_DIGESTSIGNFINAL_FAILED);
+ uint8_t digest[EVP_MAX_MD_SIZE];
+ size_t digest_len;
+ if (!tls1_channel_id_hash(s, digest, &digest_len)) {
goto err;
}
- derp = der_sig;
- sig = d2i_ECDSA_SIG(NULL, (const uint8_t **)&derp, sig_len);
+ sig = ECDSA_do_sign(digest, digest_len, ec_key);
if (sig == NULL) {
- OPENSSL_PUT_ERROR(SSL, ssl3_send_channel_id, SSL_R_D2I_ECDSA_SIG);
goto err;
}
@@ -2369,7 +2168,7 @@ int ssl3_send_channel_id(SSL *s) {
d += 64;
if (!BN_bn2bin_padded(d, 32, sig->r) ||
!BN_bn2bin_padded(d + 32, 32, sig->s)) {
- OPENSSL_PUT_ERROR(SSL, ssl3_send_channel_id, ERR_R_INTERNAL_ERROR);
+ OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
goto err;
}
@@ -2397,3 +2196,17 @@ int ssl_do_client_cert_cb(SSL *s, X509 **px509, EVP_PKEY **ppkey) {
}
return i;
}
+
+int ssl3_verify_server_cert(SSL *s) {
+ int ret = ssl_verify_cert_chain(s, s->session->cert_chain);
+ if (s->verify_mode != SSL_VERIFY_NONE && ret <= 0) {
+ int al = ssl_verify_alarm_type(s->verify_result);
+ ssl3_send_alert(s, SSL3_AL_FATAL, al);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_CERTIFICATE_VERIFY_FAILED);
+ } else {
+ ret = 1;
+ ERR_clear_error(); /* but we keep s->verify_result */
+ }
+
+ return ret;
+}
diff --git a/src/ssl/s3_enc.c b/src/ssl/s3_enc.c
index fbe68da..f1924c0 100644
--- a/src/ssl/s3_enc.c
+++ b/src/ssl/s3_enc.c
@@ -4,21 +4,21 @@
* This package is an SSL implementation written
* by Eric Young (eay@cryptsoft.com).
* The implementation was written so as to conform with Netscapes SSL.
- *g
+ *
* This library is free for commercial and non-commercial use as long as
* the following conditions are aheared to. The following conditions
* apply to all code found in this distribution, be it the RC4, RSA,
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
* included with this distribution is covered by the same copyright terms
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
- *g
+ *
* Copyright remains Eric Young's, and as such any Copyright notices in
* the code are not to be removed.
* If this package is used in a product, Eric Young should be given attribution
* as the author of the parts of the library used.
* This can be in the form of a textual message at program startup or
* in documentation (online or textual) provided with the package.
- *g
+ *
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -33,10 +33,10 @@
* Eric Young (eay@cryptsoft.com)"
* The word 'cryptographic' can be left out if the rouines from the library
* being used are not cryptographic related :-).
- * 4. If you include any Windows specific code (or a derivative thereof) fromg
+ * 4. If you include any Windows specific code (or a derivative thereof) from
* the apps directory (application code) you must include an acknowledgement:
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
- *g
+ *
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
@@ -48,7 +48,7 @@
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
- *g
+ *
* The licence and distribution terms for any publically available version or
* derivative of this code cannot be changed. i.e. this code cannot simply be
* copied and put under another distribution licence
@@ -62,7 +62,7 @@
* are met:
*
* 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.g
+ * notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
@@ -133,6 +133,8 @@
* OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR
* OTHERWISE. */
+#include <openssl/ssl.h>
+
#include <assert.h>
#include <stdio.h>
#include <string.h>
@@ -180,7 +182,7 @@ int ssl3_prf(SSL *s, uint8_t *out, size_t out_len, const uint8_t *secret,
k++;
if (k > sizeof(buf)) {
/* bug: 'buf' is too small for this ciphersuite */
- OPENSSL_PUT_ERROR(SSL, ssl3_prf, ERR_R_INTERNAL_ERROR);
+ OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
return 0;
}
@@ -189,7 +191,7 @@ int ssl3_prf(SSL *s, uint8_t *out, size_t out_len, const uint8_t *secret,
}
c++;
if (!EVP_DigestInit_ex(&sha1, EVP_sha1(), NULL)) {
- OPENSSL_PUT_ERROR(SSL, ssl3_prf, ERR_LIB_EVP);
+ OPENSSL_PUT_ERROR(SSL, ERR_LIB_EVP);
return 0;
}
EVP_DigestUpdate(&sha1, buf, k);
@@ -204,7 +206,7 @@ int ssl3_prf(SSL *s, uint8_t *out, size_t out_len, const uint8_t *secret,
EVP_DigestFinal_ex(&sha1, smd, NULL);
if (!EVP_DigestInit_ex(&md5, EVP_md5(), NULL)) {
- OPENSSL_PUT_ERROR(SSL, ssl3_prf, ERR_LIB_EVP);
+ OPENSSL_PUT_ERROR(SSL, ERR_LIB_EVP);
return 0;
}
EVP_DigestUpdate(&md5, secret, secret_len);
@@ -235,96 +237,75 @@ void ssl3_cleanup_key_block(SSL *s) {
s->s3->tmp.key_block_length = 0;
}
-int ssl3_init_finished_mac(SSL *s) {
- BIO_free(s->s3->handshake_buffer);
- ssl3_free_digest_list(s);
- s->s3->handshake_buffer = BIO_new(BIO_s_mem());
- if (s->s3->handshake_buffer == NULL) {
- return 0;
- }
- BIO_set_close(s->s3->handshake_buffer, BIO_CLOSE);
-
- return 1;
+int ssl3_init_handshake_buffer(SSL *ssl) {
+ ssl3_free_handshake_buffer(ssl);
+ ssl3_free_handshake_hash(ssl);
+ ssl->s3->handshake_buffer = BUF_MEM_new();
+ return ssl->s3->handshake_buffer != NULL;
}
-void ssl3_free_digest_list(SSL *s) {
- int i;
- if (!s->s3->handshake_dgst) {
- return;
- }
- for (i = 0; i < SSL_MAX_DIGEST; i++) {
- if (s->s3->handshake_dgst[i]) {
- EVP_MD_CTX_destroy(s->s3->handshake_dgst[i]);
- }
+/* init_digest_with_data calls |EVP_DigestInit_ex| on |ctx| with |md| and then
+ * writes the data in |buf| to it. */
+static int init_digest_with_data(EVP_MD_CTX *ctx, const EVP_MD *md,
+ const BUF_MEM *buf) {
+ if (!EVP_DigestInit_ex(ctx, md, NULL)) {
+ return 0;
}
- OPENSSL_free(s->s3->handshake_dgst);
- s->s3->handshake_dgst = NULL;
+ EVP_DigestUpdate(ctx, buf->data, buf->length);
+ return 1;
}
-int ssl3_finish_mac(SSL *s, const uint8_t *buf, int len) {
- int i;
+int ssl3_init_handshake_hash(SSL *ssl) {
+ ssl3_free_handshake_hash(ssl);
- if (s->s3->handshake_buffer) {
- return BIO_write(s->s3->handshake_buffer, (void *)buf, len) >= 0;
+ uint32_t algorithm_prf = ssl_get_algorithm_prf(ssl);
+ if (!init_digest_with_data(&ssl->s3->handshake_hash,
+ ssl_get_handshake_digest(algorithm_prf),
+ ssl->s3->handshake_buffer)) {
+ return 0;
}
- for (i = 0; i < SSL_MAX_DIGEST; i++) {
- if (s->s3->handshake_dgst[i] != NULL) {
- EVP_DigestUpdate(s->s3->handshake_dgst[i], buf, len);
- }
+ if (algorithm_prf == SSL_HANDSHAKE_MAC_DEFAULT &&
+ !init_digest_with_data(&ssl->s3->handshake_md5, EVP_md5(),
+ ssl->s3->handshake_buffer)) {
+ return 0;
}
+
return 1;
}
-int ssl3_digest_cached_records(
- SSL *s, enum should_free_handshake_buffer_t should_free_handshake_buffer) {
- int i;
- uint32_t mask;
- const EVP_MD *md;
- const uint8_t *hdata;
- size_t hdatalen;
-
- /* Allocate handshake_dgst array */
- ssl3_free_digest_list(s);
- s->s3->handshake_dgst = OPENSSL_malloc(SSL_MAX_DIGEST * sizeof(EVP_MD_CTX *));
- if (s->s3->handshake_dgst == NULL) {
- OPENSSL_PUT_ERROR(SSL, ssl3_digest_cached_records, ERR_R_MALLOC_FAILURE);
- return 0;
- }
+void ssl3_free_handshake_hash(SSL *ssl) {
+ EVP_MD_CTX_cleanup(&ssl->s3->handshake_hash);
+ EVP_MD_CTX_cleanup(&ssl->s3->handshake_md5);
+}
- memset(s->s3->handshake_dgst, 0, SSL_MAX_DIGEST * sizeof(EVP_MD_CTX *));
- if (!BIO_mem_contents(s->s3->handshake_buffer, &hdata, &hdatalen)) {
- OPENSSL_PUT_ERROR(SSL, ssl3_digest_cached_records,
- SSL_R_BAD_HANDSHAKE_LENGTH);
- return 0;
- }
+void ssl3_free_handshake_buffer(SSL *ssl) {
+ BUF_MEM_free(ssl->s3->handshake_buffer);
+ ssl->s3->handshake_buffer = NULL;
+}
- /* Loop through bits of algorithm2 field and create MD_CTX-es */
- for (i = 0; ssl_get_handshake_digest(&mask, &md, i); i++) {
- if ((mask & ssl_get_algorithm2(s)) && md) {
- s->s3->handshake_dgst[i] = EVP_MD_CTX_create();
- if (s->s3->handshake_dgst[i] == NULL) {
- OPENSSL_PUT_ERROR(SSL, ssl3_digest_cached_records, ERR_LIB_EVP);
- return 0;
- }
- if (!EVP_DigestInit_ex(s->s3->handshake_dgst[i], md, NULL)) {
- EVP_MD_CTX_destroy(s->s3->handshake_dgst[i]);
- s->s3->handshake_dgst[i] = NULL;
- OPENSSL_PUT_ERROR(SSL, ssl3_digest_cached_records, ERR_LIB_EVP);
- return 0;
- }
- EVP_DigestUpdate(s->s3->handshake_dgst[i], hdata, hdatalen);
- } else {
- s->s3->handshake_dgst[i] = NULL;
+int ssl3_update_handshake_hash(SSL *ssl, const uint8_t *in, size_t in_len) {
+ /* Depending on the state of the handshake, either the handshake buffer may be
+ * active, the rolling hash, or both. */
+
+ if (ssl->s3->handshake_buffer != NULL) {
+ size_t new_len = ssl->s3->handshake_buffer->length + in_len;
+ if (new_len < in_len) {
+ OPENSSL_PUT_ERROR(SSL, ERR_R_OVERFLOW);
+ return 0;
+ }
+ if (!BUF_MEM_grow(ssl->s3->handshake_buffer, new_len)) {
+ return 0;
}
+ memcpy(ssl->s3->handshake_buffer->data + new_len - in_len, in, in_len);
}
- if (should_free_handshake_buffer == free_handshake_buffer) {
- /* Free handshake_buffer BIO */
- BIO_free(s->s3->handshake_buffer);
- s->s3->handshake_buffer = NULL;
+ if (EVP_MD_CTX_md(&ssl->s3->handshake_hash) != NULL) {
+ EVP_DigestUpdate(&ssl->s3->handshake_hash, in, in_len);
+ }
+ if (EVP_MD_CTX_md(&ssl->s3->handshake_md5) != NULL) {
+ EVP_DigestUpdate(&ssl->s3->handshake_md5, in, in_len);
}
-
return 1;
}
@@ -356,31 +337,22 @@ static int ssl3_handshake_mac(SSL *s, int md_nid, const char *sender, int len,
int npad, n;
unsigned int i;
uint8_t md_buf[EVP_MAX_MD_SIZE];
- EVP_MD_CTX ctx, *d = NULL;
-
- if (s->s3->handshake_buffer &&
- !ssl3_digest_cached_records(s, free_handshake_buffer)) {
- return 0;
- }
-
- /* Search for digest of specified type in the handshake_dgst array. */
- for (i = 0; i < SSL_MAX_DIGEST; i++) {
- if (s->s3->handshake_dgst[i] &&
- EVP_MD_CTX_type(s->s3->handshake_dgst[i]) == md_nid) {
- d = s->s3->handshake_dgst[i];
- break;
- }
- }
-
- if (!d) {
- OPENSSL_PUT_ERROR(SSL, ssl3_handshake_mac, SSL_R_NO_REQUIRED_DIGEST);
+ EVP_MD_CTX ctx;
+ const EVP_MD_CTX *ctx_template;
+
+ if (md_nid == NID_md5) {
+ ctx_template = &s->s3->handshake_md5;
+ } else if (md_nid == EVP_MD_CTX_type(&s->s3->handshake_hash)) {
+ ctx_template = &s->s3->handshake_hash;
+ } else {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_NO_REQUIRED_DIGEST);
return 0;
}
EVP_MD_CTX_init(&ctx);
- if (!EVP_MD_CTX_copy_ex(&ctx, d)) {
+ if (!EVP_MD_CTX_copy_ex(&ctx, ctx_template)) {
EVP_MD_CTX_cleanup(&ctx);
- OPENSSL_PUT_ERROR(SSL, ssl3_handshake_mac, ERR_LIB_EVP);
+ OPENSSL_PUT_ERROR(SSL, ERR_LIB_EVP);
return 0;
}
@@ -399,7 +371,7 @@ static int ssl3_handshake_mac(SSL *s, int md_nid, const char *sender, int len,
if (!EVP_DigestInit_ex(&ctx, EVP_MD_CTX_md(&ctx), NULL)) {
EVP_MD_CTX_cleanup(&ctx);
- OPENSSL_PUT_ERROR(SSL, ssl3_handshake_mac, ERR_LIB_EVP);
+ OPENSSL_PUT_ERROR(SSL, ERR_LIB_EVP);
return 0;
}
EVP_DigestUpdate(&ctx, s->session->master_key, s->session->master_key_length);
@@ -420,7 +392,7 @@ int ssl3_record_sequence_update(uint8_t *seq, size_t seq_len) {
return 1;
}
}
- OPENSSL_PUT_ERROR(SSL, ssl3_record_sequence_update, ERR_R_OVERFLOW);
+ OPENSSL_PUT_ERROR(SSL, ERR_R_OVERFLOW);
return 0;
}
diff --git a/src/ssl/s3_lib.c b/src/ssl/s3_lib.c
index 1c28a73..617ea6e 100644
--- a/src/ssl/s3_lib.c
+++ b/src/ssl/s3_lib.c
@@ -146,12 +146,15 @@
* OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR
* OTHERWISE. */
+#include <openssl/ssl.h>
+
#include <assert.h>
#include <stdio.h>
#include <string.h>
#include <openssl/buf.h>
#include <openssl/dh.h>
+#include <openssl/digest.h>
#include <openssl/err.h>
#include <openssl/md5.h>
#include <openssl/mem.h>
@@ -186,7 +189,8 @@ int ssl3_set_handshake_header(SSL *s, int htype, unsigned long len) {
s->init_off = 0;
/* Add the message to the handshake hash. */
- return ssl3_finish_mac(s, (uint8_t *)s->init_buf->data, s->init_num);
+ return ssl3_update_handshake_hash(s, (uint8_t *)s->init_buf->data,
+ s->init_num);
}
int ssl3_handshake_write(SSL *s) { return ssl3_do_write(s, SSL3_RT_HANDSHAKE); }
@@ -199,7 +203,9 @@ int ssl3_new(SSL *s) {
goto err;
}
memset(s3, 0, sizeof *s3);
- memset(s3->rrec.seq_num, 0, sizeof(s3->rrec.seq_num));
+
+ EVP_MD_CTX_init(&s3->handshake_hash);
+ EVP_MD_CTX_init(&s3->handshake_md5);
s->s3 = s3;
@@ -219,20 +225,20 @@ void ssl3_free(SSL *s) {
return;
}
- BUF_MEM_free(s->s3->sniff_buffer);
ssl3_cleanup_key_block(s);
- ssl3_release_read_buffer(s);
- ssl3_release_write_buffer(s);
+ ssl_read_buffer_clear(s);
+ ssl_write_buffer_clear(s);
DH_free(s->s3->tmp.dh);
EC_KEY_free(s->s3->tmp.ecdh);
sk_X509_NAME_pop_free(s->s3->tmp.ca_names, X509_NAME_free);
OPENSSL_free(s->s3->tmp.certificate_types);
- OPENSSL_free(s->s3->tmp.peer_ecpointformatlist);
OPENSSL_free(s->s3->tmp.peer_ellipticcurvelist);
OPENSSL_free(s->s3->tmp.peer_psk_identity_hint);
- BIO_free(s->s3->handshake_buffer);
- ssl3_free_digest_list(s);
+ DH_free(s->s3->tmp.peer_dh_tmp);
+ EC_KEY_free(s->s3->tmp.peer_ecdh_tmp);
+ ssl3_free_handshake_buffer(s);
+ ssl3_free_handshake_hash(s);
OPENSSL_free(s->s3->alpn_selected);
OPENSSL_cleanse(s->s3, sizeof *s->s3);
@@ -240,8 +246,6 @@ void ssl3_free(SSL *s) {
s->s3 = NULL;
}
-static int ssl3_set_req_cert_type(CERT *c, const uint8_t *p, size_t len);
-
int SSL_session_reused(const SSL *ssl) {
return ssl->hit;
}
@@ -274,7 +278,7 @@ int SSL_CTX_set_tmp_dh(SSL_CTX *ctx, const DH *dh) {
DH_free(ctx->cert->dh_tmp);
ctx->cert->dh_tmp = DHparams_dup(dh);
if (ctx->cert->dh_tmp == NULL) {
- OPENSSL_PUT_ERROR(SSL, SSL_CTX_set_tmp_dh, ERR_R_DH_LIB);
+ OPENSSL_PUT_ERROR(SSL, ERR_R_DH_LIB);
return 0;
}
return 1;
@@ -284,7 +288,7 @@ int SSL_set_tmp_dh(SSL *ssl, const DH *dh) {
DH_free(ssl->cert->dh_tmp);
ssl->cert->dh_tmp = DHparams_dup(dh);
if (ssl->cert->dh_tmp == NULL) {
- OPENSSL_PUT_ERROR(SSL, SSL_set_tmp_dh, ERR_R_DH_LIB);
+ OPENSSL_PUT_ERROR(SSL, ERR_R_DH_LIB);
return 0;
}
return 1;
@@ -292,7 +296,7 @@ int SSL_set_tmp_dh(SSL *ssl, const DH *dh) {
int SSL_CTX_set_tmp_ecdh(SSL_CTX *ctx, const EC_KEY *ec_key) {
if (ec_key == NULL || EC_KEY_get0_group(ec_key) == NULL) {
- OPENSSL_PUT_ERROR(SSL, SSL_CTX_set_tmp_ecdh, ERR_R_PASSED_NULL_PARAMETER);
+ OPENSSL_PUT_ERROR(SSL, ERR_R_PASSED_NULL_PARAMETER);
return 0;
}
ctx->cert->ecdh_nid = EC_GROUP_get_curve_name(EC_KEY_get0_group(ec_key));
@@ -301,7 +305,7 @@ int SSL_CTX_set_tmp_ecdh(SSL_CTX *ctx, const EC_KEY *ec_key) {
int SSL_set_tmp_ecdh(SSL *ssl, const EC_KEY *ec_key) {
if (ec_key == NULL || EC_KEY_get0_group(ec_key) == NULL) {
- OPENSSL_PUT_ERROR(SSL, SSL_set_tmp_ecdh, ERR_R_PASSED_NULL_PARAMETER);
+ OPENSSL_PUT_ERROR(SSL, ERR_R_PASSED_NULL_PARAMETER);
return 0;
}
ssl->cert->ecdh_nid = EC_GROUP_get_curve_name(EC_KEY_get0_group(ec_key));
@@ -322,8 +326,7 @@ int SSL_CTX_set1_tls_channel_id(SSL_CTX *ctx, EVP_PKEY *private_key) {
ctx->tlsext_channel_id_enabled = 1;
if (EVP_PKEY_id(private_key) != EVP_PKEY_EC ||
EVP_PKEY_bits(private_key) != 256) {
- OPENSSL_PUT_ERROR(SSL, SSL_CTX_set1_tls_channel_id,
- SSL_R_CHANNEL_ID_NOT_P256);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_CHANNEL_ID_NOT_P256);
return 0;
}
EVP_PKEY_free(ctx->tlsext_channel_id_private);
@@ -335,7 +338,7 @@ int SSL_set1_tls_channel_id(SSL *ssl, EVP_PKEY *private_key) {
ssl->tlsext_channel_id_enabled = 1;
if (EVP_PKEY_id(private_key) != EVP_PKEY_EC ||
EVP_PKEY_bits(private_key) != 256) {
- OPENSSL_PUT_ERROR(SSL, SSL_set1_tls_channel_id, SSL_R_CHANNEL_ID_NOT_P256);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_CHANNEL_ID_NOT_P256);
return 0;
}
EVP_PKEY_free(ssl->tlsext_channel_id_private);
@@ -359,238 +362,36 @@ int SSL_set_tlsext_host_name(SSL *ssl, const char *name) {
return 1;
}
if (strlen(name) > TLSEXT_MAXLEN_host_name) {
- OPENSSL_PUT_ERROR(SSL, SSL_set_tlsext_host_name,
- SSL_R_SSL3_EXT_INVALID_SERVERNAME);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_SSL3_EXT_INVALID_SERVERNAME);
return 0;
}
ssl->tlsext_hostname = BUF_strdup(name);
if (ssl->tlsext_hostname == NULL) {
- OPENSSL_PUT_ERROR(SSL, SSL_set_tlsext_host_name, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
return 0;
}
return 1;
}
-long ssl3_ctrl(SSL *s, int cmd, long larg, void *parg) {
- int ret = 0;
-
- switch (cmd) {
- case SSL_CTRL_CHAIN:
- if (larg) {
- return ssl_cert_set1_chain(s->cert, (STACK_OF(X509) *)parg);
- } else {
- return ssl_cert_set0_chain(s->cert, (STACK_OF(X509) *)parg);
- }
-
- case SSL_CTRL_CHAIN_CERT:
- if (larg) {
- return ssl_cert_add1_chain_cert(s->cert, (X509 *)parg);
- } else {
- return ssl_cert_add0_chain_cert(s->cert, (X509 *)parg);
- }
-
- case SSL_CTRL_GET_CHAIN_CERTS:
- *(STACK_OF(X509) **)parg = s->cert->key->chain;
- ret = 1;
- break;
-
- case SSL_CTRL_SELECT_CURRENT_CERT:
- return ssl_cert_select_current(s->cert, (X509 *)parg);
-
- case SSL_CTRL_GET_CURVES: {
- const uint16_t *clist = s->s3->tmp.peer_ellipticcurvelist;
- size_t clistlen = s->s3->tmp.peer_ellipticcurvelist_length;
- if (parg) {
- size_t i;
- int *cptr = parg;
- int nid;
- for (i = 0; i < clistlen; i++) {
- nid = tls1_ec_curve_id2nid(clist[i]);
- if (nid != NID_undef) {
- cptr[i] = nid;
- } else {
- cptr[i] = TLSEXT_nid_unknown | clist[i];
- }
- }
- }
- return (int)clistlen;
- }
-
- case SSL_CTRL_SET_CURVES:
- return tls1_set_curves(&s->tlsext_ellipticcurvelist,
- &s->tlsext_ellipticcurvelist_length, parg, larg);
-
- case SSL_CTRL_SET_SIGALGS:
- return tls1_set_sigalgs(s->cert, parg, larg, 0);
-
- case SSL_CTRL_SET_CLIENT_SIGALGS:
- return tls1_set_sigalgs(s->cert, parg, larg, 1);
-
- case SSL_CTRL_GET_CLIENT_CERT_TYPES: {
- const uint8_t **pctype = parg;
- if (s->server || !s->s3->tmp.cert_req) {
- return 0;
- }
- if (pctype) {
- *pctype = s->s3->tmp.certificate_types;
- }
- return (int)s->s3->tmp.num_certificate_types;
- }
-
- case SSL_CTRL_SET_CLIENT_CERT_TYPES:
- if (!s->server) {
- return 0;
- }
- return ssl3_set_req_cert_type(s->cert, parg, larg);
-
- case SSL_CTRL_BUILD_CERT_CHAIN:
- return ssl_build_cert_chain(s->cert, s->ctx->cert_store, larg);
-
- case SSL_CTRL_SET_VERIFY_CERT_STORE:
- return ssl_cert_set_cert_store(s->cert, parg, 0, larg);
-
- case SSL_CTRL_SET_CHAIN_CERT_STORE:
- return ssl_cert_set_cert_store(s->cert, parg, 1, larg);
-
- case SSL_CTRL_GET_SERVER_TMP_KEY:
- if (s->server || !s->session || !s->session->sess_cert) {
- return 0;
- } else {
- SESS_CERT *sc;
- EVP_PKEY *ptmp;
- int rv = 0;
- sc = s->session->sess_cert;
- if (!sc->peer_dh_tmp && !sc->peer_ecdh_tmp) {
- return 0;
- }
- ptmp = EVP_PKEY_new();
- if (!ptmp) {
- return 0;
- }
- if (sc->peer_dh_tmp) {
- rv = EVP_PKEY_set1_DH(ptmp, sc->peer_dh_tmp);
- } else if (sc->peer_ecdh_tmp) {
- rv = EVP_PKEY_set1_EC_KEY(ptmp, sc->peer_ecdh_tmp);
- }
- if (rv) {
- *(EVP_PKEY **)parg = ptmp;
- return 1;
- }
- EVP_PKEY_free(ptmp);
- return 0;
- }
-
- case SSL_CTRL_GET_EC_POINT_FORMATS: {
- const uint8_t **pformat = parg;
- if (!s->s3->tmp.peer_ecpointformatlist) {
- return 0;
- }
- *pformat = s->s3->tmp.peer_ecpointformatlist;
- return (int)s->s3->tmp.peer_ecpointformatlist_length;
- }
-
- default:
- break;
+size_t SSL_get0_certificate_types(SSL *ssl, const uint8_t **out_types) {
+ if (ssl->server || !ssl->s3->tmp.cert_req) {
+ *out_types = NULL;
+ return 0;
}
-
- return ret;
+ *out_types = ssl->s3->tmp.certificate_types;
+ return ssl->s3->tmp.num_certificate_types;
}
-long ssl3_ctx_ctrl(SSL_CTX *ctx, int cmd, long larg, void *parg) {
- switch (cmd) {
- case SSL_CTRL_SET_TLSEXT_TICKET_KEYS:
- case SSL_CTRL_GET_TLSEXT_TICKET_KEYS: {
- uint8_t *keys = parg;
- if (!keys) {
- return 48;
- }
- if (larg != 48) {
- OPENSSL_PUT_ERROR(SSL, ssl3_ctx_ctrl, SSL_R_INVALID_TICKET_KEYS_LENGTH);
- return 0;
- }
- if (cmd == SSL_CTRL_SET_TLSEXT_TICKET_KEYS) {
- memcpy(ctx->tlsext_tick_key_name, keys, 16);
- memcpy(ctx->tlsext_tick_hmac_key, keys + 16, 16);
- memcpy(ctx->tlsext_tick_aes_key, keys + 32, 16);
- } else {
- memcpy(keys, ctx->tlsext_tick_key_name, 16);
- memcpy(keys + 16, ctx->tlsext_tick_hmac_key, 16);
- memcpy(keys + 32, ctx->tlsext_tick_aes_key, 16);
- }
- return 1;
- }
-
- case SSL_CTRL_SET_CURVES:
- return tls1_set_curves(&ctx->tlsext_ellipticcurvelist,
- &ctx->tlsext_ellipticcurvelist_length, parg, larg);
-
- case SSL_CTRL_SET_SIGALGS:
- return tls1_set_sigalgs(ctx->cert, parg, larg, 0);
-
- case SSL_CTRL_SET_CLIENT_SIGALGS:
- return tls1_set_sigalgs(ctx->cert, parg, larg, 1);
-
- case SSL_CTRL_SET_CLIENT_CERT_TYPES:
- return ssl3_set_req_cert_type(ctx->cert, parg, larg);
-
- case SSL_CTRL_BUILD_CERT_CHAIN:
- return ssl_build_cert_chain(ctx->cert, ctx->cert_store, larg);
-
- case SSL_CTRL_SET_VERIFY_CERT_STORE:
- return ssl_cert_set_cert_store(ctx->cert, parg, 0, larg);
-
- case SSL_CTRL_SET_CHAIN_CERT_STORE:
- return ssl_cert_set_cert_store(ctx->cert, parg, 1, larg);
-
- case SSL_CTRL_EXTRA_CHAIN_CERT:
- if (ctx->extra_certs == NULL) {
- ctx->extra_certs = sk_X509_new_null();
- if (ctx->extra_certs == NULL) {
- return 0;
- }
- }
- sk_X509_push(ctx->extra_certs, (X509 *)parg);
- break;
-
- case SSL_CTRL_GET_EXTRA_CHAIN_CERTS:
- if (ctx->extra_certs == NULL && larg == 0) {
- *(STACK_OF(X509) **)parg = ctx->cert->key->chain;
- } else {
- *(STACK_OF(X509) **)parg = ctx->extra_certs;
- }
- break;
-
- case SSL_CTRL_CLEAR_EXTRA_CHAIN_CERTS:
- sk_X509_pop_free(ctx->extra_certs, X509_free);
- ctx->extra_certs = NULL;
- break;
-
- case SSL_CTRL_CHAIN:
- if (larg) {
- return ssl_cert_set1_chain(ctx->cert, (STACK_OF(X509) *)parg);
- } else {
- return ssl_cert_set0_chain(ctx->cert, (STACK_OF(X509) *)parg);
- }
-
- case SSL_CTRL_CHAIN_CERT:
- if (larg) {
- return ssl_cert_add1_chain_cert(ctx->cert, (X509 *)parg);
- } else {
- return ssl_cert_add0_chain_cert(ctx->cert, (X509 *)parg);
- }
-
- case SSL_CTRL_GET_CHAIN_CERTS:
- *(STACK_OF(X509) **)parg = ctx->cert->key->chain;
- break;
-
- case SSL_CTRL_SELECT_CURRENT_CERT:
- return ssl_cert_select_current(ctx->cert, (X509 *)parg);
-
- default:
- return 0;
- }
+int SSL_CTX_set1_curves(SSL_CTX *ctx, const int *curves, size_t curves_len) {
+ return tls1_set_curves(&ctx->tlsext_ellipticcurvelist,
+ &ctx->tlsext_ellipticcurvelist_length, curves,
+ curves_len);
+}
- return 1;
+int SSL_set1_curves(SSL *ssl, const int *curves, size_t curves_len) {
+ return tls1_set_curves(&ssl->tlsext_ellipticcurvelist,
+ &ssl->tlsext_ellipticcurvelist_length, curves,
+ curves_len);
}
int SSL_CTX_set_tlsext_servername_callback(
@@ -604,6 +405,36 @@ int SSL_CTX_set_tlsext_servername_arg(SSL_CTX *ctx, void *arg) {
return 1;
}
+int SSL_CTX_get_tlsext_ticket_keys(SSL_CTX *ctx, void *out, size_t len) {
+ if (out == NULL) {
+ return 48;
+ }
+ if (len != 48) {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_TICKET_KEYS_LENGTH);
+ return 0;
+ }
+ uint8_t *out_bytes = out;
+ memcpy(out_bytes, ctx->tlsext_tick_key_name, 16);
+ memcpy(out_bytes + 16, ctx->tlsext_tick_hmac_key, 16);
+ memcpy(out_bytes + 32, ctx->tlsext_tick_aes_key, 16);
+ return 1;
+}
+
+int SSL_CTX_set_tlsext_ticket_keys(SSL_CTX *ctx, const void *in, size_t len) {
+ if (in == NULL) {
+ return 48;
+ }
+ if (len != 48) {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_TICKET_KEYS_LENGTH);
+ return 0;
+ }
+ const uint8_t *in_bytes = in;
+ memcpy(ctx->tlsext_tick_key_name, in_bytes, 16);
+ memcpy(ctx->tlsext_tick_hmac_key, in_bytes + 16, 16);
+ memcpy(ctx->tlsext_tick_aes_key, in_bytes + 32, 16);
+ return 1;
+}
+
int SSL_CTX_set_tlsext_ticket_key_cb(
SSL_CTX *ctx, int (*callback)(SSL *ssl, uint8_t *key_name, uint8_t *iv,
EVP_CIPHER_CTX *ctx, HMAC_CTX *hmac_ctx,
@@ -622,6 +453,11 @@ struct ssl_cipher_preference_list_st *ssl_get_cipher_preferences(SSL *s) {
return s->ctx->cipher_list_tls11;
}
+ if (s->version >= TLS1_VERSION && s->ctx != NULL &&
+ s->ctx->cipher_list_tls10 != NULL) {
+ return s->ctx->cipher_list_tls10;
+ }
+
if (s->ctx != NULL && s->ctx->cipher_list != NULL) {
return s->ctx->cipher_list;
}
@@ -708,13 +544,6 @@ int ssl3_get_req_cert_type(SSL *s, uint8_t *p) {
int have_rsa_sign = 0;
int have_ecdsa_sign = 0;
- /* If we have custom certificate types set, use them */
- if (s->cert->client_certificate_types) {
- memcpy(p, s->cert->client_certificate_types,
- s->cert->num_client_certificate_types);
- return s->cert->num_client_certificate_types;
- }
-
/* get configured sigalgs */
siglen = tls12_get_psigalgs(s, &sig);
for (i = 0; i < siglen; i += 2, sig += 2) {
@@ -742,36 +571,13 @@ int ssl3_get_req_cert_type(SSL *s, uint8_t *p) {
return ret;
}
-static int ssl3_set_req_cert_type(CERT *c, const uint8_t *p, size_t len) {
- OPENSSL_free(c->client_certificate_types);
- c->client_certificate_types = NULL;
- c->num_client_certificate_types = 0;
-
- if (!p || !len) {
- return 1;
- }
-
- if (len > 0xff) {
- return 0;
- }
-
- c->client_certificate_types = BUF_memdup(p, len);
- if (!c->client_certificate_types) {
- return 0;
- }
-
- c->num_client_certificate_types = len;
- return 1;
-}
-
/* If we are using default SHA1+MD5 algorithms switch to new SHA256 PRF and
* handshake macs if required. */
-uint32_t ssl_get_algorithm2(SSL *s) {
- static const uint32_t kMask = SSL_HANDSHAKE_MAC_DEFAULT;
- uint32_t alg2 = s->s3->tmp.new_cipher->algorithm2;
+uint32_t ssl_get_algorithm_prf(SSL *s) {
+ uint32_t algorithm_prf = s->s3->tmp.new_cipher->algorithm_prf;
if (s->enc_method->enc_flags & SSL_ENC_FLAG_SHA256_PRF &&
- (alg2 & kMask) == kMask) {
+ algorithm_prf == SSL_HANDSHAKE_MAC_DEFAULT) {
return SSL_HANDSHAKE_MAC_SHA256;
}
- return alg2;
+ return algorithm_prf;
}
diff --git a/src/ssl/s3_meth.c b/src/ssl/s3_meth.c
index 66bbb29..01c1101 100644
--- a/src/ssl/s3_meth.c
+++ b/src/ssl/s3_meth.c
@@ -54,6 +54,8 @@
* copied and put under another distribution licence
* [including the GNU Public Licence.] */
+#include <openssl/ssl.h>
+
#include "internal.h"
@@ -68,8 +70,6 @@ static const SSL_PROTOCOL_METHOD TLS_protocol_method = {
ssl3_read_close_notify,
ssl3_write_app_data,
ssl3_dispatch_alert,
- ssl3_ctrl,
- ssl3_ctx_ctrl,
ssl3_supports_cipher,
SSL3_HM_HEADER_LENGTH,
ssl3_set_handshake_header,
diff --git a/src/ssl/s3_pkt.c b/src/ssl/s3_pkt.c
index 4a9ae83..3c2435d 100644
--- a/src/ssl/s3_pkt.c
+++ b/src/ssl/s3_pkt.c
@@ -106,6 +106,8 @@
* (eay@cryptsoft.com). This product includes software written by Tim
* Hudson (tjh@cryptsoft.com). */
+#include <openssl/ssl.h>
+
#include <assert.h>
#include <limits.h>
#include <stdio.h>
@@ -120,282 +122,65 @@
#include "internal.h"
-static int do_ssl3_write(SSL *s, int type, const uint8_t *buf, unsigned int len,
- char fragment);
-static int ssl3_get_record(SSL *s);
+static int do_ssl3_write(SSL *s, int type, const uint8_t *buf, unsigned len);
-int ssl3_read_n(SSL *s, int n, int extend) {
- /* If |extend| is 0, obtain new n-byte packet;
- * if |extend| is 1, increase packet by another n bytes.
- *
- * The packet will be in the sub-array of |s->s3->rbuf.buf| specified by
- * |s->packet| and |s->packet_length|. (If DTLS and |extend| is 0, additional
- * bytes will be read into |rbuf|, up to the size of the buffer.)
- *
- * TODO(davidben): |dtls1_get_record| and |ssl3_get_record| have very
- * different needs. Separate the two record layers. In DTLS, |BIO_read| is
- * called at most once, and only when |extend| is 0. In TLS, the buffer never
- * contains more than one record. */
- int i, len, left;
- uintptr_t align = 0;
- uint8_t *pkt;
- SSL3_BUFFER *rb;
-
- if (n <= 0) {
- return n;
- }
+/* kMaxWarningAlerts is the number of consecutive warning alerts that will be
+ * processed. */
+static const uint8_t kMaxWarningAlerts = 4;
- rb = &s->s3->rbuf;
- if (rb->buf == NULL && !ssl3_setup_read_buffer(s)) {
- return -1;
- }
-
- left = rb->left;
-
- align = (uintptr_t)rb->buf + SSL3_RT_HEADER_LENGTH;
- align = (0 - align) & (SSL3_ALIGN_PAYLOAD - 1);
-
- if (!extend) {
- /* start with empty packet ... */
- if (left == 0) {
- rb->offset = align;
- } else if (align != 0 && left >= SSL3_RT_HEADER_LENGTH) {
- /* check if next packet length is large enough to justify payload
- * alignment... */
- pkt = rb->buf + rb->offset;
- if (pkt[0] == SSL3_RT_APPLICATION_DATA && (pkt[3] << 8 | pkt[4]) >= 128) {
- /* Note that even if packet is corrupted and its length field is
- * insane, we can only be led to wrong decision about whether memmove
- * will occur or not. Header values has no effect on memmove arguments
- * and therefore no buffer overrun can be triggered. */
- memmove(rb->buf + align, pkt, left);
- rb->offset = align;
+/* ssl3_get_record reads a new input record. On success, it places it in
+ * |ssl->s3->rrec| and returns one. Otherwise it returns <= 0 on error or if
+ * more data is needed. */
+static int ssl3_get_record(SSL *ssl) {
+ int ret;
+again:
+ /* Ensure the buffer is large enough to decrypt in-place. */
+ ret = ssl_read_buffer_extend_to(ssl, ssl_record_prefix_len(ssl));
+ if (ret <= 0) {
+ return ret;
+ }
+ assert(ssl_read_buffer_len(ssl) >= ssl_record_prefix_len(ssl));
+
+ uint8_t *out = ssl_read_buffer(ssl) + ssl_record_prefix_len(ssl);
+ size_t max_out = ssl_read_buffer_len(ssl) - ssl_record_prefix_len(ssl);
+ uint8_t type, alert;
+ size_t len, consumed;
+ switch (tls_open_record(ssl, &type, out, &len, &consumed, &alert, max_out,
+ ssl_read_buffer(ssl), ssl_read_buffer_len(ssl))) {
+ case ssl_open_record_success:
+ ssl_read_buffer_consume(ssl, consumed);
+
+ if (len > 0xffff) {
+ OPENSSL_PUT_ERROR(SSL, ERR_R_OVERFLOW);
+ return -1;
}
- }
- s->packet = rb->buf + rb->offset;
- s->packet_length = 0;
- /* ... now we can act as if 'extend' was set */
- }
-
- /* In DTLS, if there is leftover data from the previous packet or |extend| is
- * true, clamp to the previous read. DTLS records may not span packet
- * boundaries. */
- if (SSL_IS_DTLS(s) && n > left && (left > 0 || extend)) {
- n = left;
- }
- /* if there is enough in the buffer from a previous read, take some */
- if (left >= n) {
- s->packet_length += n;
- rb->left = left - n;
- rb->offset += n;
- return n;
- }
-
- /* else we need to read more data */
-
- len = s->packet_length;
- pkt = rb->buf + align;
- /* Move any available bytes to front of buffer: |len| bytes already pointed
- * to by |packet|, |left| extra ones at the end. */
- if (s->packet != pkt) {
- /* len > 0 */
- memmove(pkt, s->packet, len + left);
- s->packet = pkt;
- rb->offset = len + align;
- }
-
- if (n > (int)(rb->len - rb->offset)) {
- OPENSSL_PUT_ERROR(SSL, ssl3_read_n, ERR_R_INTERNAL_ERROR);
- return -1;
- }
-
- int max = n;
- if (SSL_IS_DTLS(s) && !extend) {
- max = rb->len - rb->offset;
- }
-
- while (left < n) {
- /* Now we have len+left bytes at the front of s->s3->rbuf.buf and need to
- * read in more until we have len+n (up to len+max if possible). */
- ERR_clear_system_error();
- if (s->rbio != NULL) {
- s->rwstate = SSL_READING;
- i = BIO_read(s->rbio, pkt + len + left, max - left);
- } else {
- OPENSSL_PUT_ERROR(SSL, ssl3_read_n, SSL_R_READ_BIO_NOT_SET);
- i = -1;
- }
-
- if (i <= 0) {
- rb->left = left;
- if (len + left == 0) {
- ssl3_release_read_buffer(s);
+ SSL3_RECORD *rr = &ssl->s3->rrec;
+ rr->type = type;
+ rr->length = (uint16_t)len;
+ rr->off = 0;
+ rr->data = out;
+ return 1;
+
+ case ssl_open_record_partial:
+ ret = ssl_read_buffer_extend_to(ssl, consumed);
+ if (ret <= 0) {
+ return ret;
}
- return i;
- }
- left += i;
- /* reads should *never* span multiple packets for DTLS because the
- * underlying transport protocol is message oriented as opposed to byte
- * oriented as in the TLS case. */
- if (SSL_IS_DTLS(s) && n > left) {
- n = left; /* makes the while condition false */
- }
- }
+ goto again;
- /* done reading, now the book-keeping */
- rb->offset += n;
- rb->left = left - n;
- s->packet_length += n;
- s->rwstate = SSL_NOTHING;
+ case ssl_open_record_discard:
+ ssl_read_buffer_consume(ssl, consumed);
+ goto again;
- return n;
-}
-
-/* MAX_EMPTY_RECORDS defines the number of consecutive, empty records that will
- * be processed per call to ssl3_get_record. Without this limit an attacker
- * could send empty records at a faster rate than we can process and cause
- * ssl3_get_record to loop forever. */
-#define MAX_EMPTY_RECORDS 32
-
-/* Call this to get a new input record. It will return <= 0 if more data is
- * needed, normally due to an error or non-blocking IO. When it finishes, one
- * packet has been decoded and can be found in
- * ssl->s3->rrec.type - is the type of record
- * ssl->s3->rrec.data - data
- * ssl->s3->rrec.length - number of bytes */
-/* used only by ssl3_read_bytes */
-static int ssl3_get_record(SSL *s) {
- uint8_t ssl_major, ssl_minor;
- int al, n, i, ret = -1;
- SSL3_RECORD *rr = &s->s3->rrec;
- uint8_t *p;
- uint16_t version;
- size_t extra;
- unsigned empty_record_count = 0;
-
-again:
- /* check if we have the header */
- if (s->rstate != SSL_ST_READ_BODY ||
- s->packet_length < SSL3_RT_HEADER_LENGTH) {
- n = ssl3_read_n(s, SSL3_RT_HEADER_LENGTH, 0);
- if (n <= 0) {
- return n; /* error or non-blocking */
- }
- s->rstate = SSL_ST_READ_BODY;
-
- /* Some bytes were read, so the read buffer must be existant and
- * |s->s3->init_extra| is defined. */
- assert(s->s3->rbuf.buf != NULL);
- extra = s->s3->init_extra ? SSL3_RT_MAX_EXTRA : 0;
-
- p = s->packet;
- if (s->msg_callback) {
- s->msg_callback(0, 0, SSL3_RT_HEADER, p, 5, s, s->msg_callback_arg);
- }
-
- /* Pull apart the header into the SSL3_RECORD */
- rr->type = *(p++);
- ssl_major = *(p++);
- ssl_minor = *(p++);
- version = (((uint16_t)ssl_major) << 8) | ssl_minor;
- n2s(p, rr->length);
-
- if (s->s3->have_version && version != s->version) {
- OPENSSL_PUT_ERROR(SSL, ssl3_get_record, SSL_R_WRONG_VERSION_NUMBER);
- al = SSL_AD_PROTOCOL_VERSION;
- goto f_err;
- }
-
- if ((version >> 8) != SSL3_VERSION_MAJOR) {
- OPENSSL_PUT_ERROR(SSL, ssl3_get_record, SSL_R_WRONG_VERSION_NUMBER);
- goto err;
- }
-
- if (rr->length > SSL3_RT_MAX_ENCRYPTED_LENGTH + extra) {
- al = SSL_AD_RECORD_OVERFLOW;
- OPENSSL_PUT_ERROR(SSL, ssl3_get_record, SSL_R_ENCRYPTED_LENGTH_TOO_LONG);
- goto f_err;
- }
-
- /* now s->rstate == SSL_ST_READ_BODY */
- } else {
- /* |packet_length| is non-zero and |s->rstate| is |SSL_ST_READ_BODY|. The
- * read buffer must be existant and |s->s3->init_extra| is defined. */
- assert(s->s3->rbuf.buf != NULL);
- extra = s->s3->init_extra ? SSL3_RT_MAX_EXTRA : 0;
- }
-
- /* s->rstate == SSL_ST_READ_BODY, get and decode the data */
-
- if (rr->length > s->packet_length - SSL3_RT_HEADER_LENGTH) {
- /* now s->packet_length == SSL3_RT_HEADER_LENGTH */
- i = rr->length;
- n = ssl3_read_n(s, i, 1);
- if (n <= 0) {
- /* Error or non-blocking IO. Now |n| == |rr->length|, and
- * |s->packet_length| == |SSL3_RT_HEADER_LENGTH| + |rr->length|. */
- return n;
- }
- }
-
- s->rstate = SSL_ST_READ_HEADER; /* set state for later operations */
-
- /* |rr->data| points to |rr->length| bytes of ciphertext in |s->packet|. */
- rr->data = &s->packet[SSL3_RT_HEADER_LENGTH];
-
- /* Decrypt the packet in-place.
- *
- * TODO(davidben): This assumes |s->version| is the same as the record-layer
- * version which isn't always true, but it only differs with the NULL cipher
- * which ignores the parameter. */
- size_t plaintext_len;
- if (!SSL_AEAD_CTX_open(s->aead_read_ctx, rr->data, &plaintext_len, rr->length,
- rr->type, s->version, s->s3->read_sequence, rr->data,
- rr->length)) {
- al = SSL_AD_BAD_RECORD_MAC;
- OPENSSL_PUT_ERROR(SSL, ssl3_get_record,
- SSL_R_DECRYPTION_FAILED_OR_BAD_RECORD_MAC);
- goto f_err;
- }
- if (!ssl3_record_sequence_update(s->s3->read_sequence, 8)) {
- goto err;
- }
- if (plaintext_len > SSL3_RT_MAX_PLAIN_LENGTH + extra) {
- al = SSL_AD_RECORD_OVERFLOW;
- OPENSSL_PUT_ERROR(SSL, ssl3_get_record, SSL_R_DATA_LENGTH_TOO_LONG);
- goto f_err;
- }
- assert(plaintext_len <= (1u << 16));
- rr->length = plaintext_len;
-
- rr->off = 0;
- /* So at this point the following is true:
- * ssl->s3->rrec.type is the type of record;
- * ssl->s3->rrec.length is the number of bytes in the record;
- * ssl->s3->rrec.off is the offset to first valid byte;
- * ssl->s3->rrec.data the first byte of the record body. */
-
- /* we have pulled in a full packet so zero things */
- s->packet_length = 0;
-
- /* just read a 0 length packet */
- if (rr->length == 0) {
- empty_record_count++;
- if (empty_record_count > MAX_EMPTY_RECORDS) {
- al = SSL_AD_UNEXPECTED_MESSAGE;
- OPENSSL_PUT_ERROR(SSL, ssl3_get_record, SSL_R_TOO_MANY_EMPTY_FRAGMENTS);
- goto f_err;
- }
- goto again;
+ case ssl_open_record_error:
+ ssl3_send_alert(ssl, SSL3_AL_FATAL, alert);
+ return -1;
}
- return 1;
-
-f_err:
- ssl3_send_alert(s, SSL3_AL_FATAL, al);
-err:
- return ret;
+ assert(0);
+ OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
+ return -1;
}
int ssl3_write_app_data(SSL *ssl, const void *buf, int len) {
@@ -420,7 +205,7 @@ int ssl3_write_bytes(SSL *s, int type, const void *buf_, int len) {
return i;
}
if (i == 0) {
- OPENSSL_PUT_ERROR(SSL, ssl3_write_bytes, SSL_R_SSL_HANDSHAKE_FAILURE);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_SSL_HANDSHAKE_FAILURE);
return -1;
}
}
@@ -433,33 +218,22 @@ int ssl3_write_bytes(SSL *s, int type, const void *buf_, int len) {
* beyond the end of the users buffer ... so we trap and report the error in
* a way the user will notice. */
if (len < 0 || (size_t)len < tot) {
- OPENSSL_PUT_ERROR(SSL, ssl3_write_bytes, SSL_R_BAD_LENGTH);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_LENGTH);
return -1;
}
- int record_split_done = 0;
n = (len - tot);
for (;;) {
/* max contains the maximum number of bytes that we can put into a
* record. */
unsigned max = s->max_send_fragment;
- /* fragment is true if do_ssl3_write should send the first byte in its own
- * record in order to randomise a CBC IV. */
- int fragment = 0;
- if (!record_split_done && s->s3->need_record_splitting &&
- type == SSL3_RT_APPLICATION_DATA) {
- /* Only the the first record per write call needs to be split. The
- * remaining plaintext was determined before the IV was randomized. */
- fragment = 1;
- record_split_done = 1;
- }
if (n > max) {
nw = max;
} else {
nw = n;
}
- i = do_ssl3_write(s, type, &buf[tot], nw, fragment);
+ i = do_ssl3_write(s, type, &buf[tot], nw);
if (i <= 0) {
s->s3->wnum = tot;
return i;
@@ -475,65 +249,10 @@ int ssl3_write_bytes(SSL *s, int type, const void *buf_, int len) {
}
}
-/* ssl3_seal_record seals a new record of type |type| and plaintext |in| and
- * writes it to |out|. At most |max_out| bytes will be written. It returns one
- * on success and zero on error. On success, it updates the write sequence
- * number. */
-static int ssl3_seal_record(SSL *s, uint8_t *out, size_t *out_len,
- size_t max_out, uint8_t type, const uint8_t *in,
- size_t in_len) {
- if (max_out < SSL3_RT_HEADER_LENGTH) {
- OPENSSL_PUT_ERROR(SSL, ssl3_seal_record, SSL_R_BUFFER_TOO_SMALL);
- return 0;
- }
-
- out[0] = type;
-
- /* Some servers hang if initial ClientHello is larger than 256 bytes and
- * record version number > TLS 1.0. */
- uint16_t wire_version = s->version;
- if (!s->s3->have_version && s->version > SSL3_VERSION) {
- wire_version = TLS1_VERSION;
- }
- out[1] = wire_version >> 8;
- out[2] = wire_version & 0xff;
-
- size_t ciphertext_len;
- if (!SSL_AEAD_CTX_seal(s->aead_write_ctx, out + SSL3_RT_HEADER_LENGTH,
- &ciphertext_len, max_out - SSL3_RT_HEADER_LENGTH,
- type, wire_version, s->s3->write_sequence, in,
- in_len) ||
- !ssl3_record_sequence_update(s->s3->write_sequence, 8)) {
- return 0;
- }
-
- if (ciphertext_len >= 1 << 16) {
- OPENSSL_PUT_ERROR(SSL, ssl3_seal_record, ERR_R_OVERFLOW);
- return 0;
- }
- out[3] = ciphertext_len >> 8;
- out[4] = ciphertext_len & 0xff;
-
- *out_len = SSL3_RT_HEADER_LENGTH + ciphertext_len;
-
- if (s->msg_callback) {
- s->msg_callback(1 /* write */, 0, SSL3_RT_HEADER, out, SSL3_RT_HEADER_LENGTH,
- s, s->msg_callback_arg);
- }
-
- return 1;
-}
-
-/* do_ssl3_write writes an SSL record of the given type. If |fragment| is 1
- * then it splits the record into a one byte record and a record with the rest
- * of the data in order to randomise a CBC IV. */
-static int do_ssl3_write(SSL *s, int type, const uint8_t *buf, unsigned int len,
- char fragment) {
- SSL3_BUFFER *wb = &s->s3->wbuf;
-
- /* first check if there is a SSL3_BUFFER still being written out. This will
- * happen with non blocking IO */
- if (wb->left != 0) {
+/* do_ssl3_write writes an SSL record of the given type. */
+static int do_ssl3_write(SSL *s, int type, const uint8_t *buf, unsigned len) {
+ /* If there is still data from the previous record, flush it. */
+ if (ssl_write_buffer_is_pending(s)) {
return ssl3_write_pending(s, type, buf, len);
}
@@ -546,113 +265,53 @@ static int do_ssl3_write(SSL *s, int type, const uint8_t *buf, unsigned int len,
/* if it went, fall through and send more stuff */
}
- if (wb->buf == NULL && !ssl3_setup_write_buffer(s)) {
+ if (len > SSL3_RT_MAX_PLAIN_LENGTH) {
+ OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
return -1;
}
if (len == 0) {
return 0;
}
- if (len == 1) {
- /* No sense in fragmenting a one-byte record. */
- fragment = 0;
- }
- /* Align the output so the ciphertext is aligned to |SSL3_ALIGN_PAYLOAD|. */
- uintptr_t align;
- if (fragment) {
- /* Only CBC-mode ciphers require fragmenting. CBC-mode ciphertext is a
- * multiple of the block size which we may assume is aligned. Thus we only
- * need to account for a second copy of the record header. */
- align = (uintptr_t)wb->buf + 2 * SSL3_RT_HEADER_LENGTH;
- } else {
- align = (uintptr_t)wb->buf + SSL3_RT_HEADER_LENGTH;
- }
- align = (0 - align) & (SSL3_ALIGN_PAYLOAD - 1);
- uint8_t *out = wb->buf + align;
- wb->offset = align;
- size_t max_out = wb->len - wb->offset;
-
- const uint8_t *orig_buf = buf;
- unsigned int orig_len = len;
- size_t fragment_len = 0;
- if (fragment) {
- /* Write the first byte in its own record as a countermeasure against
- * known-IV weaknesses in CBC ciphersuites. (See
- * http://www.openssl.org/~bodo/tls-cbc.txt.) */
- if (!ssl3_seal_record(s, out, &fragment_len, max_out, type, buf, 1)) {
- return -1;
- }
- out += fragment_len;
- max_out -= fragment_len;
- buf++;
- len--;
+ size_t max_out = len + ssl_max_seal_overhead(s);
+ if (max_out < len) {
+ OPENSSL_PUT_ERROR(SSL, ERR_R_OVERFLOW);
+ return -1;
}
-
- assert((((uintptr_t)out + SSL3_RT_HEADER_LENGTH) & (SSL3_ALIGN_PAYLOAD - 1))
- == 0);
+ uint8_t *out;
size_t ciphertext_len;
- if (!ssl3_seal_record(s, out, &ciphertext_len, max_out, type, buf, len)) {
+ if (!ssl_write_buffer_init(s, &out, max_out) ||
+ !tls_seal_record(s, out, &ciphertext_len, max_out, type, buf, len)) {
return -1;
}
- ciphertext_len += fragment_len;
-
- /* now let's set up wb */
- wb->left = ciphertext_len;
+ ssl_write_buffer_set_len(s, ciphertext_len);
/* memorize arguments so that ssl3_write_pending can detect bad write retries
* later */
- s->s3->wpend_tot = orig_len;
- s->s3->wpend_buf = orig_buf;
+ s->s3->wpend_tot = len;
+ s->s3->wpend_buf = buf;
s->s3->wpend_type = type;
- s->s3->wpend_ret = orig_len;
+ s->s3->wpend_ret = len;
/* we now just need to write the buffer */
- return ssl3_write_pending(s, type, orig_buf, orig_len);
+ return ssl3_write_pending(s, type, buf, len);
}
-/* if s->s3->wbuf.left != 0, we need to call this */
int ssl3_write_pending(SSL *s, int type, const uint8_t *buf, unsigned int len) {
- int i;
- SSL3_BUFFER *wb = &(s->s3->wbuf);
-
if (s->s3->wpend_tot > (int)len ||
(s->s3->wpend_buf != buf &&
!(s->mode & SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER)) ||
s->s3->wpend_type != type) {
- OPENSSL_PUT_ERROR(SSL, ssl3_write_pending, SSL_R_BAD_WRITE_RETRY);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_WRITE_RETRY);
return -1;
}
- for (;;) {
- ERR_clear_system_error();
- if (s->wbio != NULL) {
- s->rwstate = SSL_WRITING;
- i = BIO_write(s->wbio, (char *)&(wb->buf[wb->offset]),
- (unsigned int)wb->left);
- } else {
- OPENSSL_PUT_ERROR(SSL, ssl3_write_pending, SSL_R_BIO_NOT_SET);
- i = -1;
- }
- if (i == wb->left) {
- wb->left = 0;
- wb->offset += i;
- ssl3_release_write_buffer(s);
- s->rwstate = SSL_NOTHING;
- return s->s3->wpend_ret;
- } else if (i <= 0) {
- if (SSL_IS_DTLS(s)) {
- /* For DTLS, just drop it. That's kind of the whole point in
- * using a datagram service */
- wb->left = 0;
- }
- return i;
- }
- /* TODO(davidben): This codepath is used in DTLS, but the write
- * payload may not split across packets. */
- wb->offset += i;
- wb->left -= i;
+ int ret = ssl_write_buffer_flush(s);
+ if (ret <= 0) {
+ return ret;
}
+ return s->s3->wpend_ret;
}
/* ssl3_expect_change_cipher_spec informs the record layer that a
@@ -662,8 +321,7 @@ int ssl3_write_pending(SSL *s, int type, const uint8_t *buf, unsigned int len) {
* function returns zero. Otherwise, the function returns one. */
int ssl3_expect_change_cipher_spec(SSL *s) {
if (s->s3->handshake_fragment_len > 0 || s->s3->tmp.reuse_message) {
- OPENSSL_PUT_ERROR(SSL, ssl3_expect_change_cipher_spec,
- SSL_R_UNPROCESSED_HANDSHAKE_DATA);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_UNPROCESSED_HANDSHAKE_DATA);
return 0;
}
@@ -714,7 +372,7 @@ int ssl3_read_bytes(SSL *s, int type, uint8_t *buf, int len, int peek) {
if ((type && type != SSL3_RT_APPLICATION_DATA && type != SSL3_RT_HANDSHAKE) ||
(peek && type != SSL3_RT_APPLICATION_DATA)) {
- OPENSSL_PUT_ERROR(SSL, ssl3_read_bytes, ERR_R_INTERNAL_ERROR);
+ OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
return -1;
}
@@ -753,7 +411,7 @@ int ssl3_read_bytes(SSL *s, int type, uint8_t *buf, int len, int peek) {
return i;
}
if (i == 0) {
- OPENSSL_PUT_ERROR(SSL, ssl3_read_bytes, SSL_R_SSL_HANDSHAKE_FAILURE);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_SSL_HANDSHAKE_FAILURE);
return -1;
}
}
@@ -768,7 +426,7 @@ start:
rr = &s->s3->rrec;
/* get new packet if necessary */
- if (rr->length == 0 || s->rstate == SSL_ST_READ_BODY) {
+ if (rr->length == 0) {
ret = ssl3_get_record(s);
if (ret <= 0) {
return ret;
@@ -782,8 +440,7 @@ start:
if (s->s3->change_cipher_spec && rr->type != SSL3_RT_HANDSHAKE &&
rr->type != SSL3_RT_ALERT) {
al = SSL_AD_UNEXPECTED_MESSAGE;
- OPENSSL_PUT_ERROR(SSL, ssl3_read_bytes,
- SSL_R_DATA_BETWEEN_CCS_AND_FINISHED);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_DATA_BETWEEN_CCS_AND_FINISHED);
goto f_err;
}
@@ -791,7 +448,7 @@ start:
* Handshake record. */
if (rr->type == SSL3_RT_HANDSHAKE && (s->s3->flags & SSL3_FLAGS_EXPECT_CCS)) {
al = SSL_AD_UNEXPECTED_MESSAGE;
- OPENSSL_PUT_ERROR(SSL, ssl3_read_bytes, SSL_R_HANDSHAKE_RECORD_BEFORE_CCS);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_HANDSHAKE_RECORD_BEFORE_CCS);
goto f_err;
}
@@ -803,7 +460,9 @@ start:
return 0;
}
- if (type == rr->type) {
+ if (type != 0 && type == rr->type) {
+ s->s3->warning_alert_count = 0;
+
/* SSL3_RT_APPLICATION_DATA or SSL3_RT_HANDSHAKE */
/* make sure that we are not getting application data when we are doing a
* handshake for the first time */
@@ -812,10 +471,15 @@ start:
/* TODO(davidben): Is this check redundant with the handshake_func
* check? */
al = SSL_AD_UNEXPECTED_MESSAGE;
- OPENSSL_PUT_ERROR(SSL, ssl3_read_bytes, SSL_R_APP_DATA_IN_HANDSHAKE);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_APP_DATA_IN_HANDSHAKE);
goto f_err;
}
+ /* Discard empty records. */
+ if (rr->length == 0) {
+ goto start;
+ }
+
if (len <= 0) {
return len;
}
@@ -831,11 +495,9 @@ start:
rr->length -= n;
rr->off += n;
if (rr->length == 0) {
- s->rstate = SSL_ST_READ_HEADER;
rr->off = 0;
- if (s->s3->rbuf.left == 0) {
- ssl3_release_read_buffer(s);
- }
+ /* The record has been consumed, so we may now clear the buffer. */
+ ssl_read_buffer_discard(s);
}
}
@@ -849,7 +511,7 @@ start:
* are fatal. Renegotiations as a server are never supported. */
if (!s->accept_peer_renegotiations || s->server) {
al = SSL_AD_NO_RENEGOTIATION;
- OPENSSL_PUT_ERROR(SSL, ssl3_read_bytes, SSL_R_NO_RENEGOTIATION);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_NO_RENEGOTIATION);
goto f_err;
}
@@ -872,7 +534,7 @@ start:
s->s3->handshake_fragment[2] != 0 ||
s->s3->handshake_fragment[3] != 0) {
al = SSL_AD_DECODE_ERROR;
- OPENSSL_PUT_ERROR(SSL, ssl3_read_bytes, SSL_R_BAD_HELLO_REQUEST);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_HELLO_REQUEST);
goto f_err;
}
s->s3->handshake_fragment_len = 0;
@@ -886,7 +548,7 @@ start:
/* This cannot happen. If a handshake is in progress, |type| must be
* |SSL3_RT_HANDSHAKE|. */
assert(0);
- OPENSSL_PUT_ERROR(SSL, ssl3_read_bytes, ERR_R_INTERNAL_ERROR);
+ OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
goto err;
}
@@ -894,9 +556,9 @@ start:
* protocol, namely in HTTPS, just before reading the HTTP response. Require
* the record-layer be idle and avoid complexities of sending a handshake
* record while an application_data record is being written. */
- if (s->s3->wbuf.left != 0 || s->s3->rbuf.left != 0) {
+ if (ssl_write_buffer_is_pending(s)) {
al = SSL_AD_NO_RENEGOTIATION;
- OPENSSL_PUT_ERROR(SSL, ssl3_read_bytes, SSL_R_NO_RENEGOTIATION);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_NO_RENEGOTIATION);
goto f_err;
}
@@ -907,7 +569,7 @@ start:
return i;
}
if (i == 0) {
- OPENSSL_PUT_ERROR(SSL, ssl3_read_bytes, SSL_R_SSL_HANDSHAKE_FAILURE);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_SSL_HANDSHAKE_FAILURE);
return -1;
}
@@ -921,7 +583,7 @@ start:
/* Alerts may not be fragmented. */
if (rr->length < 2) {
al = SSL_AD_DECODE_ERROR;
- OPENSSL_PUT_ERROR(SSL, ssl3_read_bytes, SSL_R_BAD_ALERT);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_ALERT);
goto f_err;
}
@@ -960,7 +622,14 @@ start:
* peer refused it where we carry on. */
else if (alert_descr == SSL_AD_NO_RENEGOTIATION) {
al = SSL_AD_HANDSHAKE_FAILURE;
- OPENSSL_PUT_ERROR(SSL, ssl3_read_bytes, SSL_R_NO_RENEGOTIATION);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_NO_RENEGOTIATION);
+ goto f_err;
+ }
+
+ s->s3->warning_alert_count++;
+ if (s->s3->warning_alert_count > kMaxWarningAlerts) {
+ al = SSL_AD_UNEXPECTED_MESSAGE;
+ OPENSSL_PUT_ERROR(SSL, SSL_R_TOO_MANY_WARNING_ALERTS);
goto f_err;
}
} else if (alert_level == SSL3_AL_FATAL) {
@@ -968,8 +637,7 @@ start:
s->rwstate = SSL_NOTHING;
s->s3->fatal_alert = alert_descr;
- OPENSSL_PUT_ERROR(SSL, ssl3_read_bytes,
- SSL_AD_REASON_OFFSET + alert_descr);
+ OPENSSL_PUT_ERROR(SSL, SSL_AD_REASON_OFFSET + alert_descr);
BIO_snprintf(tmp, sizeof(tmp), "%d", alert_descr);
ERR_add_error_data(2, "SSL alert number ", tmp);
s->shutdown |= SSL_RECEIVED_SHUTDOWN;
@@ -977,7 +645,7 @@ start:
return 0;
} else {
al = SSL_AD_ILLEGAL_PARAMETER;
- OPENSSL_PUT_ERROR(SSL, ssl3_read_bytes, SSL_R_UNKNOWN_ALERT_TYPE);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_UNKNOWN_ALERT_TYPE);
goto f_err;
}
@@ -985,10 +653,9 @@ start:
}
if (s->shutdown & SSL_SENT_SHUTDOWN) {
- /* but we have not received a shutdown */
- s->rwstate = SSL_NOTHING;
+ /* close_notify has been sent, so discard all records other than alerts. */
rr->length = 0;
- return 0;
+ goto start;
}
if (rr->type == SSL3_RT_CHANGE_CIPHER_SPEC) {
@@ -996,20 +663,20 @@ start:
* record payload has to look like */
if (rr->length != 1 || rr->off != 0 || rr->data[0] != SSL3_MT_CCS) {
al = SSL_AD_ILLEGAL_PARAMETER;
- OPENSSL_PUT_ERROR(SSL, ssl3_read_bytes, SSL_R_BAD_CHANGE_CIPHER_SPEC);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_CHANGE_CIPHER_SPEC);
goto f_err;
}
/* Check we have a cipher to change to */
if (s->s3->tmp.new_cipher == NULL) {
al = SSL_AD_UNEXPECTED_MESSAGE;
- OPENSSL_PUT_ERROR(SSL, ssl3_read_bytes, SSL_R_CCS_RECEIVED_EARLY);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_CCS_RECEIVED_EARLY);
goto f_err;
}
if (!(s->s3->flags & SSL3_FLAGS_EXPECT_CCS)) {
al = SSL_AD_UNEXPECTED_MESSAGE;
- OPENSSL_PUT_ERROR(SSL, ssl3_read_bytes, SSL_R_CCS_RECEIVED_EARLY);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_CCS_RECEIVED_EARLY);
goto f_err;
}
@@ -1035,7 +702,7 @@ start:
rr->type != SSL3_RT_HANDSHAKE);
al = SSL_AD_UNEXPECTED_MESSAGE;
- OPENSSL_PUT_ERROR(SSL, ssl3_read_bytes, SSL_R_UNEXPECTED_RECORD);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_RECORD);
f_err:
ssl3_send_alert(s, SSL3_AL_FATAL, al);
@@ -1055,8 +722,7 @@ int ssl3_do_change_cipher_spec(SSL *s) {
if (s->s3->tmp.key_block == NULL) {
if (s->session == NULL || s->session->master_key_length == 0) {
/* might happen if dtls1_read_bytes() calls this */
- OPENSSL_PUT_ERROR(SSL, ssl3_do_change_cipher_spec,
- SSL_R_CCS_RECEIVED_EARLY);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_CCS_RECEIVED_EARLY);
return 0;
}
@@ -1092,8 +758,9 @@ int ssl3_send_alert(SSL *s, int level, int desc) {
s->s3->alert_dispatch = 1;
s->s3->send_alert[0] = level;
s->s3->send_alert[1] = desc;
- if (s->s3->wbuf.left == 0) {
- /* data is still being written out. */
+ if (!ssl_write_buffer_is_pending(s)) {
+ /* Nothing is being written out, so the alert may be dispatched
+ * immediately. */
return s->method->ssl_dispatch_alert(s);
}
@@ -1107,7 +774,7 @@ int ssl3_dispatch_alert(SSL *s) {
void (*cb)(const SSL *ssl, int type, int val) = NULL;
s->s3->alert_dispatch = 0;
- i = do_ssl3_write(s, SSL3_RT_ALERT, &s->s3->send_alert[0], 2, 0);
+ i = do_ssl3_write(s, SSL3_RT_ALERT, &s->s3->send_alert[0], 2);
if (i <= 0) {
s->s3->alert_dispatch = 1;
} else {
diff --git a/src/ssl/s3_srvr.c b/src/ssl/s3_srvr.c
index a72e17e..b428043 100644
--- a/src/ssl/s3_srvr.c
+++ b/src/ssl/s3_srvr.c
@@ -146,6 +146,8 @@
* OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR
* OTHERWISE. */
+#include <openssl/ssl.h>
+
#include <assert.h>
#include <stdio.h>
#include <string.h>
@@ -172,10 +174,6 @@
#include "../crypto/dh/internal.h"
-/* INITIAL_SNIFF_BUFFER_SIZE is the number of bytes read in the initial sniff
- * buffer. */
-#define INITIAL_SNIFF_BUFFER_SIZE 8
-
int ssl3_accept(SSL *s) {
BUF_MEM *buf = NULL;
uint32_t alg_a;
@@ -199,7 +197,7 @@ int ssl3_accept(SSL *s) {
s->in_handshake++;
if (s->cert == NULL) {
- OPENSSL_PUT_ERROR(SSL, ssl3_accept, SSL_R_NO_CERTIFICATE_SET);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_NO_CERTIFICATE_SET);
return -1;
}
@@ -230,8 +228,8 @@ int ssl3_accept(SSL *s) {
goto end;
}
- if (!ssl3_init_finished_mac(s)) {
- OPENSSL_PUT_ERROR(SSL, ssl3_accept, ERR_R_INTERNAL_ERROR);
+ if (!ssl3_init_handshake_buffer(s)) {
+ OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
ret = -1;
goto end;
}
@@ -310,8 +308,19 @@ int ssl3_accept(SSL *s) {
s->init_num = 0;
break;
+ case SSL3_ST_SW_CERT_STATUS_A:
+ case SSL3_ST_SW_CERT_STATUS_B:
+ ret = ssl3_send_certificate_status(s);
+ if (ret <= 0) {
+ goto end;
+ }
+ s->state = SSL3_ST_SW_KEY_EXCH_A;
+ s->init_num = 0;
+ break;
+
case SSL3_ST_SW_KEY_EXCH_A:
case SSL3_ST_SW_KEY_EXCH_B:
+ case SSL3_ST_SW_KEY_EXCH_C:
alg_a = s->s3->tmp.new_cipher->algorithm_auth;
/* Send a ServerKeyExchange message if:
@@ -473,7 +482,7 @@ int ssl3_accept(SSL *s) {
/* If this is a full handshake with ChannelID then record the hashshake
* hashes in |s->session| in case we need them to verify a ChannelID
* signature on a resumption of this session in the future. */
- if (!s->hit && s->s3->tlsext_channel_id_new) {
+ if (!s->hit) {
ret = tls1_record_handshake_hashes_for_channel_id(s);
if (ret <= 0) {
goto end;
@@ -550,6 +559,8 @@ int ssl3_accept(SSL *s) {
if (s->ctx->retain_only_sha256_of_client_certs) {
X509_free(s->session->peer);
s->session->peer = NULL;
+ sk_X509_pop_free(s->session->cert_chain, X509_free);
+ s->session->cert_chain = NULL;
}
s->s3->initial_handshake_complete = 1;
@@ -564,7 +575,7 @@ int ssl3_accept(SSL *s) {
goto end;
default:
- OPENSSL_PUT_ERROR(SSL, ssl3_accept, SSL_R_UNKNOWN_STATE);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_UNKNOWN_STATE);
ret = -1;
goto end;
}
@@ -587,42 +598,16 @@ end:
return ret;
}
-static int ssl3_read_sniff_buffer(SSL *s, size_t n) {
- if (s->s3->sniff_buffer == NULL) {
- s->s3->sniff_buffer = BUF_MEM_new();
- }
- if (s->s3->sniff_buffer == NULL || !BUF_MEM_grow(s->s3->sniff_buffer, n)) {
- return -1;
- }
-
- while (s->s3->sniff_buffer_len < n) {
- int ret;
-
- s->rwstate = SSL_READING;
- ret = BIO_read(s->rbio, s->s3->sniff_buffer->data + s->s3->sniff_buffer_len,
- n - s->s3->sniff_buffer_len);
- if (ret <= 0) {
- return ret;
- }
- s->rwstate = SSL_NOTHING;
- s->s3->sniff_buffer_len += ret;
- }
-
- return 1;
-}
-
int ssl3_get_initial_bytes(SSL *s) {
- int ret;
- const uint8_t *p;
-
- /* Read the first 8 bytes. To recognize a ClientHello or V2ClientHello only
- * needs the first 6 bytes, but 8 is needed to recognize CONNECT below. */
- ret = ssl3_read_sniff_buffer(s, INITIAL_SNIFF_BUFFER_SIZE);
+ /* Read the first 5 bytes, the size of the TLS record header. This is
+ * sufficient to detect a V2ClientHello and ensures that we never read beyond
+ * the first record. */
+ int ret = ssl_read_buffer_extend_to(s, SSL3_RT_HEADER_LENGTH);
if (ret <= 0) {
return ret;
}
- assert(s->s3->sniff_buffer_len >= INITIAL_SNIFF_BUFFER_SIZE);
- p = (const uint8_t *)s->s3->sniff_buffer->data;
+ assert(ssl_read_buffer_len(s) == SSL3_RT_HEADER_LENGTH);
+ const uint8_t *p = ssl_read_buffer(s);
/* Some dedicated error codes for protocol mixups should the application wish
* to interpret them differently. (These do not overlap with ClientHello or
@@ -631,46 +616,25 @@ int ssl3_get_initial_bytes(SSL *s) {
strncmp("POST ", (const char *)p, 5) == 0 ||
strncmp("HEAD ", (const char *)p, 5) == 0 ||
strncmp("PUT ", (const char *)p, 4) == 0) {
- OPENSSL_PUT_ERROR(SSL, ssl3_get_initial_bytes, SSL_R_HTTP_REQUEST);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_HTTP_REQUEST);
return -1;
}
- if (strncmp("CONNECT ", (const char *)p, 8) == 0) {
- OPENSSL_PUT_ERROR(SSL, ssl3_get_initial_bytes, SSL_R_HTTPS_PROXY_REQUEST);
+ if (strncmp("CONNE", (const char *)p, 5) == 0) {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_HTTPS_PROXY_REQUEST);
return -1;
}
- /* Determine if this is a ClientHello or V2ClientHello. */
+ /* Determine if this is a V2ClientHello. */
if ((p[0] & 0x80) && p[2] == SSL2_MT_CLIENT_HELLO &&
p[3] >= SSL3_VERSION_MAJOR) {
/* This is a V2ClientHello. */
s->state = SSL3_ST_SR_V2_CLIENT_HELLO;
return 1;
}
- if (p[0] == SSL3_RT_HANDSHAKE && p[1] >= SSL3_VERSION_MAJOR &&
- p[5] == SSL3_MT_CLIENT_HELLO) {
- /* This is a ClientHello. Initialize the record layer with the already
- * consumed data and continue the handshake. */
- if (!ssl3_setup_read_buffer(s)) {
- return -1;
- }
- assert(s->rstate == SSL_ST_READ_HEADER);
- /* There cannot have already been data in the record layer. */
- assert(s->s3->rbuf.left == 0);
- memcpy(s->s3->rbuf.buf, p, s->s3->sniff_buffer_len);
- s->s3->rbuf.offset = 0;
- s->s3->rbuf.left = s->s3->sniff_buffer_len;
- s->packet_length = 0;
-
- BUF_MEM_free(s->s3->sniff_buffer);
- s->s3->sniff_buffer = NULL;
- s->s3->sniff_buffer_len = 0;
-
- s->state = SSL3_ST_SR_CLNT_HELLO_A;
- return 1;
- }
- OPENSSL_PUT_ERROR(SSL, ssl3_get_initial_bytes, SSL_R_UNKNOWN_PROTOCOL);
- return -1;
+ /* Fall through to the standard logic. */
+ s->state = SSL3_ST_SR_CLNT_HELLO_A;
+ return 1;
}
int ssl3_get_v2_client_hello(SSL *s) {
@@ -683,36 +647,34 @@ int ssl3_get_v2_client_hello(SSL *s) {
CBB client_hello, hello_body, cipher_suites;
uint8_t random[SSL3_RANDOM_SIZE];
- /* Read the remainder of the V2ClientHello. We have previously read 8 bytes
- * in ssl3_get_initial_bytes. */
- assert(s->s3->sniff_buffer_len >= INITIAL_SNIFF_BUFFER_SIZE);
- p = (const uint8_t *)s->s3->sniff_buffer->data;
+ /* Determine the length of the V2ClientHello. */
+ assert(ssl_read_buffer_len(s) >= SSL3_RT_HEADER_LENGTH);
+ p = ssl_read_buffer(s);
msg_length = ((p[0] & 0x7f) << 8) | p[1];
if (msg_length > (1024 * 4)) {
- OPENSSL_PUT_ERROR(SSL, ssl3_get_v2_client_hello, SSL_R_RECORD_TOO_LARGE);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_RECORD_TOO_LARGE);
return -1;
}
- if (msg_length < INITIAL_SNIFF_BUFFER_SIZE - 2) {
- /* Reject lengths that are too short early. We have already read 8 bytes,
- * so we should not attempt to process an (invalid) V2ClientHello which
- * would be shorter than that. */
- OPENSSL_PUT_ERROR(SSL, ssl3_get_v2_client_hello,
- SSL_R_RECORD_LENGTH_MISMATCH);
+ if (msg_length < SSL3_RT_HEADER_LENGTH - 2) {
+ /* Reject lengths that are too short early. We have already read
+ * |SSL3_RT_HEADER_LENGTH| bytes, so we should not attempt to process an
+ * (invalid) V2ClientHello which would be shorter than that. */
+ OPENSSL_PUT_ERROR(SSL, SSL_R_RECORD_LENGTH_MISMATCH);
return -1;
}
- ret = ssl3_read_sniff_buffer(s, msg_length + 2);
+ /* Read the remainder of the V2ClientHello. */
+ ret = ssl_read_buffer_extend_to(s, 2 + msg_length);
if (ret <= 0) {
return ret;
}
- assert(s->s3->sniff_buffer_len == msg_length + 2);
- CBS_init(&v2_client_hello, (const uint8_t *)s->s3->sniff_buffer->data + 2,
- msg_length);
+ assert(ssl_read_buffer_len(s) == msg_length + 2);
+ CBS_init(&v2_client_hello, ssl_read_buffer(s) + 2, msg_length);
- /* The V2ClientHello without the length is incorporated into the Finished
+ /* The V2ClientHello without the length is incorporated into the handshake
* hash. */
- if (!ssl3_finish_mac(s, CBS_data(&v2_client_hello),
- CBS_len(&v2_client_hello))) {
+ if (!ssl3_update_handshake_hash(s, CBS_data(&v2_client_hello),
+ CBS_len(&v2_client_hello))) {
return -1;
}
if (s->msg_callback) {
@@ -729,7 +691,7 @@ int ssl3_get_v2_client_hello(SSL *s) {
!CBS_get_bytes(&v2_client_hello, &session_id, session_id_length) ||
!CBS_get_bytes(&v2_client_hello, &challenge, challenge_length) ||
CBS_len(&v2_client_hello) != 0) {
- OPENSSL_PUT_ERROR(SSL, ssl3_get_v2_client_hello, SSL_R_DECODE_ERROR);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
return -1;
}
@@ -747,12 +709,10 @@ int ssl3_get_v2_client_hello(SSL *s) {
rand_len);
/* Write out an equivalent SSLv3 ClientHello. */
+ CBB_zero(&client_hello);
if (!CBB_init_fixed(&client_hello, (uint8_t *)s->init_buf->data,
- s->init_buf->max)) {
- OPENSSL_PUT_ERROR(SSL, ssl3_get_v2_client_hello, ERR_R_MALLOC_FAILURE);
- return -1;
- }
- if (!CBB_add_u8(&client_hello, SSL3_MT_CLIENT_HELLO) ||
+ s->init_buf->max) ||
+ !CBB_add_u8(&client_hello, SSL3_MT_CLIENT_HELLO) ||
!CBB_add_u24_length_prefixed(&client_hello, &hello_body) ||
!CBB_add_u16(&hello_body, version) ||
!CBB_add_bytes(&hello_body, random, SSL3_RANDOM_SIZE) ||
@@ -760,7 +720,7 @@ int ssl3_get_v2_client_hello(SSL *s) {
!CBB_add_u8(&hello_body, 0) ||
!CBB_add_u16_length_prefixed(&hello_body, &cipher_suites)) {
CBB_cleanup(&client_hello);
- OPENSSL_PUT_ERROR(SSL, ssl3_get_v2_client_hello, ERR_R_INTERNAL_ERROR);
+ OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
return -1;
}
@@ -769,7 +729,7 @@ int ssl3_get_v2_client_hello(SSL *s) {
uint32_t cipher_spec;
if (!CBS_get_u24(&cipher_specs, &cipher_spec)) {
CBB_cleanup(&client_hello);
- OPENSSL_PUT_ERROR(SSL, ssl3_get_v2_client_hello, SSL_R_DECODE_ERROR);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
return -1;
}
@@ -779,7 +739,7 @@ int ssl3_get_v2_client_hello(SSL *s) {
}
if (!CBB_add_u16(&cipher_suites, cipher_spec)) {
CBB_cleanup(&client_hello);
- OPENSSL_PUT_ERROR(SSL, ssl3_get_v2_client_hello, ERR_R_INTERNAL_ERROR);
+ OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
return -1;
}
}
@@ -788,7 +748,7 @@ int ssl3_get_v2_client_hello(SSL *s) {
if (!CBB_add_u8(&hello_body, 1) || !CBB_add_u8(&hello_body, 0) ||
!CBB_finish(&client_hello, NULL, &len)) {
CBB_cleanup(&client_hello);
- OPENSSL_PUT_ERROR(SSL, ssl3_get_v2_client_hello, ERR_R_INTERNAL_ERROR);
+ OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
return -1;
}
@@ -798,10 +758,9 @@ int ssl3_get_v2_client_hello(SSL *s) {
/* The handshake message header is 4 bytes. */
s->s3->tmp.message_size = len - 4;
- /* Drop the sniff buffer. */
- BUF_MEM_free(s->s3->sniff_buffer);
- s->s3->sniff_buffer = NULL;
- s->s3->sniff_buffer_len = 0;
+ /* Consume and discard the V2ClientHello. */
+ ssl_read_buffer_consume(s, 2 + msg_length);
+ ssl_read_buffer_discard(s);
return 1;
}
@@ -815,6 +774,7 @@ int ssl3_get_client_hello(SSL *s) {
CBS client_hello;
uint16_t client_version;
CBS client_random, session_id, cipher_suites, compression_methods;
+ SSL_SESSION *session = NULL;
/* We do this so that we will respond with our native type. If we are TLSv1
* and we get SSLv3, we will respond with TLSv1, This down switching should
@@ -847,8 +807,7 @@ int ssl3_get_client_hello(SSL *s) {
early_ctx.client_hello_len = n;
if (!ssl_early_callback_init(&early_ctx)) {
al = SSL_AD_DECODE_ERROR;
- OPENSSL_PUT_ERROR(SSL, ssl3_get_client_hello,
- SSL_R_CLIENTHELLO_PARSE_FAILED);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_CLIENTHELLO_PARSE_FAILED);
goto f_err;
}
@@ -863,8 +822,7 @@ int ssl3_get_client_hello(SSL *s) {
case -1:
/* Connection rejected. */
al = SSL_AD_ACCESS_DENIED;
- OPENSSL_PUT_ERROR(SSL, ssl3_get_client_hello,
- SSL_R_CONNECTION_REJECTED);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_CONNECTION_REJECTED);
goto f_err;
default:
@@ -875,7 +833,7 @@ int ssl3_get_client_hello(SSL *s) {
break;
default:
- OPENSSL_PUT_ERROR(SSL, ssl3_get_client_hello, SSL_R_UNKNOWN_STATE);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_UNKNOWN_STATE);
return -1;
}
@@ -885,7 +843,7 @@ int ssl3_get_client_hello(SSL *s) {
!CBS_get_u8_length_prefixed(&client_hello, &session_id) ||
CBS_len(&session_id) > SSL_MAX_SSL_SESSION_ID_LENGTH) {
al = SSL_AD_DECODE_ERROR;
- OPENSSL_PUT_ERROR(SSL, ssl3_get_client_hello, SSL_R_DECODE_ERROR);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
goto f_err;
}
@@ -902,7 +860,7 @@ int ssl3_get_client_hello(SSL *s) {
if (!CBS_get_u8_length_prefixed(&client_hello, &cookie) ||
CBS_len(&cookie) > DTLS1_COOKIE_LENGTH) {
al = SSL_AD_DECODE_ERROR;
- OPENSSL_PUT_ERROR(SSL, ssl3_get_client_hello, SSL_R_DECODE_ERROR);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
goto f_err;
}
}
@@ -916,7 +874,7 @@ int ssl3_get_client_hello(SSL *s) {
/* Select version to use */
uint16_t version = ssl3_get_mutual_version(s, client_version);
if (version == 0) {
- OPENSSL_PUT_ERROR(SSL, ssl3_get_client_hello, SSL_R_UNSUPPORTED_PROTOCOL);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_UNSUPPORTED_PROTOCOL);
s->version = s->client_version;
al = SSL_AD_PROTOCOL_VERSION;
goto f_err;
@@ -929,19 +887,23 @@ int ssl3_get_client_hello(SSL *s) {
s->s3->have_version = 1;
} else if (SSL_IS_DTLS(s) ? (s->client_version > s->version)
: (s->client_version < s->version)) {
- OPENSSL_PUT_ERROR(SSL, ssl3_get_client_hello, SSL_R_WRONG_VERSION_NUMBER);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_WRONG_VERSION_NUMBER);
al = SSL_AD_PROTOCOL_VERSION;
goto f_err;
}
s->hit = 0;
- int session_ret = ssl_get_prev_session(s, &early_ctx);
- if (session_ret == PENDING_SESSION) {
- s->rwstate = SSL_PENDING_SESSION;
- goto err;
- } else if (session_ret == -1) {
- goto err;
+ int send_new_ticket = 0;
+ switch (ssl_get_prev_session(s, &session, &send_new_ticket, &early_ctx)) {
+ case ssl_session_success:
+ break;
+ case ssl_session_error:
+ goto err;
+ case ssl_session_retry:
+ s->rwstate = SSL_PENDING_SESSION;
+ goto err;
}
+ s->tlsext_ticket_expected = send_new_ticket;
/* The EMS state is needed when making the resumption decision, but
* extensions are not normally parsed until later. This detects the EMS
@@ -956,34 +918,40 @@ int ssl3_get_client_hello(SSL *s) {
&ems_data, &ems_len) &&
ems_len == 0;
- if (session_ret == 1) {
- if (s->session->extended_master_secret &&
+ if (session != NULL) {
+ if (session->extended_master_secret &&
!have_extended_master_secret) {
/* A ClientHello without EMS that attempts to resume a session with EMS
* is fatal to the connection. */
al = SSL_AD_HANDSHAKE_FAILURE;
- OPENSSL_PUT_ERROR(SSL, ssl3_get_client_hello,
- SSL_R_RESUMED_EMS_SESSION_WITHOUT_EMS_EXTENSION);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_RESUMED_EMS_SESSION_WITHOUT_EMS_EXTENSION);
goto f_err;
}
s->hit =
/* Only resume if the session's version matches the negotiated version:
* most clients do not accept a mismatch. */
- s->version == s->session->ssl_version &&
+ s->version == session->ssl_version &&
/* If the client offers the EMS extension, but the previous session
* didn't use it, then negotiate a new session. */
- have_extended_master_secret == s->session->extended_master_secret;
+ have_extended_master_secret == session->extended_master_secret;
}
- if (!s->hit && !ssl_get_new_session(s, 1)) {
+ if (s->hit) {
+ /* Use the new session. */
+ SSL_SESSION_free(s->session);
+ s->session = session;
+ session = NULL;
+
+ s->verify_result = s->session->verify_result;
+ } else if (!ssl_get_new_session(s, 1)) {
goto err;
}
if (s->ctx->dos_protection_cb != NULL && s->ctx->dos_protection_cb(&early_ctx) == 0) {
/* Connection rejected for DOS reasons. */
al = SSL_AD_ACCESS_DENIED;
- OPENSSL_PUT_ERROR(SSL, ssl3_get_client_hello, SSL_R_CONNECTION_REJECTED);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_CONNECTION_REJECTED);
goto f_err;
}
@@ -993,7 +961,7 @@ int ssl3_get_client_hello(SSL *s) {
!CBS_get_u8_length_prefixed(&client_hello, &compression_methods) ||
CBS_len(&compression_methods) == 0) {
al = SSL_AD_DECODE_ERROR;
- OPENSSL_PUT_ERROR(SSL, ssl3_get_client_hello, SSL_R_DECODE_ERROR);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
goto f_err;
}
@@ -1020,8 +988,7 @@ int ssl3_get_client_hello(SSL *s) {
/* we need to have the cipher in the cipher list if we are asked to reuse
* it */
al = SSL_AD_ILLEGAL_PARAMETER;
- OPENSSL_PUT_ERROR(SSL, ssl3_get_client_hello,
- SSL_R_REQUIRED_CIPHER_MISSING);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_REQUIRED_CIPHER_MISSING);
goto f_err;
}
}
@@ -1030,15 +997,14 @@ int ssl3_get_client_hello(SSL *s) {
if (memchr(CBS_data(&compression_methods), 0,
CBS_len(&compression_methods)) == NULL) {
al = SSL_AD_ILLEGAL_PARAMETER;
- OPENSSL_PUT_ERROR(SSL, ssl3_get_client_hello,
- SSL_R_NO_COMPRESSION_SPECIFIED);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_NO_COMPRESSION_SPECIFIED);
goto f_err;
}
/* TLS extensions. */
if (s->version >= SSL3_VERSION &&
!ssl_parse_clienthello_tlsext(s, &client_hello)) {
- OPENSSL_PUT_ERROR(SSL, ssl3_get_client_hello, SSL_R_PARSE_TLSEXT);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_PARSE_TLSEXT);
goto err;
}
@@ -1046,13 +1012,13 @@ int ssl3_get_client_hello(SSL *s) {
if (CBS_len(&client_hello) != 0) {
/* wrong packet length */
al = SSL_AD_DECODE_ERROR;
- OPENSSL_PUT_ERROR(SSL, ssl3_get_client_hello, SSL_R_BAD_PACKET_LENGTH);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_PACKET_LENGTH);
goto f_err;
}
if (have_extended_master_secret != s->s3->tmp.extended_master_secret) {
al = SSL_AD_INTERNAL_ERROR;
- OPENSSL_PUT_ERROR(SSL, ssl3_get_client_hello, SSL_R_EMS_STATE_INCONSISTENT);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_EMS_STATE_INCONSISTENT);
goto f_err;
}
@@ -1060,7 +1026,7 @@ int ssl3_get_client_hello(SSL *s) {
if (!s->hit) {
if (ciphers == NULL) {
al = SSL_AD_ILLEGAL_PARAMETER;
- OPENSSL_PUT_ERROR(SSL, ssl3_get_client_hello, SSL_R_NO_CIPHERS_PASSED);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_NO_CIPHERS_PASSED);
goto f_err;
}
@@ -1069,7 +1035,7 @@ int ssl3_get_client_hello(SSL *s) {
int rv = s->cert->cert_cb(s, s->cert->cert_cb_arg);
if (rv == 0) {
al = SSL_AD_INTERNAL_ERROR;
- OPENSSL_PUT_ERROR(SSL, ssl3_get_client_hello, SSL_R_CERT_CB_ERROR);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_CERT_CB_ERROR);
goto f_err;
}
if (rv < 0) {
@@ -1082,7 +1048,7 @@ int ssl3_get_client_hello(SSL *s) {
if (c == NULL) {
al = SSL_AD_HANDSHAKE_FAILURE;
- OPENSSL_PUT_ERROR(SSL, ssl3_get_client_hello, SSL_R_NO_SHARED_CIPHER);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_NO_SHARED_CIPHER);
goto f_err;
}
s->s3->tmp.new_cipher = c;
@@ -1104,11 +1070,15 @@ int ssl3_get_client_hello(SSL *s) {
s->s3->tmp.cert_request = 0;
}
+ /* Now that the cipher is known, initialize the handshake hash. */
+ if (!ssl3_init_handshake_hash(s)) {
+ goto f_err;
+ }
+
/* In TLS 1.2, client authentication requires hashing the handshake transcript
* under a different hash. Otherwise, release the handshake buffer. */
- if ((!SSL_USE_SIGALGS(s) || !s->s3->tmp.cert_request) &&
- !ssl3_digest_cached_records(s, free_handshake_buffer)) {
- goto f_err;
+ if (!SSL_USE_SIGALGS(s) || !s->s3->tmp.cert_request) {
+ ssl3_free_handshake_buffer(s);
}
/* we now have the following setup;
@@ -1132,6 +1102,7 @@ int ssl3_get_client_hello(SSL *s) {
err:
sk_SSL_CIPHER_free(ciphers);
+ SSL_SESSION_free(session);
return ret;
}
@@ -1152,8 +1123,7 @@ int ssl3_send_server_hello(SSL *s) {
/* If this is a resumption and the original handshake didn't support
* ChannelID then we didn't record the original handshake hashes in the
* session and so cannot resume with ChannelIDs. */
- if (s->hit && s->s3->tlsext_channel_id_new &&
- s->session->original_handshake_hash_len == 0) {
+ if (s->hit && s->session->original_handshake_hash_len == 0) {
s->s3->tlsext_channel_id_valid = 0;
}
@@ -1167,7 +1137,7 @@ int ssl3_send_server_hello(SSL *s) {
/* Random stuff */
if (!ssl_fill_hello_random(s->s3->server_random, SSL3_RANDOM_SIZE,
1 /* server */)) {
- OPENSSL_PUT_ERROR(SSL, ssl3_send_server_hello, ERR_R_INTERNAL_ERROR);
+ OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
return -1;
}
memcpy(p, s->s3->server_random, SSL3_RANDOM_SIZE);
@@ -1191,7 +1161,7 @@ int ssl3_send_server_hello(SSL *s) {
sl = s->session->session_id_length;
if (sl > (int)sizeof(s->session->session_id)) {
- OPENSSL_PUT_ERROR(SSL, ssl3_send_server_hello, ERR_R_INTERNAL_ERROR);
+ OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
return -1;
}
*(p++) = sl;
@@ -1203,13 +1173,10 @@ int ssl3_send_server_hello(SSL *s) {
/* put the compression method */
*(p++) = 0;
- if (ssl_prepare_serverhello_tlsext(s) <= 0) {
- OPENSSL_PUT_ERROR(SSL, ssl3_send_server_hello, SSL_R_SERVERHELLO_TLSEXT);
- return -1;
- }
+
p = ssl_add_serverhello_tlsext(s, p, buf + SSL3_RT_MAX_PLAIN_LENGTH);
if (p == NULL) {
- OPENSSL_PUT_ERROR(SSL, ssl3_send_server_hello, ERR_R_INTERNAL_ERROR);
+ OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
return -1;
}
@@ -1225,6 +1192,32 @@ int ssl3_send_server_hello(SSL *s) {
return ssl_do_write(s);
}
+int ssl3_send_certificate_status(SSL *ssl) {
+ if (ssl->state == SSL3_ST_SW_CERT_STATUS_A) {
+ CBB out, ocsp_response;
+ size_t length;
+
+ CBB_zero(&out);
+ if (!CBB_init_fixed(&out, ssl_handshake_start(ssl),
+ ssl->init_buf->max - SSL_HM_HEADER_LENGTH(ssl)) ||
+ !CBB_add_u8(&out, TLSEXT_STATUSTYPE_ocsp) ||
+ !CBB_add_u24_length_prefixed(&out, &ocsp_response) ||
+ !CBB_add_bytes(&ocsp_response, ssl->ctx->ocsp_response,
+ ssl->ctx->ocsp_response_length) ||
+ !CBB_finish(&out, NULL, &length) ||
+ !ssl_set_handshake_header(ssl, SSL3_MT_CERTIFICATE_STATUS, length)) {
+ OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
+ CBB_cleanup(&out);
+ return -1;
+ }
+
+ ssl->state = SSL3_ST_SW_CERT_STATUS_B;
+ }
+
+ /* SSL3_ST_SW_CERT_STATUS_B */
+ return ssl_do_write(ssl);
+}
+
int ssl3_send_server_done(SSL *s) {
if (s->state == SSL3_ST_SW_SRVR_DONE_A) {
if (!ssl_set_handshake_header(s, SSL3_MT_SERVER_DONE, 0)) {
@@ -1246,7 +1239,8 @@ int ssl3_send_server_key_exchange(SSL *s) {
BN_CTX *bn_ctx = NULL;
const char *psk_identity_hint = NULL;
size_t psk_identity_hint_len = 0;
- EVP_PKEY *pkey;
+ size_t sig_len;
+ size_t max_sig_len;
uint8_t *p, *d;
int al, i;
uint32_t alg_k;
@@ -1254,11 +1248,26 @@ int ssl3_send_server_key_exchange(SSL *s) {
int n;
CERT *cert;
BIGNUM *r[4];
- int nr[4], kn;
+ int nr[4];
BUF_MEM *buf;
EVP_MD_CTX md_ctx;
+ if (s->state == SSL3_ST_SW_KEY_EXCH_C) {
+ return ssl_do_write(s);
+ }
+
+ if (ssl_cipher_has_server_public_key(s->s3->tmp.new_cipher)) {
+ if (!ssl_has_private_key(s)) {
+ al = SSL_AD_INTERNAL_ERROR;
+ goto f_err;
+ }
+ max_sig_len = ssl_private_key_max_signature_len(s);
+ } else {
+ max_sig_len = 0;
+ }
+
EVP_MD_CTX_init(&md_ctx);
+ enum ssl_private_key_result_t sign_result;
if (s->state == SSL3_ST_SW_KEY_EXCH_A) {
alg_k = s->s3->tmp.new_cipher->algorithm_mkey;
alg_a = s->s3->tmp.new_cipher->algorithm_auth;
@@ -1286,25 +1295,23 @@ int ssl3_send_server_key_exchange(SSL *s) {
}
if (dhp == NULL) {
al = SSL_AD_HANDSHAKE_FAILURE;
- OPENSSL_PUT_ERROR(SSL, ssl3_send_server_key_exchange,
- SSL_R_MISSING_TMP_DH_KEY);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_MISSING_TMP_DH_KEY);
goto f_err;
}
if (s->s3->tmp.dh != NULL) {
- OPENSSL_PUT_ERROR(SSL, ssl3_send_server_key_exchange,
- ERR_R_INTERNAL_ERROR);
+ OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
goto err;
}
dh = DHparams_dup(dhp);
if (dh == NULL) {
- OPENSSL_PUT_ERROR(SSL, ssl3_send_server_key_exchange, ERR_R_DH_LIB);
+ OPENSSL_PUT_ERROR(SSL, ERR_R_DH_LIB);
goto err;
}
s->s3->tmp.dh = dh;
if (!DH_generate_key(dh)) {
- OPENSSL_PUT_ERROR(SSL, ssl3_send_server_key_exchange, ERR_R_DH_LIB);
+ OPENSSL_PUT_ERROR(SSL, ERR_R_DH_LIB);
goto err;
}
@@ -1328,14 +1335,12 @@ int ssl3_send_server_key_exchange(SSL *s) {
}
if (nid == NID_undef) {
al = SSL_AD_HANDSHAKE_FAILURE;
- OPENSSL_PUT_ERROR(SSL, ssl3_send_server_key_exchange,
- SSL_R_MISSING_TMP_ECDH_KEY);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_MISSING_TMP_ECDH_KEY);
goto f_err;
}
if (s->s3->tmp.ecdh != NULL) {
- OPENSSL_PUT_ERROR(SSL, ssl3_send_server_key_exchange,
- ERR_R_INTERNAL_ERROR);
+ OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
goto err;
}
ecdh = EC_KEY_new_by_curve_name(nid);
@@ -1345,15 +1350,14 @@ int ssl3_send_server_key_exchange(SSL *s) {
s->s3->tmp.ecdh = ecdh;
if (!EC_KEY_generate_key(ecdh)) {
- OPENSSL_PUT_ERROR(SSL, ssl3_send_server_key_exchange, ERR_R_ECDH_LIB);
+ OPENSSL_PUT_ERROR(SSL, ERR_R_ECDH_LIB);
goto err;
}
/* We only support ephemeral ECDH keys over named (not generic) curves. */
const EC_GROUP *group = EC_KEY_get0_group(ecdh);
if (!tls1_ec_nid2curve_id(&curve_id, EC_GROUP_get_curve_name(group))) {
- OPENSSL_PUT_ERROR(SSL, ssl3_send_server_key_exchange,
- SSL_R_UNSUPPORTED_ELLIPTIC_CURVE);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_UNSUPPORTED_ELLIPTIC_CURVE);
goto err;
}
@@ -1366,8 +1370,7 @@ int ssl3_send_server_key_exchange(SSL *s) {
encodedPoint = (uint8_t *)OPENSSL_malloc(encodedlen * sizeof(uint8_t));
bn_ctx = BN_CTX_new();
if (encodedPoint == NULL || bn_ctx == NULL) {
- OPENSSL_PUT_ERROR(SSL, ssl3_send_server_key_exchange,
- ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
goto err;
}
@@ -1376,7 +1379,7 @@ int ssl3_send_server_key_exchange(SSL *s) {
encodedPoint, encodedlen, bn_ctx);
if (encodedlen == 0) {
- OPENSSL_PUT_ERROR(SSL, ssl3_send_server_key_exchange, ERR_R_ECDH_LIB);
+ OPENSSL_PUT_ERROR(SSL, ERR_R_ECDH_LIB);
goto err;
}
@@ -1396,8 +1399,7 @@ int ssl3_send_server_key_exchange(SSL *s) {
r[3] = NULL;
} else if (!(alg_k & SSL_kPSK)) {
al = SSL_AD_HANDSHAKE_FAILURE;
- OPENSSL_PUT_ERROR(SSL, ssl3_send_server_key_exchange,
- SSL_R_UNKNOWN_KEY_EXCHANGE_TYPE);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_UNKNOWN_KEY_EXCHANGE_TYPE);
goto f_err;
}
@@ -1406,20 +1408,8 @@ int ssl3_send_server_key_exchange(SSL *s) {
n += 2 + nr[i];
}
- if (ssl_cipher_has_server_public_key(s->s3->tmp.new_cipher)) {
- pkey = ssl_get_sign_pkey(s, s->s3->tmp.new_cipher);
- if (pkey == NULL) {
- al = SSL_AD_DECODE_ERROR;
- goto f_err;
- }
- kn = EVP_PKEY_size(pkey);
- } else {
- pkey = NULL;
- kn = 0;
- }
-
- if (!BUF_MEM_grow_clean(buf, n + SSL_HM_HEADER_LENGTH(s) + kn)) {
- OPENSSL_PUT_ERROR(SSL, ssl3_send_server_key_exchange, ERR_LIB_BUF);
+ if (!BUF_MEM_grow_clean(buf, n + SSL_HM_HEADER_LENGTH(s) + max_sig_len)) {
+ OPENSSL_PUT_ERROR(SSL, ERR_LIB_BUF);
goto err;
}
d = p = ssl_handshake_start(s);
@@ -1458,54 +1448,81 @@ int ssl3_send_server_key_exchange(SSL *s) {
encodedPoint = NULL;
}
- /* not anonymous */
- if (pkey != NULL) {
- /* n is the length of the params, they start at &(d[4]) and p points to
+ if (ssl_cipher_has_server_public_key(s->s3->tmp.new_cipher)) {
+ /* n is the length of the params, they start at d and p points to
* the space at the end. */
const EVP_MD *md;
- size_t sig_len = EVP_PKEY_size(pkey);
+ uint8_t digest[EVP_MAX_MD_SIZE];
+ unsigned int digest_length;
+
+ const int pkey_type = ssl_private_key_type(s);
/* Determine signature algorithm. */
if (SSL_USE_SIGALGS(s)) {
- md = tls1_choose_signing_digest(s, pkey);
- if (!tls12_get_sigandhash(p, pkey, md)) {
+ md = tls1_choose_signing_digest(s);
+ if (!tls12_get_sigandhash(s, p, md)) {
/* Should never happen */
al = SSL_AD_INTERNAL_ERROR;
- OPENSSL_PUT_ERROR(SSL, ssl3_send_server_key_exchange,
- ERR_R_INTERNAL_ERROR);
+ OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
goto f_err;
}
p += 2;
- } else if (pkey->type == EVP_PKEY_RSA) {
+ } else if (pkey_type == EVP_PKEY_RSA) {
md = EVP_md5_sha1();
} else {
md = EVP_sha1();
}
- if (!EVP_DigestSignInit(&md_ctx, NULL, md, NULL, pkey) ||
- !EVP_DigestSignUpdate(&md_ctx, s->s3->client_random,
- SSL3_RANDOM_SIZE) ||
- !EVP_DigestSignUpdate(&md_ctx, s->s3->server_random,
- SSL3_RANDOM_SIZE) ||
- !EVP_DigestSignUpdate(&md_ctx, d, n) ||
- !EVP_DigestSignFinal(&md_ctx, &p[2], &sig_len)) {
- OPENSSL_PUT_ERROR(SSL, ssl3_send_server_key_exchange, ERR_LIB_EVP);
+ if (!EVP_DigestInit_ex(&md_ctx, md, NULL) ||
+ !EVP_DigestUpdate(&md_ctx, s->s3->client_random, SSL3_RANDOM_SIZE) ||
+ !EVP_DigestUpdate(&md_ctx, s->s3->server_random, SSL3_RANDOM_SIZE) ||
+ !EVP_DigestUpdate(&md_ctx, d, n) ||
+ !EVP_DigestFinal_ex(&md_ctx, digest, &digest_length)) {
+ OPENSSL_PUT_ERROR(SSL, ERR_LIB_EVP);
goto err;
}
- s2n(sig_len, p);
- n += sig_len + 2;
- if (SSL_USE_SIGALGS(s)) {
- n += 2;
- }
+ sign_result = ssl_private_key_sign(s, &p[2], &sig_len, max_sig_len,
+ EVP_MD_CTX_md(&md_ctx), digest,
+ digest_length);
+ } else {
+ /* This key exchange doesn't involve a signature. */
+ sign_result = ssl_private_key_success;
+ sig_len = 0;
}
+ } else {
+ assert(s->state == SSL3_ST_SW_KEY_EXCH_B);
+ /* Restore |p|. */
+ p = ssl_handshake_start(s) + s->init_num - SSL_HM_HEADER_LENGTH(s);
+ sign_result = ssl_private_key_sign_complete(s, &p[2], &sig_len,
+ max_sig_len);
+ }
- if (!ssl_set_handshake_header(s, SSL3_MT_SERVER_KEY_EXCHANGE, n)) {
+ switch (sign_result) {
+ case ssl_private_key_success:
+ s->rwstate = SSL_NOTHING;
+ break;
+ case ssl_private_key_failure:
+ s->rwstate = SSL_NOTHING;
+ goto err;
+ case ssl_private_key_retry:
+ s->rwstate = SSL_PRIVATE_KEY_OPERATION;
+ /* Stash away |p|. */
+ s->init_num = p - ssl_handshake_start(s) + SSL_HM_HEADER_LENGTH(s);
+ s->state = SSL3_ST_SW_KEY_EXCH_B;
goto err;
- }
}
- s->state = SSL3_ST_SW_KEY_EXCH_B;
+ if (ssl_cipher_has_server_public_key(s->s3->tmp.new_cipher)) {
+ s2n(sig_len, p);
+ p += sig_len;
+ }
+ if (!ssl_set_handshake_header(s, SSL3_MT_SERVER_KEY_EXCHANGE,
+ p - ssl_handshake_start(s))) {
+ goto err;
+ }
+ s->state = SSL3_ST_SW_KEY_EXCH_C;
+
EVP_MD_CTX_cleanup(&md_ctx);
return ssl_do_write(s);
@@ -1558,7 +1575,7 @@ int ssl3_send_certificate_request(SSL *s) {
name = sk_X509_NAME_value(sk, i);
j = i2d_X509_NAME(name, NULL);
if (!BUF_MEM_grow_clean(buf, SSL_HM_HEADER_LENGTH(s) + n + j + 2)) {
- OPENSSL_PUT_ERROR(SSL, ssl3_send_certificate_request, ERR_R_BUF_LIB);
+ OPENSSL_PUT_ERROR(SSL, ERR_R_BUF_LIB);
goto err;
}
p = ssl_handshake_start(s) + n;
@@ -1629,30 +1646,27 @@ int ssl3_get_client_key_exchange(SSL *s) {
* then this is the only field in the message. */
if (!CBS_get_u16_length_prefixed(&client_key_exchange, &psk_identity) ||
((alg_k & SSL_kPSK) && CBS_len(&client_key_exchange) != 0)) {
- OPENSSL_PUT_ERROR(SSL, ssl3_get_client_key_exchange, SSL_R_DECODE_ERROR);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
al = SSL_AD_DECODE_ERROR;
goto f_err;
}
if (s->psk_server_callback == NULL) {
- OPENSSL_PUT_ERROR(SSL, ssl3_get_client_key_exchange,
- SSL_R_PSK_NO_SERVER_CB);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_PSK_NO_SERVER_CB);
al = SSL_AD_INTERNAL_ERROR;
goto f_err;
}
if (CBS_len(&psk_identity) > PSK_MAX_IDENTITY_LEN ||
CBS_contains_zero_byte(&psk_identity)) {
- OPENSSL_PUT_ERROR(SSL, ssl3_get_client_key_exchange,
- SSL_R_DATA_LENGTH_TOO_LONG);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_DATA_LENGTH_TOO_LONG);
al = SSL_AD_ILLEGAL_PARAMETER;
goto f_err;
}
if (!CBS_strdup(&psk_identity, &s->session->psk_identity)) {
al = SSL_AD_INTERNAL_ERROR;
- OPENSSL_PUT_ERROR(SSL, ssl3_get_client_key_exchange,
- ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
goto f_err;
}
@@ -1660,14 +1674,12 @@ int ssl3_get_client_key_exchange(SSL *s) {
psk_len =
s->psk_server_callback(s, s->session->psk_identity, psk, sizeof(psk));
if (psk_len > PSK_MAX_PSK_LEN) {
- OPENSSL_PUT_ERROR(SSL, ssl3_get_client_key_exchange,
- ERR_R_INTERNAL_ERROR);
+ OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
al = SSL_AD_INTERNAL_ERROR;
goto f_err;
} else if (psk_len == 0) {
/* PSK related to the given identity not found */
- OPENSSL_PUT_ERROR(SSL, ssl3_get_client_key_exchange,
- SSL_R_PSK_IDENTITY_NOT_FOUND);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_PSK_IDENTITY_NOT_FOUND);
al = SSL_AD_UNKNOWN_PSK_IDENTITY;
goto f_err;
}
@@ -1681,11 +1693,10 @@ int ssl3_get_client_key_exchange(SSL *s) {
uint8_t good;
size_t rsa_size, decrypt_len, premaster_index, j;
- pkey = s->cert->pkeys[SSL_PKEY_RSA_ENC].privatekey;
+ pkey = s->cert->privatekey;
if (pkey == NULL || pkey->type != EVP_PKEY_RSA || pkey->pkey.rsa == NULL) {
al = SSL_AD_HANDSHAKE_FAILURE;
- OPENSSL_PUT_ERROR(SSL, ssl3_get_client_key_exchange,
- SSL_R_MISSING_RSA_CERTIFICATE);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_MISSING_RSA_CERTIFICATE);
goto f_err;
}
rsa = pkey->pkey.rsa;
@@ -1698,8 +1709,7 @@ int ssl3_get_client_key_exchange(SSL *s) {
CBS_len(&client_key_exchange) != 0) {
if (!(s->options & SSL_OP_TLS_D5_BUG)) {
al = SSL_AD_DECODE_ERROR;
- OPENSSL_PUT_ERROR(SSL, ssl3_get_client_key_exchange,
- SSL_R_TLS_RSA_ENCRYPTED_VALUE_LENGTH_IS_WRONG);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_TLS_RSA_ENCRYPTED_VALUE_LENGTH_IS_WRONG);
goto f_err;
} else {
encrypted_premaster_secret = copy;
@@ -1716,8 +1726,7 @@ int ssl3_get_client_key_exchange(SSL *s) {
rsa_size = RSA_size(rsa);
if (rsa_size < SSL_MAX_MASTER_KEY_LENGTH) {
al = SSL_AD_DECRYPT_ERROR;
- OPENSSL_PUT_ERROR(SSL, ssl3_get_client_key_exchange,
- SSL_R_DECRYPTION_FAILED);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_DECRYPTION_FAILED);
goto f_err;
}
@@ -1733,8 +1742,7 @@ int ssl3_get_client_key_exchange(SSL *s) {
/* Allocate a buffer large enough for an RSA decryption. */
decrypt_buf = OPENSSL_malloc(rsa_size);
if (decrypt_buf == NULL) {
- OPENSSL_PUT_ERROR(SSL, ssl3_get_client_key_exchange,
- ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
goto err;
}
@@ -1748,8 +1756,7 @@ int ssl3_get_client_key_exchange(SSL *s) {
if (decrypt_len != rsa_size) {
/* This should never happen, but do a check so we do not read
* uninitialized memory. */
- OPENSSL_PUT_ERROR(SSL, ssl3_get_client_key_exchange,
- ERR_R_INTERNAL_ERROR);
+ OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
goto err;
}
@@ -1772,8 +1779,7 @@ int ssl3_get_client_key_exchange(SSL *s) {
BUF_memdup(decrypt_buf + (rsa_size - SSL_MAX_MASTER_KEY_LENGTH),
SSL_MAX_MASTER_KEY_LENGTH);
if (premaster_secret == NULL) {
- OPENSSL_PUT_ERROR(SSL, ssl3_get_client_key_exchange,
- ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
goto err;
}
OPENSSL_free(decrypt_buf);
@@ -1804,38 +1810,35 @@ int ssl3_get_client_key_exchange(SSL *s) {
if (!CBS_get_u16_length_prefixed(&client_key_exchange, &dh_Yc) ||
CBS_len(&dh_Yc) == 0 || CBS_len(&client_key_exchange) != 0) {
- OPENSSL_PUT_ERROR(SSL, ssl3_get_client_key_exchange,
- SSL_R_DH_PUBLIC_VALUE_LENGTH_IS_WRONG);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_DH_PUBLIC_VALUE_LENGTH_IS_WRONG);
al = SSL_R_DECODE_ERROR;
goto f_err;
}
if (s->s3->tmp.dh == NULL) {
al = SSL_AD_HANDSHAKE_FAILURE;
- OPENSSL_PUT_ERROR(SSL, ssl3_get_client_key_exchange,
- SSL_R_MISSING_TMP_DH_KEY);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_MISSING_TMP_DH_KEY);
goto f_err;
}
dh_srvr = s->s3->tmp.dh;
pub = BN_bin2bn(CBS_data(&dh_Yc), CBS_len(&dh_Yc), NULL);
if (pub == NULL) {
- OPENSSL_PUT_ERROR(SSL, ssl3_get_client_key_exchange, SSL_R_BN_LIB);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_BN_LIB);
goto err;
}
/* Allocate a buffer for the premaster secret. */
premaster_secret = OPENSSL_malloc(DH_size(dh_srvr));
if (premaster_secret == NULL) {
- OPENSSL_PUT_ERROR(SSL, ssl3_get_client_key_exchange,
- ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
BN_clear_free(pub);
goto err;
}
dh_len = DH_compute_key(premaster_secret, pub, dh_srvr);
if (dh_len <= 0) {
- OPENSSL_PUT_ERROR(SSL, ssl3_get_client_key_exchange, ERR_R_DH_LIB);
+ OPENSSL_PUT_ERROR(SSL, ERR_R_DH_LIB);
BN_clear_free(pub);
goto err;
}
@@ -1856,8 +1859,7 @@ int ssl3_get_client_key_exchange(SSL *s) {
/* initialize structures for server's ECDH key pair */
srvr_ecdh = EC_KEY_new();
if (srvr_ecdh == NULL) {
- OPENSSL_PUT_ERROR(SSL, ssl3_get_client_key_exchange,
- ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
goto err;
}
@@ -1870,15 +1872,14 @@ int ssl3_get_client_key_exchange(SSL *s) {
if (!EC_KEY_set_group(srvr_ecdh, group) ||
!EC_KEY_set_private_key(srvr_ecdh, priv_key)) {
- OPENSSL_PUT_ERROR(SSL, ssl3_get_client_key_exchange, ERR_R_EC_LIB);
+ OPENSSL_PUT_ERROR(SSL, ERR_R_EC_LIB);
goto err;
}
/* Let's get client's public key */
clnt_ecpoint = EC_POINT_new(group);
if (clnt_ecpoint == NULL) {
- OPENSSL_PUT_ERROR(SSL, ssl3_get_client_key_exchange,
- ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
goto err;
}
@@ -1887,35 +1888,33 @@ int ssl3_get_client_key_exchange(SSL *s) {
if (!CBS_get_u8_length_prefixed(&client_key_exchange, &ecdh_Yc) ||
CBS_len(&client_key_exchange) != 0) {
al = SSL_AD_DECODE_ERROR;
- OPENSSL_PUT_ERROR(SSL, ssl3_get_client_key_exchange, SSL_R_DECODE_ERROR);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
goto f_err;
}
bn_ctx = BN_CTX_new();
if (bn_ctx == NULL) {
- OPENSSL_PUT_ERROR(SSL, ssl3_get_client_key_exchange,
- ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
goto err;
}
if (!EC_POINT_oct2point(group, clnt_ecpoint, CBS_data(&ecdh_Yc),
CBS_len(&ecdh_Yc), bn_ctx)) {
- OPENSSL_PUT_ERROR(SSL, ssl3_get_client_key_exchange, ERR_R_EC_LIB);
+ OPENSSL_PUT_ERROR(SSL, ERR_R_EC_LIB);
goto err;
}
/* Allocate a buffer for both the secret and the PSK. */
field_size = EC_GROUP_get_degree(group);
if (field_size <= 0) {
- OPENSSL_PUT_ERROR(SSL, ssl3_get_client_key_exchange, ERR_R_ECDH_LIB);
+ OPENSSL_PUT_ERROR(SSL, ERR_R_ECDH_LIB);
goto err;
}
ecdh_len = (field_size + 7) / 8;
premaster_secret = OPENSSL_malloc(ecdh_len);
if (premaster_secret == NULL) {
- OPENSSL_PUT_ERROR(SSL, ssl3_get_client_key_exchange,
- ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
goto err;
}
@@ -1923,7 +1922,7 @@ int ssl3_get_client_key_exchange(SSL *s) {
ecdh_len = ECDH_compute_key(premaster_secret, ecdh_len, clnt_ecpoint,
srvr_ecdh, NULL);
if (ecdh_len <= 0) {
- OPENSSL_PUT_ERROR(SSL, ssl3_get_client_key_exchange, ERR_R_ECDH_LIB);
+ OPENSSL_PUT_ERROR(SSL, ERR_R_ECDH_LIB);
goto err;
}
@@ -1945,15 +1944,13 @@ int ssl3_get_client_key_exchange(SSL *s) {
premaster_secret_len = psk_len;
premaster_secret = OPENSSL_malloc(premaster_secret_len);
if (premaster_secret == NULL) {
- OPENSSL_PUT_ERROR(SSL, ssl3_get_client_key_exchange,
- ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
goto err;
}
memset(premaster_secret, 0, premaster_secret_len);
} else {
al = SSL_AD_HANDSHAKE_FAILURE;
- OPENSSL_PUT_ERROR(SSL, ssl3_get_client_key_exchange,
- SSL_R_UNKNOWN_CIPHER_TYPE);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_UNKNOWN_CIPHER_TYPE);
goto f_err;
}
@@ -1964,18 +1961,14 @@ int ssl3_get_client_key_exchange(SSL *s) {
uint8_t *new_data;
size_t new_len;
- if (!CBB_init(&new_premaster, 2 + psk_len + 2 + premaster_secret_len)) {
- OPENSSL_PUT_ERROR(SSL, ssl3_get_client_key_exchange,
- ERR_R_MALLOC_FAILURE);
- goto err;
- }
- if (!CBB_add_u16_length_prefixed(&new_premaster, &child) ||
+ CBB_zero(&new_premaster);
+ if (!CBB_init(&new_premaster, 2 + psk_len + 2 + premaster_secret_len) ||
+ !CBB_add_u16_length_prefixed(&new_premaster, &child) ||
!CBB_add_bytes(&child, premaster_secret, premaster_secret_len) ||
!CBB_add_u16_length_prefixed(&new_premaster, &child) ||
!CBB_add_bytes(&child, psk, psk_len) ||
!CBB_finish(&new_premaster, &new_data, &new_len)) {
- OPENSSL_PUT_ERROR(SSL, ssl3_get_client_key_exchange,
- ERR_R_INTERNAL_ERROR);
+ OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
CBB_cleanup(&new_premaster);
goto err;
}
@@ -2031,10 +2024,7 @@ int ssl3_get_cert_verify(SSL *s) {
* CertificateVerify is required if and only if there's a client certificate.
* */
if (peer == NULL) {
- if (s->s3->handshake_buffer &&
- !ssl3_digest_cached_records(s, free_handshake_buffer)) {
- return -1;
- }
+ ssl3_free_handshake_buffer(s);
return 1;
}
@@ -2055,8 +2045,7 @@ int ssl3_get_cert_verify(SSL *s) {
if (!(X509_certificate_type(peer, pkey) & EVP_PKT_SIGN) ||
(pkey->type != EVP_PKEY_RSA && pkey->type != EVP_PKEY_EC)) {
al = SSL_AD_UNSUPPORTED_CERTIFICATE;
- OPENSSL_PUT_ERROR(SSL, ssl3_get_cert_verify,
- SSL_R_PEER_ERROR_UNSUPPORTED_CERTIFICATE_TYPE);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_PEER_ERROR_UNSUPPORTED_CERTIFICATE_TYPE);
goto f_err;
}
@@ -2069,16 +2058,13 @@ int ssl3_get_cert_verify(SSL *s) {
}
/* Compute the digest. */
- if (!ssl3_cert_verify_hash(s, digest, &digest_length, &md, pkey)) {
+ if (!ssl3_cert_verify_hash(s, digest, &digest_length, &md, pkey->type)) {
goto err;
}
/* The handshake buffer is no longer necessary, and we may hash the current
* message.*/
- if (s->s3->handshake_buffer &&
- !ssl3_digest_cached_records(s, free_handshake_buffer)) {
- goto err;
- }
+ ssl3_free_handshake_buffer(s);
if (!ssl3_hash_current_message(s)) {
goto err;
}
@@ -2087,7 +2073,7 @@ int ssl3_get_cert_verify(SSL *s) {
if (!CBS_get_u16_length_prefixed(&certificate_verify, &signature) ||
CBS_len(&certificate_verify) != 0) {
al = SSL_AD_DECODE_ERROR;
- OPENSSL_PUT_ERROR(SSL, ssl3_get_cert_verify, SSL_R_DECODE_ERROR);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
goto f_err;
}
@@ -2100,7 +2086,7 @@ int ssl3_get_cert_verify(SSL *s) {
!EVP_PKEY_verify(pctx, CBS_data(&signature), CBS_len(&signature), digest,
digest_length)) {
al = SSL_AD_DECRYPT_ERROR;
- OPENSSL_PUT_ERROR(SSL, ssl3_get_cert_verify, SSL_R_BAD_SIGNATURE);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_SIGNATURE);
goto f_err;
}
@@ -2137,15 +2123,14 @@ int ssl3_get_client_certificate(SSL *s) {
if (s->s3->tmp.message_type == SSL3_MT_CLIENT_KEY_EXCHANGE) {
if ((s->verify_mode & SSL_VERIFY_PEER) &&
(s->verify_mode & SSL_VERIFY_FAIL_IF_NO_PEER_CERT)) {
- OPENSSL_PUT_ERROR(SSL, ssl3_get_client_certificate,
- SSL_R_PEER_DID_NOT_RETURN_A_CERTIFICATE);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_PEER_DID_NOT_RETURN_A_CERTIFICATE);
al = SSL_AD_HANDSHAKE_FAILURE;
goto f_err;
}
/* If tls asked for a client cert, the client must return a 0 list */
if (s->version > SSL3_VERSION && s->s3->tmp.cert_request) {
- OPENSSL_PUT_ERROR(SSL, ssl3_get_client_certificate,
+ OPENSSL_PUT_ERROR(SSL,
SSL_R_TLS_PEER_DID_NOT_RESPOND_WITH_CERTIFICATE_LIST);
al = SSL_AD_UNEXPECTED_MESSAGE;
goto f_err;
@@ -2157,8 +2142,7 @@ int ssl3_get_client_certificate(SSL *s) {
if (s->s3->tmp.message_type != SSL3_MT_CERTIFICATE) {
al = SSL_AD_UNEXPECTED_MESSAGE;
- OPENSSL_PUT_ERROR(SSL, ssl3_get_client_certificate,
- SSL_R_WRONG_MESSAGE_TYPE);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_WRONG_MESSAGE_TYPE);
goto f_err;
}
@@ -2166,14 +2150,14 @@ int ssl3_get_client_certificate(SSL *s) {
sk = sk_X509_new_null();
if (sk == NULL) {
- OPENSSL_PUT_ERROR(SSL, ssl3_get_client_certificate, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
goto err;
}
if (!CBS_get_u24_length_prefixed(&certificate_msg, &certificate_list) ||
CBS_len(&certificate_msg) != 0) {
al = SSL_AD_DECODE_ERROR;
- OPENSSL_PUT_ERROR(SSL, ssl3_get_client_certificate, SSL_R_DECODE_ERROR);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
goto f_err;
}
@@ -2183,7 +2167,7 @@ int ssl3_get_client_certificate(SSL *s) {
if (!CBS_get_u24_length_prefixed(&certificate_list, &certificate)) {
al = SSL_AD_DECODE_ERROR;
- OPENSSL_PUT_ERROR(SSL, ssl3_get_client_certificate, SSL_R_DECODE_ERROR);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
goto f_err;
}
@@ -2201,50 +2185,42 @@ int ssl3_get_client_certificate(SSL *s) {
x = d2i_X509(NULL, &data, CBS_len(&certificate));
if (x == NULL) {
al = SSL_AD_BAD_CERTIFICATE;
- OPENSSL_PUT_ERROR(SSL, ssl3_get_client_certificate, ERR_R_ASN1_LIB);
+ OPENSSL_PUT_ERROR(SSL, ERR_R_ASN1_LIB);
goto f_err;
}
if (data != CBS_data(&certificate) + CBS_len(&certificate)) {
al = SSL_AD_DECODE_ERROR;
- OPENSSL_PUT_ERROR(SSL, ssl3_get_client_certificate,
- SSL_R_CERT_LENGTH_MISMATCH);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_CERT_LENGTH_MISMATCH);
goto f_err;
}
if (!sk_X509_push(sk, x)) {
- OPENSSL_PUT_ERROR(SSL, ssl3_get_client_certificate, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
goto err;
}
x = NULL;
}
if (sk_X509_num(sk) <= 0) {
+ /* No client certificate so the handshake buffer may be discarded. */
+ ssl3_free_handshake_buffer(s);
+
/* TLS does not mind 0 certs returned */
if (s->version == SSL3_VERSION) {
al = SSL_AD_HANDSHAKE_FAILURE;
- OPENSSL_PUT_ERROR(SSL, ssl3_get_client_certificate,
- SSL_R_NO_CERTIFICATES_RETURNED);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_NO_CERTIFICATES_RETURNED);
goto f_err;
- }
- /* Fail for TLS only if we required a certificate */
- else if ((s->verify_mode & SSL_VERIFY_PEER) &&
+ } else if ((s->verify_mode & SSL_VERIFY_PEER) &&
(s->verify_mode & SSL_VERIFY_FAIL_IF_NO_PEER_CERT)) {
- OPENSSL_PUT_ERROR(SSL, ssl3_get_client_certificate,
- SSL_R_PEER_DID_NOT_RETURN_A_CERTIFICATE);
+ /* Fail for TLS only if we required a certificate */
+ OPENSSL_PUT_ERROR(SSL, SSL_R_PEER_DID_NOT_RETURN_A_CERTIFICATE);
al = SSL_AD_HANDSHAKE_FAILURE;
goto f_err;
}
- /* No client certificate so digest cached records */
- if (s->s3->handshake_buffer &&
- !ssl3_digest_cached_records(s, free_handshake_buffer)) {
- al = SSL_AD_INTERNAL_ERROR;
- goto f_err;
- }
} else {
i = ssl_verify_cert_chain(s, sk);
if (i <= 0) {
al = ssl_verify_alarm_type(s->verify_result);
- OPENSSL_PUT_ERROR(SSL, ssl3_get_client_certificate,
- SSL_R_CERTIFICATE_VERIFY_FAILED);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_CERTIFICATE_VERIFY_FAILED);
goto f_err;
}
}
@@ -2253,17 +2229,8 @@ int ssl3_get_client_certificate(SSL *s) {
s->session->peer = sk_X509_shift(sk);
s->session->verify_result = s->verify_result;
- /* With the current implementation, sess_cert will always be NULL when we
- * arrive here. */
- if (s->session->sess_cert == NULL) {
- s->session->sess_cert = ssl_sess_cert_new();
- if (s->session->sess_cert == NULL) {
- OPENSSL_PUT_ERROR(SSL, ssl3_get_client_certificate, ERR_R_MALLOC_FAILURE);
- goto err;
- }
- }
- sk_X509_pop_free(s->session->sess_cert->cert_chain, X509_free);
- s->session->sess_cert->cert_chain = sk;
+ sk_X509_pop_free(s->session->cert_chain, X509_free);
+ s->session->cert_chain = sk;
/* Inconsistency alert: cert_chain does *not* include the peer's own
* certificate, while we do include it in s3_clnt.c */
@@ -2283,17 +2250,8 @@ err:
}
int ssl3_send_server_certificate(SSL *s) {
- CERT_PKEY *cpk;
-
if (s->state == SSL3_ST_SW_CERT_A) {
- cpk = ssl_get_server_send_pkey(s);
- if (cpk == NULL) {
- OPENSSL_PUT_ERROR(SSL, ssl3_send_server_certificate,
- ERR_R_INTERNAL_ERROR);
- return 0;
- }
-
- if (!ssl3_output_cert_chain(s, cpk)) {
+ if (!ssl3_output_cert_chain(s)) {
return 0;
}
s->state = SSL3_ST_SW_CERT_B;
@@ -2444,8 +2402,7 @@ int ssl3_get_next_proto(SSL *s) {
/* Clients cannot send a NextProtocol message if we didn't see the extension
* in their ClientHello */
if (!s->s3->next_proto_neg_seen) {
- OPENSSL_PUT_ERROR(SSL, ssl3_get_next_proto,
- SSL_R_GOT_NEXT_PROTO_WITHOUT_EXTENSION);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_GOT_NEXT_PROTO_WITHOUT_EXTENSION);
return -1;
}
@@ -2465,8 +2422,7 @@ int ssl3_get_next_proto(SSL *s) {
* TODO(davidben): Is this check now redundant with
* SSL3_FLAGS_EXPECT_CCS? */
if (!s->s3->change_cipher_spec) {
- OPENSSL_PUT_ERROR(SSL, ssl3_get_next_proto,
- SSL_R_GOT_NEXT_PROTO_BEFORE_A_CCS);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_GOT_NEXT_PROTO_BEFORE_A_CCS);
return -1;
}
@@ -2492,11 +2448,10 @@ int ssl3_get_next_proto(SSL *s) {
int ssl3_get_channel_id(SSL *s) {
int ret = -1, ok;
long n;
- EVP_MD_CTX md_ctx;
- uint8_t channel_id_hash[SHA256_DIGEST_LENGTH];
- unsigned int channel_id_hash_len;
+ uint8_t channel_id_hash[EVP_MAX_MD_SIZE];
+ size_t channel_id_hash_len;
const uint8_t *p;
- uint16_t extension_type, expected_extension_type;
+ uint16_t extension_type;
EC_GROUP *p256 = NULL;
EC_KEY *key = NULL;
EC_POINT *point = NULL;
@@ -2515,15 +2470,9 @@ int ssl3_get_channel_id(SSL *s) {
/* Before incorporating the EncryptedExtensions message to the handshake
* hash, compute the hash that should have been signed. */
- channel_id_hash_len = sizeof(channel_id_hash);
- EVP_MD_CTX_init(&md_ctx);
- if (!EVP_DigestInit_ex(&md_ctx, EVP_sha256(), NULL) ||
- !tls1_channel_id_hash(&md_ctx, s) ||
- !EVP_DigestFinal(&md_ctx, channel_id_hash, &channel_id_hash_len)) {
- EVP_MD_CTX_cleanup(&md_ctx);
+ if (!tls1_channel_id_hash(s, channel_id_hash, &channel_id_hash_len)) {
return -1;
}
- EVP_MD_CTX_cleanup(&md_ctx);
assert(channel_id_hash_len == SHA256_DIGEST_LENGTH);
if (!ssl3_hash_current_message(s)) {
@@ -2536,8 +2485,7 @@ int ssl3_get_channel_id(SSL *s) {
*
* TODO(davidben): Is this check now redundant with SSL3_FLAGS_EXPECT_CCS? */
if (!s->s3->change_cipher_spec) {
- OPENSSL_PUT_ERROR(SSL, ssl3_get_channel_id,
- SSL_R_GOT_CHANNEL_ID_BEFORE_A_CCS);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_GOT_CHANNEL_ID_BEFORE_A_CCS);
return -1;
}
@@ -2554,23 +2502,19 @@ int ssl3_get_channel_id(SSL *s) {
* uint8 y[32];
* uint8 r[32];
* uint8 s[32]; */
- expected_extension_type = TLSEXT_TYPE_channel_id;
- if (s->s3->tlsext_channel_id_new) {
- expected_extension_type = TLSEXT_TYPE_channel_id_new;
- }
if (!CBS_get_u16(&encrypted_extensions, &extension_type) ||
!CBS_get_u16_length_prefixed(&encrypted_extensions, &extension) ||
CBS_len(&encrypted_extensions) != 0 ||
- extension_type != expected_extension_type ||
+ extension_type != TLSEXT_TYPE_channel_id ||
CBS_len(&extension) != TLSEXT_CHANNEL_ID_SIZE) {
- OPENSSL_PUT_ERROR(SSL, ssl3_get_channel_id, SSL_R_INVALID_MESSAGE);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_MESSAGE);
return -1;
}
p256 = EC_GROUP_new_by_curve_name(NID_X9_62_prime256v1);
if (!p256) {
- OPENSSL_PUT_ERROR(SSL, ssl3_get_channel_id, SSL_R_NO_P256_SUPPORT);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_NO_P256_SUPPORT);
return -1;
}
@@ -2604,8 +2548,7 @@ int ssl3_get_channel_id(SSL *s) {
/* We stored the handshake hash in |tlsext_channel_id| the first time that we
* were called. */
if (!ECDSA_do_verify(channel_id_hash, channel_id_hash_len, &sig, key)) {
- OPENSSL_PUT_ERROR(SSL, ssl3_get_channel_id,
- SSL_R_CHANNEL_ID_SIGNATURE_INVALID);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_CHANNEL_ID_SIGNATURE_INVALID);
s->s3->tlsext_channel_id_valid = 0;
goto err;
}
diff --git a/src/ssl/ssl_aead_ctx.c b/src/ssl/ssl_aead_ctx.c
index c2fba1d..f9001c7 100644
--- a/src/ssl/ssl_aead_ctx.c
+++ b/src/ssl/ssl_aead_ctx.c
@@ -12,6 +12,8 @@
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
+#include <openssl/ssl.h>
+
#include <assert.h>
#include <string.h>
@@ -34,7 +36,7 @@ SSL_AEAD_CTX *SSL_AEAD_CTX_new(enum evp_aead_direction_t direction,
const EVP_AEAD *aead;
size_t discard;
if (!ssl_cipher_get_evp_aead(&aead, &discard, &discard, cipher, version)) {
- OPENSSL_PUT_ERROR(SSL, SSL_AEAD_CTX_new, ERR_R_INTERNAL_ERROR);
+ OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
return 0;
}
@@ -43,7 +45,7 @@ SSL_AEAD_CTX *SSL_AEAD_CTX_new(enum evp_aead_direction_t direction,
/* This is a "stateful" AEAD (for compatibility with pre-AEAD cipher
* suites). */
if (mac_key_len + enc_key_len + fixed_iv_len > sizeof(merged_key)) {
- OPENSSL_PUT_ERROR(SSL, SSL_AEAD_CTX_new, ERR_R_INTERNAL_ERROR);
+ OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
return 0;
}
memcpy(merged_key, mac_key, mac_key_len);
@@ -56,7 +58,7 @@ SSL_AEAD_CTX *SSL_AEAD_CTX_new(enum evp_aead_direction_t direction,
SSL_AEAD_CTX *aead_ctx = (SSL_AEAD_CTX *)OPENSSL_malloc(sizeof(SSL_AEAD_CTX));
if (aead_ctx == NULL) {
- OPENSSL_PUT_ERROR(SSL, SSL_AEAD_CTX_new, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
return NULL;
}
memset(aead_ctx, 0, sizeof(SSL_AEAD_CTX));
@@ -76,16 +78,17 @@ SSL_AEAD_CTX *SSL_AEAD_CTX_new(enum evp_aead_direction_t direction,
if (fixed_iv_len > sizeof(aead_ctx->fixed_nonce) ||
fixed_iv_len > aead_ctx->variable_nonce_len) {
SSL_AEAD_CTX_free(aead_ctx);
- OPENSSL_PUT_ERROR(SSL, SSL_AEAD_CTX_new, ERR_R_INTERNAL_ERROR);
+ OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
return 0;
}
aead_ctx->variable_nonce_len -= fixed_iv_len;
memcpy(aead_ctx->fixed_nonce, fixed_iv, fixed_iv_len);
aead_ctx->fixed_nonce_len = fixed_iv_len;
- aead_ctx->variable_nonce_included_in_record =
- (cipher->algorithm2 &
- SSL_CIPHER_ALGORITHM2_VARIABLE_NONCE_INCLUDED_IN_RECORD) != 0;
+ /* AES-GCM uses an explicit nonce. */
+ if (cipher->algorithm_enc & (SSL_AES128GCM | SSL_AES256GCM)) {
+ aead_ctx->variable_nonce_included_in_record = 1;
+ }
} else {
aead_ctx->variable_nonce_included_in_record = 1;
aead_ctx->random_variable_nonce = 1;
@@ -146,7 +149,7 @@ int SSL_AEAD_CTX_open(SSL_AEAD_CTX *aead, uint8_t *out, size_t *out_len,
if (aead == NULL) {
/* Handle the initial NULL cipher. */
if (in_len > max_out) {
- OPENSSL_PUT_ERROR(SSL, SSL_AEAD_CTX_open, SSL_R_BUFFER_TOO_SMALL);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_BUFFER_TOO_SMALL);
return 0;
}
memmove(out, in, in_len);
@@ -161,7 +164,7 @@ int SSL_AEAD_CTX_open(SSL_AEAD_CTX *aead, uint8_t *out, size_t *out_len,
size_t overhead = SSL_AEAD_CTX_max_overhead(aead);
if (in_len < overhead) {
/* Publicly invalid. */
- OPENSSL_PUT_ERROR(SSL, SSL_AEAD_CTX_open, SSL_R_BAD_PACKET_LENGTH);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_PACKET_LENGTH);
return 0;
}
plaintext_len = in_len - overhead;
@@ -178,7 +181,7 @@ int SSL_AEAD_CTX_open(SSL_AEAD_CTX *aead, uint8_t *out, size_t *out_len,
if (aead->variable_nonce_included_in_record) {
if (in_len < aead->variable_nonce_len) {
/* Publicly invalid. */
- OPENSSL_PUT_ERROR(SSL, SSL_AEAD_CTX_open, SSL_R_BAD_PACKET_LENGTH);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_PACKET_LENGTH);
return 0;
}
memcpy(nonce + nonce_len, in, aead->variable_nonce_len);
@@ -201,7 +204,7 @@ int SSL_AEAD_CTX_seal(SSL_AEAD_CTX *aead, uint8_t *out, size_t *out_len,
if (aead == NULL) {
/* Handle the initial NULL cipher. */
if (in_len > max_out) {
- OPENSSL_PUT_ERROR(SSL, SSL_AEAD_CTX_seal, SSL_R_BUFFER_TOO_SMALL);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_BUFFER_TOO_SMALL);
return 0;
}
memmove(out, in, in_len);
@@ -235,11 +238,11 @@ int SSL_AEAD_CTX_seal(SSL_AEAD_CTX *aead, uint8_t *out, size_t *out_len,
size_t extra_len = 0;
if (aead->variable_nonce_included_in_record) {
if (max_out < aead->variable_nonce_len) {
- OPENSSL_PUT_ERROR(SSL, SSL_AEAD_CTX_seal, SSL_R_BUFFER_TOO_SMALL);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_BUFFER_TOO_SMALL);
return 0;
}
if (out < in + in_len && in < out + aead->variable_nonce_len) {
- OPENSSL_PUT_ERROR(SSL, SSL_AEAD_CTX_seal, SSL_R_OUTPUT_ALIASES_INPUT);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_OUTPUT_ALIASES_INPUT);
return 0;
}
memcpy(out, nonce + aead->fixed_nonce_len, aead->variable_nonce_len);
diff --git a/src/ssl/ssl_asn1.c b/src/ssl/ssl_asn1.c
index 76052df..0d4760d 100644
--- a/src/ssl/ssl_asn1.c
+++ b/src/ssl/ssl_asn1.c
@@ -80,6 +80,8 @@
* OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR
* OTHERWISE. */
+#include <openssl/ssl.h>
+
#include <limits.h>
#include <string.h>
@@ -114,8 +116,10 @@
* signedCertTimestampList [15] OCTET STRING OPTIONAL,
* -- contents of SCT extension
* ocspResponse [16] OCTET STRING OPTIONAL,
- * -- stapled OCSP response from the server
+ * -- stapled OCSP response from the server
* extendedMasterSecret [17] BOOLEAN OPTIONAL,
+ * keyExchangeInfo [18] INTEGER OPTIONAL,
+ * certChain [19] SEQUENCE OF Certificate OPTIONAL,
* }
*
* Note: historically this serialization has included other optional
@@ -154,8 +158,28 @@ static const int kOCSPResponseTag =
CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 16;
static const int kExtendedMasterSecretTag =
CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 17;
+static const int kKeyExchangeInfoTag =
+ CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 18;
+static const int kCertChainTag =
+ CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 19;
+
+static int add_X509(CBB *cbb, X509 *x509) {
+ int len = i2d_X509(x509, NULL);
+ if (len < 0) {
+ return 0;
+ }
+ uint8_t *buf;
+ if (!CBB_add_space(cbb, &buf, len)) {
+ OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
+ return 0;
+ }
+ if (buf != NULL && i2d_X509(x509, &buf) < 0) {
+ return 0;
+ }
+ return 1;
+}
-static int SSL_SESSION_to_bytes_full(SSL_SESSION *in, uint8_t **out_data,
+static int SSL_SESSION_to_bytes_full(const SSL_SESSION *in, uint8_t **out_data,
size_t *out_len, int for_ticket) {
CBB cbb, session, child, child2;
@@ -163,11 +187,9 @@ static int SSL_SESSION_to_bytes_full(SSL_SESSION *in, uint8_t **out_data,
return 0;
}
- if (!CBB_init(&cbb, 0)) {
- return 0;
- }
-
- if (!CBB_add_asn1(&cbb, &session, CBS_ASN1_SEQUENCE) ||
+ CBB_zero(&cbb);
+ if (!CBB_init(&cbb, 0) ||
+ !CBB_add_asn1(&cbb, &session, CBS_ASN1_SEQUENCE) ||
!CBB_add_asn1_uint64(&session, SSL_SESSION_ASN1_VERSION) ||
!CBB_add_asn1_uint64(&session, in->ssl_version) ||
!CBB_add_asn1(&session, &child, CBS_ASN1_OCTETSTRING) ||
@@ -178,14 +200,14 @@ static int SSL_SESSION_to_bytes_full(SSL_SESSION *in, uint8_t **out_data,
for_ticket ? 0 : in->session_id_length) ||
!CBB_add_asn1(&session, &child, CBS_ASN1_OCTETSTRING) ||
!CBB_add_bytes(&child, in->master_key, in->master_key_length)) {
- OPENSSL_PUT_ERROR(SSL, SSL_SESSION_to_bytes_full, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
goto err;
}
if (in->time != 0) {
if (!CBB_add_asn1(&session, &child, kTimeTag) ||
!CBB_add_asn1_uint64(&child, in->time)) {
- OPENSSL_PUT_ERROR(SSL, SSL_SESSION_to_bytes_full, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
goto err;
}
}
@@ -193,7 +215,7 @@ static int SSL_SESSION_to_bytes_full(SSL_SESSION *in, uint8_t **out_data,
if (in->timeout != 0) {
if (!CBB_add_asn1(&session, &child, kTimeoutTag) ||
!CBB_add_asn1_uint64(&child, in->timeout)) {
- OPENSSL_PUT_ERROR(SSL, SSL_SESSION_to_bytes_full, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
goto err;
}
}
@@ -201,17 +223,11 @@ static int SSL_SESSION_to_bytes_full(SSL_SESSION *in, uint8_t **out_data,
/* The peer certificate is only serialized if the SHA-256 isn't
* serialized instead. */
if (in->peer && !in->peer_sha256_valid) {
- uint8_t *buf;
- int len = i2d_X509(in->peer, NULL);
- if (len < 0) {
- goto err;
- }
- if (!CBB_add_asn1(&session, &child, kPeerTag) ||
- !CBB_add_space(&child, &buf, len)) {
- OPENSSL_PUT_ERROR(SSL, SSL_SESSION_to_bytes_full, ERR_R_MALLOC_FAILURE);
+ if (!CBB_add_asn1(&session, &child, kPeerTag)) {
+ OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
goto err;
}
- if (buf != NULL && i2d_X509(in->peer, &buf) < 0) {
+ if (!add_X509(&child, in->peer)) {
goto err;
}
}
@@ -221,14 +237,14 @@ static int SSL_SESSION_to_bytes_full(SSL_SESSION *in, uint8_t **out_data,
if (!CBB_add_asn1(&session, &child, kSessionIDContextTag) ||
!CBB_add_asn1(&child, &child2, CBS_ASN1_OCTETSTRING) ||
!CBB_add_bytes(&child2, in->sid_ctx, in->sid_ctx_length)) {
- OPENSSL_PUT_ERROR(SSL, SSL_SESSION_to_bytes_full, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
goto err;
}
if (in->verify_result != X509_V_OK) {
if (!CBB_add_asn1(&session, &child, kVerifyResultTag) ||
!CBB_add_asn1_uint64(&child, in->verify_result)) {
- OPENSSL_PUT_ERROR(SSL, SSL_SESSION_to_bytes_full, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
goto err;
}
}
@@ -238,7 +254,7 @@ static int SSL_SESSION_to_bytes_full(SSL_SESSION *in, uint8_t **out_data,
!CBB_add_asn1(&child, &child2, CBS_ASN1_OCTETSTRING) ||
!CBB_add_bytes(&child2, (const uint8_t *)in->tlsext_hostname,
strlen(in->tlsext_hostname))) {
- OPENSSL_PUT_ERROR(SSL, SSL_SESSION_to_bytes_full, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
goto err;
}
}
@@ -248,7 +264,7 @@ static int SSL_SESSION_to_bytes_full(SSL_SESSION *in, uint8_t **out_data,
!CBB_add_asn1(&child, &child2, CBS_ASN1_OCTETSTRING) ||
!CBB_add_bytes(&child2, (const uint8_t *)in->psk_identity,
strlen(in->psk_identity))) {
- OPENSSL_PUT_ERROR(SSL, SSL_SESSION_to_bytes_full, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
goto err;
}
}
@@ -256,7 +272,7 @@ static int SSL_SESSION_to_bytes_full(SSL_SESSION *in, uint8_t **out_data,
if (in->tlsext_tick_lifetime_hint > 0) {
if (!CBB_add_asn1(&session, &child, kTicketLifetimeHintTag) ||
!CBB_add_asn1_uint64(&child, in->tlsext_tick_lifetime_hint)) {
- OPENSSL_PUT_ERROR(SSL, SSL_SESSION_to_bytes_full, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
goto err;
}
}
@@ -265,7 +281,7 @@ static int SSL_SESSION_to_bytes_full(SSL_SESSION *in, uint8_t **out_data,
if (!CBB_add_asn1(&session, &child, kTicketTag) ||
!CBB_add_asn1(&child, &child2, CBS_ASN1_OCTETSTRING) ||
!CBB_add_bytes(&child2, in->tlsext_tick, in->tlsext_ticklen)) {
- OPENSSL_PUT_ERROR(SSL, SSL_SESSION_to_bytes_full, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
goto err;
}
}
@@ -274,7 +290,7 @@ static int SSL_SESSION_to_bytes_full(SSL_SESSION *in, uint8_t **out_data,
if (!CBB_add_asn1(&session, &child, kPeerSHA256Tag) ||
!CBB_add_asn1(&child, &child2, CBS_ASN1_OCTETSTRING) ||
!CBB_add_bytes(&child2, in->peer_sha256, sizeof(in->peer_sha256))) {
- OPENSSL_PUT_ERROR(SSL, SSL_SESSION_to_bytes_full, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
goto err;
}
}
@@ -284,7 +300,7 @@ static int SSL_SESSION_to_bytes_full(SSL_SESSION *in, uint8_t **out_data,
!CBB_add_asn1(&child, &child2, CBS_ASN1_OCTETSTRING) ||
!CBB_add_bytes(&child2, in->original_handshake_hash,
in->original_handshake_hash_len)) {
- OPENSSL_PUT_ERROR(SSL, SSL_SESSION_to_bytes_full, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
goto err;
}
}
@@ -294,7 +310,7 @@ static int SSL_SESSION_to_bytes_full(SSL_SESSION *in, uint8_t **out_data,
!CBB_add_asn1(&child, &child2, CBS_ASN1_OCTETSTRING) ||
!CBB_add_bytes(&child2, in->tlsext_signed_cert_timestamp_list,
in->tlsext_signed_cert_timestamp_list_length)) {
- OPENSSL_PUT_ERROR(SSL, SSL_SESSION_to_bytes_full, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
goto err;
}
}
@@ -303,7 +319,7 @@ static int SSL_SESSION_to_bytes_full(SSL_SESSION *in, uint8_t **out_data,
if (!CBB_add_asn1(&session, &child, kOCSPResponseTag) ||
!CBB_add_asn1(&child, &child2, CBS_ASN1_OCTETSTRING) ||
!CBB_add_bytes(&child2, in->ocsp_response, in->ocsp_response_length)) {
- OPENSSL_PUT_ERROR(SSL, SSL_SESSION_to_bytes_full, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
goto err;
}
}
@@ -312,13 +328,35 @@ static int SSL_SESSION_to_bytes_full(SSL_SESSION *in, uint8_t **out_data,
if (!CBB_add_asn1(&session, &child, kExtendedMasterSecretTag) ||
!CBB_add_asn1(&child, &child2, CBS_ASN1_BOOLEAN) ||
!CBB_add_u8(&child2, 0xff)) {
- OPENSSL_PUT_ERROR(SSL, SSL_SESSION_to_bytes_full, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
goto err;
}
}
+ if (in->key_exchange_info > 0 &&
+ (!CBB_add_asn1(&session, &child, kKeyExchangeInfoTag) ||
+ !CBB_add_asn1_uint64(&child, in->key_exchange_info))) {
+ OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+
+ /* The certificate chain is only serialized if the leaf's SHA-256 isn't
+ * serialized instead. */
+ if (in->cert_chain != NULL && !in->peer_sha256_valid) {
+ if (!CBB_add_asn1(&session, &child, kCertChainTag)) {
+ OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+ size_t i;
+ for (i = 0; i < sk_X509_num(in->cert_chain); i++) {
+ if (!add_X509(&child, sk_X509_value(in->cert_chain, i))) {
+ goto err;
+ }
+ }
+ }
+
if (!CBB_finish(&cbb, out_data, out_len)) {
- OPENSSL_PUT_ERROR(SSL, SSL_SESSION_to_bytes_full, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
goto err;
}
return 1;
@@ -328,11 +366,12 @@ static int SSL_SESSION_to_bytes_full(SSL_SESSION *in, uint8_t **out_data,
return 0;
}
-int SSL_SESSION_to_bytes(SSL_SESSION *in, uint8_t **out_data, size_t *out_len) {
+int SSL_SESSION_to_bytes(const SSL_SESSION *in, uint8_t **out_data,
+ size_t *out_len) {
return SSL_SESSION_to_bytes_full(in, out_data, out_len, 0);
}
-int SSL_SESSION_to_bytes_for_ticket(SSL_SESSION *in, uint8_t **out_data,
+int SSL_SESSION_to_bytes_for_ticket(const SSL_SESSION *in, uint8_t **out_data,
size_t *out_len) {
return SSL_SESSION_to_bytes_full(in, out_data, out_len, 1);
}
@@ -347,7 +386,7 @@ int i2d_SSL_SESSION(SSL_SESSION *in, uint8_t **pp) {
if (len > INT_MAX) {
OPENSSL_free(out);
- OPENSSL_PUT_ERROR(SSL, i2d_SSL_SESSION, ERR_R_OVERFLOW);
+ OPENSSL_PUT_ERROR(SSL, ERR_R_OVERFLOW);
return -1;
}
@@ -370,17 +409,16 @@ static int SSL_SESSION_parse_string(CBS *cbs, char **out, unsigned tag) {
CBS value;
int present;
if (!CBS_get_optional_asn1_octet_string(cbs, &value, &present, tag)) {
- OPENSSL_PUT_ERROR(SSL, SSL_SESSION_parse_string, SSL_R_INVALID_SSL_SESSION);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_SSL_SESSION);
return 0;
}
if (present) {
if (CBS_contains_zero_byte(&value)) {
- OPENSSL_PUT_ERROR(SSL, SSL_SESSION_parse_string,
- SSL_R_INVALID_SSL_SESSION);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_SSL_SESSION);
return 0;
}
if (!CBS_strdup(&value, out)) {
- OPENSSL_PUT_ERROR(SSL, SSL_SESSION_parse_string, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
return 0;
}
} else {
@@ -397,170 +435,168 @@ static int SSL_SESSION_parse_string(CBS *cbs, char **out, unsigned tag) {
* |*out_ptr| to NULL. It returns one on success, whether or not the
* element was found, and zero on decode error. */
static int SSL_SESSION_parse_octet_string(CBS *cbs, uint8_t **out_ptr,
- size_t *out_len, unsigned tag) {
+ size_t *out_len, unsigned tag) {
CBS value;
if (!CBS_get_optional_asn1_octet_string(cbs, &value, NULL, tag)) {
- OPENSSL_PUT_ERROR(SSL, SSL_SESSION_parse_octet_string,
- SSL_R_INVALID_SSL_SESSION);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_SSL_SESSION);
return 0;
}
if (!CBS_stow(&value, out_ptr, out_len)) {
- OPENSSL_PUT_ERROR(SSL, SSL_SESSION_parse_octet_string,
- ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
return 0;
}
return 1;
}
-static SSL_SESSION *SSL_SESSION_parse(CBS *cbs) {
- SSL_SESSION *ret = NULL;
- CBS session, cipher, session_id, master_key;
- CBS peer, sid_ctx, peer_sha256, original_handshake_hash;
- int has_peer, has_peer_sha256, extended_master_secret;
- uint64_t version, ssl_version;
- uint64_t session_time, timeout, verify_result, ticket_lifetime_hint;
-
- ret = SSL_SESSION_new();
- if (ret == NULL) {
- goto err;
+/* SSL_SESSION_parse_bounded_octet_string parses an optional ASN.1 OCTET STRING
+ * explicitly tagged with |tag| of size at most |max_out|. */
+static int SSL_SESSION_parse_bounded_octet_string(
+ CBS *cbs, uint8_t *out, unsigned *out_len, unsigned max_out, unsigned tag) {
+ CBS value;
+ if (!CBS_get_optional_asn1_octet_string(cbs, &value, NULL, tag) ||
+ CBS_len(&value) > max_out) {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_SSL_SESSION);
+ return 0;
}
+ memcpy(out, CBS_data(&value), CBS_len(&value));
+ *out_len = (unsigned)CBS_len(&value);
+ return 1;
+}
- if (!CBS_get_asn1(cbs, &session, CBS_ASN1_SEQUENCE) ||
- !CBS_get_asn1_uint64(&session, &version) ||
- !CBS_get_asn1_uint64(&session, &ssl_version) ||
- !CBS_get_asn1(&session, &cipher, CBS_ASN1_OCTETSTRING) ||
- !CBS_get_asn1(&session, &session_id, CBS_ASN1_OCTETSTRING) ||
- !CBS_get_asn1(&session, &master_key, CBS_ASN1_OCTETSTRING) ||
- !CBS_get_optional_asn1_uint64(&session, &session_time, kTimeTag,
- time(NULL)) ||
- !CBS_get_optional_asn1_uint64(&session, &timeout, kTimeoutTag, 3) ||
- !CBS_get_optional_asn1(&session, &peer, &has_peer, kPeerTag) ||
- !CBS_get_optional_asn1_octet_string(&session, &sid_ctx, NULL,
- kSessionIDContextTag) ||
- !CBS_get_optional_asn1_uint64(&session, &verify_result, kVerifyResultTag,
- X509_V_OK)) {
- OPENSSL_PUT_ERROR(SSL, SSL_SESSION_parse, SSL_R_INVALID_SSL_SESSION);
- goto err;
- }
- if (!SSL_SESSION_parse_string(&session, &ret->tlsext_hostname,
- kHostNameTag) ||
- !SSL_SESSION_parse_string(&session, &ret->psk_identity,
- kPSKIdentityTag)) {
- goto err;
- }
- if (!CBS_get_optional_asn1_uint64(&session, &ticket_lifetime_hint,
- kTicketLifetimeHintTag, 0)) {
- OPENSSL_PUT_ERROR(SSL, SSL_SESSION_parse, SSL_R_INVALID_SSL_SESSION);
- goto err;
- }
- if (!SSL_SESSION_parse_octet_string(&session, &ret->tlsext_tick,
- &ret->tlsext_ticklen, kTicketTag)) {
- goto err;
+static int SSL_SESSION_parse_long(CBS *cbs, long *out, unsigned tag,
+ long default_value) {
+ uint64_t value;
+ if (!CBS_get_optional_asn1_uint64(cbs, &value, tag,
+ (uint64_t)default_value) ||
+ value > LONG_MAX) {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_SSL_SESSION);
+ return 0;
}
- if (!CBS_get_optional_asn1_octet_string(&session, &peer_sha256,
- &has_peer_sha256, kPeerSHA256Tag) ||
- !CBS_get_optional_asn1_octet_string(&session, &original_handshake_hash,
- NULL, kOriginalHandshakeHashTag)) {
- OPENSSL_PUT_ERROR(SSL, SSL_SESSION_parse, SSL_R_INVALID_SSL_SESSION);
- goto err;
+ *out = (long)value;
+ return 1;
+}
+
+static int SSL_SESSION_parse_u32(CBS *cbs, uint32_t *out, unsigned tag,
+ uint32_t default_value) {
+ uint64_t value;
+ if (!CBS_get_optional_asn1_uint64(cbs, &value, tag,
+ (uint64_t)default_value) ||
+ value > 0xffffffff) {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_SSL_SESSION);
+ return 0;
}
- if (!SSL_SESSION_parse_octet_string(
- &session, &ret->tlsext_signed_cert_timestamp_list,
- &ret->tlsext_signed_cert_timestamp_list_length,
- kSignedCertTimestampListTag) ||
- !SSL_SESSION_parse_octet_string(
- &session, &ret->ocsp_response, &ret->ocsp_response_length,
- kOCSPResponseTag)) {
- goto err;
+ *out = (uint32_t)value;
+ return 1;
+}
+
+static X509 *parse_x509(CBS *cbs) {
+ const uint8_t *ptr = CBS_data(cbs);
+ X509 *ret = d2i_X509(NULL, &ptr, CBS_len(cbs));
+ if (ret == NULL) {
+ return NULL;
}
- if (!CBS_get_optional_asn1_bool(&session, &extended_master_secret,
- kExtendedMasterSecretTag,
- 0 /* default to false */) ||
- CBS_len(&session) != 0) {
- OPENSSL_PUT_ERROR(SSL, SSL_SESSION_parse, SSL_R_INVALID_SSL_SESSION);
+ CBS_skip(cbs, ptr - CBS_data(cbs));
+ return ret;
+}
+
+static SSL_SESSION *SSL_SESSION_parse(CBS *cbs) {
+ SSL_SESSION *ret = SSL_SESSION_new();
+ if (ret == NULL) {
goto err;
}
- ret->extended_master_secret = extended_master_secret;
- if (version != SSL_SESSION_ASN1_VERSION) {
- OPENSSL_PUT_ERROR(SSL, SSL_SESSION_parse, SSL_R_INVALID_SSL_SESSION);
+ CBS session;
+ uint64_t version, ssl_version;
+ if (!CBS_get_asn1(cbs, &session, CBS_ASN1_SEQUENCE) ||
+ !CBS_get_asn1_uint64(&session, &version) ||
+ version != SSL_SESSION_ASN1_VERSION ||
+ !CBS_get_asn1_uint64(&session, &ssl_version)) {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_SSL_SESSION);
goto err;
}
-
/* Only support SSLv3/TLS and DTLS. */
if ((ssl_version >> 8) != SSL3_VERSION_MAJOR &&
(ssl_version >> 8) != (DTLS1_VERSION >> 8)) {
- OPENSSL_PUT_ERROR(SSL, SSL_SESSION_parse, SSL_R_UNKNOWN_SSL_VERSION);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_UNKNOWN_SSL_VERSION);
goto err;
}
ret->ssl_version = ssl_version;
+ CBS cipher;
uint16_t cipher_value;
- if (!CBS_get_u16(&cipher, &cipher_value) || CBS_len(&cipher) != 0) {
- OPENSSL_PUT_ERROR(SSL, SSL_SESSION_parse, SSL_R_CIPHER_CODE_WRONG_LENGTH);
+ if (!CBS_get_asn1(&session, &cipher, CBS_ASN1_OCTETSTRING) ||
+ !CBS_get_u16(&cipher, &cipher_value) ||
+ CBS_len(&cipher) != 0) {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_SSL_SESSION);
goto err;
}
ret->cipher = SSL_get_cipher_by_value(cipher_value);
if (ret->cipher == NULL) {
- OPENSSL_PUT_ERROR(SSL, SSL_SESSION_parse, SSL_R_UNSUPPORTED_CIPHER);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_UNSUPPORTED_CIPHER);
goto err;
}
- if (CBS_len(&session_id) > SSL3_MAX_SSL_SESSION_ID_LENGTH) {
- OPENSSL_PUT_ERROR(SSL, SSL_SESSION_parse, SSL_R_INVALID_SSL_SESSION);
+ CBS session_id, master_key;
+ if (!CBS_get_asn1(&session, &session_id, CBS_ASN1_OCTETSTRING) ||
+ CBS_len(&session_id) > SSL3_MAX_SSL_SESSION_ID_LENGTH ||
+ !CBS_get_asn1(&session, &master_key, CBS_ASN1_OCTETSTRING) ||
+ CBS_len(&master_key) > SSL_MAX_MASTER_KEY_LENGTH) {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_SSL_SESSION);
goto err;
}
memcpy(ret->session_id, CBS_data(&session_id), CBS_len(&session_id));
ret->session_id_length = CBS_len(&session_id);
-
- if (CBS_len(&master_key) > SSL_MAX_MASTER_KEY_LENGTH) {
- OPENSSL_PUT_ERROR(SSL, SSL_SESSION_parse, SSL_R_INVALID_SSL_SESSION);
- goto err;
- }
memcpy(ret->master_key, CBS_data(&master_key), CBS_len(&master_key));
ret->master_key_length = CBS_len(&master_key);
- if (session_time > LONG_MAX ||
- timeout > LONG_MAX) {
- OPENSSL_PUT_ERROR(SSL, SSL_SESSION_parse, SSL_R_INVALID_SSL_SESSION);
+ if (!SSL_SESSION_parse_long(&session, &ret->time, kTimeTag, time(NULL)) ||
+ !SSL_SESSION_parse_long(&session, &ret->timeout, kTimeoutTag, 3)) {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_SSL_SESSION);
goto err;
}
- ret->time = session_time;
- ret->timeout = timeout;
+ CBS peer;
+ int has_peer;
+ if (!CBS_get_optional_asn1(&session, &peer, &has_peer, kPeerTag)) {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_SSL_SESSION);
+ goto err;
+ }
X509_free(ret->peer);
ret->peer = NULL;
if (has_peer) {
- const uint8_t *ptr;
- ptr = CBS_data(&peer);
- ret->peer = d2i_X509(NULL, &ptr, CBS_len(&peer));
+ ret->peer = parse_x509(&peer);
if (ret->peer == NULL) {
goto err;
}
- if (ptr != CBS_data(&peer) + CBS_len(&peer)) {
- OPENSSL_PUT_ERROR(SSL, SSL_SESSION_parse, SSL_R_INVALID_SSL_SESSION);
+ if (CBS_len(&peer) != 0) {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_SSL_SESSION);
goto err;
}
}
- if (CBS_len(&sid_ctx) > sizeof(ret->sid_ctx)) {
- OPENSSL_PUT_ERROR(SSL, SSL_SESSION_parse, SSL_R_INVALID_SSL_SESSION);
- goto err;
- }
- memcpy(ret->sid_ctx, CBS_data(&sid_ctx), CBS_len(&sid_ctx));
- ret->sid_ctx_length = CBS_len(&sid_ctx);
-
- if (verify_result > LONG_MAX ||
- ticket_lifetime_hint > 0xffffffff) {
- OPENSSL_PUT_ERROR(SSL, SSL_SESSION_parse, SSL_R_INVALID_SSL_SESSION);
+ if (!SSL_SESSION_parse_bounded_octet_string(
+ &session, ret->sid_ctx, &ret->sid_ctx_length, sizeof(ret->sid_ctx),
+ kSessionIDContextTag) ||
+ !SSL_SESSION_parse_long(&session, &ret->verify_result, kVerifyResultTag,
+ X509_V_OK) ||
+ !SSL_SESSION_parse_string(&session, &ret->tlsext_hostname,
+ kHostNameTag) ||
+ !SSL_SESSION_parse_string(&session, &ret->psk_identity,
+ kPSKIdentityTag) ||
+ !SSL_SESSION_parse_u32(&session, &ret->tlsext_tick_lifetime_hint,
+ kTicketLifetimeHintTag, 0) ||
+ !SSL_SESSION_parse_octet_string(&session, &ret->tlsext_tick,
+ &ret->tlsext_ticklen, kTicketTag)) {
goto err;
}
- ret->verify_result = verify_result;
- ret->tlsext_tick_lifetime_hint = ticket_lifetime_hint;
- if (has_peer_sha256) {
- if (CBS_len(&peer_sha256) != sizeof(ret->peer_sha256)) {
- OPENSSL_PUT_ERROR(SSL, SSL_SESSION_parse, SSL_R_INVALID_SSL_SESSION);
+ if (CBS_peek_asn1_tag(&session, kPeerSHA256Tag)) {
+ CBS child, peer_sha256;
+ if (!CBS_get_asn1(&session, &child, kPeerSHA256Tag) ||
+ !CBS_get_asn1(&child, &peer_sha256, CBS_ASN1_OCTETSTRING) ||
+ CBS_len(&peer_sha256) != sizeof(ret->peer_sha256) ||
+ CBS_len(&child) != 0) {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_SSL_SESSION);
goto err;
}
memcpy(ret->peer_sha256, CBS_data(&peer_sha256), sizeof(ret->peer_sha256));
@@ -569,14 +605,67 @@ static SSL_SESSION *SSL_SESSION_parse(CBS *cbs) {
ret->peer_sha256_valid = 0;
}
- if (CBS_len(&original_handshake_hash) >
- sizeof(ret->original_handshake_hash)) {
- OPENSSL_PUT_ERROR(SSL, SSL_SESSION_parse, SSL_R_INVALID_SSL_SESSION);
+ if (!SSL_SESSION_parse_bounded_octet_string(
+ &session, ret->original_handshake_hash,
+ &ret->original_handshake_hash_len,
+ sizeof(ret->original_handshake_hash), kOriginalHandshakeHashTag) ||
+ !SSL_SESSION_parse_octet_string(
+ &session, &ret->tlsext_signed_cert_timestamp_list,
+ &ret->tlsext_signed_cert_timestamp_list_length,
+ kSignedCertTimestampListTag) ||
+ !SSL_SESSION_parse_octet_string(
+ &session, &ret->ocsp_response, &ret->ocsp_response_length,
+ kOCSPResponseTag)) {
+ goto err;
+ }
+
+ int extended_master_secret;
+ if (!CBS_get_optional_asn1_bool(&session, &extended_master_secret,
+ kExtendedMasterSecretTag,
+ 0 /* default to false */)) {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_SSL_SESSION);
+ goto err;
+ }
+ ret->extended_master_secret = !!extended_master_secret;
+
+ if (!SSL_SESSION_parse_u32(&session, &ret->key_exchange_info,
+ kKeyExchangeInfoTag, 0)) {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_SSL_SESSION);
+ goto err;
+ }
+
+ CBS cert_chain;
+ int has_cert_chain;
+ if (!CBS_get_optional_asn1(&session, &cert_chain, &has_cert_chain,
+ kCertChainTag)) {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_SSL_SESSION);
+ goto err;
+ }
+ sk_X509_pop_free(ret->cert_chain, X509_free);
+ ret->cert_chain = NULL;
+ if (has_cert_chain) {
+ ret->cert_chain = sk_X509_new_null();
+ if (ret->cert_chain == NULL) {
+ OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+ while (CBS_len(&cert_chain) > 0) {
+ X509 *x509 = parse_x509(&cert_chain);
+ if (x509 == NULL) {
+ goto err;
+ }
+ if (!sk_X509_push(ret->cert_chain, x509)) {
+ OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
+ X509_free(x509);
+ goto err;
+ }
+ }
+ }
+
+ if (CBS_len(&session) != 0) {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_SSL_SESSION);
goto err;
}
- memcpy(ret->original_handshake_hash, CBS_data(&original_handshake_hash),
- CBS_len(&original_handshake_hash));
- ret->original_handshake_hash_len = CBS_len(&original_handshake_hash);
return ret;
@@ -593,7 +682,7 @@ SSL_SESSION *SSL_SESSION_from_bytes(const uint8_t *in, size_t in_len) {
return NULL;
}
if (CBS_len(&cbs) != 0) {
- OPENSSL_PUT_ERROR(SSL, SSL_SESSION_from_bytes, SSL_R_INVALID_SSL_SESSION);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_SSL_SESSION);
SSL_SESSION_free(ret);
return NULL;
}
@@ -602,7 +691,7 @@ SSL_SESSION *SSL_SESSION_from_bytes(const uint8_t *in, size_t in_len) {
SSL_SESSION *d2i_SSL_SESSION(SSL_SESSION **a, const uint8_t **pp, long length) {
if (length < 0) {
- OPENSSL_PUT_ERROR(SSL, d2i_SSL_SESSION, ERR_R_INTERNAL_ERROR);
+ OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
return NULL;
}
diff --git a/src/ssl/ssl_buffer.c b/src/ssl/ssl_buffer.c
new file mode 100644
index 0000000..63dcd80
--- /dev/null
+++ b/src/ssl/ssl_buffer.c
@@ -0,0 +1,318 @@
+/* Copyright (c) 2015, Google Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
+
+#include <openssl/ssl.h>
+
+#include <assert.h>
+#include <limits.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <openssl/bio.h>
+#include <openssl/err.h>
+#include <openssl/mem.h>
+#include <openssl/type_check.h>
+
+#include "internal.h"
+
+
+OPENSSL_COMPILE_ASSERT(0xffff <= INT_MAX, uint16_fits_in_int);
+
+OPENSSL_COMPILE_ASSERT((SSL3_ALIGN_PAYLOAD & (SSL3_ALIGN_PAYLOAD - 1)) == 0,
+ align_to_a_power_of_two);
+
+/* setup_buffer initializes |buf| with capacity |cap|, aligned such that data
+ * written after |header_len| is aligned to a |SSL3_ALIGN_PAYLOAD|-byte
+ * boundary. It returns one on success and zero on error. */
+static int setup_buffer(SSL3_BUFFER *buf, size_t header_len, size_t cap) {
+ if (buf->buf != NULL || cap > 0xffff) {
+ OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
+ return 0;
+ }
+
+ /* Add up to |SSL3_ALIGN_PAYLOAD| - 1 bytes of slack for alignment. */
+ buf->buf = OPENSSL_malloc(cap + SSL3_ALIGN_PAYLOAD - 1);
+ if (buf->buf == NULL) {
+ OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
+ return 0;
+ }
+
+ /* Arrange the buffer such that the record body is aligned. */
+ buf->offset = (0 - header_len - (uintptr_t)buf->buf) &
+ (SSL3_ALIGN_PAYLOAD - 1);
+ buf->len = 0;
+ buf->cap = cap;
+ return 1;
+}
+
+static void consume_buffer(SSL3_BUFFER *buf, size_t len) {
+ if (len > buf->len) {
+ abort();
+ }
+ buf->offset += (uint16_t)len;
+ buf->len -= (uint16_t)len;
+ buf->cap -= (uint16_t)len;
+}
+
+static void clear_buffer(SSL3_BUFFER *buf) {
+ OPENSSL_free(buf->buf);
+ memset(buf, 0, sizeof(SSL3_BUFFER));
+}
+
+OPENSSL_COMPILE_ASSERT(DTLS1_RT_HEADER_LENGTH + SSL3_RT_MAX_ENCRYPTED_LENGTH +
+ SSL3_RT_MAX_EXTRA <= 0xffff,
+ maximum_read_buffer_too_large);
+
+/* setup_read_buffer initializes the read buffer if not already initialized. It
+ * returns one on success and zero on failure. */
+static int setup_read_buffer(SSL *ssl) {
+ SSL3_BUFFER *buf = &ssl->s3->read_buffer;
+
+ if (buf->buf != NULL) {
+ return 1;
+ }
+
+ size_t header_len = ssl_record_prefix_len(ssl);
+ size_t cap = SSL3_RT_MAX_ENCRYPTED_LENGTH;
+ if (SSL_IS_DTLS(ssl)) {
+ cap += DTLS1_RT_HEADER_LENGTH;
+ } else {
+ cap += SSL3_RT_HEADER_LENGTH;
+ }
+ if (ssl->options & SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER) {
+ cap += SSL3_RT_MAX_EXTRA;
+ }
+
+ return setup_buffer(buf, header_len, cap);
+}
+
+uint8_t *ssl_read_buffer(SSL *ssl) {
+ return ssl->s3->read_buffer.buf + ssl->s3->read_buffer.offset;
+}
+
+size_t ssl_read_buffer_len(const SSL *ssl) {
+ return ssl->s3->read_buffer.len;
+}
+
+static int dtls_read_buffer_next_packet(SSL *ssl) {
+ SSL3_BUFFER *buf = &ssl->s3->read_buffer;
+
+ if (buf->len > 0) {
+ /* It is an error to call |dtls_read_buffer_extend| when the read buffer is
+ * not empty. */
+ OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
+ return -1;
+ }
+
+ /* Read a single packet from |ssl->rbio|. |buf->cap| must fit in an int. */
+ ssl->rwstate = SSL_READING;
+ int ret = BIO_read(ssl->rbio, buf->buf + buf->offset, (int)buf->cap);
+ if (ret <= 0) {
+ return ret;
+ }
+ ssl->rwstate = SSL_NOTHING;
+ /* |BIO_read| was bound by |buf->cap|, so this cannot overflow. */
+ buf->len = (uint16_t)ret;
+ return 1;
+}
+
+static int tls_read_buffer_extend_to(SSL *ssl, size_t len) {
+ SSL3_BUFFER *buf = &ssl->s3->read_buffer;
+
+ if (len > buf->cap) {
+ /* This may occur if |SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER| was toggled after
+ * |setup_read_buffer| was called. Stay within bounds, but do not attempt to
+ * recover. */
+ OPENSSL_PUT_ERROR(SSL, SSL_R_BUFFER_TOO_SMALL);
+ return -1;
+ }
+
+ /* Read until the target length is reached. */
+ while (buf->len < len) {
+ /* The amount of data to read is bounded by |buf->cap|, which must fit in an
+ * int. */
+ ssl->rwstate = SSL_READING;
+ int ret = BIO_read(ssl->rbio, buf->buf + buf->offset + buf->len,
+ (int)(len - buf->len));
+ if (ret <= 0) {
+ return ret;
+ }
+ ssl->rwstate = SSL_NOTHING;
+ /* |BIO_read| was bound by |buf->cap - buf->len|, so this cannot
+ * overflow. */
+ buf->len += (uint16_t)ret;
+ }
+
+ return 1;
+}
+
+int ssl_read_buffer_extend_to(SSL *ssl, size_t len) {
+ /* |ssl_read_buffer_extend_to| implicitly discards any consumed data. */
+ ssl_read_buffer_discard(ssl);
+
+ if (!setup_read_buffer(ssl)) {
+ return -1;
+ }
+
+ if (ssl->rbio == NULL) {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_BIO_NOT_SET);
+ return -1;
+ }
+
+ ERR_clear_system_error();
+
+ int ret;
+ if (SSL_IS_DTLS(ssl)) {
+ /* |len| is ignored for a datagram transport. */
+ ret = dtls_read_buffer_next_packet(ssl);
+ } else {
+ ret = tls_read_buffer_extend_to(ssl, len);
+ }
+
+ if (ret <= 0) {
+ /* If the buffer was empty originally and remained empty after attempting to
+ * extend it, release the buffer until the next attempt. */
+ ssl_read_buffer_discard(ssl);
+ }
+ return ret;
+}
+
+void ssl_read_buffer_consume(SSL *ssl, size_t len) {
+ SSL3_BUFFER *buf = &ssl->s3->read_buffer;
+
+ consume_buffer(buf, len);
+ if (!SSL_IS_DTLS(ssl)) {
+ /* The TLS stack never reads beyond the current record, so there will never
+ * be unconsumed data. If read-ahead is ever reimplemented,
+ * |ssl_read_buffer_discard| will require a |memcpy| to shift the excess
+ * back to the front of the buffer, to ensure there is enough space for the
+ * next record. */
+ assert(buf->len == 0);
+ }
+}
+
+void ssl_read_buffer_discard(SSL *ssl) {
+ if (ssl->s3->read_buffer.len == 0) {
+ ssl_read_buffer_clear(ssl);
+ }
+}
+
+void ssl_read_buffer_clear(SSL *ssl) {
+ clear_buffer(&ssl->s3->read_buffer);
+}
+
+
+int ssl_write_buffer_is_pending(const SSL *ssl) {
+ return ssl->s3->write_buffer.len > 0;
+}
+
+OPENSSL_COMPILE_ASSERT(SSL3_RT_HEADER_LENGTH * 2 +
+ SSL3_RT_SEND_MAX_ENCRYPTED_OVERHEAD * 2 +
+ SSL3_RT_MAX_PLAIN_LENGTH <= 0xffff,
+ maximum_tls_write_buffer_too_large);
+
+OPENSSL_COMPILE_ASSERT(DTLS1_RT_HEADER_LENGTH +
+ SSL3_RT_SEND_MAX_ENCRYPTED_OVERHEAD +
+ SSL3_RT_MAX_PLAIN_LENGTH <= 0xffff,
+ maximum_dtls_write_buffer_too_large);
+
+int ssl_write_buffer_init(SSL *ssl, uint8_t **out_ptr, size_t max_len) {
+ SSL3_BUFFER *buf = &ssl->s3->write_buffer;
+
+ if (buf->buf != NULL) {
+ OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
+ return 0;
+ }
+
+ size_t header_len = ssl_seal_prefix_len(ssl);
+
+ /* TODO(davidben): This matches the original behavior in keeping the malloc
+ * size consistent. Does this matter? |cap| could just be |max_len|. */
+ size_t cap = SSL3_RT_MAX_PLAIN_LENGTH + SSL3_RT_SEND_MAX_ENCRYPTED_OVERHEAD;
+ if (SSL_IS_DTLS(ssl)) {
+ cap += DTLS1_RT_HEADER_LENGTH;
+ } else {
+ cap += SSL3_RT_HEADER_LENGTH;
+ if (ssl->mode & SSL_MODE_CBC_RECORD_SPLITTING) {
+ cap += SSL3_RT_HEADER_LENGTH + SSL3_RT_SEND_MAX_ENCRYPTED_OVERHEAD;
+ }
+ }
+
+ if (max_len > cap) {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_BUFFER_TOO_SMALL);
+ return 0;
+ }
+
+ if (!setup_buffer(buf, header_len, cap)) {
+ return 0;
+ }
+ *out_ptr = buf->buf + buf->offset;
+ return 1;
+}
+
+void ssl_write_buffer_set_len(SSL *ssl, size_t len) {
+ SSL3_BUFFER *buf = &ssl->s3->write_buffer;
+
+ if (len > buf->cap) {
+ abort();
+ }
+ buf->len = len;
+}
+
+static int tls_write_buffer_flush(SSL *ssl) {
+ SSL3_BUFFER *buf = &ssl->s3->write_buffer;
+
+ while (buf->len > 0) {
+ ssl->rwstate = SSL_WRITING;
+ int ret = BIO_write(ssl->wbio, buf->buf + buf->offset, buf->len);
+ if (ret <= 0) {
+ return ret;
+ }
+ ssl->rwstate = SSL_NOTHING;
+ consume_buffer(buf, (size_t)ret);
+ }
+ ssl_write_buffer_clear(ssl);
+ return 1;
+}
+
+static int dtls_write_buffer_flush(SSL *ssl) {
+ SSL3_BUFFER *buf = &ssl->s3->write_buffer;
+ if (buf->len == 0) {
+ return 1;
+ }
+
+ int ret = BIO_write(ssl->wbio, buf->buf + buf->offset, buf->len);
+ /* Drop the write buffer whether or not the write succeeded synchronously.
+ * TODO(davidben): How does this interact with the retry flag? */
+ ssl_write_buffer_clear(ssl);
+ return (ret <= 0) ? ret : 1;
+}
+
+int ssl_write_buffer_flush(SSL *ssl) {
+ if (ssl->wbio == NULL) {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_BIO_NOT_SET);
+ return -1;
+ }
+ ERR_clear_system_error();
+
+ if (SSL_IS_DTLS(ssl)) {
+ return dtls_write_buffer_flush(ssl);
+ } else {
+ return tls_write_buffer_flush(ssl);
+ }
+}
+
+void ssl_write_buffer_clear(SSL *ssl) {
+ clear_buffer(&ssl->s3->write_buffer);
+}
diff --git a/src/ssl/ssl_cert.c b/src/ssl/ssl_cert.c
index 85aa079..4094b27 100644
--- a/src/ssl/ssl_cert.c
+++ b/src/ssl/ssl_cert.c
@@ -112,84 +112,64 @@
* ECC cipher suite support in OpenSSL originally developed by
* SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project. */
-#include <errno.h>
-#include <stdio.h>
+#include <openssl/ssl.h>
+
#include <string.h>
-#include <openssl/bio.h>
#include <openssl/bn.h>
#include <openssl/buf.h>
#include <openssl/ec_key.h>
#include <openssl/dh.h>
#include <openssl/err.h>
#include <openssl/mem.h>
-#include <openssl/obj.h>
-#include <openssl/pem.h>
#include <openssl/x509.h>
#include <openssl/x509v3.h>
#include "../crypto/dh/internal.h"
-#include "../crypto/directory.h"
#include "../crypto/internal.h"
#include "internal.h"
-static CRYPTO_once_t g_x509_store_ex_data_index_once;
-static int g_x509_store_ex_data_index;
-
-static void ssl_x509_store_ex_data_index_init(void) {
- g_x509_store_ex_data_index = X509_STORE_CTX_get_ex_new_index(
- 0, "SSL for verify callback", NULL, NULL, NULL);
-}
-
int SSL_get_ex_data_X509_STORE_CTX_idx(void) {
- CRYPTO_once(&g_x509_store_ex_data_index_once,
- ssl_x509_store_ex_data_index_init);
- return g_x509_store_ex_data_index;
+ /* The ex_data index to go from |X509_STORE_CTX| to |SSL| always uses the
+ * reserved app_data slot. Before ex_data was introduced, app_data was used.
+ * Avoid breaking any software which assumes |X509_STORE_CTX_get_app_data|
+ * works. */
+ return 0;
}
CERT *ssl_cert_new(void) {
- CERT *ret;
-
- ret = (CERT *)OPENSSL_malloc(sizeof(CERT));
+ CERT *ret = (CERT *)OPENSSL_malloc(sizeof(CERT));
if (ret == NULL) {
- OPENSSL_PUT_ERROR(SSL, ssl_cert_new, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
return NULL;
}
memset(ret, 0, sizeof(CERT));
- ret->key = &ret->pkeys[SSL_PKEY_RSA_ENC];
return ret;
}
CERT *ssl_cert_dup(CERT *cert) {
- CERT *ret;
- int i;
-
- ret = (CERT *)OPENSSL_malloc(sizeof(CERT));
+ CERT *ret = (CERT *)OPENSSL_malloc(sizeof(CERT));
if (ret == NULL) {
- OPENSSL_PUT_ERROR(SSL, ssl_cert_dup, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
return NULL;
}
memset(ret, 0, sizeof(CERT));
- ret->key = &ret->pkeys[cert->key - &cert->pkeys[0]];
- /* or ret->key = ret->pkeys + (cert->key - cert->pkeys), if you find that
- * more readable */
-
ret->mask_k = cert->mask_k;
ret->mask_a = cert->mask_a;
if (cert->dh_tmp != NULL) {
ret->dh_tmp = DHparams_dup(cert->dh_tmp);
if (ret->dh_tmp == NULL) {
- OPENSSL_PUT_ERROR(SSL, ssl_cert_dup, ERR_R_DH_LIB);
+ OPENSSL_PUT_ERROR(SSL, ERR_R_DH_LIB);
goto err;
}
if (cert->dh_tmp->priv_key) {
BIGNUM *b = BN_dup(cert->dh_tmp->priv_key);
if (!b) {
- OPENSSL_PUT_ERROR(SSL, ssl_cert_dup, ERR_R_BN_LIB);
+ OPENSSL_PUT_ERROR(SSL, ERR_R_BN_LIB);
goto err;
}
ret->dh_tmp->priv_key = b;
@@ -197,7 +177,7 @@ CERT *ssl_cert_dup(CERT *cert) {
if (cert->dh_tmp->pub_key) {
BIGNUM *b = BN_dup(cert->dh_tmp->pub_key);
if (!b) {
- OPENSSL_PUT_ERROR(SSL, ssl_cert_dup, ERR_R_BN_LIB);
+ OPENSSL_PUT_ERROR(SSL, ERR_R_BN_LIB);
goto err;
}
ret->dh_tmp->pub_key = b;
@@ -208,67 +188,25 @@ CERT *ssl_cert_dup(CERT *cert) {
ret->ecdh_nid = cert->ecdh_nid;
ret->ecdh_tmp_cb = cert->ecdh_tmp_cb;
- for (i = 0; i < SSL_PKEY_NUM; i++) {
- CERT_PKEY *cpk = cert->pkeys + i;
- CERT_PKEY *rpk = ret->pkeys + i;
- if (cpk->x509 != NULL) {
- rpk->x509 = X509_up_ref(cpk->x509);
- }
-
- if (cpk->privatekey != NULL) {
- rpk->privatekey = EVP_PKEY_up_ref(cpk->privatekey);
- }
-
- if (cpk->chain) {
- rpk->chain = X509_chain_up_ref(cpk->chain);
- if (!rpk->chain) {
- OPENSSL_PUT_ERROR(SSL, ssl_cert_dup, ERR_R_MALLOC_FAILURE);
- goto err;
- }
- }
+ if (cert->x509 != NULL) {
+ ret->x509 = X509_up_ref(cert->x509);
}
- /* Copy over signature algorithm configuration. */
- if (cert->conf_sigalgs) {
- ret->conf_sigalgs = BUF_memdup(cert->conf_sigalgs, cert->conf_sigalgslen);
- if (!ret->conf_sigalgs) {
- goto err;
- }
- ret->conf_sigalgslen = cert->conf_sigalgslen;
+ if (cert->privatekey != NULL) {
+ ret->privatekey = EVP_PKEY_up_ref(cert->privatekey);
}
- if (cert->client_sigalgs) {
- ret->client_sigalgs = BUF_memdup(cert->client_sigalgs,
- cert->client_sigalgslen);
- if (!ret->client_sigalgs) {
+ if (cert->chain) {
+ ret->chain = X509_chain_up_ref(cert->chain);
+ if (!ret->chain) {
+ OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
goto err;
}
- ret->client_sigalgslen = cert->client_sigalgslen;
- }
-
- /* Copy any custom client certificate types */
- if (cert->client_certificate_types) {
- ret->client_certificate_types = BUF_memdup(
- cert->client_certificate_types, cert->num_client_certificate_types);
- if (!ret->client_certificate_types) {
- goto err;
- }
- ret->num_client_certificate_types = cert->num_client_certificate_types;
}
ret->cert_cb = cert->cert_cb;
ret->cert_cb_arg = cert->cert_cb_arg;
- if (cert->verify_store) {
- CRYPTO_refcount_inc(&cert->verify_store->references);
- ret->verify_store = cert->verify_store;
- }
-
- if (cert->chain_store) {
- CRYPTO_refcount_inc(&cert->chain_store->references);
- ret->chain_store = cert->chain_store;
- }
-
return ret;
err:
@@ -277,27 +215,18 @@ err:
}
/* Free up and clear all certificates and chains */
-void ssl_cert_clear_certs(CERT *c) {
- int i;
- if (c == NULL) {
+void ssl_cert_clear_certs(CERT *cert) {
+ if (cert == NULL) {
return;
}
- for (i = 0; i < SSL_PKEY_NUM; i++) {
- CERT_PKEY *cpk = c->pkeys + i;
- if (cpk->x509) {
- X509_free(cpk->x509);
- cpk->x509 = NULL;
- }
- if (cpk->privatekey) {
- EVP_PKEY_free(cpk->privatekey);
- cpk->privatekey = NULL;
- }
- if (cpk->chain) {
- sk_X509_pop_free(cpk->chain, X509_free);
- cpk->chain = NULL;
- }
- }
+ X509_free(cert->x509);
+ cert->x509 = NULL;
+ EVP_PKEY_free(cert->privatekey);
+ cert->privatekey = NULL;
+ sk_X509_pop_free(cert->chain, X509_free);
+ cert->chain = NULL;
+ cert->key_method = NULL;
}
void ssl_cert_free(CERT *c) {
@@ -309,38 +238,29 @@ void ssl_cert_free(CERT *c) {
ssl_cert_clear_certs(c);
OPENSSL_free(c->peer_sigalgs);
- OPENSSL_free(c->conf_sigalgs);
- OPENSSL_free(c->client_sigalgs);
- OPENSSL_free(c->shared_sigalgs);
- OPENSSL_free(c->client_certificate_types);
- X509_STORE_free(c->verify_store);
- X509_STORE_free(c->chain_store);
+ OPENSSL_free(c->digest_nids);
OPENSSL_free(c);
}
-int ssl_cert_set0_chain(CERT *c, STACK_OF(X509) *chain) {
- CERT_PKEY *cpk = c->key;
- if (!cpk) {
- return 0;
- }
- sk_X509_pop_free(cpk->chain, X509_free);
- cpk->chain = chain;
+int ssl_cert_set0_chain(CERT *cert, STACK_OF(X509) *chain) {
+ sk_X509_pop_free(cert->chain, X509_free);
+ cert->chain = chain;
return 1;
}
-int ssl_cert_set1_chain(CERT *c, STACK_OF(X509) *chain) {
+int ssl_cert_set1_chain(CERT *cert, STACK_OF(X509) *chain) {
STACK_OF(X509) *dchain;
- if (!chain) {
- return ssl_cert_set0_chain(c, NULL);
+ if (chain == NULL) {
+ return ssl_cert_set0_chain(cert, NULL);
}
dchain = X509_chain_up_ref(chain);
- if (!dchain) {
+ if (dchain == NULL) {
return 0;
}
- if (!ssl_cert_set0_chain(c, dchain)) {
+ if (!ssl_cert_set0_chain(cert, dchain)) {
sk_X509_pop_free(dchain, X509_free);
return 0;
}
@@ -348,158 +268,71 @@ int ssl_cert_set1_chain(CERT *c, STACK_OF(X509) *chain) {
return 1;
}
-int ssl_cert_add0_chain_cert(CERT *c, X509 *x) {
- CERT_PKEY *cpk = c->key;
- if (!cpk) {
- return 0;
+int ssl_cert_add0_chain_cert(CERT *cert, X509 *x509) {
+ if (cert->chain == NULL) {
+ cert->chain = sk_X509_new_null();
}
-
- if (!cpk->chain) {
- cpk->chain = sk_X509_new_null();
- }
- if (!cpk->chain || !sk_X509_push(cpk->chain, x)) {
+ if (cert->chain == NULL || !sk_X509_push(cert->chain, x509)) {
return 0;
}
return 1;
}
-int ssl_cert_add1_chain_cert(CERT *c, X509 *x) {
- if (!ssl_cert_add0_chain_cert(c, x)) {
+int ssl_cert_add1_chain_cert(CERT *cert, X509 *x509) {
+ if (!ssl_cert_add0_chain_cert(cert, x509)) {
return 0;
}
- X509_up_ref(x);
+ X509_up_ref(x509);
return 1;
}
-int ssl_cert_select_current(CERT *c, X509 *x) {
- int i;
- if (x == NULL) {
- return 0;
- }
-
- for (i = 0; i < SSL_PKEY_NUM; i++) {
- if (c->pkeys[i].x509 == x) {
- c->key = &c->pkeys[i];
- return 1;
- }
- }
-
- for (i = 0; i < SSL_PKEY_NUM; i++) {
- if (c->pkeys[i].x509 && !X509_cmp(c->pkeys[i].x509, x)) {
- c->key = &c->pkeys[i];
- return 1;
- }
- }
-
- return 0;
-}
-
void ssl_cert_set_cert_cb(CERT *c, int (*cb)(SSL *ssl, void *arg), void *arg) {
c->cert_cb = cb;
c->cert_cb_arg = arg;
}
-SESS_CERT *ssl_sess_cert_new(void) {
- SESS_CERT *ret;
-
- ret = OPENSSL_malloc(sizeof *ret);
- if (ret == NULL) {
- OPENSSL_PUT_ERROR(SSL, ssl_sess_cert_new, ERR_R_MALLOC_FAILURE);
- return NULL;
- }
-
- memset(ret, 0, sizeof *ret);
-
- return ret;
-}
-
-SESS_CERT *ssl_sess_cert_dup(const SESS_CERT *sess_cert) {
- SESS_CERT *ret = ssl_sess_cert_new();
- if (ret == NULL) {
- return NULL;
- }
-
- if (sess_cert->cert_chain != NULL) {
- ret->cert_chain = X509_chain_up_ref(sess_cert->cert_chain);
- if (ret->cert_chain == NULL) {
- ssl_sess_cert_free(ret);
- return NULL;
- }
- }
- if (sess_cert->peer_cert != NULL) {
- ret->peer_cert = X509_up_ref(sess_cert->peer_cert);
- }
- if (sess_cert->peer_dh_tmp != NULL) {
- ret->peer_dh_tmp = sess_cert->peer_dh_tmp;
- DH_up_ref(ret->peer_dh_tmp);
- }
- if (sess_cert->peer_ecdh_tmp != NULL) {
- ret->peer_ecdh_tmp = sess_cert->peer_ecdh_tmp;
- EC_KEY_up_ref(ret->peer_ecdh_tmp);
- }
- return ret;
-}
-
-void ssl_sess_cert_free(SESS_CERT *sess_cert) {
- if (sess_cert == NULL) {
- return;
+int ssl_verify_cert_chain(SSL *ssl, STACK_OF(X509) *cert_chain) {
+ if (cert_chain == NULL || sk_X509_num(cert_chain) == 0) {
+ return 0;
}
- sk_X509_pop_free(sess_cert->cert_chain, X509_free);
- X509_free(sess_cert->peer_cert);
- DH_free(sess_cert->peer_dh_tmp);
- EC_KEY_free(sess_cert->peer_ecdh_tmp);
-
- OPENSSL_free(sess_cert);
-}
-
-int ssl_verify_cert_chain(SSL *s, STACK_OF(X509) *sk) {
- X509 *x;
- int i;
- X509_STORE *verify_store;
+ X509 *leaf = sk_X509_value(cert_chain, 0);
+ int ret = 0;
X509_STORE_CTX ctx;
-
- if (s->cert->verify_store) {
- verify_store = s->cert->verify_store;
- } else {
- verify_store = s->ctx->cert_store;
- }
-
- if (sk == NULL || sk_X509_num(sk) == 0) {
+ if (!X509_STORE_CTX_init(&ctx, ssl->ctx->cert_store, leaf, cert_chain)) {
+ OPENSSL_PUT_ERROR(SSL, ERR_R_X509_LIB);
return 0;
}
-
- x = sk_X509_value(sk, 0);
- if (!X509_STORE_CTX_init(&ctx, verify_store, x, sk)) {
- OPENSSL_PUT_ERROR(SSL, ssl_verify_cert_chain, ERR_R_X509_LIB);
- return 0;
+ if (!X509_STORE_CTX_set_ex_data(&ctx, SSL_get_ex_data_X509_STORE_CTX_idx(),
+ ssl)) {
+ goto err;
}
- X509_STORE_CTX_set_ex_data(&ctx, SSL_get_ex_data_X509_STORE_CTX_idx(), s);
/* We need to inherit the verify parameters. These can be determined by the
* context: if its a server it will verify SSL client certificates or vice
* versa. */
- X509_STORE_CTX_set_default(&ctx, s->server ? "ssl_client" : "ssl_server");
+ X509_STORE_CTX_set_default(&ctx, ssl->server ? "ssl_client" : "ssl_server");
/* Anything non-default in "param" should overwrite anything in the ctx. */
- X509_VERIFY_PARAM_set1(X509_STORE_CTX_get0_param(&ctx), s->param);
+ X509_VERIFY_PARAM_set1(X509_STORE_CTX_get0_param(&ctx), ssl->param);
- if (s->verify_callback) {
- X509_STORE_CTX_set_verify_cb(&ctx, s->verify_callback);
+ if (ssl->verify_callback) {
+ X509_STORE_CTX_set_verify_cb(&ctx, ssl->verify_callback);
}
- if (s->ctx->app_verify_callback != NULL) {
- i = s->ctx->app_verify_callback(&ctx, s->ctx->app_verify_arg);
+ if (ssl->ctx->app_verify_callback != NULL) {
+ ret = ssl->ctx->app_verify_callback(&ctx, ssl->ctx->app_verify_arg);
} else {
- i = X509_verify_cert(&ctx);
+ ret = X509_verify_cert(&ctx);
}
- s->verify_result = ctx.error;
- X509_STORE_CTX_cleanup(&ctx);
+ ssl->verify_result = ctx.error;
- return i;
+err:
+ X509_STORE_CTX_cleanup(&ctx);
+ return ret;
}
static void set_client_CA_list(STACK_OF(X509_NAME) **ca_list,
@@ -508,15 +341,17 @@ static void set_client_CA_list(STACK_OF(X509_NAME) **ca_list,
*ca_list = name_list;
}
-STACK_OF(X509_NAME) *SSL_dup_CA_list(STACK_OF(X509_NAME) *sk) {
- size_t i;
- STACK_OF(X509_NAME) *ret;
- X509_NAME *name;
+STACK_OF(X509_NAME) *SSL_dup_CA_list(STACK_OF(X509_NAME) *list) {
+ STACK_OF(X509_NAME) *ret = sk_X509_NAME_new_null();
+ if (ret == NULL) {
+ return NULL;
+ }
- ret = sk_X509_NAME_new_null();
- for (i = 0; i < sk_X509_NAME_num(sk); i++) {
- name = X509_NAME_dup(sk_X509_NAME_value(sk, i));
+ size_t i;
+ for (i = 0; i < sk_X509_NAME_num(list); i++) {
+ X509_NAME *name = X509_NAME_dup(sk_X509_NAME_value(list, i));
if (name == NULL || !sk_X509_NAME_push(ret, name)) {
+ X509_NAME_free(name);
sk_X509_NAME_pop_free(ret, X509_NAME_free);
return NULL;
}
@@ -525,38 +360,38 @@ STACK_OF(X509_NAME) *SSL_dup_CA_list(STACK_OF(X509_NAME) *sk) {
return ret;
}
-void SSL_set_client_CA_list(SSL *s, STACK_OF(X509_NAME) *name_list) {
- set_client_CA_list(&(s->client_CA), name_list);
+void SSL_set_client_CA_list(SSL *ssl, STACK_OF(X509_NAME) *name_list) {
+ set_client_CA_list(&ssl->client_CA, name_list);
}
void SSL_CTX_set_client_CA_list(SSL_CTX *ctx, STACK_OF(X509_NAME) *name_list) {
- set_client_CA_list(&(ctx->client_CA), name_list);
+ set_client_CA_list(&ctx->client_CA, name_list);
}
STACK_OF(X509_NAME) *SSL_CTX_get_client_CA_list(const SSL_CTX *ctx) {
return ctx->client_CA;
}
-STACK_OF(X509_NAME) *SSL_get_client_CA_list(const SSL *s) {
- if (s->server) {
- if (s->client_CA != NULL) {
- return s->client_CA;
- } else {
- return s->ctx->client_CA;
- }
- } else {
- if ((s->version >> 8) == SSL3_VERSION_MAJOR && s->s3 != NULL) {
- return s->s3->tmp.ca_names;
- } else {
- return NULL;
- }
+STACK_OF(X509_NAME) *SSL_get_client_CA_list(const SSL *ssl) {
+ /* For historical reasons, this function is used both to query configuration
+ * state on a server as well as handshake state on a client. However, whether
+ * |ssl| is a client or server is not known until explicitly configured with
+ * |SSL_set_connect_state|. If |handshake_func| is NULL, |ssl| is in an
+ * indeterminate mode and |ssl->server| is unset. */
+ if (ssl->handshake_func != NULL && !ssl->server) {
+ return ssl->s3->tmp.ca_names;
+ }
+
+ if (ssl->client_CA != NULL) {
+ return ssl->client_CA;
}
+ return ssl->ctx->client_CA;
}
-static int add_client_CA(STACK_OF(X509_NAME) **sk, X509 *x) {
+static int add_client_CA(STACK_OF(X509_NAME) **sk, X509 *x509) {
X509_NAME *name;
- if (x == NULL) {
+ if (x509 == NULL) {
return 0;
}
if (*sk == NULL) {
@@ -566,7 +401,7 @@ static int add_client_CA(STACK_OF(X509_NAME) **sk, X509 *x) {
}
}
- name = X509_NAME_dup(X509_get_subject_name(x));
+ name = X509_NAME_dup(X509_get_subject_name(x509));
if (name == NULL) {
return 0;
}
@@ -579,195 +414,12 @@ static int add_client_CA(STACK_OF(X509_NAME) **sk, X509 *x) {
return 1;
}
-int SSL_add_client_CA(SSL *ssl, X509 *x) {
- return add_client_CA(&(ssl->client_CA), x);
-}
-
-int SSL_CTX_add_client_CA(SSL_CTX *ctx, X509 *x) {
- return add_client_CA(&(ctx->client_CA), x);
+int SSL_add_client_CA(SSL *ssl, X509 *x509) {
+ return add_client_CA(&ssl->client_CA, x509);
}
-static int xname_cmp(const X509_NAME **a, const X509_NAME **b) {
- return X509_NAME_cmp(*a, *b);
-}
-
-/* Load CA certs from a file into a STACK. Note that it is somewhat misnamed;
- * it doesn't really have anything to do with clients (except that a common use
- * for a stack of CAs is to send it to the client). Actually, it doesn't have
- * much to do with CAs, either, since it will load any old cert.
- *
- * \param file the file containing one or more certs.
- * \return a ::STACK containing the certs. */
-STACK_OF(X509_NAME) *SSL_load_client_CA_file(const char *file) {
- BIO *in;
- X509 *x = NULL;
- X509_NAME *xn = NULL;
- STACK_OF(X509_NAME) *ret = NULL, *sk;
-
- sk = sk_X509_NAME_new(xname_cmp);
- in = BIO_new(BIO_s_file());
-
- if (sk == NULL || in == NULL) {
- OPENSSL_PUT_ERROR(SSL, SSL_load_client_CA_file, ERR_R_MALLOC_FAILURE);
- goto err;
- }
-
- if (!BIO_read_filename(in, file)) {
- goto err;
- }
-
- for (;;) {
- if (PEM_read_bio_X509(in, &x, NULL, NULL) == NULL) {
- break;
- }
- if (ret == NULL) {
- ret = sk_X509_NAME_new_null();
- if (ret == NULL) {
- OPENSSL_PUT_ERROR(SSL, SSL_load_client_CA_file, ERR_R_MALLOC_FAILURE);
- goto err;
- }
- }
- xn = X509_get_subject_name(x);
- if (xn == NULL) {
- goto err;
- }
-
- /* check for duplicates */
- xn = X509_NAME_dup(xn);
- if (xn == NULL) {
- goto err;
- }
- if (sk_X509_NAME_find(sk, NULL, xn)) {
- X509_NAME_free(xn);
- } else {
- sk_X509_NAME_push(sk, xn);
- sk_X509_NAME_push(ret, xn);
- }
- }
-
- if (0) {
- err:
- sk_X509_NAME_pop_free(ret, X509_NAME_free);
- ret = NULL;
- }
-
- sk_X509_NAME_free(sk);
- BIO_free(in);
- X509_free(x);
- if (ret != NULL) {
- ERR_clear_error();
- }
- return ret;
-}
-
-/* Add a file of certs to a stack.
- *
- * \param stack the stack to add to.
- * \param file the file to add from. All certs in this file that are not
- * already in the stack will be added.
- * \return 1 for success, 0 for failure. Note that in the case of failure some
- * certs may have been added to \c stack. */
-int SSL_add_file_cert_subjects_to_stack(STACK_OF(X509_NAME) *stack,
- const char *file) {
- BIO *in;
- X509 *x = NULL;
- X509_NAME *xn = NULL;
- int ret = 1;
- int (*oldcmp)(const X509_NAME **a, const X509_NAME **b);
-
- oldcmp = sk_X509_NAME_set_cmp_func(stack, xname_cmp);
- in = BIO_new(BIO_s_file());
-
- if (in == NULL) {
- OPENSSL_PUT_ERROR(SSL, SSL_add_file_cert_subjects_to_stack,
- ERR_R_MALLOC_FAILURE);
- goto err;
- }
-
- if (!BIO_read_filename(in, file)) {
- goto err;
- }
-
- for (;;) {
- if (PEM_read_bio_X509(in, &x, NULL, NULL) == NULL) {
- break;
- }
- xn = X509_get_subject_name(x);
- if (xn == NULL) {
- goto err;
- }
- xn = X509_NAME_dup(xn);
- if (xn == NULL) {
- goto err;
- }
- if (sk_X509_NAME_find(stack, NULL, xn)) {
- X509_NAME_free(xn);
- } else {
- sk_X509_NAME_push(stack, xn);
- }
- }
-
- ERR_clear_error();
-
- if (0) {
- err:
- ret = 0;
- }
-
- BIO_free(in);
- X509_free(x);
-
- (void) sk_X509_NAME_set_cmp_func(stack, oldcmp);
-
- return ret;
-}
-
-/* Add a directory of certs to a stack.
- *
- * \param stack the stack to append to.
- * \param dir the directory to append from. All files in this directory will be
- * examined as potential certs. Any that are acceptable to
- * SSL_add_dir_cert_subjects_to_stack() that are not already in the stack will
- * be included.
- * \return 1 for success, 0 for failure. Note that in the case of failure some
- * certs may have been added to \c stack. */
-int SSL_add_dir_cert_subjects_to_stack(STACK_OF(X509_NAME) *stack,
- const char *dir) {
- OPENSSL_DIR_CTX *d = NULL;
- const char *filename;
- int ret = 0;
-
- /* Note that a side effect is that the CAs will be sorted by name */
- while ((filename = OPENSSL_DIR_read(&d, dir))) {
- char buf[1024];
- int r;
-
- if (strlen(dir) + strlen(filename) + 2 > sizeof(buf)) {
- OPENSSL_PUT_ERROR(SSL, SSL_add_dir_cert_subjects_to_stack,
- SSL_R_PATH_TOO_LONG);
- goto err;
- }
-
- r = BIO_snprintf(buf, sizeof buf, "%s/%s", dir, filename);
- if (r <= 0 || r >= (int)sizeof(buf) ||
- !SSL_add_file_cert_subjects_to_stack(stack, buf)) {
- goto err;
- }
- }
-
- if (errno) {
- OPENSSL_PUT_ERROR(SSL, SSL_add_dir_cert_subjects_to_stack, ERR_R_SYS_LIB);
- ERR_add_error_data(3, "OPENSSL_DIR_read(&ctx, '", dir, "')");
- goto err;
- }
-
- ret = 1;
-
-err:
- if (d) {
- OPENSSL_DIR_end(&d);
- }
- return ret;
+int SSL_CTX_add_client_CA(SSL_CTX *ctx, X509 *x509) {
+ return add_client_CA(&ctx->client_CA, x509);
}
/* Add a certificate to a BUF_MEM structure */
@@ -777,7 +429,7 @@ static int ssl_add_cert_to_buf(BUF_MEM *buf, unsigned long *l, X509 *x) {
n = i2d_X509(x, NULL);
if (!BUF_MEM_grow_clean(buf, (int)(n + (*l) + 3))) {
- OPENSSL_PUT_ERROR(SSL, ssl_add_cert_to_buf, ERR_R_BUF_LIB);
+ OPENSSL_PUT_ERROR(SSL, ERR_R_BUF_LIB);
return 0;
}
p = (uint8_t *)&(buf->data[*l]);
@@ -789,34 +441,21 @@ static int ssl_add_cert_to_buf(BUF_MEM *buf, unsigned long *l, X509 *x) {
}
/* Add certificate chain to internal SSL BUF_MEM structure. */
-int ssl_add_cert_chain(SSL *s, CERT_PKEY *cpk, unsigned long *l) {
- BUF_MEM *buf = s->init_buf;
+int ssl_add_cert_chain(SSL *ssl, unsigned long *l) {
+ CERT *cert = ssl->cert;
+ BUF_MEM *buf = ssl->init_buf;
int no_chain = 0;
size_t i;
- X509 *x = cpk->x509;
- STACK_OF(X509) *extra_certs;
- X509_STORE *chain_store;
+ X509 *x = cert->x509;
+ STACK_OF(X509) *chain = cert->chain;
if (x == NULL) {
- OPENSSL_PUT_ERROR(SSL, ssl_add_cert_chain, SSL_R_NO_CERTIFICATE_SET);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_NO_CERTIFICATE_SET);
return 0;
}
- if (s->cert->chain_store) {
- chain_store = s->cert->chain_store;
- } else {
- chain_store = s->ctx->cert_store;
- }
-
- /* If we have a certificate specific chain use it, else use parent ctx. */
- if (cpk && cpk->chain) {
- extra_certs = cpk->chain;
- } else {
- extra_certs = s->ctx->extra_certs;
- }
-
- if ((s->mode & SSL_MODE_NO_AUTO_CHAIN) || extra_certs) {
+ if ((ssl->mode & SSL_MODE_NO_AUTO_CHAIN) || chain != NULL) {
no_chain = 1;
}
@@ -825,8 +464,8 @@ int ssl_add_cert_chain(SSL *s, CERT_PKEY *cpk, unsigned long *l) {
return 0;
}
- for (i = 0; i < sk_X509_num(extra_certs); i++) {
- x = sk_X509_value(extra_certs, i);
+ for (i = 0; i < sk_X509_num(chain); i++) {
+ x = sk_X509_value(chain, i);
if (!ssl_add_cert_to_buf(buf, l, x)) {
return 0;
}
@@ -834,8 +473,8 @@ int ssl_add_cert_chain(SSL *s, CERT_PKEY *cpk, unsigned long *l) {
} else {
X509_STORE_CTX xs_ctx;
- if (!X509_STORE_CTX_init(&xs_ctx, chain_store, x, NULL)) {
- OPENSSL_PUT_ERROR(SSL, ssl_add_cert_chain, ERR_R_X509_LIB);
+ if (!X509_STORE_CTX_init(&xs_ctx, ssl->ctx->cert_store, x, NULL)) {
+ OPENSSL_PUT_ERROR(SSL, ERR_R_X509_LIB);
return 0;
}
X509_verify_cert(&xs_ctx);
@@ -855,132 +494,65 @@ int ssl_add_cert_chain(SSL *s, CERT_PKEY *cpk, unsigned long *l) {
return 1;
}
-/* Build a certificate chain for current certificate */
-int ssl_build_cert_chain(CERT *c, X509_STORE *chain_store, int flags) {
- CERT_PKEY *cpk = c->key;
- X509_STORE_CTX xs_ctx;
- STACK_OF(X509) *chain = NULL, *untrusted = NULL;
- X509 *x;
- int i, rv = 0;
- uint32_t error;
-
- if (!cpk->x509) {
- OPENSSL_PUT_ERROR(SSL, ssl_build_cert_chain, SSL_R_NO_CERTIFICATE_SET);
- goto err;
- }
-
- /* Rearranging and check the chain: add everything to a store */
- if (flags & SSL_BUILD_CHAIN_FLAG_CHECK) {
- size_t j;
- chain_store = X509_STORE_new();
- if (!chain_store) {
- goto err;
- }
-
- for (j = 0; j < sk_X509_num(cpk->chain); j++) {
- x = sk_X509_value(cpk->chain, j);
- if (!X509_STORE_add_cert(chain_store, x)) {
- error = ERR_peek_last_error();
- if (ERR_GET_LIB(error) != ERR_LIB_X509 ||
- ERR_GET_REASON(error) != X509_R_CERT_ALREADY_IN_HASH_TABLE) {
- goto err;
- }
- ERR_clear_error();
- }
- }
+int SSL_CTX_set0_chain(SSL_CTX *ctx, STACK_OF(X509) *chain) {
+ return ssl_cert_set0_chain(ctx->cert, chain);
+}
- /* Add EE cert too: it might be self signed */
- if (!X509_STORE_add_cert(chain_store, cpk->x509)) {
- error = ERR_peek_last_error();
- if (ERR_GET_LIB(error) != ERR_LIB_X509 ||
- ERR_GET_REASON(error) != X509_R_CERT_ALREADY_IN_HASH_TABLE) {
- goto err;
- }
- ERR_clear_error();
- }
- } else {
- if (c->chain_store) {
- chain_store = c->chain_store;
- }
+int SSL_CTX_set1_chain(SSL_CTX *ctx, STACK_OF(X509) *chain) {
+ return ssl_cert_set1_chain(ctx->cert, chain);
+}
- if (flags & SSL_BUILD_CHAIN_FLAG_UNTRUSTED) {
- untrusted = cpk->chain;
- }
- }
+int SSL_set0_chain(SSL *ssl, STACK_OF(X509) *chain) {
+ return ssl_cert_set0_chain(ssl->cert, chain);
+}
- if (!X509_STORE_CTX_init(&xs_ctx, chain_store, cpk->x509, untrusted)) {
- OPENSSL_PUT_ERROR(SSL, ssl_build_cert_chain, ERR_R_X509_LIB);
- goto err;
- }
+int SSL_set1_chain(SSL *ssl, STACK_OF(X509) *chain) {
+ return ssl_cert_set1_chain(ssl->cert, chain);
+}
- i = X509_verify_cert(&xs_ctx);
- if (i <= 0 && flags & SSL_BUILD_CHAIN_FLAG_IGNORE_ERROR) {
- if (flags & SSL_BUILD_CHAIN_FLAG_CLEAR_ERROR) {
- ERR_clear_error();
- }
- i = 1;
- rv = 2;
- }
+int SSL_CTX_add0_chain_cert(SSL_CTX *ctx, X509 *x509) {
+ return ssl_cert_add0_chain_cert(ctx->cert, x509);
+}
- if (i > 0) {
- chain = X509_STORE_CTX_get1_chain(&xs_ctx);
- }
- if (i <= 0) {
- OPENSSL_PUT_ERROR(SSL, ssl_build_cert_chain,
- SSL_R_CERTIFICATE_VERIFY_FAILED);
- i = X509_STORE_CTX_get_error(&xs_ctx);
- ERR_add_error_data(2, "Verify error:", X509_verify_cert_error_string(i));
+int SSL_CTX_add1_chain_cert(SSL_CTX *ctx, X509 *x509) {
+ return ssl_cert_add1_chain_cert(ctx->cert, x509);
+}
- X509_STORE_CTX_cleanup(&xs_ctx);
- goto err;
- }
+int SSL_CTX_add_extra_chain_cert(SSL_CTX *ctx, X509 *x509) {
+ return SSL_CTX_add0_chain_cert(ctx, x509);
+}
- X509_STORE_CTX_cleanup(&xs_ctx);
- if (cpk->chain) {
- sk_X509_pop_free(cpk->chain, X509_free);
- }
+int SSL_add0_chain_cert(SSL *ssl, X509 *x509) {
+ return ssl_cert_add0_chain_cert(ssl->cert, x509);
+}
- /* Remove EE certificate from chain */
- x = sk_X509_shift(chain);
- X509_free(x);
- if (flags & SSL_BUILD_CHAIN_FLAG_NO_ROOT) {
- if (sk_X509_num(chain) > 0) {
- /* See if last cert is self signed */
- x = sk_X509_value(chain, sk_X509_num(chain) - 1);
- X509_check_purpose(x, -1, 0);
- if (x->ex_flags & EXFLAG_SS) {
- x = sk_X509_pop(chain);
- X509_free(x);
- }
- }
- }
+int SSL_add1_chain_cert(SSL *ssl, X509 *x509) {
+ return ssl_cert_add1_chain_cert(ssl->cert, x509);
+}
- cpk->chain = chain;
- if (rv == 0) {
- rv = 1;
- }
+int SSL_CTX_clear_chain_certs(SSL_CTX *ctx) {
+ return SSL_CTX_set0_chain(ctx, NULL);
+}
-err:
- if (flags & SSL_BUILD_CHAIN_FLAG_CHECK) {
- X509_STORE_free(chain_store);
- }
+int SSL_CTX_clear_extra_chain_certs(SSL_CTX *ctx) {
+ return SSL_CTX_clear_chain_certs(ctx);
+}
- return rv;
+int SSL_clear_chain_certs(SSL *ssl) {
+ return SSL_set0_chain(ssl, NULL);
}
-int ssl_cert_set_cert_store(CERT *c, X509_STORE *store, int chain, int ref) {
- X509_STORE **pstore;
- if (chain) {
- pstore = &c->chain_store;
- } else {
- pstore = &c->verify_store;
- }
+int SSL_CTX_get0_chain_certs(const SSL_CTX *ctx, STACK_OF(X509) **out_chain) {
+ *out_chain = ctx->cert->chain;
+ return 1;
+}
- X509_STORE_free(*pstore);
- *pstore = store;
+int SSL_CTX_get_extra_chain_certs(const SSL_CTX *ctx,
+ STACK_OF(X509) **out_chain) {
+ return SSL_CTX_get0_chain_certs(ctx, out_chain);
+}
- if (ref && store) {
- CRYPTO_refcount_inc(&store->references);
- }
+int SSL_get0_chain_certs(const SSL *ssl, STACK_OF(X509) **out_chain) {
+ *out_chain = ssl->cert->chain;
return 1;
}
diff --git a/src/ssl/ssl_cipher.c b/src/ssl/ssl_cipher.c
index 8d03c9e..b23d775 100644
--- a/src/ssl/ssl_cipher.c
+++ b/src/ssl/ssl_cipher.c
@@ -138,6 +138,8 @@
* OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR
* OTHERWISE. */
+#include <openssl/ssl.h>
+
#include <assert.h>
#include <stdio.h>
#include <string.h>
@@ -155,6 +157,12 @@
/* kCiphers is an array of all supported ciphers, sorted by id. */
const SSL_CIPHER kCiphers[] = {
/* The RSA ciphers */
+ /* Cipher 02 */
+ {
+ SSL3_TXT_RSA_NULL_SHA, SSL3_CK_RSA_NULL_SHA, SSL_kRSA, SSL_aRSA,
+ SSL_eNULL, SSL_SHA1, SSL_SSLV3, SSL_FIPS, SSL_HANDSHAKE_MAC_DEFAULT, 0, 0,
+ },
+
/* Cipher 04 */
{
SSL3_TXT_RSA_RC4_128_MD5, SSL3_CK_RSA_RC4_128_MD5, SSL_kRSA, SSL_aRSA,
@@ -270,8 +278,7 @@ const SSL_CIPHER kCiphers[] = {
TLS1_TXT_RSA_WITH_AES_128_GCM_SHA256,
TLS1_CK_RSA_WITH_AES_128_GCM_SHA256, SSL_kRSA, SSL_aRSA, SSL_AES128GCM,
SSL_AEAD, SSL_TLSV1_2, SSL_HIGH | SSL_FIPS,
- SSL_HANDSHAKE_MAC_SHA256 |
- SSL_CIPHER_ALGORITHM2_VARIABLE_NONCE_INCLUDED_IN_RECORD,
+ SSL_HANDSHAKE_MAC_SHA256,
128, 128,
},
@@ -280,8 +287,7 @@ const SSL_CIPHER kCiphers[] = {
TLS1_TXT_RSA_WITH_AES_256_GCM_SHA384,
TLS1_CK_RSA_WITH_AES_256_GCM_SHA384, SSL_kRSA, SSL_aRSA, SSL_AES256GCM,
SSL_AEAD, SSL_TLSV1_2, SSL_HIGH | SSL_FIPS,
- SSL_HANDSHAKE_MAC_SHA384 |
- SSL_CIPHER_ALGORITHM2_VARIABLE_NONCE_INCLUDED_IN_RECORD,
+ SSL_HANDSHAKE_MAC_SHA384,
256, 256,
},
@@ -290,8 +296,7 @@ const SSL_CIPHER kCiphers[] = {
TLS1_TXT_DHE_RSA_WITH_AES_128_GCM_SHA256,
TLS1_CK_DHE_RSA_WITH_AES_128_GCM_SHA256, SSL_kDHE, SSL_aRSA, SSL_AES128GCM,
SSL_AEAD, SSL_TLSV1_2, SSL_HIGH | SSL_FIPS,
- SSL_HANDSHAKE_MAC_SHA256 |
- SSL_CIPHER_ALGORITHM2_VARIABLE_NONCE_INCLUDED_IN_RECORD,
+ SSL_HANDSHAKE_MAC_SHA256,
128, 128,
},
@@ -300,8 +305,7 @@ const SSL_CIPHER kCiphers[] = {
TLS1_TXT_DHE_RSA_WITH_AES_256_GCM_SHA384,
TLS1_CK_DHE_RSA_WITH_AES_256_GCM_SHA384, SSL_kDHE, SSL_aRSA, SSL_AES256GCM,
SSL_AEAD, SSL_TLSV1_2, SSL_HIGH | SSL_FIPS,
- SSL_HANDSHAKE_MAC_SHA384 |
- SSL_CIPHER_ALGORITHM2_VARIABLE_NONCE_INCLUDED_IN_RECORD,
+ SSL_HANDSHAKE_MAC_SHA384,
256, 256,
},
@@ -395,8 +399,7 @@ const SSL_CIPHER kCiphers[] = {
TLS1_TXT_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, SSL_kECDHE, SSL_aECDSA,
SSL_AES128GCM, SSL_AEAD, SSL_TLSV1_2, SSL_HIGH | SSL_FIPS,
- SSL_HANDSHAKE_MAC_SHA256 |
- SSL_CIPHER_ALGORITHM2_VARIABLE_NONCE_INCLUDED_IN_RECORD,
+ SSL_HANDSHAKE_MAC_SHA256,
128, 128,
},
@@ -405,8 +408,7 @@ const SSL_CIPHER kCiphers[] = {
TLS1_TXT_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
TLS1_CK_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, SSL_kECDHE, SSL_aECDSA,
SSL_AES256GCM, SSL_AEAD, SSL_TLSV1_2, SSL_HIGH | SSL_FIPS,
- SSL_HANDSHAKE_MAC_SHA384 |
- SSL_CIPHER_ALGORITHM2_VARIABLE_NONCE_INCLUDED_IN_RECORD,
+ SSL_HANDSHAKE_MAC_SHA384,
256, 256,
},
@@ -415,8 +417,7 @@ const SSL_CIPHER kCiphers[] = {
TLS1_TXT_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, SSL_kECDHE, SSL_aRSA,
SSL_AES128GCM, SSL_AEAD, SSL_TLSV1_2, SSL_HIGH | SSL_FIPS,
- SSL_HANDSHAKE_MAC_SHA256 |
- SSL_CIPHER_ALGORITHM2_VARIABLE_NONCE_INCLUDED_IN_RECORD,
+ SSL_HANDSHAKE_MAC_SHA256,
128, 128,
},
@@ -425,8 +426,7 @@ const SSL_CIPHER kCiphers[] = {
TLS1_TXT_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
TLS1_CK_ECDHE_RSA_WITH_AES_256_GCM_SHA384, SSL_kECDHE, SSL_aRSA,
SSL_AES256GCM, SSL_AEAD, SSL_TLSV1_2, SSL_HIGH | SSL_FIPS,
- SSL_HANDSHAKE_MAC_SHA384 |
- SSL_CIPHER_ALGORITHM2_VARIABLE_NONCE_INCLUDED_IN_RECORD,
+ SSL_HANDSHAKE_MAC_SHA384,
256, 256,
},
@@ -448,15 +448,15 @@ const SSL_CIPHER kCiphers[] = {
SSL_HANDSHAKE_MAC_DEFAULT, 256, 256,
},
+#if !defined(BORINGSSL_ANDROID_SYSTEM)
/* ChaCha20-Poly1305 cipher suites. */
-#if !defined(ANDROID)
{
TLS1_TXT_ECDHE_RSA_WITH_CHACHA20_POLY1305,
TLS1_CK_ECDHE_RSA_CHACHA20_POLY1305, SSL_kECDHE, SSL_aRSA,
SSL_CHACHA20POLY1305, SSL_AEAD, SSL_TLSV1_2, SSL_HIGH,
SSL_HANDSHAKE_MAC_SHA256,
- 256, 0,
+ 256, 256,
},
{
@@ -464,33 +464,13 @@ const SSL_CIPHER kCiphers[] = {
TLS1_CK_ECDHE_ECDSA_CHACHA20_POLY1305, SSL_kECDHE, SSL_aECDSA,
SSL_CHACHA20POLY1305, SSL_AEAD, SSL_TLSV1_2, SSL_HIGH,
SSL_HANDSHAKE_MAC_SHA256,
- 256, 0,
- },
-
- {
- TLS1_TXT_DHE_RSA_WITH_CHACHA20_POLY1305,
- TLS1_CK_DHE_RSA_CHACHA20_POLY1305, SSL_kDHE, SSL_aRSA,
- SSL_CHACHA20POLY1305, SSL_AEAD, SSL_TLSV1_2, SSL_HIGH,
- SSL_HANDSHAKE_MAC_SHA256,
- 256, 0,
+ 256, 256,
},
#endif
};
static const size_t kCiphersLen = sizeof(kCiphers) / sizeof(kCiphers[0]);
-struct handshake_digest {
- uint32_t mask;
- const EVP_MD *(*md_func)(void);
-};
-
-static const struct handshake_digest ssl_handshake_digests[SSL_MAX_DIGEST] = {
- {SSL_HANDSHAKE_MAC_MD5, EVP_md5},
- {SSL_HANDSHAKE_MAC_SHA, EVP_sha1},
- {SSL_HANDSHAKE_MAC_SHA256, EVP_sha256},
- {SSL_HANDSHAKE_MAC_SHA384, EVP_sha384},
-};
-
#define CIPHER_ADD 1
#define CIPHER_KILL 2
#define CIPHER_DEL 3
@@ -521,7 +501,8 @@ typedef struct cipher_alias_st {
} CIPHER_ALIAS;
static const CIPHER_ALIAS kCipherAliases[] = {
- {SSL_TXT_ALL, ~0u, ~0u, ~0u, ~0u, ~0u, ~0u},
+ /* "ALL" doesn't include eNULL (must be specifically enabled) */
+ {SSL_TXT_ALL, ~0u, ~0u, ~SSL_eNULL, ~0u, ~0u, ~0u},
/* The "COMPLEMENTOFDEFAULT" rule is omitted. It matches nothing. */
@@ -542,7 +523,7 @@ static const CIPHER_ALIAS kCipherAliases[] = {
{SSL_TXT_kPSK, SSL_kPSK, ~0u, ~0u, ~0u, ~0u, ~0u},
/* server authentication aliases */
- {SSL_TXT_aRSA, ~0u, SSL_aRSA, ~0u, ~0u, ~0u, ~0u},
+ {SSL_TXT_aRSA, ~0u, SSL_aRSA, ~SSL_eNULL, ~0u, ~0u, ~0u},
{SSL_TXT_aECDSA, ~0u, SSL_aECDSA, ~0u, ~0u, ~0u, ~0u},
{SSL_TXT_ECDSA, ~0u, SSL_aECDSA, ~0u, ~0u, ~0u, ~0u},
{SSL_TXT_aPSK, ~0u, SSL_aPSK, ~0u, ~0u, ~0u, ~0u},
@@ -552,7 +533,7 @@ static const CIPHER_ALIAS kCipherAliases[] = {
{SSL_TXT_EDH, SSL_kDHE, ~0u, ~0u, ~0u, ~0u, ~0u},
{SSL_TXT_ECDHE, SSL_kECDHE, ~0u, ~0u, ~0u, ~0u, ~0u},
{SSL_TXT_EECDH, SSL_kECDHE, ~0u, ~0u, ~0u, ~0u, ~0u},
- {SSL_TXT_RSA, SSL_kRSA, SSL_aRSA, ~0u, ~0u, ~0u, ~0u},
+ {SSL_TXT_RSA, SSL_kRSA, SSL_aRSA, ~SSL_eNULL, ~0u, ~0u, ~0u},
{SSL_TXT_PSK, SSL_kPSK, SSL_aPSK, ~0u, ~0u, ~0u, ~0u},
/* symmetric encryption aliases */
@@ -566,21 +547,21 @@ static const CIPHER_ALIAS kCipherAliases[] = {
/* MAC aliases */
{SSL_TXT_MD5, ~0u, ~0u, ~0u, SSL_MD5, ~0u, ~0u},
- {SSL_TXT_SHA1, ~0u, ~0u, ~0u, SSL_SHA1, ~0u, ~0u},
- {SSL_TXT_SHA, ~0u, ~0u, ~0u, SSL_SHA1, ~0u, ~0u},
+ {SSL_TXT_SHA1, ~0u, ~0u, ~SSL_eNULL, SSL_SHA1, ~0u, ~0u},
+ {SSL_TXT_SHA, ~0u, ~0u, ~SSL_eNULL, SSL_SHA1, ~0u, ~0u},
{SSL_TXT_SHA256, ~0u, ~0u, ~0u, SSL_SHA256, ~0u, ~0u},
{SSL_TXT_SHA384, ~0u, ~0u, ~0u, SSL_SHA384, ~0u, ~0u},
/* protocol version aliases */
- {SSL_TXT_SSLV3, ~0u, ~0u, ~0u, ~0u, SSL_SSLV3, ~0u},
- {SSL_TXT_TLSV1, ~0u, ~0u, ~0u, ~0u, SSL_TLSV1, ~0u},
- {SSL_TXT_TLSV1_2, ~0u, ~0u, ~0u, ~0u, SSL_TLSV1_2, ~0u},
+ {SSL_TXT_SSLV3, ~0u, ~0u, ~SSL_eNULL, ~0u, SSL_SSLV3, ~0u},
+ {SSL_TXT_TLSV1, ~0u, ~0u, ~SSL_eNULL, ~0u, SSL_TLSV1, ~0u},
+ {SSL_TXT_TLSV1_2, ~0u, ~0u, ~SSL_eNULL, ~0u, SSL_TLSV1_2, ~0u},
/* strength classes */
{SSL_TXT_MEDIUM, ~0u, ~0u, ~0u, ~0u, ~0u, SSL_MEDIUM},
{SSL_TXT_HIGH, ~0u, ~0u, ~0u, ~0u, ~0u, SSL_HIGH},
/* FIPS 140-2 approved ciphersuite */
- {SSL_TXT_FIPS, ~0u, ~0u, ~0u, ~0u, ~0u, SSL_FIPS},
+ {SSL_TXT_FIPS, ~0u, ~0u, ~SSL_eNULL, ~0u, ~0u, SSL_FIPS},
};
static const size_t kCipherAliasesLen =
@@ -630,7 +611,7 @@ int ssl_cipher_get_evp_aead(const EVP_AEAD **out_aead,
*out_fixed_iv_len = 4;
return 1;
-#if !defined(ANDROID)
+#if !defined(BORINGSSL_ANDROID_SYSTEM)
case SSL_CHACHA20POLY1305:
*out_aead = EVP_aead_chacha20_poly1305();
*out_fixed_iv_len = 0;
@@ -725,19 +706,36 @@ int ssl_cipher_get_evp_aead(const EVP_AEAD **out_aead,
return 0;
}
+ case SSL_eNULL:
+ switch (cipher->algorithm_mac) {
+ case SSL_SHA1:
+ if (version == SSL3_VERSION) {
+ *out_aead = EVP_aead_null_sha1_ssl3();
+ } else {
+ *out_aead = EVP_aead_null_sha1_tls();
+ }
+ *out_mac_secret_len = SHA_DIGEST_LENGTH;
+ return 1;
+ default:
+ return 0;
+ }
+
default:
return 0;
}
}
-int ssl_get_handshake_digest(uint32_t *out_mask, const EVP_MD **out_md,
- size_t idx) {
- if (idx >= SSL_MAX_DIGEST) {
- return 0;
+const EVP_MD *ssl_get_handshake_digest(uint32_t algorithm_prf) {
+ switch (algorithm_prf) {
+ case SSL_HANDSHAKE_MAC_DEFAULT:
+ return EVP_sha1();
+ case SSL_HANDSHAKE_MAC_SHA256:
+ return EVP_sha256();
+ case SSL_HANDSHAKE_MAC_SHA384:
+ return EVP_sha384();
+ default:
+ return NULL;
}
- *out_mask = ssl_handshake_digests[idx].mask;
- *out_md = ssl_handshake_digests[idx].md_func();
- return 1;
}
#define ITEM_SEP(a) \
@@ -979,7 +977,7 @@ static int ssl_cipher_strength_sort(CIPHER_ORDER **head_p,
number_uses = OPENSSL_malloc((max_strength_bits + 1) * sizeof(int));
if (!number_uses) {
- OPENSSL_PUT_ERROR(SSL, ssl_cipher_strength_sort, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
return 0;
}
memset(number_uses, 0, (max_strength_bits + 1) * sizeof(int));
@@ -1041,8 +1039,7 @@ static int ssl_cipher_process_rulestr(const SSL_PROTOCOL_METHOD *ssl_method,
continue;
} else if (!(ch >= 'a' && ch <= 'z') && !(ch >= 'A' && ch <= 'Z') &&
!(ch >= '0' && ch <= '9')) {
- OPENSSL_PUT_ERROR(SSL, ssl_cipher_process_rulestr,
- SSL_R_UNEXPECTED_OPERATOR_IN_GROUP);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_OPERATOR_IN_GROUP);
retval = in_group = 0;
break;
} else {
@@ -1062,7 +1059,7 @@ static int ssl_cipher_process_rulestr(const SSL_PROTOCOL_METHOD *ssl_method,
l++;
} else if (ch == '[') {
if (in_group) {
- OPENSSL_PUT_ERROR(SSL, ssl_cipher_process_rulestr, SSL_R_NESTED_GROUP);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_NESTED_GROUP);
retval = in_group = 0;
break;
}
@@ -1077,8 +1074,7 @@ static int ssl_cipher_process_rulestr(const SSL_PROTOCOL_METHOD *ssl_method,
/* If preference groups are enabled, the only legal operator is +.
* Otherwise the in_group bits will get mixed up. */
if (has_group && rule != CIPHER_ADD) {
- OPENSSL_PUT_ERROR(SSL, ssl_cipher_process_rulestr,
- SSL_R_MIXED_SPECIAL_OPERATOR_WITH_GROUPS);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_MIXED_SPECIAL_OPERATOR_WITH_GROUPS);
retval = in_group = 0;
break;
}
@@ -1110,8 +1106,7 @@ static int ssl_cipher_process_rulestr(const SSL_PROTOCOL_METHOD *ssl_method,
if (buf_len == 0) {
/* We hit something we cannot deal with, it is no command or separator
* nor alphanumeric, so we call this an error. */
- OPENSSL_PUT_ERROR(SSL, ssl_cipher_process_rulestr,
- SSL_R_INVALID_COMMAND);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_COMMAND);
retval = in_group = 0;
l++;
break;
@@ -1165,8 +1160,7 @@ static int ssl_cipher_process_rulestr(const SSL_PROTOCOL_METHOD *ssl_method,
if (buf_len == 8 && !strncmp(buf, "STRENGTH", 8)) {
ok = ssl_cipher_strength_sort(head_p, tail_p);
} else {
- OPENSSL_PUT_ERROR(SSL, ssl_cipher_process_rulestr,
- SSL_R_INVALID_COMMAND);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_COMMAND);
}
if (ok == 0) {
@@ -1186,7 +1180,7 @@ static int ssl_cipher_process_rulestr(const SSL_PROTOCOL_METHOD *ssl_method,
}
if (in_group) {
- OPENSSL_PUT_ERROR(SSL, ssl_cipher_process_rulestr, SSL_R_INVALID_COMMAND);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_COMMAND);
retval = 0;
}
@@ -1216,7 +1210,7 @@ ssl_create_cipher_list(const SSL_PROTOCOL_METHOD *ssl_method,
* allocation. */
co_list = (CIPHER_ORDER *)OPENSSL_malloc(sizeof(CIPHER_ORDER) * kCiphersLen);
if (co_list == NULL) {
- OPENSSL_PUT_ERROR(SSL, ssl_create_cipher_list, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
return NULL;
}
@@ -1391,13 +1385,27 @@ int SSL_CIPHER_has_MD5_HMAC(const SSL_CIPHER *cipher) {
}
int SSL_CIPHER_is_AESGCM(const SSL_CIPHER *cipher) {
- return (cipher->algorithm_mac & (SSL_AES128GCM | SSL_AES256GCM)) != 0;
+ return (cipher->algorithm_enc & (SSL_AES128GCM | SSL_AES256GCM)) != 0;
}
int SSL_CIPHER_is_CHACHA20POLY1305(const SSL_CIPHER *cipher) {
return (cipher->algorithm_enc & SSL_CHACHA20POLY1305) != 0;
}
+int SSL_CIPHER_is_NULL(const SSL_CIPHER *cipher) {
+ return (cipher->algorithm_enc & SSL_eNULL) != 0;
+}
+
+int SSL_CIPHER_is_RC4(const SSL_CIPHER *cipher) {
+ return (cipher->algorithm_enc & SSL_RC4) != 0;
+}
+
+int SSL_CIPHER_is_block_cipher(const SSL_CIPHER *cipher) {
+ /* Neither stream cipher nor AEAD. */
+ return (cipher->algorithm_enc & (SSL_RC4 | SSL_eNULL)) == 0 &&
+ cipher->algorithm_mac != SSL_AEAD;
+}
+
/* return the actual cipher being used */
const char *SSL_CIPHER_get_name(const SSL_CIPHER *cipher) {
if (cipher != NULL) {
@@ -1472,27 +1480,24 @@ static const char *ssl_cipher_get_enc_name(const SSL_CIPHER *cipher) {
}
static const char *ssl_cipher_get_prf_name(const SSL_CIPHER *cipher) {
- if ((cipher->algorithm2 & SSL_HANDSHAKE_MAC_DEFAULT) ==
- SSL_HANDSHAKE_MAC_DEFAULT) {
- /* Before TLS 1.2, the PRF component is the hash used in the HMAC, which is
- * only ever MD5 or SHA-1. */
- switch (cipher->algorithm_mac) {
- case SSL_MD5:
- return "MD5";
- case SSL_SHA1:
- return "SHA";
- default:
- assert(0);
- return "UNKNOWN";
- }
- } else if (cipher->algorithm2 & SSL_HANDSHAKE_MAC_SHA256) {
- return "SHA256";
- } else if (cipher->algorithm2 & SSL_HANDSHAKE_MAC_SHA384) {
- return "SHA384";
- } else {
- assert(0);
- return "UNKNOWN";
+ switch (cipher->algorithm_prf) {
+ case SSL_HANDSHAKE_MAC_DEFAULT:
+ /* Before TLS 1.2, the PRF component is the hash used in the HMAC, which is
+ * only ever MD5 or SHA-1. */
+ switch (cipher->algorithm_mac) {
+ case SSL_MD5:
+ return "MD5";
+ case SSL_SHA1:
+ return "SHA";
+ }
+ break;
+ case SSL_HANDSHAKE_MAC_SHA256:
+ return "SHA256";
+ case SSL_HANDSHAKE_MAC_SHA384:
+ return "SHA384";
}
+ assert(0);
+ return "UNKNOWN";
}
char *SSL_CIPHER_get_rfc_name(const SSL_CIPHER *cipher) {
@@ -1625,6 +1630,10 @@ const char *SSL_CIPHER_description(const SSL_CIPHER *cipher, char *buf,
enc = "ChaCha20-Poly1305";
break;
+ case SSL_eNULL:
+ enc="None";
+ break;
+
default:
enc = "unknown";
break;
@@ -1674,29 +1683,28 @@ const char *SSL_CIPHER_get_version(const SSL_CIPHER *cipher) {
return "TLSv1/SSLv3";
}
-void *SSL_COMP_get_compression_methods(void) { return NULL; }
+COMP_METHOD *SSL_COMP_get_compression_methods(void) { return NULL; }
-int SSL_COMP_add_compression_method(int id, void *cm) { return 1; }
+int SSL_COMP_add_compression_method(int id, COMP_METHOD *cm) { return 1; }
-const char *SSL_COMP_get_name(const void *comp) { return NULL; }
+const char *SSL_COMP_get_name(const COMP_METHOD *comp) { return NULL; }
-int ssl_cipher_get_cert_index(const SSL_CIPHER *cipher) {
+int ssl_cipher_get_key_type(const SSL_CIPHER *cipher) {
uint32_t alg_a = cipher->algorithm_auth;
if (alg_a & SSL_aECDSA) {
- return SSL_PKEY_ECC;
+ return EVP_PKEY_EC;
} else if (alg_a & SSL_aRSA) {
- return SSL_PKEY_RSA_ENC;
+ return EVP_PKEY_RSA;
}
- return -1;
+ return EVP_PKEY_NONE;
}
int ssl_cipher_has_server_public_key(const SSL_CIPHER *cipher) {
- /* PSK-authenticated ciphers do not use a public key, except for
- * RSA_PSK. */
- if ((cipher->algorithm_auth & SSL_aPSK) &&
- !(cipher->algorithm_mkey & SSL_kRSA)) {
+ /* PSK-authenticated ciphers do not use a certificate. (RSA_PSK is not
+ * supported.) */
+ if (cipher->algorithm_auth & SSL_aPSK) {
return 0;
}
@@ -1713,3 +1721,34 @@ int ssl_cipher_requires_server_key_exchange(const SSL_CIPHER *cipher) {
/* It is optional in all others. */
return 0;
}
+
+size_t ssl_cipher_get_record_split_len(const SSL_CIPHER *cipher) {
+ size_t block_size;
+ switch (cipher->algorithm_enc) {
+ case SSL_3DES:
+ block_size = 8;
+ break;
+ case SSL_AES128:
+ case SSL_AES256:
+ block_size = 16;
+ break;
+ default:
+ return 0;
+ }
+
+ size_t mac_len;
+ switch (cipher->algorithm_mac) {
+ case SSL_MD5:
+ mac_len = MD5_DIGEST_LENGTH;
+ break;
+ case SSL_SHA1:
+ mac_len = SHA_DIGEST_LENGTH;
+ break;
+ default:
+ return 0;
+ }
+
+ size_t ret = 1 + mac_len;
+ ret += block_size - (ret % block_size);
+ return ret;
+}
diff --git a/src/ssl/ssl_file.c b/src/ssl/ssl_file.c
new file mode 100644
index 0000000..88ad5b7
--- /dev/null
+++ b/src/ssl/ssl_file.c
@@ -0,0 +1,623 @@
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+/* ====================================================================
+ * Copyright (c) 1998-2007 The OpenSSL Project. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ * software must display the following acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ * endorse or promote products derived from this software without
+ * prior written permission. For written permission, please contact
+ * openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ * nor may "OpenSSL" appear in their names without prior written
+ * permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ * acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com). This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com).
+ *
+ */
+
+#include <openssl/ssl.h>
+
+#include <errno.h>
+#include <string.h>
+
+#include <openssl/bio.h>
+#include <openssl/err.h>
+#include <openssl/mem.h>
+#include <openssl/pem.h>
+#include <openssl/stack.h>
+#include <openssl/x509.h>
+
+#include "../crypto/directory.h"
+#include "internal.h"
+
+
+static int xname_cmp(const X509_NAME **a, const X509_NAME **b) {
+ return X509_NAME_cmp(*a, *b);
+}
+
+/* TODO(davidben): Is there any reason this doesn't call
+ * |SSL_add_file_cert_subjects_to_stack|? */
+STACK_OF(X509_NAME) *SSL_load_client_CA_file(const char *file) {
+ BIO *in;
+ X509 *x = NULL;
+ X509_NAME *xn = NULL;
+ STACK_OF(X509_NAME) *ret = NULL, *sk;
+
+ sk = sk_X509_NAME_new(xname_cmp);
+ in = BIO_new(BIO_s_file());
+
+ if (sk == NULL || in == NULL) {
+ OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+
+ if (!BIO_read_filename(in, file)) {
+ goto err;
+ }
+
+ for (;;) {
+ if (PEM_read_bio_X509(in, &x, NULL, NULL) == NULL) {
+ break;
+ }
+ if (ret == NULL) {
+ ret = sk_X509_NAME_new_null();
+ if (ret == NULL) {
+ OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+ }
+ xn = X509_get_subject_name(x);
+ if (xn == NULL) {
+ goto err;
+ }
+
+ /* check for duplicates */
+ xn = X509_NAME_dup(xn);
+ if (xn == NULL) {
+ goto err;
+ }
+ if (sk_X509_NAME_find(sk, NULL, xn)) {
+ X509_NAME_free(xn);
+ } else {
+ sk_X509_NAME_push(sk, xn);
+ sk_X509_NAME_push(ret, xn);
+ }
+ }
+
+ if (0) {
+ err:
+ sk_X509_NAME_pop_free(ret, X509_NAME_free);
+ ret = NULL;
+ }
+
+ sk_X509_NAME_free(sk);
+ BIO_free(in);
+ X509_free(x);
+ if (ret != NULL) {
+ ERR_clear_error();
+ }
+ return ret;
+}
+
+int SSL_add_file_cert_subjects_to_stack(STACK_OF(X509_NAME) *stack,
+ const char *file) {
+ BIO *in;
+ X509 *x = NULL;
+ X509_NAME *xn = NULL;
+ int ret = 1;
+ int (*oldcmp)(const X509_NAME **a, const X509_NAME **b);
+
+ oldcmp = sk_X509_NAME_set_cmp_func(stack, xname_cmp);
+ in = BIO_new(BIO_s_file());
+
+ if (in == NULL) {
+ OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+
+ if (!BIO_read_filename(in, file)) {
+ goto err;
+ }
+
+ for (;;) {
+ if (PEM_read_bio_X509(in, &x, NULL, NULL) == NULL) {
+ break;
+ }
+ xn = X509_get_subject_name(x);
+ if (xn == NULL) {
+ goto err;
+ }
+ xn = X509_NAME_dup(xn);
+ if (xn == NULL) {
+ goto err;
+ }
+ if (sk_X509_NAME_find(stack, NULL, xn)) {
+ X509_NAME_free(xn);
+ } else {
+ sk_X509_NAME_push(stack, xn);
+ }
+ }
+
+ ERR_clear_error();
+
+ if (0) {
+ err:
+ ret = 0;
+ }
+
+ BIO_free(in);
+ X509_free(x);
+
+ (void) sk_X509_NAME_set_cmp_func(stack, oldcmp);
+
+ return ret;
+}
+
+/* Add a directory of certs to a stack.
+ *
+ * \param stack the stack to append to.
+ * \param dir the directory to append from. All files in this directory will be
+ * examined as potential certs. Any that are acceptable to
+ * SSL_add_dir_cert_subjects_to_stack() that are not already in the stack will
+ * be included.
+ * \return 1 for success, 0 for failure. Note that in the case of failure some
+ * certs may have been added to \c stack. */
+int SSL_add_dir_cert_subjects_to_stack(STACK_OF(X509_NAME) *stack,
+ const char *dir) {
+ OPENSSL_DIR_CTX *d = NULL;
+ const char *filename;
+ int ret = 0;
+
+ /* Note that a side effect is that the CAs will be sorted by name */
+ while ((filename = OPENSSL_DIR_read(&d, dir))) {
+ char buf[1024];
+ int r;
+
+ if (strlen(dir) + strlen(filename) + 2 > sizeof(buf)) {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_PATH_TOO_LONG);
+ goto err;
+ }
+
+ r = BIO_snprintf(buf, sizeof buf, "%s/%s", dir, filename);
+ if (r <= 0 || r >= (int)sizeof(buf) ||
+ !SSL_add_file_cert_subjects_to_stack(stack, buf)) {
+ goto err;
+ }
+ }
+
+ if (errno) {
+ OPENSSL_PUT_ERROR(SSL, ERR_R_SYS_LIB);
+ ERR_add_error_data(3, "OPENSSL_DIR_read(&ctx, '", dir, "')");
+ goto err;
+ }
+
+ ret = 1;
+
+err:
+ if (d) {
+ OPENSSL_DIR_end(&d);
+ }
+ return ret;
+}
+
+int SSL_use_certificate_file(SSL *ssl, const char *file, int type) {
+ int reason_code;
+ BIO *in;
+ int ret = 0;
+ X509 *x = NULL;
+
+ in = BIO_new(BIO_s_file());
+ if (in == NULL) {
+ OPENSSL_PUT_ERROR(SSL, ERR_R_BUF_LIB);
+ goto end;
+ }
+
+ if (BIO_read_filename(in, file) <= 0) {
+ OPENSSL_PUT_ERROR(SSL, ERR_R_SYS_LIB);
+ goto end;
+ }
+
+ if (type == SSL_FILETYPE_ASN1) {
+ reason_code = ERR_R_ASN1_LIB;
+ x = d2i_X509_bio(in, NULL);
+ } else if (type == SSL_FILETYPE_PEM) {
+ reason_code = ERR_R_PEM_LIB;
+ x = PEM_read_bio_X509(in, NULL, ssl->ctx->default_passwd_callback,
+ ssl->ctx->default_passwd_callback_userdata);
+ } else {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_SSL_FILETYPE);
+ goto end;
+ }
+
+ if (x == NULL) {
+ OPENSSL_PUT_ERROR(SSL, reason_code);
+ goto end;
+ }
+
+ ret = SSL_use_certificate(ssl, x);
+
+end:
+ X509_free(x);
+ BIO_free(in);
+
+ return ret;
+}
+
+int SSL_use_RSAPrivateKey_file(SSL *ssl, const char *file, int type) {
+ int reason_code, ret = 0;
+ BIO *in;
+ RSA *rsa = NULL;
+
+ in = BIO_new(BIO_s_file());
+ if (in == NULL) {
+ OPENSSL_PUT_ERROR(SSL, ERR_R_BUF_LIB);
+ goto end;
+ }
+
+ if (BIO_read_filename(in, file) <= 0) {
+ OPENSSL_PUT_ERROR(SSL, ERR_R_SYS_LIB);
+ goto end;
+ }
+
+ if (type == SSL_FILETYPE_ASN1) {
+ reason_code = ERR_R_ASN1_LIB;
+ rsa = d2i_RSAPrivateKey_bio(in, NULL);
+ } else if (type == SSL_FILETYPE_PEM) {
+ reason_code = ERR_R_PEM_LIB;
+ rsa =
+ PEM_read_bio_RSAPrivateKey(in, NULL, ssl->ctx->default_passwd_callback,
+ ssl->ctx->default_passwd_callback_userdata);
+ } else {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_SSL_FILETYPE);
+ goto end;
+ }
+
+ if (rsa == NULL) {
+ OPENSSL_PUT_ERROR(SSL, reason_code);
+ goto end;
+ }
+ ret = SSL_use_RSAPrivateKey(ssl, rsa);
+ RSA_free(rsa);
+
+end:
+ BIO_free(in);
+ return ret;
+}
+
+int SSL_use_PrivateKey_file(SSL *ssl, const char *file, int type) {
+ int reason_code, ret = 0;
+ BIO *in;
+ EVP_PKEY *pkey = NULL;
+
+ in = BIO_new(BIO_s_file());
+ if (in == NULL) {
+ OPENSSL_PUT_ERROR(SSL, ERR_R_BUF_LIB);
+ goto end;
+ }
+
+ if (BIO_read_filename(in, file) <= 0) {
+ OPENSSL_PUT_ERROR(SSL, ERR_R_SYS_LIB);
+ goto end;
+ }
+
+ if (type == SSL_FILETYPE_PEM) {
+ reason_code = ERR_R_PEM_LIB;
+ pkey = PEM_read_bio_PrivateKey(in, NULL, ssl->ctx->default_passwd_callback,
+ ssl->ctx->default_passwd_callback_userdata);
+ } else if (type == SSL_FILETYPE_ASN1) {
+ reason_code = ERR_R_ASN1_LIB;
+ pkey = d2i_PrivateKey_bio(in, NULL);
+ } else {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_SSL_FILETYPE);
+ goto end;
+ }
+
+ if (pkey == NULL) {
+ OPENSSL_PUT_ERROR(SSL, reason_code);
+ goto end;
+ }
+ ret = SSL_use_PrivateKey(ssl, pkey);
+ EVP_PKEY_free(pkey);
+
+end:
+ BIO_free(in);
+ return ret;
+}
+
+int SSL_CTX_use_certificate_file(SSL_CTX *ctx, const char *file, int type) {
+ int reason_code;
+ BIO *in;
+ int ret = 0;
+ X509 *x = NULL;
+
+ in = BIO_new(BIO_s_file());
+ if (in == NULL) {
+ OPENSSL_PUT_ERROR(SSL, ERR_R_BUF_LIB);
+ goto end;
+ }
+
+ if (BIO_read_filename(in, file) <= 0) {
+ OPENSSL_PUT_ERROR(SSL, ERR_R_SYS_LIB);
+ goto end;
+ }
+
+ if (type == SSL_FILETYPE_ASN1) {
+ reason_code = ERR_R_ASN1_LIB;
+ x = d2i_X509_bio(in, NULL);
+ } else if (type == SSL_FILETYPE_PEM) {
+ reason_code = ERR_R_PEM_LIB;
+ x = PEM_read_bio_X509(in, NULL, ctx->default_passwd_callback,
+ ctx->default_passwd_callback_userdata);
+ } else {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_SSL_FILETYPE);
+ goto end;
+ }
+
+ if (x == NULL) {
+ OPENSSL_PUT_ERROR(SSL, reason_code);
+ goto end;
+ }
+
+ ret = SSL_CTX_use_certificate(ctx, x);
+
+end:
+ X509_free(x);
+ BIO_free(in);
+ return ret;
+}
+
+int SSL_CTX_use_RSAPrivateKey_file(SSL_CTX *ctx, const char *file, int type) {
+ int reason_code, ret = 0;
+ BIO *in;
+ RSA *rsa = NULL;
+
+ in = BIO_new(BIO_s_file());
+ if (in == NULL) {
+ OPENSSL_PUT_ERROR(SSL, ERR_R_BUF_LIB);
+ goto end;
+ }
+
+ if (BIO_read_filename(in, file) <= 0) {
+ OPENSSL_PUT_ERROR(SSL, ERR_R_SYS_LIB);
+ goto end;
+ }
+
+ if (type == SSL_FILETYPE_ASN1) {
+ reason_code = ERR_R_ASN1_LIB;
+ rsa = d2i_RSAPrivateKey_bio(in, NULL);
+ } else if (type == SSL_FILETYPE_PEM) {
+ reason_code = ERR_R_PEM_LIB;
+ rsa = PEM_read_bio_RSAPrivateKey(in, NULL, ctx->default_passwd_callback,
+ ctx->default_passwd_callback_userdata);
+ } else {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_SSL_FILETYPE);
+ goto end;
+ }
+
+ if (rsa == NULL) {
+ OPENSSL_PUT_ERROR(SSL, reason_code);
+ goto end;
+ }
+ ret = SSL_CTX_use_RSAPrivateKey(ctx, rsa);
+ RSA_free(rsa);
+
+end:
+ BIO_free(in);
+ return ret;
+}
+
+int SSL_CTX_use_PrivateKey_file(SSL_CTX *ctx, const char *file, int type) {
+ int reason_code, ret = 0;
+ BIO *in;
+ EVP_PKEY *pkey = NULL;
+
+ in = BIO_new(BIO_s_file());
+ if (in == NULL) {
+ OPENSSL_PUT_ERROR(SSL, ERR_R_BUF_LIB);
+ goto end;
+ }
+
+ if (BIO_read_filename(in, file) <= 0) {
+ OPENSSL_PUT_ERROR(SSL, ERR_R_SYS_LIB);
+ goto end;
+ }
+
+ if (type == SSL_FILETYPE_PEM) {
+ reason_code = ERR_R_PEM_LIB;
+ pkey = PEM_read_bio_PrivateKey(in, NULL, ctx->default_passwd_callback,
+ ctx->default_passwd_callback_userdata);
+ } else if (type == SSL_FILETYPE_ASN1) {
+ reason_code = ERR_R_ASN1_LIB;
+ pkey = d2i_PrivateKey_bio(in, NULL);
+ } else {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_SSL_FILETYPE);
+ goto end;
+ }
+
+ if (pkey == NULL) {
+ OPENSSL_PUT_ERROR(SSL, reason_code);
+ goto end;
+ }
+ ret = SSL_CTX_use_PrivateKey(ctx, pkey);
+ EVP_PKEY_free(pkey);
+
+end:
+ BIO_free(in);
+ return ret;
+}
+
+/* Read a file that contains our certificate in "PEM" format, possibly followed
+ * by a sequence of CA certificates that should be sent to the peer in the
+ * Certificate message. */
+int SSL_CTX_use_certificate_chain_file(SSL_CTX *ctx, const char *file) {
+ BIO *in;
+ int ret = 0;
+ X509 *x = NULL;
+
+ ERR_clear_error(); /* clear error stack for SSL_CTX_use_certificate() */
+
+ in = BIO_new(BIO_s_file());
+ if (in == NULL) {
+ OPENSSL_PUT_ERROR(SSL, ERR_R_BUF_LIB);
+ goto end;
+ }
+
+ if (BIO_read_filename(in, file) <= 0) {
+ OPENSSL_PUT_ERROR(SSL, ERR_R_SYS_LIB);
+ goto end;
+ }
+
+ x = PEM_read_bio_X509_AUX(in, NULL, ctx->default_passwd_callback,
+ ctx->default_passwd_callback_userdata);
+ if (x == NULL) {
+ OPENSSL_PUT_ERROR(SSL, ERR_R_PEM_LIB);
+ goto end;
+ }
+
+ ret = SSL_CTX_use_certificate(ctx, x);
+
+ if (ERR_peek_error() != 0) {
+ ret = 0; /* Key/certificate mismatch doesn't imply ret==0 ... */
+ }
+
+ if (ret) {
+ /* If we could set up our certificate, now proceed to the CA
+ * certificates. */
+ X509 *ca;
+ int r;
+ uint32_t err;
+
+ SSL_CTX_clear_chain_certs(ctx);
+
+ while ((ca = PEM_read_bio_X509(in, NULL, ctx->default_passwd_callback,
+ ctx->default_passwd_callback_userdata)) !=
+ NULL) {
+ r = SSL_CTX_add0_chain_cert(ctx, ca);
+ if (!r) {
+ X509_free(ca);
+ ret = 0;
+ goto end;
+ }
+ /* Note that we must not free r if it was successfully added to the chain
+ * (while we must free the main certificate, since its reference count is
+ * increased by SSL_CTX_use_certificate). */
+ }
+
+ /* When the while loop ends, it's usually just EOF. */
+ err = ERR_peek_last_error();
+ if (ERR_GET_LIB(err) == ERR_LIB_PEM &&
+ ERR_GET_REASON(err) == PEM_R_NO_START_LINE) {
+ ERR_clear_error();
+ } else {
+ ret = 0; /* some real error */
+ }
+ }
+
+end:
+ X509_free(x);
+ BIO_free(in);
+ return ret;
+}
+
+void SSL_CTX_set_default_passwd_cb(SSL_CTX *ctx, pem_password_cb *cb) {
+ ctx->default_passwd_callback = cb;
+}
+
+void SSL_CTX_set_default_passwd_cb_userdata(SSL_CTX *ctx, void *data) {
+ ctx->default_passwd_callback_userdata = data;
+}
+
+IMPLEMENT_PEM_rw(SSL_SESSION, SSL_SESSION, PEM_STRING_SSL_SESSION, SSL_SESSION)
diff --git a/src/ssl/ssl_lib.c b/src/ssl/ssl_lib.c
index 9e1e308..74bd633 100644
--- a/src/ssl/ssl_lib.c
+++ b/src/ssl/ssl_lib.c
@@ -138,11 +138,14 @@
* OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR
* OTHERWISE. */
+#include <openssl/ssl.h>
+
#include <assert.h>
#include <stdio.h>
#include <string.h>
#include <openssl/bytestring.h>
+#include <openssl/crypto.h>
#include <openssl/dh.h>
#include <openssl/err.h>
#include <openssl/lhash.h>
@@ -155,6 +158,10 @@
#include "../crypto/internal.h"
+/* |SSL_R_UNKNOWN_PROTOCOL| is no longer emitted, but continue to define it
+ * to avoid downstream churn. */
+OPENSSL_DECLARE_ERROR_REASON(SSL, UNKNOWN_PROTOCOL)
+
/* Some error codes are special. Ensure the make_errors.go script never
* regresses this. */
OPENSSL_COMPILE_ASSERT(SSL_R_TLSV1_ALERT_NO_RENEGOTIATION ==
@@ -164,91 +171,192 @@ OPENSSL_COMPILE_ASSERT(SSL_R_TLSV1_ALERT_NO_RENEGOTIATION ==
/* kMaxHandshakeSize is the maximum size, in bytes, of a handshake message. */
static const size_t kMaxHandshakeSize = (1u << 24) - 1;
-static CRYPTO_EX_DATA_CLASS g_ex_data_class_ssl = CRYPTO_EX_DATA_CLASS_INIT;
-static CRYPTO_EX_DATA_CLASS g_ex_data_class_ssl_ctx = CRYPTO_EX_DATA_CLASS_INIT;
+static CRYPTO_EX_DATA_CLASS g_ex_data_class_ssl =
+ CRYPTO_EX_DATA_CLASS_INIT_WITH_APP_DATA;
+static CRYPTO_EX_DATA_CLASS g_ex_data_class_ssl_ctx =
+ CRYPTO_EX_DATA_CLASS_INIT_WITH_APP_DATA;
-int SSL_clear(SSL *ssl) {
- if (ssl->method == NULL) {
- OPENSSL_PUT_ERROR(SSL, SSL_clear, SSL_R_NO_METHOD_SPECIFIED);
- return 0;
+int SSL_library_init(void) {
+ CRYPTO_library_init();
+ return 1;
+}
+
+static uint32_t ssl_session_hash(const SSL_SESSION *a) {
+ uint32_t hash =
+ ((uint32_t)a->session_id[0]) ||
+ ((uint32_t)a->session_id[1] << 8) ||
+ ((uint32_t)a->session_id[2] << 16) ||
+ ((uint32_t)a->session_id[3] << 24);
+
+ return hash;
+}
+
+/* NB: If this function (or indeed the hash function which uses a sort of
+ * coarser function than this one) is changed, ensure
+ * SSL_CTX_has_matching_session_id() is checked accordingly. It relies on being
+ * able to construct an SSL_SESSION that will collide with any existing session
+ * with a matching session ID. */
+static int ssl_session_cmp(const SSL_SESSION *a, const SSL_SESSION *b) {
+ if (a->ssl_version != b->ssl_version) {
+ return 1;
}
- if (ssl_clear_bad_session(ssl)) {
- SSL_SESSION_free(ssl->session);
- ssl->session = NULL;
+ if (a->session_id_length != b->session_id_length) {
+ return 1;
}
- ssl->hit = 0;
- ssl->shutdown = 0;
+ return memcmp(a->session_id, b->session_id, a->session_id_length);
+}
- /* SSL_clear may be called before or after the |ssl| is initialized in either
- * accept or connect state. In the latter case, SSL_clear should preserve the
- * half and reset |ssl->state| accordingly. */
- if (ssl->handshake_func != NULL) {
- if (ssl->server) {
- SSL_set_accept_state(ssl);
- } else {
- SSL_set_connect_state(ssl);
- }
- } else {
- assert(ssl->state == 0);
+SSL_CTX *SSL_CTX_new(const SSL_METHOD *method) {
+ SSL_CTX *ret = NULL;
+
+ if (method == NULL) {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_NULL_SSL_METHOD_PASSED);
+ return NULL;
}
- /* TODO(davidben): Some state on |ssl| is reset both in |SSL_new| and
- * |SSL_clear| because it is per-connection state rather than configuration
- * state. Per-connection state should be on |ssl->s3| and |ssl->d1| so it is
- * naturally reset at the right points between |SSL_new|, |SSL_clear|, and
- * |ssl3_new|. */
+ if (SSL_get_ex_data_X509_STORE_CTX_idx() < 0) {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_X509_VERIFICATION_SETUP_PROBLEMS);
+ goto err;
+ }
- ssl->rwstate = SSL_NOTHING;
- ssl->rstate = SSL_ST_READ_HEADER;
+ ret = (SSL_CTX *)OPENSSL_malloc(sizeof(SSL_CTX));
+ if (ret == NULL) {
+ goto err;
+ }
- BUF_MEM_free(ssl->init_buf);
- ssl->init_buf = NULL;
+ memset(ret, 0, sizeof(SSL_CTX));
- ssl->packet = NULL;
- ssl->packet_length = 0;
+ ret->method = method->method;
- ssl_clear_cipher_ctx(ssl);
+ CRYPTO_MUTEX_init(&ret->lock);
- OPENSSL_free(ssl->next_proto_negotiated);
- ssl->next_proto_negotiated = NULL;
- ssl->next_proto_negotiated_len = 0;
+ ret->session_cache_mode = SSL_SESS_CACHE_SERVER;
+ ret->session_cache_size = SSL_SESSION_CACHE_MAX_SIZE_DEFAULT;
- /* The ssl->d1->mtu is simultaneously configuration (preserved across
- * clear) and connection-specific state (gets reset).
- *
- * TODO(davidben): Avoid this. */
- unsigned mtu = 0;
- if (ssl->d1 != NULL) {
- mtu = ssl->d1->mtu;
+ /* We take the system default */
+ ret->session_timeout = SSL_DEFAULT_SESSION_TIMEOUT;
+
+ ret->references = 1;
+
+ ret->max_cert_list = SSL_MAX_CERT_LIST_DEFAULT;
+ ret->verify_mode = SSL_VERIFY_NONE;
+ ret->cert = ssl_cert_new();
+ if (ret->cert == NULL) {
+ goto err;
}
- ssl->method->ssl_free(ssl);
- if (!ssl->method->ssl_new(ssl)) {
- return 0;
+ ret->sessions = lh_SSL_SESSION_new(ssl_session_hash, ssl_session_cmp);
+ if (ret->sessions == NULL) {
+ goto err;
+ }
+ ret->cert_store = X509_STORE_new();
+ if (ret->cert_store == NULL) {
+ goto err;
}
- ssl->enc_method = ssl3_get_enc_method(ssl->version);
- assert(ssl->enc_method != NULL);
- if (SSL_IS_DTLS(ssl) && (SSL_get_options(ssl) & SSL_OP_NO_QUERY_MTU)) {
- ssl->d1->mtu = mtu;
+ ssl_create_cipher_list(ret->method, &ret->cipher_list,
+ &ret->cipher_list_by_id, SSL_DEFAULT_CIPHER_LIST);
+ if (ret->cipher_list == NULL ||
+ sk_SSL_CIPHER_num(ret->cipher_list->ciphers) <= 0) {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_LIBRARY_HAS_NO_CIPHERS);
+ goto err2;
}
- ssl->client_version = ssl->version;
+ ret->param = X509_VERIFY_PARAM_new();
+ if (!ret->param) {
+ goto err;
+ }
- return 1;
+ ret->client_CA = sk_X509_NAME_new_null();
+ if (ret->client_CA == NULL) {
+ goto err;
+ }
+
+ CRYPTO_new_ex_data(&g_ex_data_class_ssl_ctx, ret, &ret->ex_data);
+
+ ret->max_send_fragment = SSL3_RT_MAX_PLAIN_LENGTH;
+
+ /* Setup RFC4507 ticket keys */
+ if (!RAND_bytes(ret->tlsext_tick_key_name, 16) ||
+ !RAND_bytes(ret->tlsext_tick_hmac_key, 16) ||
+ !RAND_bytes(ret->tlsext_tick_aes_key, 16)) {
+ ret->options |= SSL_OP_NO_TICKET;
+ }
+
+ /* Default is to connect to non-RI servers. When RI is more widely deployed
+ * might change this. */
+ ret->options |= SSL_OP_LEGACY_SERVER_CONNECT;
+
+ /* Lock the SSL_CTX to the specified version, for compatibility with legacy
+ * uses of SSL_METHOD. */
+ if (method->version != 0) {
+ SSL_CTX_set_max_version(ret, method->version);
+ SSL_CTX_set_min_version(ret, method->version);
+ }
+
+ return ret;
+
+err:
+ OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
+err2:
+ SSL_CTX_free(ret);
+ return NULL;
+}
+
+void SSL_CTX_free(SSL_CTX *ctx) {
+ if (ctx == NULL ||
+ !CRYPTO_refcount_dec_and_test_zero(&ctx->references)) {
+ return;
+ }
+
+ X509_VERIFY_PARAM_free(ctx->param);
+
+ /* Free internal session cache. However: the remove_cb() may reference the
+ * ex_data of SSL_CTX, thus the ex_data store can only be removed after the
+ * sessions were flushed. As the ex_data handling routines might also touch
+ * the session cache, the most secure solution seems to be: empty (flush) the
+ * cache, then free ex_data, then finally free the cache. (See ticket
+ * [openssl.org #212].) */
+ SSL_CTX_flush_sessions(ctx, 0);
+
+ CRYPTO_free_ex_data(&g_ex_data_class_ssl_ctx, ctx, &ctx->ex_data);
+
+ CRYPTO_MUTEX_cleanup(&ctx->lock);
+ lh_SSL_SESSION_free(ctx->sessions);
+ X509_STORE_free(ctx->cert_store);
+ ssl_cipher_preference_list_free(ctx->cipher_list);
+ sk_SSL_CIPHER_free(ctx->cipher_list_by_id);
+ ssl_cipher_preference_list_free(ctx->cipher_list_tls10);
+ ssl_cipher_preference_list_free(ctx->cipher_list_tls11);
+ ssl_cert_free(ctx->cert);
+ sk_SSL_CUSTOM_EXTENSION_pop_free(ctx->client_custom_extensions,
+ SSL_CUSTOM_EXTENSION_free);
+ sk_SSL_CUSTOM_EXTENSION_pop_free(ctx->server_custom_extensions,
+ SSL_CUSTOM_EXTENSION_free);
+ sk_X509_NAME_pop_free(ctx->client_CA, X509_NAME_free);
+ sk_SRTP_PROTECTION_PROFILE_free(ctx->srtp_profiles);
+ OPENSSL_free(ctx->psk_identity_hint);
+ OPENSSL_free(ctx->tlsext_ellipticcurvelist);
+ OPENSSL_free(ctx->alpn_client_proto_list);
+ OPENSSL_free(ctx->ocsp_response);
+ OPENSSL_free(ctx->signed_cert_timestamp_list);
+ EVP_PKEY_free(ctx->tlsext_channel_id_private);
+ BIO_free(ctx->keylog_bio);
+
+ OPENSSL_free(ctx);
}
SSL *SSL_new(SSL_CTX *ctx) {
SSL *s;
if (ctx == NULL) {
- OPENSSL_PUT_ERROR(SSL, SSL_new, SSL_R_NULL_SSL_CTX);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_NULL_SSL_CTX);
return NULL;
}
if (ctx->method == NULL) {
- OPENSSL_PUT_ERROR(SSL, SSL_new, SSL_R_SSL_CTX_HAS_NO_DEFAULT_SSL_VERSION);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_SSL_CTX_HAS_NO_DEFAULT_SSL_VERSION);
return NULL;
}
@@ -289,17 +397,8 @@ SSL *SSL_new(SSL_CTX *ctx) {
CRYPTO_refcount_inc(&ctx->references);
s->ctx = ctx;
- s->tlsext_ticket_expected = 0;
CRYPTO_refcount_inc(&ctx->references);
s->initial_ctx = ctx;
- if (ctx->tlsext_ecpointformatlist) {
- s->tlsext_ecpointformatlist = BUF_memdup(
- ctx->tlsext_ecpointformatlist, ctx->tlsext_ecpointformatlist_length);
- if (!s->tlsext_ecpointformatlist) {
- goto err;
- }
- s->tlsext_ecpointformatlist_length = ctx->tlsext_ecpointformatlist_length;
- }
if (ctx->tlsext_ellipticcurvelist) {
s->tlsext_ellipticcurvelist =
@@ -310,7 +409,6 @@ SSL *SSL_new(SSL_CTX *ctx) {
}
s->tlsext_ellipticcurvelist_length = ctx->tlsext_ellipticcurvelist_length;
}
- s->next_proto_negotiated = NULL;
if (s->ctx->alpn_client_proto_list) {
s->alpn_client_proto_list = BUF_memdup(s->ctx->alpn_client_proto_list,
@@ -331,7 +429,6 @@ SSL *SSL_new(SSL_CTX *ctx) {
assert(s->enc_method != NULL);
s->rwstate = SSL_NOTHING;
- s->rstate = SSL_ST_READ_HEADER;
CRYPTO_new_ex_data(&g_ex_data_class_ssl, s, &s->ex_data);
@@ -358,16 +455,474 @@ SSL *SSL_new(SSL_CTX *ctx) {
err:
SSL_free(s);
- OPENSSL_PUT_ERROR(SSL, SSL_new, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
return NULL;
}
+void SSL_free(SSL *ssl) {
+ if (ssl == NULL) {
+ return;
+ }
+
+ X509_VERIFY_PARAM_free(ssl->param);
+
+ CRYPTO_free_ex_data(&g_ex_data_class_ssl, ssl, &ssl->ex_data);
+
+ if (ssl->bbio != NULL) {
+ /* If the buffering BIO is in place, pop it off */
+ if (ssl->bbio == ssl->wbio) {
+ ssl->wbio = BIO_pop(ssl->wbio);
+ }
+ BIO_free(ssl->bbio);
+ ssl->bbio = NULL;
+ }
+
+ int free_wbio = ssl->wbio != ssl->rbio;
+ BIO_free_all(ssl->rbio);
+ if (free_wbio) {
+ BIO_free_all(ssl->wbio);
+ }
+
+ BUF_MEM_free(ssl->init_buf);
+
+ /* add extra stuff */
+ ssl_cipher_preference_list_free(ssl->cipher_list);
+ sk_SSL_CIPHER_free(ssl->cipher_list_by_id);
+
+ ssl_clear_bad_session(ssl);
+ SSL_SESSION_free(ssl->session);
+
+ ssl_clear_cipher_ctx(ssl);
+
+ ssl_cert_free(ssl->cert);
+
+ OPENSSL_free(ssl->tlsext_hostname);
+ SSL_CTX_free(ssl->initial_ctx);
+ OPENSSL_free(ssl->tlsext_ellipticcurvelist);
+ OPENSSL_free(ssl->alpn_client_proto_list);
+ EVP_PKEY_free(ssl->tlsext_channel_id_private);
+ OPENSSL_free(ssl->psk_identity_hint);
+ sk_X509_NAME_pop_free(ssl->client_CA, X509_NAME_free);
+ OPENSSL_free(ssl->next_proto_negotiated);
+ sk_SRTP_PROTECTION_PROFILE_free(ssl->srtp_profiles);
+
+ if (ssl->method != NULL) {
+ ssl->method->ssl_free(ssl);
+ }
+ SSL_CTX_free(ssl->ctx);
+
+ OPENSSL_free(ssl);
+}
+
+void SSL_set_connect_state(SSL *ssl) {
+ ssl->server = 0;
+ ssl->shutdown = 0;
+ ssl->state = SSL_ST_CONNECT;
+ ssl->handshake_func = ssl->method->ssl_connect;
+ /* clear the current cipher */
+ ssl_clear_cipher_ctx(ssl);
+}
+
+void SSL_set_accept_state(SSL *ssl) {
+ ssl->server = 1;
+ ssl->shutdown = 0;
+ ssl->state = SSL_ST_ACCEPT;
+ ssl->handshake_func = ssl->method->ssl_accept;
+ /* clear the current cipher */
+ ssl_clear_cipher_ctx(ssl);
+}
+
+void SSL_set_bio(SSL *ssl, BIO *rbio, BIO *wbio) {
+ /* If the output buffering BIO is still in place, remove it. */
+ if (ssl->bbio != NULL) {
+ if (ssl->wbio == ssl->bbio) {
+ ssl->wbio = ssl->wbio->next_bio;
+ ssl->bbio->next_bio = NULL;
+ }
+ }
+
+ if (ssl->rbio != rbio) {
+ BIO_free_all(ssl->rbio);
+ }
+ if (ssl->wbio != wbio && ssl->rbio != ssl->wbio) {
+ BIO_free_all(ssl->wbio);
+ }
+ ssl->rbio = rbio;
+ ssl->wbio = wbio;
+}
+
+BIO *SSL_get_rbio(const SSL *ssl) { return ssl->rbio; }
+
+BIO *SSL_get_wbio(const SSL *ssl) { return ssl->wbio; }
+
+int SSL_do_handshake(SSL *ssl) {
+ if (ssl->handshake_func == NULL) {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_CONNECTION_TYPE_NOT_SET);
+ return -1;
+ }
+
+ if (!SSL_in_init(ssl)) {
+ return 1;
+ }
+
+ return ssl->handshake_func(ssl);
+}
+
+int SSL_connect(SSL *ssl) {
+ if (ssl->handshake_func == 0) {
+ /* Not properly initialized yet */
+ SSL_set_connect_state(ssl);
+ }
+
+ if (ssl->handshake_func != ssl->method->ssl_connect) {
+ OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
+ return -1;
+ }
+
+ return ssl->handshake_func(ssl);
+}
+
+int SSL_accept(SSL *ssl) {
+ if (ssl->handshake_func == 0) {
+ /* Not properly initialized yet */
+ SSL_set_accept_state(ssl);
+ }
+
+ if (ssl->handshake_func != ssl->method->ssl_accept) {
+ OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
+ return -1;
+ }
+
+ return ssl->handshake_func(ssl);
+}
+
+int SSL_read(SSL *ssl, void *buf, int num) {
+ if (ssl->handshake_func == 0) {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_UNINITIALIZED);
+ return -1;
+ }
+
+ if (ssl->shutdown & SSL_RECEIVED_SHUTDOWN) {
+ ssl->rwstate = SSL_NOTHING;
+ return 0;
+ }
+
+ ERR_clear_system_error();
+ return ssl->method->ssl_read_app_data(ssl, buf, num, 0);
+}
+
+int SSL_peek(SSL *ssl, void *buf, int num) {
+ if (ssl->handshake_func == 0) {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_UNINITIALIZED);
+ return -1;
+ }
+
+ if (ssl->shutdown & SSL_RECEIVED_SHUTDOWN) {
+ return 0;
+ }
+
+ ERR_clear_system_error();
+ return ssl->method->ssl_read_app_data(ssl, buf, num, 1);
+}
+
+int SSL_write(SSL *ssl, const void *buf, int num) {
+ if (ssl->handshake_func == 0) {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_UNINITIALIZED);
+ return -1;
+ }
+
+ if (ssl->shutdown & SSL_SENT_SHUTDOWN) {
+ ssl->rwstate = SSL_NOTHING;
+ OPENSSL_PUT_ERROR(SSL, SSL_R_PROTOCOL_IS_SHUTDOWN);
+ return -1;
+ }
+
+ ERR_clear_system_error();
+ return ssl->method->ssl_write_app_data(ssl, buf, num);
+}
+
+int SSL_shutdown(SSL *ssl) {
+ /* Note that this function behaves differently from what one might expect.
+ * Return values are 0 for no success (yet), 1 for success; but calling it
+ * once is usually not enough, even if blocking I/O is used (see
+ * ssl3_shutdown). */
+
+ if (ssl->handshake_func == 0) {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_UNINITIALIZED);
+ return -1;
+ }
+
+ if (SSL_in_init(ssl)) {
+ return 1;
+ }
+
+ /* Do nothing if configured not to send a close_notify. */
+ if (ssl->quiet_shutdown) {
+ ssl->shutdown = SSL_SENT_SHUTDOWN | SSL_RECEIVED_SHUTDOWN;
+ return 1;
+ }
+
+ if (!(ssl->shutdown & SSL_SENT_SHUTDOWN)) {
+ ssl->shutdown |= SSL_SENT_SHUTDOWN;
+ ssl3_send_alert(ssl, SSL3_AL_WARNING, SSL_AD_CLOSE_NOTIFY);
+
+ /* our shutdown alert has been sent now, and if it still needs to be
+ * written, ssl->s3->alert_dispatch will be true */
+ if (ssl->s3->alert_dispatch) {
+ return -1; /* return WANT_WRITE */
+ }
+ } else if (ssl->s3->alert_dispatch) {
+ /* resend it if not sent */
+ int ret = ssl->method->ssl_dispatch_alert(ssl);
+ if (ret == -1) {
+ /* we only get to return -1 here the 2nd/Nth invocation, we must have
+ * already signalled return 0 upon a previous invoation, return
+ * WANT_WRITE */
+ return ret;
+ }
+ } else if (!(ssl->shutdown & SSL_RECEIVED_SHUTDOWN)) {
+ /* If we are waiting for a close from our peer, we are closed */
+ ssl->method->ssl_read_close_notify(ssl);
+ if (!(ssl->shutdown & SSL_RECEIVED_SHUTDOWN)) {
+ return -1; /* return WANT_READ */
+ }
+ }
+
+ if (ssl->shutdown == (SSL_SENT_SHUTDOWN | SSL_RECEIVED_SHUTDOWN) &&
+ !ssl->s3->alert_dispatch) {
+ return 1;
+ } else {
+ return 0;
+ }
+}
+
+int SSL_get_error(const SSL *ssl, int ret_code) {
+ int reason;
+ uint32_t err;
+ BIO *bio;
+
+ if (ret_code > 0) {
+ return SSL_ERROR_NONE;
+ }
+
+ /* Make things return SSL_ERROR_SYSCALL when doing SSL_do_handshake etc,
+ * where we do encode the error */
+ err = ERR_peek_error();
+ if (err != 0) {
+ if (ERR_GET_LIB(err) == ERR_LIB_SYS) {
+ return SSL_ERROR_SYSCALL;
+ }
+ return SSL_ERROR_SSL;
+ }
+
+ if (ret_code == 0) {
+ if ((ssl->shutdown & SSL_RECEIVED_SHUTDOWN) &&
+ (ssl->s3->warn_alert == SSL_AD_CLOSE_NOTIFY)) {
+ /* The socket was cleanly shut down with a close_notify. */
+ return SSL_ERROR_ZERO_RETURN;
+ }
+ /* An EOF was observed which violates the protocol, and the underlying
+ * transport does not participate in the error queue. Bubble up to the
+ * caller. */
+ return SSL_ERROR_SYSCALL;
+ }
+
+ if (SSL_want_session(ssl)) {
+ return SSL_ERROR_PENDING_SESSION;
+ }
+
+ if (SSL_want_certificate(ssl)) {
+ return SSL_ERROR_PENDING_CERTIFICATE;
+ }
+
+ if (SSL_want_read(ssl)) {
+ bio = SSL_get_rbio(ssl);
+ if (BIO_should_read(bio)) {
+ return SSL_ERROR_WANT_READ;
+ }
+
+ if (BIO_should_write(bio)) {
+ /* This one doesn't make too much sense ... We never try to write to the
+ * rbio, and an application program where rbio and wbio are separate
+ * couldn't even know what it should wait for. However if we ever set
+ * s->rwstate incorrectly (so that we have SSL_want_read(s) instead of
+ * SSL_want_write(s)) and rbio and wbio *are* the same, this test works
+ * around that bug; so it might be safer to keep it. */
+ return SSL_ERROR_WANT_WRITE;
+ }
+
+ if (BIO_should_io_special(bio)) {
+ reason = BIO_get_retry_reason(bio);
+ if (reason == BIO_RR_CONNECT) {
+ return SSL_ERROR_WANT_CONNECT;
+ }
+
+ if (reason == BIO_RR_ACCEPT) {
+ return SSL_ERROR_WANT_ACCEPT;
+ }
+
+ return SSL_ERROR_SYSCALL; /* unknown */
+ }
+ }
+
+ if (SSL_want_write(ssl)) {
+ bio = SSL_get_wbio(ssl);
+ if (BIO_should_write(bio)) {
+ return SSL_ERROR_WANT_WRITE;
+ }
+
+ if (BIO_should_read(bio)) {
+ /* See above (SSL_want_read(ssl) with BIO_should_write(bio)) */
+ return SSL_ERROR_WANT_READ;
+ }
+
+ if (BIO_should_io_special(bio)) {
+ reason = BIO_get_retry_reason(bio);
+ if (reason == BIO_RR_CONNECT) {
+ return SSL_ERROR_WANT_CONNECT;
+ }
+
+ if (reason == BIO_RR_ACCEPT) {
+ return SSL_ERROR_WANT_ACCEPT;
+ }
+
+ return SSL_ERROR_SYSCALL;
+ }
+ }
+
+ if (SSL_want_x509_lookup(ssl)) {
+ return SSL_ERROR_WANT_X509_LOOKUP;
+ }
+
+ if (SSL_want_channel_id_lookup(ssl)) {
+ return SSL_ERROR_WANT_CHANNEL_ID_LOOKUP;
+ }
+
+ if (SSL_want_private_key_operation(ssl)) {
+ return SSL_ERROR_WANT_PRIVATE_KEY_OPERATION;
+ }
+
+ return SSL_ERROR_SYSCALL;
+}
+
+void SSL_CTX_set_min_version(SSL_CTX *ctx, uint16_t version) {
+ ctx->min_version = version;
+}
+
+void SSL_CTX_set_max_version(SSL_CTX *ctx, uint16_t version) {
+ ctx->max_version = version;
+}
+
+void SSL_set_min_version(SSL *ssl, uint16_t version) {
+ ssl->min_version = version;
+}
+
+void SSL_set_max_version(SSL *ssl, uint16_t version) {
+ ssl->max_version = version;
+}
+
+uint32_t SSL_CTX_set_options(SSL_CTX *ctx, uint32_t options) {
+ ctx->options |= options;
+ return ctx->options;
+}
+
+uint32_t SSL_CTX_clear_options(SSL_CTX *ctx, uint32_t options) {
+ ctx->options &= ~options;
+ return ctx->options;
+}
+
+uint32_t SSL_CTX_get_options(const SSL_CTX *ctx) { return ctx->options; }
+
+uint32_t SSL_set_options(SSL *ssl, uint32_t options) {
+ ssl->options |= options;
+ return ssl->options;
+}
+
+uint32_t SSL_clear_options(SSL *ssl, uint32_t options) {
+ ssl->options &= ~options;
+ return ssl->options;
+}
+
+uint32_t SSL_get_options(const SSL *ssl) { return ssl->options; }
+
+uint32_t SSL_CTX_set_mode(SSL_CTX *ctx, uint32_t mode) {
+ ctx->mode |= mode;
+ return ctx->mode;
+}
+
+uint32_t SSL_CTX_clear_mode(SSL_CTX *ctx, uint32_t mode) {
+ ctx->mode &= ~mode;
+ return ctx->mode;
+}
+
+uint32_t SSL_CTX_get_mode(const SSL_CTX *ctx) { return ctx->mode; }
+
+uint32_t SSL_set_mode(SSL *ssl, uint32_t mode) {
+ ssl->mode |= mode;
+ return ssl->mode;
+}
+
+uint32_t SSL_clear_mode(SSL *ssl, uint32_t mode) {
+ ssl->mode &= ~mode;
+ return ssl->mode;
+}
+
+uint32_t SSL_get_mode(const SSL *ssl) { return ssl->mode; }
+
+X509 *SSL_get_peer_certificate(const SSL *ssl) {
+ if (ssl == NULL || ssl->session == NULL || ssl->session->peer == NULL) {
+ return NULL;
+ }
+ return X509_up_ref(ssl->session->peer);
+}
+
+STACK_OF(X509) *SSL_get_peer_cert_chain(const SSL *ssl) {
+ if (ssl == NULL || ssl->session == NULL) {
+ return NULL;
+ }
+ return ssl->session->cert_chain;
+}
+
+int SSL_get_tls_unique(const SSL *ssl, uint8_t *out, size_t *out_len,
+ size_t max_out) {
+ /* The tls-unique value is the first Finished message in the handshake, which
+ * is the client's in a full handshake and the server's for a resumption. See
+ * https://tools.ietf.org/html/rfc5929#section-3.1. */
+ const uint8_t *finished = ssl->s3->previous_client_finished;
+ size_t finished_len = ssl->s3->previous_client_finished_len;
+ if (ssl->hit) {
+ /* tls-unique is broken for resumed sessions unless EMS is used. */
+ if (!ssl->session->extended_master_secret) {
+ goto err;
+ }
+ finished = ssl->s3->previous_server_finished;
+ finished_len = ssl->s3->previous_server_finished_len;
+ }
+
+ if (!ssl->s3->initial_handshake_complete ||
+ ssl->version < TLS1_VERSION) {
+ goto err;
+ }
+
+ *out_len = finished_len;
+ if (finished_len > max_out) {
+ *out_len = max_out;
+ }
+
+ memcpy(out, finished, *out_len);
+ return 1;
+
+err:
+ *out_len = 0;
+ memset(out, 0, max_out);
+ return 0;
+}
+
int SSL_CTX_set_session_id_context(SSL_CTX *ctx, const uint8_t *sid_ctx,
- unsigned int sid_ctx_len) {
- if (sid_ctx_len > sizeof ctx->sid_ctx) {
- OPENSSL_PUT_ERROR(SSL, SSL_CTX_set_session_id_context,
- SSL_R_SSL_SESSION_ID_CONTEXT_TOO_LONG);
+ unsigned sid_ctx_len) {
+ if (sid_ctx_len > sizeof(ctx->sid_ctx)) {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_SSL_SESSION_ID_CONTEXT_TOO_LONG);
return 0;
}
ctx->sid_ctx_length = sid_ctx_len;
@@ -377,10 +932,9 @@ int SSL_CTX_set_session_id_context(SSL_CTX *ctx, const uint8_t *sid_ctx,
}
int SSL_set_session_id_context(SSL *ssl, const uint8_t *sid_ctx,
- unsigned int sid_ctx_len) {
+ unsigned sid_ctx_len) {
if (sid_ctx_len > SSL_MAX_SID_CTX_LENGTH) {
- OPENSSL_PUT_ERROR(SSL, SSL_set_session_id_context,
- SSL_R_SSL_SESSION_ID_CONTEXT_TOO_LONG);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_SSL_SESSION_ID_CONTEXT_TOO_LONG);
return 0;
}
ssl->sid_ctx_length = sid_ctx_len;
@@ -400,7 +954,7 @@ int SSL_set_generate_session_id(SSL *ssl, GEN_SESSION_CB cb) {
}
int SSL_has_matching_session_id(const SSL *ssl, const uint8_t *id,
- unsigned int id_len) {
+ unsigned id_len) {
/* A quick examination of SSL_SESSION_hash and SSL_SESSION_cmp shows how we
* can "construct" a session to give us the desired check - ie. to find if
* there's a session in the hash table that would conflict with any new
@@ -422,28 +976,28 @@ int SSL_has_matching_session_id(const SSL *ssl, const uint8_t *id,
return p != NULL;
}
-int SSL_CTX_set_purpose(SSL_CTX *s, int purpose) {
- return X509_VERIFY_PARAM_set_purpose(s->param, purpose);
+int SSL_CTX_set_purpose(SSL_CTX *ctx, int purpose) {
+ return X509_VERIFY_PARAM_set_purpose(ctx->param, purpose);
}
-int SSL_set_purpose(SSL *s, int purpose) {
- return X509_VERIFY_PARAM_set_purpose(s->param, purpose);
+int SSL_set_purpose(SSL *ssl, int purpose) {
+ return X509_VERIFY_PARAM_set_purpose(ssl->param, purpose);
}
-int SSL_CTX_set_trust(SSL_CTX *s, int trust) {
- return X509_VERIFY_PARAM_set_trust(s->param, trust);
+int SSL_CTX_set_trust(SSL_CTX *ctx, int trust) {
+ return X509_VERIFY_PARAM_set_trust(ctx->param, trust);
}
-int SSL_set_trust(SSL *s, int trust) {
- return X509_VERIFY_PARAM_set_trust(s->param, trust);
+int SSL_set_trust(SSL *ssl, int trust) {
+ return X509_VERIFY_PARAM_set_trust(ssl->param, trust);
}
-int SSL_CTX_set1_param(SSL_CTX *ctx, X509_VERIFY_PARAM *vpm) {
- return X509_VERIFY_PARAM_set1(ctx->param, vpm);
+int SSL_CTX_set1_param(SSL_CTX *ctx, const X509_VERIFY_PARAM *param) {
+ return X509_VERIFY_PARAM_set1(ctx->param, param);
}
-int SSL_set1_param(SSL *ssl, X509_VERIFY_PARAM *vpm) {
- return X509_VERIFY_PARAM_set1(ssl->param, vpm);
+int SSL_set1_param(SSL *ssl, const X509_VERIFY_PARAM *param) {
+ return X509_VERIFY_PARAM_set1(ssl->param, param);
}
void ssl_cipher_preference_list_free(
@@ -515,86 +1069,7 @@ X509_VERIFY_PARAM *SSL_CTX_get0_param(SSL_CTX *ctx) { return ctx->param; }
X509_VERIFY_PARAM *SSL_get0_param(SSL *ssl) { return ssl->param; }
-void SSL_certs_clear(SSL *s) { ssl_cert_clear_certs(s->cert); }
-
-void SSL_free(SSL *ssl) {
- if (ssl == NULL) {
- return;
- }
-
- X509_VERIFY_PARAM_free(ssl->param);
-
- CRYPTO_free_ex_data(&g_ex_data_class_ssl, ssl, &ssl->ex_data);
-
- if (ssl->bbio != NULL) {
- /* If the buffering BIO is in place, pop it off */
- if (ssl->bbio == ssl->wbio) {
- ssl->wbio = BIO_pop(ssl->wbio);
- }
- BIO_free(ssl->bbio);
- ssl->bbio = NULL;
- }
-
- int free_wbio = ssl->wbio != ssl->rbio;
- BIO_free_all(ssl->rbio);
- if (free_wbio) {
- BIO_free_all(ssl->wbio);
- }
-
- BUF_MEM_free(ssl->init_buf);
-
- /* add extra stuff */
- ssl_cipher_preference_list_free(ssl->cipher_list);
- sk_SSL_CIPHER_free(ssl->cipher_list_by_id);
-
- ssl_clear_bad_session(ssl);
- SSL_SESSION_free(ssl->session);
-
- ssl_clear_cipher_ctx(ssl);
-
- ssl_cert_free(ssl->cert);
-
- OPENSSL_free(ssl->tlsext_hostname);
- SSL_CTX_free(ssl->initial_ctx);
- OPENSSL_free(ssl->tlsext_ecpointformatlist);
- OPENSSL_free(ssl->tlsext_ellipticcurvelist);
- OPENSSL_free(ssl->alpn_client_proto_list);
- EVP_PKEY_free(ssl->tlsext_channel_id_private);
- OPENSSL_free(ssl->psk_identity_hint);
- sk_X509_NAME_pop_free(ssl->client_CA, X509_NAME_free);
- OPENSSL_free(ssl->next_proto_negotiated);
- sk_SRTP_PROTECTION_PROFILE_free(ssl->srtp_profiles);
-
- if (ssl->method != NULL) {
- ssl->method->ssl_free(ssl);
- }
- SSL_CTX_free(ssl->ctx);
-
- OPENSSL_free(ssl);
-}
-
-void SSL_set_bio(SSL *s, BIO *rbio, BIO *wbio) {
- /* If the output buffering BIO is still in place, remove it. */
- if (s->bbio != NULL) {
- if (s->wbio == s->bbio) {
- s->wbio = s->wbio->next_bio;
- s->bbio->next_bio = NULL;
- }
- }
-
- if (s->rbio != rbio) {
- BIO_free_all(s->rbio);
- }
- if (s->wbio != wbio && s->rbio != s->wbio) {
- BIO_free_all(s->wbio);
- }
- s->rbio = rbio;
- s->wbio = wbio;
-}
-
-BIO *SSL_get_rbio(const SSL *s) { return s->rbio; }
-
-BIO *SSL_get_wbio(const SSL *s) { return s->wbio; }
+void SSL_certs_clear(SSL *ssl) { ssl_cert_clear_certs(ssl->cert); }
int SSL_get_fd(const SSL *s) { return SSL_get_rfd(s); }
@@ -630,7 +1105,7 @@ int SSL_set_fd(SSL *s, int fd) {
bio = BIO_new(BIO_s_fd());
if (bio == NULL) {
- OPENSSL_PUT_ERROR(SSL, SSL_set_fd, ERR_R_BUF_LIB);
+ OPENSSL_PUT_ERROR(SSL, ERR_R_BUF_LIB);
goto err;
}
BIO_set_fd(bio, fd, BIO_NOCLOSE);
@@ -650,7 +1125,7 @@ int SSL_set_wfd(SSL *s, int fd) {
bio = BIO_new(BIO_s_fd());
if (bio == NULL) {
- OPENSSL_PUT_ERROR(SSL, SSL_set_wfd, ERR_R_BUF_LIB);
+ OPENSSL_PUT_ERROR(SSL, ERR_R_BUF_LIB);
goto err;
}
BIO_set_fd(bio, fd, BIO_NOCLOSE);
@@ -674,7 +1149,7 @@ int SSL_set_rfd(SSL *s, int fd) {
bio = BIO_new(BIO_s_fd());
if (bio == NULL) {
- OPENSSL_PUT_ERROR(SSL, SSL_set_rfd, ERR_R_BUF_LIB);
+ OPENSSL_PUT_ERROR(SSL, ERR_R_BUF_LIB);
goto err;
}
BIO_set_fd(bio, fd, BIO_NOCLOSE);
@@ -718,14 +1193,18 @@ size_t SSL_get_peer_finished(const SSL *s, void *buf, size_t count) {
return ret;
}
-int SSL_get_verify_mode(const SSL *s) { return s->verify_mode; }
+int SSL_get_verify_mode(const SSL *ssl) { return ssl->verify_mode; }
+
+int SSL_get_verify_depth(const SSL *ssl) {
+ return X509_VERIFY_PARAM_get_depth(ssl->param);
+}
-int SSL_get_verify_depth(const SSL *s) {
- return X509_VERIFY_PARAM_get_depth(s->param);
+int SSL_get_extms_support(const SSL *ssl) {
+ return ssl->s3->tmp.extended_master_secret == 1;
}
-int (*SSL_get_verify_callback(const SSL *s))(int, X509_STORE_CTX *) {
- return s->verify_callback;
+int (*SSL_get_verify_callback(const SSL *ssl))(int, X509_STORE_CTX *) {
+ return ssl->verify_callback;
}
int SSL_CTX_get_verify_mode(const SSL_CTX *ctx) { return ctx->verify_mode; }
@@ -734,20 +1213,21 @@ int SSL_CTX_get_verify_depth(const SSL_CTX *ctx) {
return X509_VERIFY_PARAM_get_depth(ctx->param);
}
-int (*SSL_CTX_get_verify_callback(const SSL_CTX *ctx))(int, X509_STORE_CTX *) {
+int (*SSL_CTX_get_verify_callback(const SSL_CTX *ctx))(
+ int ok, X509_STORE_CTX *store_ctx) {
return ctx->default_verify_callback;
}
-void SSL_set_verify(SSL *s, int mode,
- int (*callback)(int ok, X509_STORE_CTX *ctx)) {
- s->verify_mode = mode;
+void SSL_set_verify(SSL *ssl, int mode,
+ int (*callback)(int ok, X509_STORE_CTX *store_ctx)) {
+ ssl->verify_mode = mode;
if (callback != NULL) {
- s->verify_callback = callback;
+ ssl->verify_callback = callback;
}
}
-void SSL_set_verify_depth(SSL *s, int depth) {
- X509_VERIFY_PARAM_set_depth(s->param, depth);
+void SSL_set_verify_depth(SSL *ssl, int depth) {
+ X509_VERIFY_PARAM_set_depth(ssl->param, depth);
}
int SSL_CTX_get_read_ahead(const SSL_CTX *ctx) { return 0; }
@@ -759,226 +1239,47 @@ void SSL_CTX_set_read_ahead(SSL_CTX *ctx, int yes) { }
void SSL_set_read_ahead(SSL *s, int yes) { }
int SSL_pending(const SSL *s) {
- if (s->rstate == SSL_ST_READ_BODY) {
- return 0;
- }
-
return (s->s3->rrec.type == SSL3_RT_APPLICATION_DATA) ? s->s3->rrec.length
: 0;
}
-X509 *SSL_get_peer_certificate(const SSL *s) {
- X509 *r;
-
- if (s == NULL || s->session == NULL) {
- r = NULL;
- } else {
- r = s->session->peer;
- }
-
- if (r == NULL) {
- return NULL;
- }
-
- return X509_up_ref(r);
-}
-
-STACK_OF(X509) *SSL_get_peer_cert_chain(const SSL *s) {
- STACK_OF(X509) *r;
-
- if (s == NULL || s->session == NULL || s->session->sess_cert == NULL) {
- r = NULL;
- } else {
- r = s->session->sess_cert->cert_chain;
- }
-
- /* If we are a client, cert_chain includes the peer's own certificate; if we
- * are a server, it does not. */
- return r;
-}
-
/* Fix this so it checks all the valid key/cert options */
int SSL_CTX_check_private_key(const SSL_CTX *ctx) {
- if (ctx == NULL || ctx->cert == NULL || ctx->cert->key->x509 == NULL) {
- OPENSSL_PUT_ERROR(SSL, SSL_CTX_check_private_key,
- SSL_R_NO_CERTIFICATE_ASSIGNED);
+ if (ctx->cert->x509 == NULL) {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_NO_CERTIFICATE_ASSIGNED);
return 0;
}
- if (ctx->cert->key->privatekey == NULL) {
- OPENSSL_PUT_ERROR(SSL, SSL_CTX_check_private_key,
- SSL_R_NO_PRIVATE_KEY_ASSIGNED);
+ if (ctx->cert->privatekey == NULL) {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_NO_PRIVATE_KEY_ASSIGNED);
return 0;
}
- return X509_check_private_key(ctx->cert->key->x509,
- ctx->cert->key->privatekey);
+ return X509_check_private_key(ctx->cert->x509, ctx->cert->privatekey);
}
/* Fix this function so that it takes an optional type parameter */
int SSL_check_private_key(const SSL *ssl) {
- if (ssl == NULL) {
- OPENSSL_PUT_ERROR(SSL, SSL_check_private_key, ERR_R_PASSED_NULL_PARAMETER);
- return 0;
- }
-
- if (ssl->cert == NULL) {
- OPENSSL_PUT_ERROR(SSL, SSL_check_private_key,
- SSL_R_NO_CERTIFICATE_ASSIGNED);
- return 0;
- }
-
- if (ssl->cert->key->x509 == NULL) {
- OPENSSL_PUT_ERROR(SSL, SSL_check_private_key,
- SSL_R_NO_CERTIFICATE_ASSIGNED);
+ if (ssl->cert->x509 == NULL) {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_NO_CERTIFICATE_ASSIGNED);
return 0;
}
- if (ssl->cert->key->privatekey == NULL) {
- OPENSSL_PUT_ERROR(SSL, SSL_check_private_key,
- SSL_R_NO_PRIVATE_KEY_ASSIGNED);
+ if (ssl->cert->privatekey == NULL) {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_NO_PRIVATE_KEY_ASSIGNED);
return 0;
}
- return X509_check_private_key(ssl->cert->key->x509,
- ssl->cert->key->privatekey);
-}
-
-int SSL_accept(SSL *s) {
- if (s->handshake_func == 0) {
- /* Not properly initialized yet */
- SSL_set_accept_state(s);
- }
-
- if (s->handshake_func != s->method->ssl_accept) {
- OPENSSL_PUT_ERROR(SSL, SSL_accept, ERR_R_INTERNAL_ERROR);
- return -1;
- }
-
- return s->handshake_func(s);
-}
-
-int SSL_connect(SSL *s) {
- if (s->handshake_func == 0) {
- /* Not properly initialized yet */
- SSL_set_connect_state(s);
- }
-
- if (s->handshake_func != s->method->ssl_connect) {
- OPENSSL_PUT_ERROR(SSL, SSL_connect, ERR_R_INTERNAL_ERROR);
- return -1;
- }
-
- return s->handshake_func(s);
+ return X509_check_private_key(ssl->cert->x509, ssl->cert->privatekey);
}
-long SSL_get_default_timeout(const SSL *s) {
+long SSL_get_default_timeout(const SSL *ssl) {
return SSL_DEFAULT_SESSION_TIMEOUT;
}
-int SSL_read(SSL *s, void *buf, int num) {
- if (s->handshake_func == 0) {
- OPENSSL_PUT_ERROR(SSL, SSL_read, SSL_R_UNINITIALIZED);
- return -1;
- }
-
- if (s->shutdown & SSL_RECEIVED_SHUTDOWN) {
- s->rwstate = SSL_NOTHING;
- return 0;
- }
-
- ERR_clear_system_error();
- return s->method->ssl_read_app_data(s, buf, num, 0);
-}
-
-int SSL_peek(SSL *s, void *buf, int num) {
- if (s->handshake_func == 0) {
- OPENSSL_PUT_ERROR(SSL, SSL_peek, SSL_R_UNINITIALIZED);
- return -1;
- }
-
- if (s->shutdown & SSL_RECEIVED_SHUTDOWN) {
- return 0;
- }
-
- ERR_clear_system_error();
- return s->method->ssl_read_app_data(s, buf, num, 1);
-}
-
-int SSL_write(SSL *s, const void *buf, int num) {
- if (s->handshake_func == 0) {
- OPENSSL_PUT_ERROR(SSL, SSL_write, SSL_R_UNINITIALIZED);
- return -1;
- }
-
- if (s->shutdown & SSL_SENT_SHUTDOWN) {
- s->rwstate = SSL_NOTHING;
- OPENSSL_PUT_ERROR(SSL, SSL_write, SSL_R_PROTOCOL_IS_SHUTDOWN);
- return -1;
- }
-
- ERR_clear_system_error();
- return s->method->ssl_write_app_data(s, buf, num);
-}
-
-int SSL_shutdown(SSL *s) {
- /* Note that this function behaves differently from what one might expect.
- * Return values are 0 for no success (yet), 1 for success; but calling it
- * once is usually not enough, even if blocking I/O is used (see
- * ssl3_shutdown). */
-
- if (s->handshake_func == 0) {
- OPENSSL_PUT_ERROR(SSL, SSL_shutdown, SSL_R_UNINITIALIZED);
- return -1;
- }
-
- if (SSL_in_init(s)) {
- return 1;
- }
-
- /* Do nothing if configured not to send a close_notify. */
- if (s->quiet_shutdown) {
- s->shutdown = SSL_SENT_SHUTDOWN | SSL_RECEIVED_SHUTDOWN;
- return 1;
- }
-
- if (!(s->shutdown & SSL_SENT_SHUTDOWN)) {
- s->shutdown |= SSL_SENT_SHUTDOWN;
- ssl3_send_alert(s, SSL3_AL_WARNING, SSL_AD_CLOSE_NOTIFY);
-
- /* our shutdown alert has been sent now, and if it still needs to be
- * written, s->s3->alert_dispatch will be true */
- if (s->s3->alert_dispatch) {
- return -1; /* return WANT_WRITE */
- }
- } else if (s->s3->alert_dispatch) {
- /* resend it if not sent */
- int ret = s->method->ssl_dispatch_alert(s);
- if (ret == -1) {
- /* we only get to return -1 here the 2nd/Nth invocation, we must have
- * already signalled return 0 upon a previous invoation, return
- * WANT_WRITE */
- return ret;
- }
- } else if (!(s->shutdown & SSL_RECEIVED_SHUTDOWN)) {
- /* If we are waiting for a close from our peer, we are closed */
- s->method->ssl_read_close_notify(s);
- if (!(s->shutdown & SSL_RECEIVED_SHUTDOWN)) {
- return -1; /* return WANT_READ */
- }
- }
-
- if (s->shutdown == (SSL_SENT_SHUTDOWN | SSL_RECEIVED_SHUTDOWN) &&
- !s->s3->alert_dispatch) {
- return 1;
- } else {
- return 0;
- }
-}
-
int SSL_renegotiate(SSL *ssl) {
/* Caller-initiated renegotiation is not supported. */
- OPENSSL_PUT_ERROR(SSL, SSL_renegotiate, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+ OPENSSL_PUT_ERROR(SSL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
return 0;
}
@@ -986,54 +1287,6 @@ int SSL_renegotiate_pending(SSL *ssl) {
return SSL_in_init(ssl) && ssl->s3->initial_handshake_complete;
}
-uint32_t SSL_CTX_set_options(SSL_CTX *ctx, uint32_t options) {
- ctx->options |= options;
- return ctx->options;
-}
-
-uint32_t SSL_set_options(SSL *ssl, uint32_t options) {
- ssl->options |= options;
- return ssl->options;
-}
-
-uint32_t SSL_CTX_clear_options(SSL_CTX *ctx, uint32_t options) {
- ctx->options &= ~options;
- return ctx->options;
-}
-
-uint32_t SSL_clear_options(SSL *ssl, uint32_t options) {
- ssl->options &= ~options;
- return ssl->options;
-}
-
-uint32_t SSL_CTX_get_options(const SSL_CTX *ctx) { return ctx->options; }
-
-uint32_t SSL_get_options(const SSL *ssl) { return ssl->options; }
-
-uint32_t SSL_CTX_set_mode(SSL_CTX *ctx, uint32_t mode) {
- ctx->mode |= mode;
- return ctx->mode;
-}
-
-uint32_t SSL_set_mode(SSL *ssl, uint32_t mode) {
- ssl->mode |= mode;
- return ssl->mode;
-}
-
-uint32_t SSL_CTX_clear_mode(SSL_CTX *ctx, uint32_t mode) {
- ctx->mode &= ~mode;
- return ctx->mode;
-}
-
-uint32_t SSL_clear_mode(SSL *ssl, uint32_t mode) {
- ssl->mode &= ~mode;
- return ssl->mode;
-}
-
-uint32_t SSL_CTX_get_mode(const SSL_CTX *ctx) { return ctx->mode; }
-
-uint32_t SSL_get_mode(const SSL *ssl) { return ssl->mode; }
-
size_t SSL_CTX_get_max_cert_list(const SSL_CTX *ctx) {
return ctx->max_cert_list;
}
@@ -1088,10 +1341,6 @@ int SSL_get_secure_renegotiation_support(const SSL *ssl) {
return ssl->s3->send_connection_binding;
}
-long SSL_ctrl(SSL *s, int cmd, long larg, void *parg) {
- return s->method->ssl_ctrl(s, cmd, larg, parg);
-}
-
LHASH_OF(SSL_SESSION) *SSL_CTX_sessions(SSL_CTX *ctx) { return ctx->sessions; }
size_t SSL_CTX_sess_number(const SSL_CTX *ctx) {
@@ -1118,10 +1367,6 @@ int SSL_CTX_get_session_cache_mode(const SSL_CTX *ctx) {
return ctx->session_cache_mode;
}
-long SSL_CTX_ctrl(SSL_CTX *ctx, int cmd, long larg, void *parg) {
- return ctx->method->ssl_ctx_ctrl(ctx, cmd, larg, parg);
-}
-
/* return a STACK of the ciphers available for the SSL and in order of
* preference */
STACK_OF(SSL_CIPHER) *SSL_get_ciphers(const SSL *s) {
@@ -1138,6 +1383,11 @@ STACK_OF(SSL_CIPHER) *SSL_get_ciphers(const SSL *s) {
return s->ctx->cipher_list_tls11->ciphers;
}
+ if (s->version >= TLS1_VERSION && s->ctx != NULL &&
+ s->ctx->cipher_list_tls10 != NULL) {
+ return s->ctx->cipher_list_tls10->ciphers;
+ }
+
if (s->ctx != NULL && s->ctx->cipher_list != NULL) {
return s->ctx->cipher_list->ciphers;
}
@@ -1199,7 +1449,21 @@ int SSL_CTX_set_cipher_list(SSL_CTX *ctx, const char *str) {
if (sk == NULL) {
return 0;
} else if (sk_SSL_CIPHER_num(sk) == 0) {
- OPENSSL_PUT_ERROR(SSL, SSL_CTX_set_cipher_list, SSL_R_NO_CIPHER_MATCH);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_NO_CIPHER_MATCH);
+ return 0;
+ }
+
+ return 1;
+}
+
+int SSL_CTX_set_cipher_list_tls10(SSL_CTX *ctx, const char *str) {
+ STACK_OF(SSL_CIPHER) *sk;
+
+ sk = ssl_create_cipher_list(ctx->method, &ctx->cipher_list_tls10, NULL, str);
+ if (sk == NULL) {
+ return 0;
+ } else if (sk_SSL_CIPHER_num(sk) == 0) {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_NO_CIPHER_MATCH);
return 0;
}
@@ -1213,8 +1477,7 @@ int SSL_CTX_set_cipher_list_tls11(SSL_CTX *ctx, const char *str) {
if (sk == NULL) {
return 0;
} else if (sk_SSL_CIPHER_num(sk) == 0) {
- OPENSSL_PUT_ERROR(SSL, SSL_CTX_set_cipher_list_tls11,
- SSL_R_NO_CIPHER_MATCH);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_NO_CIPHER_MATCH);
return 0;
}
@@ -1232,7 +1495,7 @@ int SSL_set_cipher_list(SSL *s, const char *str) {
if (sk == NULL) {
return 0;
} else if (sk_SSL_CIPHER_num(sk) == 0) {
- OPENSSL_PUT_ERROR(SSL, SSL_set_cipher_list, SSL_R_NO_CIPHER_MATCH);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_NO_CIPHER_MATCH);
return 0;
}
@@ -1268,9 +1531,13 @@ int ssl_cipher_list_to_bytes(SSL *s, STACK_OF(SSL_CIPHER) *sk, uint8_t *p) {
return 0;
}
- /* Add SCSVs. */
- if (!s->s3->initial_handshake_complete) {
+ /* For SSLv3, the SCSV is added. Otherwise the renegotiation extension is
+ * added. */
+ if (s->client_version == SSL3_VERSION &&
+ !s->s3->initial_handshake_complete) {
s2n(SSL3_CK_SCSV & 0xffff, p);
+ /* The renegotiation extension is required to be at index zero. */
+ s->s3->tmp.extensions.sent |= (1u << 0);
}
if (s->mode & SSL_MODE_SEND_FALLBACK_SCSV) {
@@ -1290,14 +1557,13 @@ STACK_OF(SSL_CIPHER) *ssl_bytes_to_cipher_list(SSL *s, const CBS *cbs) {
}
if (CBS_len(&cipher_suites) % 2 != 0) {
- OPENSSL_PUT_ERROR(SSL, ssl_bytes_to_cipher_list,
- SSL_R_ERROR_IN_RECEIVED_CIPHER_LIST);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_ERROR_IN_RECEIVED_CIPHER_LIST);
return NULL;
}
sk = sk_SSL_CIPHER_new_null();
if (sk == NULL) {
- OPENSSL_PUT_ERROR(SSL, ssl_bytes_to_cipher_list, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
goto err;
}
@@ -1305,7 +1571,7 @@ STACK_OF(SSL_CIPHER) *ssl_bytes_to_cipher_list(SSL *s, const CBS *cbs) {
uint16_t cipher_suite;
if (!CBS_get_u16(&cipher_suites, &cipher_suite)) {
- OPENSSL_PUT_ERROR(SSL, ssl_bytes_to_cipher_list, ERR_R_INTERNAL_ERROR);
+ OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
goto err;
}
@@ -1313,8 +1579,7 @@ STACK_OF(SSL_CIPHER) *ssl_bytes_to_cipher_list(SSL *s, const CBS *cbs) {
if (s->s3 && cipher_suite == (SSL3_CK_SCSV & 0xffff)) {
/* SCSV is fatal if renegotiating. */
if (s->s3->initial_handshake_complete) {
- OPENSSL_PUT_ERROR(SSL, ssl_bytes_to_cipher_list,
- SSL_R_SCSV_RECEIVED_WHEN_RENEGOTIATING);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_SCSV_RECEIVED_WHEN_RENEGOTIATING);
ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE);
goto err;
}
@@ -1327,8 +1592,7 @@ STACK_OF(SSL_CIPHER) *ssl_bytes_to_cipher_list(SSL *s, const CBS *cbs) {
uint16_t max_version = ssl3_get_max_server_version(s);
if (SSL_IS_DTLS(s) ? (uint16_t)s->version > max_version
: (uint16_t)s->version < max_version) {
- OPENSSL_PUT_ERROR(SSL, ssl_bytes_to_cipher_list,
- SSL_R_INAPPROPRIATE_FALLBACK);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_INAPPROPRIATE_FALLBACK);
ssl3_send_alert(s, SSL3_AL_FATAL, SSL3_AD_INAPPROPRIATE_FALLBACK);
goto err;
}
@@ -1337,7 +1601,7 @@ STACK_OF(SSL_CIPHER) *ssl_bytes_to_cipher_list(SSL *s, const CBS *cbs) {
c = SSL_get_cipher_by_value(cipher_suite);
if (c != NULL && !sk_SSL_CIPHER_push(sk, c)) {
- OPENSSL_PUT_ERROR(SSL, ssl_bytes_to_cipher_list, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
goto err;
}
}
@@ -1415,39 +1679,37 @@ void SSL_get0_ocsp_response(const SSL *ssl, const uint8_t **out,
*out_len = session->ocsp_response_length;
}
-/* SSL_select_next_proto implements the standard protocol selection. It is
- * expected that this function is called from the callback set by
- * SSL_CTX_set_next_proto_select_cb.
- *
- * The protocol data is assumed to be a vector of 8-bit, length prefixed byte
- * strings. The length byte itself is not included in the length. A byte
- * string of length 0 is invalid. No byte string may be truncated.
- *
- * The current, but experimental algorithm for selecting the protocol is:
- *
- * 1) If the server doesn't support NPN then this is indicated to the
- * callback. In this case, the client application has to abort the connection
- * or have a default application level protocol.
- *
- * 2) If the server supports NPN, but advertises an empty list then the
- * client selects the first protcol in its list, but indicates via the
- * API that this fallback case was enacted.
- *
- * 3) Otherwise, the client finds the first protocol in the server's list
- * that it supports and selects this protocol. This is because it's
- * assumed that the server has better information about which protocol
- * a client should use.
- *
- * 4) If the client doesn't support any of the server's advertised
- * protocols, then this is treated the same as case 2.
- *
- * It returns either
- * OPENSSL_NPN_NEGOTIATED if a common protocol was found, or
- * OPENSSL_NPN_NO_OVERLAP if the fallback case was reached.
- */
-int SSL_select_next_proto(uint8_t **out, uint8_t *outlen, const uint8_t *server,
- unsigned int server_len, const uint8_t *client,
- unsigned int client_len) {
+int SSL_CTX_set_signed_cert_timestamp_list(SSL_CTX *ctx, const uint8_t *list,
+ size_t list_len) {
+ OPENSSL_free(ctx->signed_cert_timestamp_list);
+ ctx->signed_cert_timestamp_list_length = 0;
+
+ ctx->signed_cert_timestamp_list = BUF_memdup(list, list_len);
+ if (ctx->signed_cert_timestamp_list == NULL) {
+ return 0;
+ }
+ ctx->signed_cert_timestamp_list_length = list_len;
+
+ return 1;
+}
+
+int SSL_CTX_set_ocsp_response(SSL_CTX *ctx, const uint8_t *response,
+ size_t response_len) {
+ OPENSSL_free(ctx->ocsp_response);
+ ctx->ocsp_response_length = 0;
+
+ ctx->ocsp_response = BUF_memdup(response, response_len);
+ if (ctx->ocsp_response == NULL) {
+ return 0;
+ }
+ ctx->ocsp_response_length = response_len;
+
+ return 1;
+}
+
+int SSL_select_next_proto(uint8_t **out, uint8_t *out_len,
+ const uint8_t *server, unsigned server_len,
+ const uint8_t *client, unsigned client_len) {
unsigned int i, j;
const uint8_t *result;
int status = OPENSSL_NPN_UNSUPPORTED;
@@ -1475,57 +1737,31 @@ int SSL_select_next_proto(uint8_t **out, uint8_t *outlen, const uint8_t *server,
found:
*out = (uint8_t *)result + 1;
- *outlen = result[0];
+ *out_len = result[0];
return status;
}
-/* SSL_get0_next_proto_negotiated sets *data and *len to point to the client's
- * requested protocol for this connection and returns 0. If the client didn't
- * request any protocol, then *data is set to NULL.
- *
- * Note that the client can request any protocol it chooses. The value returned
- * from this function need not be a member of the list of supported protocols
- * provided by the callback. */
-void SSL_get0_next_proto_negotiated(const SSL *s, const uint8_t **data,
- unsigned *len) {
- *data = s->next_proto_negotiated;
- if (!*data) {
- *len = 0;
+void SSL_get0_next_proto_negotiated(const SSL *ssl, const uint8_t **out_data,
+ unsigned *out_len) {
+ *out_data = ssl->next_proto_negotiated;
+ if (*out_data == NULL) {
+ *out_len = 0;
} else {
- *len = s->next_proto_negotiated_len;
+ *out_len = ssl->next_proto_negotiated_len;
}
}
-/* SSL_CTX_set_next_protos_advertised_cb sets a callback that is called when a
- * TLS server needs a list of supported protocols for Next Protocol
- * Negotiation. The returned list must be in wire format. The list is returned
- * by setting |out| to point to it and |outlen| to its length. This memory will
- * not be modified, but one should assume that the SSL* keeps a reference to
- * it.
- *
- * The callback should return SSL_TLSEXT_ERR_OK if it wishes to advertise.
- * Otherwise, no such extension will be included in the ServerHello. */
void SSL_CTX_set_next_protos_advertised_cb(
SSL_CTX *ctx,
- int (*cb)(SSL *ssl, const uint8_t **out, unsigned int *outlen, void *arg),
+ int (*cb)(SSL *ssl, const uint8_t **out, unsigned *out_len, void *arg),
void *arg) {
ctx->next_protos_advertised_cb = cb;
ctx->next_protos_advertised_cb_arg = arg;
}
-/* SSL_CTX_set_next_proto_select_cb sets a callback that is called when a
- * client needs to select a protocol from the server's provided list. |out|
- * must be set to point to the selected protocol (which may be within |in|).
- * The length of the protocol name must be written into |outlen|. The server's
- * advertised protocols are provided in |in| and |inlen|. The callback can
- * assume that |in| is syntactically valid.
- *
- * The client must select a protocol. It is fatal to the connection if this
- * callback returns a value other than SSL_TLSEXT_ERR_OK.
- */
void SSL_CTX_set_next_proto_select_cb(
- SSL_CTX *ctx, int (*cb)(SSL *s, uint8_t **out, uint8_t *outlen,
- const uint8_t *in, unsigned int inlen, void *arg),
+ SSL_CTX *ctx, int (*cb)(SSL *ssl, uint8_t **out, uint8_t *out_len,
+ const uint8_t *in, unsigned in_len, void *arg),
void *arg) {
ctx->next_proto_select_cb = cb;
ctx->next_proto_select_cb_arg = arg;
@@ -1554,32 +1790,25 @@ int SSL_set_alpn_protos(SSL *ssl, const uint8_t *protos, unsigned protos_len) {
return 0;
}
-/* SSL_CTX_set_alpn_select_cb sets a callback function on |ctx| that is called
- * during ClientHello processing in order to select an ALPN protocol from the
- * client's list of offered protocols. */
void SSL_CTX_set_alpn_select_cb(SSL_CTX *ctx,
int (*cb)(SSL *ssl, const uint8_t **out,
- uint8_t *outlen, const uint8_t *in,
- unsigned int inlen, void *arg),
+ uint8_t *out_len, const uint8_t *in,
+ unsigned in_len, void *arg),
void *arg) {
ctx->alpn_select_cb = cb;
ctx->alpn_select_cb_arg = arg;
}
-/* SSL_get0_alpn_selected gets the selected ALPN protocol (if any) from |ssl|.
- * On return it sets |*data| to point to |*len| bytes of protocol name (not
- * including the leading length-prefix byte). If the server didn't respond with
- * a negotiated protocol then |*len| will be zero. */
-void SSL_get0_alpn_selected(const SSL *ssl, const uint8_t **data,
- unsigned *len) {
- *data = NULL;
+void SSL_get0_alpn_selected(const SSL *ssl, const uint8_t **out_data,
+ unsigned *out_len) {
+ *out_data = NULL;
if (ssl->s3) {
- *data = ssl->s3->alpn_selected;
+ *out_data = ssl->s3->alpn_selected;
}
- if (*data == NULL) {
- *len = 0;
+ if (*out_data == NULL) {
+ *out_len = 0;
} else {
- *len = ssl->s3->alpn_selected_len;
+ *out_len = ssl->s3->alpn_selected_len;
}
}
@@ -1595,210 +1824,9 @@ int SSL_export_keying_material(SSL *s, uint8_t *out, size_t out_len,
s, out, out_len, label, label_len, context, context_len, use_context);
}
-static uint32_t ssl_session_hash(const SSL_SESSION *a) {
- uint32_t hash =
- ((uint32_t)a->session_id[0]) ||
- ((uint32_t)a->session_id[1] << 8) ||
- ((uint32_t)a->session_id[2] << 16) ||
- ((uint32_t)a->session_id[3] << 24);
-
- return hash;
-}
-
-/* NB: If this function (or indeed the hash function which uses a sort of
- * coarser function than this one) is changed, ensure
- * SSL_CTX_has_matching_session_id() is checked accordingly. It relies on being
- * able to construct an SSL_SESSION that will collide with any existing session
- * with a matching session ID. */
-static int ssl_session_cmp(const SSL_SESSION *a, const SSL_SESSION *b) {
- if (a->ssl_version != b->ssl_version) {
- return 1;
- }
-
- if (a->session_id_length != b->session_id_length) {
- return 1;
- }
-
- return memcmp(a->session_id, b->session_id, a->session_id_length);
-}
-
-SSL_CTX *SSL_CTX_new(const SSL_METHOD *method) {
- SSL_CTX *ret = NULL;
-
- if (method == NULL) {
- OPENSSL_PUT_ERROR(SSL, SSL_CTX_new, SSL_R_NULL_SSL_METHOD_PASSED);
- return NULL;
- }
-
- if (SSL_get_ex_data_X509_STORE_CTX_idx() < 0) {
- OPENSSL_PUT_ERROR(SSL, SSL_CTX_new, SSL_R_X509_VERIFICATION_SETUP_PROBLEMS);
- goto err;
- }
-
- ret = (SSL_CTX *)OPENSSL_malloc(sizeof(SSL_CTX));
- if (ret == NULL) {
- goto err;
- }
-
- memset(ret, 0, sizeof(SSL_CTX));
-
- ret->method = method->method;
-
- CRYPTO_MUTEX_init(&ret->lock);
-
- ret->cert_store = NULL;
- ret->session_cache_mode = SSL_SESS_CACHE_SERVER;
- ret->session_cache_size = SSL_SESSION_CACHE_MAX_SIZE_DEFAULT;
- ret->session_cache_head = NULL;
- ret->session_cache_tail = NULL;
-
- /* We take the system default */
- ret->session_timeout = SSL_DEFAULT_SESSION_TIMEOUT;
-
- ret->new_session_cb = 0;
- ret->remove_session_cb = 0;
- ret->get_session_cb = 0;
- ret->generate_session_id = 0;
-
- ret->references = 1;
- ret->quiet_shutdown = 0;
-
- ret->info_callback = NULL;
-
- ret->app_verify_callback = 0;
- ret->app_verify_arg = NULL;
-
- ret->max_cert_list = SSL_MAX_CERT_LIST_DEFAULT;
- ret->msg_callback = 0;
- ret->msg_callback_arg = NULL;
- ret->verify_mode = SSL_VERIFY_NONE;
- ret->sid_ctx_length = 0;
- ret->default_verify_callback = NULL;
- ret->cert = ssl_cert_new();
- if (ret->cert == NULL) {
- goto err;
- }
-
- ret->default_passwd_callback = 0;
- ret->default_passwd_callback_userdata = NULL;
- ret->client_cert_cb = 0;
-
- ret->sessions = lh_SSL_SESSION_new(ssl_session_hash, ssl_session_cmp);
- if (ret->sessions == NULL) {
- goto err;
- }
- ret->cert_store = X509_STORE_new();
- if (ret->cert_store == NULL) {
- goto err;
- }
-
- ssl_create_cipher_list(ret->method, &ret->cipher_list,
- &ret->cipher_list_by_id, SSL_DEFAULT_CIPHER_LIST);
- if (ret->cipher_list == NULL ||
- sk_SSL_CIPHER_num(ret->cipher_list->ciphers) <= 0) {
- OPENSSL_PUT_ERROR(SSL, SSL_CTX_new, SSL_R_LIBRARY_HAS_NO_CIPHERS);
- goto err2;
- }
-
- ret->param = X509_VERIFY_PARAM_new();
- if (!ret->param) {
- goto err;
- }
-
- ret->client_CA = sk_X509_NAME_new_null();
- if (ret->client_CA == NULL) {
- goto err;
- }
-
- CRYPTO_new_ex_data(&g_ex_data_class_ssl_ctx, ret, &ret->ex_data);
-
- ret->extra_certs = NULL;
-
- ret->max_send_fragment = SSL3_RT_MAX_PLAIN_LENGTH;
-
- ret->tlsext_servername_callback = 0;
- ret->tlsext_servername_arg = NULL;
- /* Setup RFC4507 ticket keys */
- if (!RAND_bytes(ret->tlsext_tick_key_name, 16) ||
- !RAND_bytes(ret->tlsext_tick_hmac_key, 16) ||
- !RAND_bytes(ret->tlsext_tick_aes_key, 16)) {
- ret->options |= SSL_OP_NO_TICKET;
- }
-
- ret->next_protos_advertised_cb = 0;
- ret->next_proto_select_cb = 0;
- ret->psk_identity_hint = NULL;
- ret->psk_client_callback = NULL;
- ret->psk_server_callback = NULL;
-
- /* Default is to connect to non-RI servers. When RI is more widely deployed
- * might change this. */
- ret->options |= SSL_OP_LEGACY_SERVER_CONNECT;
-
- /* Lock the SSL_CTX to the specified version, for compatibility with legacy
- * uses of SSL_METHOD. */
- if (method->version != 0) {
- SSL_CTX_set_max_version(ret, method->version);
- SSL_CTX_set_min_version(ret, method->version);
- }
-
- return ret;
-
-err:
- OPENSSL_PUT_ERROR(SSL, SSL_CTX_new, ERR_R_MALLOC_FAILURE);
-err2:
- SSL_CTX_free(ret);
- return NULL;
-}
-
-void SSL_CTX_free(SSL_CTX *ctx) {
- if (ctx == NULL ||
- !CRYPTO_refcount_dec_and_test_zero(&ctx->references)) {
- return;
- }
-
- X509_VERIFY_PARAM_free(ctx->param);
-
- /* Free internal session cache. However: the remove_cb() may reference the
- * ex_data of SSL_CTX, thus the ex_data store can only be removed after the
- * sessions were flushed. As the ex_data handling routines might also touch
- * the session cache, the most secure solution seems to be: empty (flush) the
- * cache, then free ex_data, then finally free the cache. (See ticket
- * [openssl.org #212].) */
- SSL_CTX_flush_sessions(ctx, 0);
-
- CRYPTO_free_ex_data(&g_ex_data_class_ssl_ctx, ctx, &ctx->ex_data);
-
- CRYPTO_MUTEX_cleanup(&ctx->lock);
- lh_SSL_SESSION_free(ctx->sessions);
- X509_STORE_free(ctx->cert_store);
- ssl_cipher_preference_list_free(ctx->cipher_list);
- sk_SSL_CIPHER_free(ctx->cipher_list_by_id);
- ssl_cipher_preference_list_free(ctx->cipher_list_tls11);
- ssl_cert_free(ctx->cert);
- sk_X509_NAME_pop_free(ctx->client_CA, X509_NAME_free);
- sk_X509_pop_free(ctx->extra_certs, X509_free);
- sk_SRTP_PROTECTION_PROFILE_free(ctx->srtp_profiles);
- OPENSSL_free(ctx->psk_identity_hint);
- OPENSSL_free(ctx->tlsext_ecpointformatlist);
- OPENSSL_free(ctx->tlsext_ellipticcurvelist);
- OPENSSL_free(ctx->alpn_client_proto_list);
- EVP_PKEY_free(ctx->tlsext_channel_id_private);
- BIO_free(ctx->keylog_bio);
-
- OPENSSL_free(ctx);
-}
-
-void SSL_CTX_set_default_passwd_cb(SSL_CTX *ctx, pem_password_cb *cb) {
- ctx->default_passwd_callback = cb;
-}
-
-void SSL_CTX_set_default_passwd_cb_userdata(SSL_CTX *ctx, void *u) {
- ctx->default_passwd_callback_userdata = u;
-}
-
void SSL_CTX_set_cert_verify_callback(SSL_CTX *ctx,
- int (*cb)(X509_STORE_CTX *, void *),
+ int (*cb)(X509_STORE_CTX *store_ctx,
+ void *arg),
void *arg) {
ctx->app_verify_callback = cb;
ctx->app_verify_arg = arg;
@@ -1814,57 +1842,48 @@ void SSL_CTX_set_verify_depth(SSL_CTX *ctx, int depth) {
X509_VERIFY_PARAM_set_depth(ctx->param, depth);
}
-void SSL_CTX_set_cert_cb(SSL_CTX *c, int (*cb)(SSL *ssl, void *arg),
+void SSL_CTX_set_cert_cb(SSL_CTX *ctx, int (*cb)(SSL *ssl, void *arg),
void *arg) {
- ssl_cert_set_cert_cb(c->cert, cb, arg);
+ ssl_cert_set_cert_cb(ctx->cert, cb, arg);
}
-void SSL_set_cert_cb(SSL *s, int (*cb)(SSL *ssl, void *arg), void *arg) {
- ssl_cert_set_cert_cb(s->cert, cb, arg);
-}
-
-static int ssl_has_key(SSL *s, size_t idx) {
- CERT_PKEY *cpk = &s->cert->pkeys[idx];
- return cpk->x509 && cpk->privatekey;
+void SSL_set_cert_cb(SSL *ssl, int (*cb)(SSL *ssl, void *arg), void *arg) {
+ ssl_cert_set_cert_cb(ssl->cert, cb, arg);
}
void ssl_get_compatible_server_ciphers(SSL *s, uint32_t *out_mask_k,
uint32_t *out_mask_a) {
CERT *c = s->cert;
- int rsa_enc, rsa_sign, dh_tmp;
+ int have_rsa_cert = 0, dh_tmp;
uint32_t mask_k, mask_a;
- int have_ecc_cert, ecdsa_ok;
+ int have_ecc_cert = 0, ecdsa_ok;
X509 *x;
- if (c == NULL) {
- /* TODO(davidben): Is this codepath possible? */
- *out_mask_k = 0;
- *out_mask_a = 0;
- return;
- }
-
dh_tmp = (c->dh_tmp != NULL || c->dh_tmp_cb != NULL);
- rsa_enc = ssl_has_key(s, SSL_PKEY_RSA_ENC);
- rsa_sign = ssl_has_key(s, SSL_PKEY_RSA_SIGN);
- have_ecc_cert = ssl_has_key(s, SSL_PKEY_ECC);
+ if (s->cert->x509 != NULL && ssl_has_private_key(s)) {
+ if (ssl_private_key_type(s) == EVP_PKEY_RSA) {
+ have_rsa_cert = 1;
+ } else if (ssl_private_key_type(s) == EVP_PKEY_EC) {
+ have_ecc_cert = 1;
+ }
+ }
+
mask_k = 0;
mask_a = 0;
- if (rsa_enc) {
- mask_k |= SSL_kRSA;
- }
if (dh_tmp) {
mask_k |= SSL_kDHE;
}
- if (rsa_enc || rsa_sign) {
+ if (have_rsa_cert) {
+ mask_k |= SSL_kRSA;
mask_a |= SSL_aRSA;
}
/* An ECC certificate may be usable for ECDSA cipher suites depending on the
* key usage extension and on the client's curve preferences. */
if (have_ecc_cert) {
- x = c->pkeys[SSL_PKEY_ECC].x509;
+ x = c->x509;
/* This call populates extension flags (ex_flags). */
X509_check_purpose(x, -1, 0);
ecdsa_ok = (x->ex_flags & EXFLAG_KUSAGE)
@@ -1894,81 +1913,6 @@ void ssl_get_compatible_server_ciphers(SSL *s, uint32_t *out_mask_k,
*out_mask_a = mask_a;
}
-/* This handy macro borrowed from crypto/x509v3/v3_purp.c */
-#define ku_reject(x, usage) \
- (((x)->ex_flags & EXFLAG_KUSAGE) && !((x)->ex_kusage & (usage)))
-
-int ssl_check_srvr_ecc_cert_and_alg(X509 *x, SSL *s) {
- const SSL_CIPHER *cs = s->s3->tmp.new_cipher;
- uint32_t alg_a = cs->algorithm_auth;
- int signature_nid = 0, md_nid = 0, pk_nid = 0;
-
- /* This call populates the ex_flags field correctly */
- X509_check_purpose(x, -1, 0);
- if (x->sig_alg && x->sig_alg->algorithm) {
- signature_nid = OBJ_obj2nid(x->sig_alg->algorithm);
- OBJ_find_sigid_algs(signature_nid, &md_nid, &pk_nid);
- }
- if (alg_a & SSL_aECDSA) {
- /* key usage, if present, must allow signing */
- if (ku_reject(x, X509v3_KU_DIGITAL_SIGNATURE)) {
- OPENSSL_PUT_ERROR(SSL, ssl_check_srvr_ecc_cert_and_alg,
- SSL_R_ECC_CERT_NOT_FOR_SIGNING);
- return 0;
- }
- }
-
- return 1; /* all checks are ok */
-}
-
-static int ssl_get_server_cert_index(const SSL *s) {
- int idx;
- idx = ssl_cipher_get_cert_index(s->s3->tmp.new_cipher);
- if (idx == SSL_PKEY_RSA_ENC && !s->cert->pkeys[SSL_PKEY_RSA_ENC].x509) {
- idx = SSL_PKEY_RSA_SIGN;
- }
- if (idx == -1) {
- OPENSSL_PUT_ERROR(SSL, ssl_get_server_cert_index, ERR_R_INTERNAL_ERROR);
- }
- return idx;
-}
-
-CERT_PKEY *ssl_get_server_send_pkey(const SSL *s) {
- int i = ssl_get_server_cert_index(s);
-
- /* This may or may not be an error. */
- if (i < 0) {
- return NULL;
- }
-
- /* May be NULL. */
- return &s->cert->pkeys[i];
-}
-
-EVP_PKEY *ssl_get_sign_pkey(SSL *s, const SSL_CIPHER *cipher) {
- uint32_t alg_a = cipher->algorithm_auth;
- CERT *c = s->cert;
- int idx = -1;
-
- if (alg_a & SSL_aRSA) {
- if (c->pkeys[SSL_PKEY_RSA_SIGN].privatekey != NULL) {
- idx = SSL_PKEY_RSA_SIGN;
- } else if (c->pkeys[SSL_PKEY_RSA_ENC].privatekey != NULL) {
- idx = SSL_PKEY_RSA_ENC;
- }
- } else if ((alg_a & SSL_aECDSA) &&
- (c->pkeys[SSL_PKEY_ECC].privatekey != NULL)) {
- idx = SSL_PKEY_ECC;
- }
-
- if (idx == -1) {
- OPENSSL_PUT_ERROR(SSL, ssl_get_sign_pkey, ERR_R_INTERNAL_ERROR);
- return NULL;
- }
-
- return c->pkeys[idx].privatekey;
-}
-
void ssl_update_cache(SSL *s, int mode) {
/* Never cache sessions with empty session IDs. */
if (s->session->session_id_length == 0) {
@@ -2014,143 +1958,6 @@ void ssl_update_cache(SSL *s, int mode) {
}
}
-int SSL_get_error(const SSL *s, int ret_code) {
- int reason;
- uint32_t err;
- BIO *bio;
-
- if (ret_code > 0) {
- return SSL_ERROR_NONE;
- }
-
- /* Make things return SSL_ERROR_SYSCALL when doing SSL_do_handshake etc,
- * where we do encode the error */
- err = ERR_peek_error();
- if (err != 0) {
- if (ERR_GET_LIB(err) == ERR_LIB_SYS) {
- return SSL_ERROR_SYSCALL;
- }
- return SSL_ERROR_SSL;
- }
-
- if (ret_code == 0) {
- if ((s->shutdown & SSL_RECEIVED_SHUTDOWN) &&
- (s->s3->warn_alert == SSL_AD_CLOSE_NOTIFY)) {
- /* The socket was cleanly shut down with a close_notify. */
- return SSL_ERROR_ZERO_RETURN;
- }
- /* An EOF was observed which violates the protocol, and the underlying
- * transport does not participate in the error queue. Bubble up to the
- * caller. */
- return SSL_ERROR_SYSCALL;
- }
-
- if (SSL_want_session(s)) {
- return SSL_ERROR_PENDING_SESSION;
- }
-
- if (SSL_want_certificate(s)) {
- return SSL_ERROR_PENDING_CERTIFICATE;
- }
-
- if (SSL_want_read(s)) {
- bio = SSL_get_rbio(s);
- if (BIO_should_read(bio)) {
- return SSL_ERROR_WANT_READ;
- }
-
- if (BIO_should_write(bio)) {
- /* This one doesn't make too much sense ... We never try to write to the
- * rbio, and an application program where rbio and wbio are separate
- * couldn't even know what it should wait for. However if we ever set
- * s->rwstate incorrectly (so that we have SSL_want_read(s) instead of
- * SSL_want_write(s)) and rbio and wbio *are* the same, this test works
- * around that bug; so it might be safer to keep it. */
- return SSL_ERROR_WANT_WRITE;
- }
-
- if (BIO_should_io_special(bio)) {
- reason = BIO_get_retry_reason(bio);
- if (reason == BIO_RR_CONNECT) {
- return SSL_ERROR_WANT_CONNECT;
- }
-
- if (reason == BIO_RR_ACCEPT) {
- return SSL_ERROR_WANT_ACCEPT;
- }
-
- return SSL_ERROR_SYSCALL; /* unknown */
- }
- }
-
- if (SSL_want_write(s)) {
- bio = SSL_get_wbio(s);
- if (BIO_should_write(bio)) {
- return SSL_ERROR_WANT_WRITE;
- }
-
- if (BIO_should_read(bio)) {
- /* See above (SSL_want_read(s) with BIO_should_write(bio)) */
- return SSL_ERROR_WANT_READ;
- }
-
- if (BIO_should_io_special(bio)) {
- reason = BIO_get_retry_reason(bio);
- if (reason == BIO_RR_CONNECT) {
- return SSL_ERROR_WANT_CONNECT;
- }
-
- if (reason == BIO_RR_ACCEPT) {
- return SSL_ERROR_WANT_ACCEPT;
- }
-
- return SSL_ERROR_SYSCALL;
- }
- }
-
- if (SSL_want_x509_lookup(s)) {
- return SSL_ERROR_WANT_X509_LOOKUP;
- }
-
- if (SSL_want_channel_id_lookup(s)) {
- return SSL_ERROR_WANT_CHANNEL_ID_LOOKUP;
- }
-
- return SSL_ERROR_SYSCALL;
-}
-
-int SSL_do_handshake(SSL *s) {
- int ret = 1;
-
- if (s->handshake_func == NULL) {
- OPENSSL_PUT_ERROR(SSL, SSL_do_handshake, SSL_R_CONNECTION_TYPE_NOT_SET);
- return -1;
- }
-
- if (SSL_in_init(s)) {
- ret = s->handshake_func(s);
- }
- return ret;
-}
-
-void SSL_set_accept_state(SSL *ssl) {
- ssl->server = 1;
- ssl->shutdown = 0;
- ssl->state = SSL_ST_ACCEPT;
- ssl->handshake_func = ssl->method->ssl_accept;
- /* clear the current cipher */
- ssl_clear_cipher_ctx(ssl);
-}
-
-void SSL_set_connect_state(SSL *ssl) {
- ssl->server = 0;
- ssl->shutdown = 0;
- ssl->state = SSL_ST_CONNECT;
- ssl->handshake_func = ssl->method->ssl_connect;
- /* clear the current cipher */
- ssl_clear_cipher_ctx(ssl);
-}
-
static const char *ssl_get_version(int version) {
switch (version) {
case TLS1_2_VERSION:
@@ -2176,12 +1983,16 @@ static const char *ssl_get_version(int version) {
}
}
-const char *SSL_get_version(const SSL *s) {
- return ssl_get_version(s->version);
+const char *SSL_get_version(const SSL *ssl) {
+ return ssl_get_version(ssl->version);
+}
+
+const char *SSL_SESSION_get_version(const SSL_SESSION *session) {
+ return ssl_get_version(session->ssl_version);
}
-const char *SSL_SESSION_get_version(const SSL_SESSION *sess) {
- return ssl_get_version(sess->ssl_version);
+const char* SSL_get_curve_name(uint16_t curve_id) {
+ return tls1_ec_curve_id2name(curve_id);
}
void ssl_clear_cipher_ctx(SSL *s) {
@@ -2193,7 +2004,7 @@ void ssl_clear_cipher_ctx(SSL *s) {
X509 *SSL_get_certificate(const SSL *s) {
if (s->cert != NULL) {
- return s->cert->key->x509;
+ return s->cert->x509;
}
return NULL;
@@ -2201,7 +2012,7 @@ X509 *SSL_get_certificate(const SSL *s) {
EVP_PKEY *SSL_get_privatekey(const SSL *s) {
if (s->cert != NULL) {
- return s->cert->key->privatekey;
+ return s->cert->privatekey;
}
return NULL;
@@ -2209,7 +2020,7 @@ EVP_PKEY *SSL_get_privatekey(const SSL *s) {
X509 *SSL_CTX_get0_certificate(const SSL_CTX *ctx) {
if (ctx->cert != NULL) {
- return ctx->cert->key->x509;
+ return ctx->cert->x509;
}
return NULL;
@@ -2217,22 +2028,22 @@ X509 *SSL_CTX_get0_certificate(const SSL_CTX *ctx) {
EVP_PKEY *SSL_CTX_get0_privatekey(const SSL_CTX *ctx) {
if (ctx->cert != NULL) {
- return ctx->cert->key->privatekey;
+ return ctx->cert->privatekey;
}
return NULL;
}
-const SSL_CIPHER *SSL_get_current_cipher(const SSL *s) {
- if (s->aead_write_ctx == NULL) {
+const SSL_CIPHER *SSL_get_current_cipher(const SSL *ssl) {
+ if (ssl->aead_write_ctx == NULL) {
return NULL;
}
- return s->aead_write_ctx->cipher;
+ return ssl->aead_write_ctx->cipher;
}
-const void *SSL_get_current_compression(SSL *s) { return NULL; }
+const COMP_METHOD *SSL_get_current_compression(SSL *s) { return NULL; }
-const void *SSL_get_current_expansion(SSL *s) { return NULL; }
+const COMP_METHOD *SSL_get_current_expansion(SSL *s) { return NULL; }
int ssl_init_wbio_buffer(SSL *s, int push) {
BIO *bbio;
@@ -2252,7 +2063,7 @@ int ssl_init_wbio_buffer(SSL *s, int push) {
BIO_reset(bbio);
if (!BIO_set_read_buffer_size(bbio, 1)) {
- OPENSSL_PUT_ERROR(SSL, ssl_init_wbio_buffer, ERR_R_BUF_LIB);
+ OPENSSL_PUT_ERROR(SSL, ERR_R_BUF_LIB);
return 0;
}
@@ -2330,9 +2141,9 @@ int SSL_CTX_set_default_verify_paths(SSL_CTX *ctx) {
return X509_STORE_set_default_paths(ctx->cert_store);
}
-int SSL_CTX_load_verify_locations(SSL_CTX *ctx, const char *CAfile,
- const char *CApath) {
- return X509_STORE_load_locations(ctx->cert_store, CAfile, CApath);
+int SSL_CTX_load_verify_locations(SSL_CTX *ctx, const char *ca_file,
+ const char *ca_dir) {
+ return X509_STORE_load_locations(ctx->cert_store, ca_file, ca_dir);
}
void SSL_set_info_callback(SSL *ssl,
@@ -2349,7 +2160,9 @@ int SSL_state(const SSL *ssl) { return ssl->state; }
void SSL_set_state(SSL *ssl, int state) { }
-void SSL_set_verify_result(SSL *ssl, long arg) { ssl->verify_result = arg; }
+void SSL_set_verify_result(SSL *ssl, long result) {
+ ssl->verify_result = result;
+}
long SSL_get_verify_result(const SSL *ssl) { return ssl->verify_result; }
@@ -2363,12 +2176,12 @@ int SSL_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
return index;
}
-int SSL_set_ex_data(SSL *s, int idx, void *arg) {
- return CRYPTO_set_ex_data(&s->ex_data, idx, arg);
+int SSL_set_ex_data(SSL *ssl, int idx, void *arg) {
+ return CRYPTO_set_ex_data(&ssl->ex_data, idx, arg);
}
-void *SSL_get_ex_data(const SSL *s, int idx) {
- return CRYPTO_get_ex_data(&s->ex_data, idx);
+void *SSL_get_ex_data(const SSL *ssl, int idx) {
+ return CRYPTO_get_ex_data(&ssl->ex_data, idx);
}
int SSL_CTX_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
@@ -2382,12 +2195,12 @@ int SSL_CTX_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
return index;
}
-int SSL_CTX_set_ex_data(SSL_CTX *s, int idx, void *arg) {
- return CRYPTO_set_ex_data(&s->ex_data, idx, arg);
+int SSL_CTX_set_ex_data(SSL_CTX *ctx, int idx, void *arg) {
+ return CRYPTO_set_ex_data(&ctx->ex_data, idx, arg);
}
-void *SSL_CTX_get_ex_data(const SSL_CTX *s, int idx) {
- return CRYPTO_get_ex_data(&s->ex_data, idx);
+void *SSL_CTX_get_ex_data(const SSL_CTX *ctx, int idx) {
+ return CRYPTO_get_ex_data(&ctx->ex_data, idx);
}
X509_STORE *SSL_CTX_get_cert_store(const SSL_CTX *ctx) {
@@ -2435,8 +2248,7 @@ void SSL_set_tmp_ecdh_callback(SSL *ssl,
int SSL_CTX_use_psk_identity_hint(SSL_CTX *ctx, const char *identity_hint) {
if (identity_hint != NULL && strlen(identity_hint) > PSK_MAX_IDENTITY_LEN) {
- OPENSSL_PUT_ERROR(SSL, SSL_CTX_use_psk_identity_hint,
- SSL_R_DATA_LENGTH_TOO_LONG);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_DATA_LENGTH_TOO_LONG);
return 0;
}
@@ -2454,24 +2266,23 @@ int SSL_CTX_use_psk_identity_hint(SSL_CTX *ctx, const char *identity_hint) {
return 1;
}
-int SSL_use_psk_identity_hint(SSL *s, const char *identity_hint) {
- if (s == NULL) {
+int SSL_use_psk_identity_hint(SSL *ssl, const char *identity_hint) {
+ if (ssl == NULL) {
return 0;
}
if (identity_hint != NULL && strlen(identity_hint) > PSK_MAX_IDENTITY_LEN) {
- OPENSSL_PUT_ERROR(SSL, SSL_use_psk_identity_hint,
- SSL_R_DATA_LENGTH_TOO_LONG);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_DATA_LENGTH_TOO_LONG);
return 0;
}
/* Clear currently configured hint, if any. */
- OPENSSL_free(s->psk_identity_hint);
- s->psk_identity_hint = NULL;
+ OPENSSL_free(ssl->psk_identity_hint);
+ ssl->psk_identity_hint = NULL;
if (identity_hint != NULL) {
- s->psk_identity_hint = BUF_strdup(identity_hint);
- if (s->psk_identity_hint == NULL) {
+ ssl->psk_identity_hint = BUF_strdup(identity_hint);
+ if (ssl->psk_identity_hint == NULL) {
return 0;
}
}
@@ -2479,63 +2290,47 @@ int SSL_use_psk_identity_hint(SSL *s, const char *identity_hint) {
return 1;
}
-const char *SSL_get_psk_identity_hint(const SSL *s) {
- if (s == NULL) {
+const char *SSL_get_psk_identity_hint(const SSL *ssl) {
+ if (ssl == NULL) {
return NULL;
}
- return s->psk_identity_hint;
+ return ssl->psk_identity_hint;
}
-const char *SSL_get_psk_identity(const SSL *s) {
- if (s == NULL || s->session == NULL) {
+const char *SSL_get_psk_identity(const SSL *ssl) {
+ if (ssl == NULL || ssl->session == NULL) {
return NULL;
}
- return s->session->psk_identity;
+ return ssl->session->psk_identity;
}
void SSL_set_psk_client_callback(
- SSL *s, unsigned int (*cb)(SSL *ssl, const char *hint, char *identity,
- unsigned int max_identity_len, uint8_t *psk,
- unsigned int max_psk_len)) {
- s->psk_client_callback = cb;
+ SSL *ssl, unsigned (*cb)(SSL *ssl, const char *hint, char *identity,
+ unsigned max_identity_len, uint8_t *psk,
+ unsigned max_psk_len)) {
+ ssl->psk_client_callback = cb;
}
void SSL_CTX_set_psk_client_callback(
- SSL_CTX *ctx, unsigned int (*cb)(SSL *ssl, const char *hint, char *identity,
- unsigned int max_identity_len,
- uint8_t *psk, unsigned int max_psk_len)) {
+ SSL_CTX *ctx, unsigned (*cb)(SSL *ssl, const char *hint, char *identity,
+ unsigned max_identity_len, uint8_t *psk,
+ unsigned max_psk_len)) {
ctx->psk_client_callback = cb;
}
void SSL_set_psk_server_callback(
- SSL *s, unsigned int (*cb)(SSL *ssl, const char *identity, uint8_t *psk,
- unsigned int max_psk_len)) {
- s->psk_server_callback = cb;
+ SSL *ssl, unsigned (*cb)(SSL *ssl, const char *identity, uint8_t *psk,
+ unsigned max_psk_len)) {
+ ssl->psk_server_callback = cb;
}
void SSL_CTX_set_psk_server_callback(
- SSL_CTX *ctx, unsigned int (*cb)(SSL *ssl, const char *identity,
- uint8_t *psk, unsigned int max_psk_len)) {
+ SSL_CTX *ctx, unsigned (*cb)(SSL *ssl, const char *identity,
+ uint8_t *psk, unsigned max_psk_len)) {
ctx->psk_server_callback = cb;
}
-void SSL_CTX_set_min_version(SSL_CTX *ctx, uint16_t version) {
- ctx->min_version = version;
-}
-
-void SSL_CTX_set_max_version(SSL_CTX *ctx, uint16_t version) {
- ctx->max_version = version;
-}
-
-void SSL_set_min_version(SSL *ssl, uint16_t version) {
- ssl->min_version = version;
-}
-
-void SSL_set_max_version(SSL *ssl, uint16_t version) {
- ssl->max_version = version;
-}
-
void SSL_CTX_set_msg_callback(SSL_CTX *ctx,
void (*cb)(int write_p, int version,
int content_type, const void *buf,
@@ -2596,16 +2391,13 @@ int ssl_ctx_log_rsa_client_key_exchange(SSL_CTX *ctx,
}
if (encrypted_premaster_len < 8) {
- OPENSSL_PUT_ERROR(SSL, ssl_ctx_log_rsa_client_key_exchange,
- ERR_R_INTERNAL_ERROR);
- return 0;
- }
-
- if (!CBB_init(&cbb, 4 + 16 + 1 + premaster_len * 2 + 1)) {
+ OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
return 0;
}
- if (!CBB_add_bytes(&cbb, (const uint8_t *)"RSA ", 4) ||
+ CBB_zero(&cbb);
+ if (!CBB_init(&cbb, 4 + 16 + 1 + premaster_len * 2 + 1) ||
+ !CBB_add_bytes(&cbb, (const uint8_t *)"RSA ", 4) ||
/* Only the first 8 bytes of the encrypted premaster secret are
* logged. */
!cbb_add_hex(&cbb, encrypted_premaster, 8) ||
@@ -2639,15 +2431,13 @@ int ssl_ctx_log_master_secret(SSL_CTX *ctx, const uint8_t *client_random,
}
if (client_random_len != 32) {
- OPENSSL_PUT_ERROR(SSL, ssl_ctx_log_master_secret, ERR_R_INTERNAL_ERROR);
+ OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
return 0;
}
- if (!CBB_init(&cbb, 14 + 64 + 1 + master_len * 2 + 1)) {
- return 0;
- }
-
- if (!CBB_add_bytes(&cbb, (const uint8_t *)"CLIENT_RANDOM ", 14) ||
+ CBB_zero(&cbb);
+ if (!CBB_init(&cbb, 14 + 64 + 1 + master_len * 2 + 1) ||
+ !CBB_add_bytes(&cbb, (const uint8_t *)"CLIENT_RANDOM ", 14) ||
!cbb_add_hex(&cbb, client_random, 32) ||
!CBB_add_bytes(&cbb, (const uint8_t *)" ", 1) ||
!cbb_add_hex(&cbb, master, master_len) ||
@@ -2906,19 +2696,15 @@ uint16_t ssl3_version_from_wire(SSL *s, uint16_t wire_version) {
return version;
}
-int SSL_cache_hit(SSL *s) { return s->hit; }
+int SSL_cache_hit(SSL *ssl) { return SSL_session_reused(ssl); }
-int SSL_is_server(SSL *s) { return s->server; }
+int SSL_is_server(SSL *ssl) { return ssl->server; }
void SSL_CTX_set_dos_protection_cb(
SSL_CTX *ctx, int (*cb)(const struct ssl_early_callback_ctx *)) {
ctx->dos_protection_cb = cb;
}
-void SSL_enable_fastradio_padding(SSL *s, char on_off) {
- s->fastradio_padding = on_off;
-}
-
void SSL_set_reject_peer_renegotiations(SSL *s, int reject) {
s->accept_peer_renegotiations = !reject;
}
@@ -2933,43 +2719,73 @@ int SSL_get_rc4_state(const SSL *ssl, const RC4_KEY **read_key,
EVP_AEAD_CTX_get_rc4_state(&ssl->aead_write_ctx->ctx, write_key);
}
-int SSL_get_tls_unique(const SSL *ssl, uint8_t *out, size_t *out_len,
- size_t max_out) {
- /* The tls-unique value is the first Finished message in the handshake, which
- * is the client's in a full handshake and the server's for a resumption. See
- * https://tools.ietf.org/html/rfc5929#section-3.1. */
- const uint8_t *finished = ssl->s3->previous_client_finished;
- size_t finished_len = ssl->s3->previous_client_finished_len;
- if (ssl->hit) {
- /* tls-unique is broken for resumed sessions unless EMS is used. */
- if (!ssl->session->extended_master_secret) {
- goto err;
+int SSL_clear(SSL *ssl) {
+ if (ssl->method == NULL) {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_NO_METHOD_SPECIFIED);
+ return 0;
+ }
+
+ if (ssl_clear_bad_session(ssl)) {
+ SSL_SESSION_free(ssl->session);
+ ssl->session = NULL;
+ }
+
+ ssl->hit = 0;
+ ssl->shutdown = 0;
+
+ /* SSL_clear may be called before or after the |ssl| is initialized in either
+ * accept or connect state. In the latter case, SSL_clear should preserve the
+ * half and reset |ssl->state| accordingly. */
+ if (ssl->handshake_func != NULL) {
+ if (ssl->server) {
+ SSL_set_accept_state(ssl);
+ } else {
+ SSL_set_connect_state(ssl);
}
- finished = ssl->s3->previous_server_finished;
- finished_len = ssl->s3->previous_server_finished_len;
+ } else {
+ assert(ssl->state == 0);
}
- if (!ssl->s3->initial_handshake_complete ||
- ssl->version < TLS1_VERSION) {
- goto err;
+ /* TODO(davidben): Some state on |ssl| is reset both in |SSL_new| and
+ * |SSL_clear| because it is per-connection state rather than configuration
+ * state. Per-connection state should be on |ssl->s3| and |ssl->d1| so it is
+ * naturally reset at the right points between |SSL_new|, |SSL_clear|, and
+ * |ssl3_new|. */
+
+ ssl->rwstate = SSL_NOTHING;
+
+ BUF_MEM_free(ssl->init_buf);
+ ssl->init_buf = NULL;
+
+ ssl_clear_cipher_ctx(ssl);
+
+ OPENSSL_free(ssl->next_proto_negotiated);
+ ssl->next_proto_negotiated = NULL;
+ ssl->next_proto_negotiated_len = 0;
+
+ /* The ssl->d1->mtu is simultaneously configuration (preserved across
+ * clear) and connection-specific state (gets reset).
+ *
+ * TODO(davidben): Avoid this. */
+ unsigned mtu = 0;
+ if (ssl->d1 != NULL) {
+ mtu = ssl->d1->mtu;
}
- *out_len = finished_len;
- if (finished_len > max_out) {
- *out_len = max_out;
+ ssl->method->ssl_free(ssl);
+ if (!ssl->method->ssl_new(ssl)) {
+ return 0;
}
+ ssl->enc_method = ssl3_get_enc_method(ssl->version);
+ assert(ssl->enc_method != NULL);
- memcpy(out, finished, *out_len);
- return 1;
+ if (SSL_IS_DTLS(ssl) && (SSL_get_options(ssl) & SSL_OP_NO_QUERY_MTU)) {
+ ssl->d1->mtu = mtu;
+ }
-err:
- *out_len = 0;
- memset(out, 0, max_out);
- return 0;
-}
+ ssl->client_version = ssl->version;
-int SSL_initial_handshake_complete(const SSL *ssl) {
- return ssl->s3->initial_handshake_complete;
+ return 1;
}
int SSL_CTX_sess_connect(const SSL_CTX *ctx) { return 0; }
@@ -2983,3 +2799,5 @@ int SSL_CTX_sess_cb_hits(const SSL_CTX *ctx) { return 0; }
int SSL_CTX_sess_misses(const SSL_CTX *ctx) { return 0; }
int SSL_CTX_sess_timeouts(const SSL_CTX *ctx) { return 0; }
int SSL_CTX_sess_cache_full(const SSL_CTX *ctx) { return 0; }
+void ERR_load_SSL_strings(void) {}
+void SSL_load_error_strings(void) {}
diff --git a/src/ssl/ssl_rsa.c b/src/ssl/ssl_rsa.c
index 87f4c1c..ccd3858 100644
--- a/src/ssl/ssl_rsa.c
+++ b/src/ssl/ssl_rsa.c
@@ -54,79 +54,38 @@
* copied and put under another distribution licence
* [including the GNU Public Licence.] */
-#include <stdio.h>
+#include <openssl/ssl.h>
-#include <openssl/bio.h>
#include <openssl/err.h>
#include <openssl/evp.h>
#include <openssl/mem.h>
-#include <openssl/obj.h>
-#include <openssl/pem.h>
#include <openssl/x509.h>
#include "internal.h"
+
static int ssl_set_cert(CERT *c, X509 *x509);
static int ssl_set_pkey(CERT *c, EVP_PKEY *pkey);
+static int is_key_type_supported(int key_type) {
+ return key_type == EVP_PKEY_RSA || key_type == EVP_PKEY_EC;
+}
+
int SSL_use_certificate(SSL *ssl, X509 *x) {
if (x == NULL) {
- OPENSSL_PUT_ERROR(SSL, SSL_use_certificate, ERR_R_PASSED_NULL_PARAMETER);
+ OPENSSL_PUT_ERROR(SSL, ERR_R_PASSED_NULL_PARAMETER);
return 0;
}
return ssl_set_cert(ssl->cert, x);
}
-int SSL_use_certificate_file(SSL *ssl, const char *file, int type) {
- int reason_code;
- BIO *in;
- int ret = 0;
- X509 *x = NULL;
-
- in = BIO_new(BIO_s_file());
- if (in == NULL) {
- OPENSSL_PUT_ERROR(SSL, SSL_use_certificate_file, ERR_R_BUF_LIB);
- goto end;
- }
-
- if (BIO_read_filename(in, file) <= 0) {
- OPENSSL_PUT_ERROR(SSL, SSL_use_certificate_file, ERR_R_SYS_LIB);
- goto end;
- }
-
- if (type == SSL_FILETYPE_ASN1) {
- reason_code = ERR_R_ASN1_LIB;
- x = d2i_X509_bio(in, NULL);
- } else if (type == SSL_FILETYPE_PEM) {
- reason_code = ERR_R_PEM_LIB;
- x = PEM_read_bio_X509(in, NULL, ssl->ctx->default_passwd_callback,
- ssl->ctx->default_passwd_callback_userdata);
- } else {
- OPENSSL_PUT_ERROR(SSL, SSL_use_certificate_file, SSL_R_BAD_SSL_FILETYPE);
- goto end;
- }
-
- if (x == NULL) {
- OPENSSL_PUT_ERROR(SSL, SSL_use_certificate_file, reason_code);
- goto end;
- }
-
- ret = SSL_use_certificate(ssl, x);
-
-end:
- X509_free(x);
- BIO_free(in);
-
- return ret;
-}
-
int SSL_use_certificate_ASN1(SSL *ssl, const uint8_t *d, int len) {
X509 *x;
int ret;
x = d2i_X509(NULL, &d, (long)len);
if (x == NULL) {
- OPENSSL_PUT_ERROR(SSL, SSL_use_certificate_ASN1, ERR_R_ASN1_LIB);
+ OPENSSL_PUT_ERROR(SSL, ERR_R_ASN1_LIB);
return 0;
}
@@ -140,13 +99,13 @@ int SSL_use_RSAPrivateKey(SSL *ssl, RSA *rsa) {
int ret;
if (rsa == NULL) {
- OPENSSL_PUT_ERROR(SSL, SSL_use_RSAPrivateKey, ERR_R_PASSED_NULL_PARAMETER);
+ OPENSSL_PUT_ERROR(SSL, ERR_R_PASSED_NULL_PARAMETER);
return 0;
}
pkey = EVP_PKEY_new();
if (pkey == NULL) {
- OPENSSL_PUT_ERROR(SSL, SSL_use_RSAPrivateKey, ERR_R_EVP_LIB);
+ OPENSSL_PUT_ERROR(SSL, ERR_R_EVP_LIB);
return 0;
}
@@ -160,86 +119,36 @@ int SSL_use_RSAPrivateKey(SSL *ssl, RSA *rsa) {
}
static int ssl_set_pkey(CERT *c, EVP_PKEY *pkey) {
- int i;
-
- i = ssl_cert_type(pkey);
- if (i < 0) {
- OPENSSL_PUT_ERROR(SSL, ssl_set_pkey, SSL_R_UNKNOWN_CERTIFICATE_TYPE);
+ if (!is_key_type_supported(pkey->type)) {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_UNKNOWN_CERTIFICATE_TYPE);
return 0;
}
- if (c->pkeys[i].x509 != NULL) {
+ if (c->x509 != NULL) {
/* Sanity-check that the private key and the certificate match, unless the
* key is opaque (in case of, say, a smartcard). */
if (!EVP_PKEY_is_opaque(pkey) &&
- !X509_check_private_key(c->pkeys[i].x509, pkey)) {
- X509_free(c->pkeys[i].x509);
- c->pkeys[i].x509 = NULL;
+ !X509_check_private_key(c->x509, pkey)) {
+ X509_free(c->x509);
+ c->x509 = NULL;
return 0;
}
}
- EVP_PKEY_free(c->pkeys[i].privatekey);
- c->pkeys[i].privatekey = EVP_PKEY_up_ref(pkey);
- c->key = &(c->pkeys[i]);
+ EVP_PKEY_free(c->privatekey);
+ c->privatekey = EVP_PKEY_up_ref(pkey);
return 1;
}
-int SSL_use_RSAPrivateKey_file(SSL *ssl, const char *file, int type) {
- int reason_code, ret = 0;
- BIO *in;
- RSA *rsa = NULL;
-
- in = BIO_new(BIO_s_file());
- if (in == NULL) {
- OPENSSL_PUT_ERROR(SSL, SSL_use_RSAPrivateKey_file, ERR_R_BUF_LIB);
- goto end;
- }
-
- if (BIO_read_filename(in, file) <= 0) {
- OPENSSL_PUT_ERROR(SSL, SSL_use_RSAPrivateKey_file, ERR_R_SYS_LIB);
- goto end;
- }
-
- if (type == SSL_FILETYPE_ASN1) {
- reason_code = ERR_R_ASN1_LIB;
- rsa = d2i_RSAPrivateKey_bio(in, NULL);
- } else if (type == SSL_FILETYPE_PEM) {
- reason_code = ERR_R_PEM_LIB;
- rsa =
- PEM_read_bio_RSAPrivateKey(in, NULL, ssl->ctx->default_passwd_callback,
- ssl->ctx->default_passwd_callback_userdata);
- } else {
- OPENSSL_PUT_ERROR(SSL, SSL_use_RSAPrivateKey_file, SSL_R_BAD_SSL_FILETYPE);
- goto end;
- }
-
- if (rsa == NULL) {
- OPENSSL_PUT_ERROR(SSL, SSL_use_RSAPrivateKey_file, reason_code);
- goto end;
- }
- ret = SSL_use_RSAPrivateKey(ssl, rsa);
- RSA_free(rsa);
-
-end:
- BIO_free(in);
- return ret;
-}
-
-int SSL_use_RSAPrivateKey_ASN1(SSL *ssl, uint8_t *d, long len) {
- int ret;
- const uint8_t *p;
- RSA *rsa;
-
- p = d;
- rsa = d2i_RSAPrivateKey(NULL, &p, (long)len);
+int SSL_use_RSAPrivateKey_ASN1(SSL *ssl, const uint8_t *der, size_t der_len) {
+ RSA *rsa = RSA_private_key_from_bytes(der, der_len);
if (rsa == NULL) {
- OPENSSL_PUT_ERROR(SSL, SSL_use_RSAPrivateKey_ASN1, ERR_R_ASN1_LIB);
+ OPENSSL_PUT_ERROR(SSL, ERR_R_ASN1_LIB);
return 0;
}
- ret = SSL_use_RSAPrivateKey(ssl, rsa);
+ int ret = SSL_use_RSAPrivateKey(ssl, rsa);
RSA_free(rsa);
return ret;
}
@@ -248,7 +157,7 @@ int SSL_use_PrivateKey(SSL *ssl, EVP_PKEY *pkey) {
int ret;
if (pkey == NULL) {
- OPENSSL_PUT_ERROR(SSL, SSL_use_PrivateKey, ERR_R_PASSED_NULL_PARAMETER);
+ OPENSSL_PUT_ERROR(SSL, ERR_R_PASSED_NULL_PARAMETER);
return 0;
}
@@ -256,46 +165,6 @@ int SSL_use_PrivateKey(SSL *ssl, EVP_PKEY *pkey) {
return ret;
}
-int SSL_use_PrivateKey_file(SSL *ssl, const char *file, int type) {
- int reason_code, ret = 0;
- BIO *in;
- EVP_PKEY *pkey = NULL;
-
- in = BIO_new(BIO_s_file());
- if (in == NULL) {
- OPENSSL_PUT_ERROR(SSL, SSL_use_PrivateKey_file, ERR_R_BUF_LIB);
- goto end;
- }
-
- if (BIO_read_filename(in, file) <= 0) {
- OPENSSL_PUT_ERROR(SSL, SSL_use_PrivateKey_file, ERR_R_SYS_LIB);
- goto end;
- }
-
- if (type == SSL_FILETYPE_PEM) {
- reason_code = ERR_R_PEM_LIB;
- pkey = PEM_read_bio_PrivateKey(in, NULL, ssl->ctx->default_passwd_callback,
- ssl->ctx->default_passwd_callback_userdata);
- } else if (type == SSL_FILETYPE_ASN1) {
- reason_code = ERR_R_ASN1_LIB;
- pkey = d2i_PrivateKey_bio(in, NULL);
- } else {
- OPENSSL_PUT_ERROR(SSL, SSL_use_PrivateKey_file, SSL_R_BAD_SSL_FILETYPE);
- goto end;
- }
-
- if (pkey == NULL) {
- OPENSSL_PUT_ERROR(SSL, SSL_use_PrivateKey_file, reason_code);
- goto end;
- }
- ret = SSL_use_PrivateKey(ssl, pkey);
- EVP_PKEY_free(pkey);
-
-end:
- BIO_free(in);
- return ret;
-}
-
int SSL_use_PrivateKey_ASN1(int type, SSL *ssl, const uint8_t *d, long len) {
int ret;
const uint8_t *p;
@@ -304,7 +173,7 @@ int SSL_use_PrivateKey_ASN1(int type, SSL *ssl, const uint8_t *d, long len) {
p = d;
pkey = d2i_PrivateKey(type, NULL, &p, (long)len);
if (pkey == NULL) {
- OPENSSL_PUT_ERROR(SSL, SSL_use_PrivateKey_ASN1, ERR_R_ASN1_LIB);
+ OPENSSL_PUT_ERROR(SSL, ERR_R_ASN1_LIB);
return 0;
}
@@ -315,8 +184,7 @@ int SSL_use_PrivateKey_ASN1(int type, SSL *ssl, const uint8_t *d, long len) {
int SSL_CTX_use_certificate(SSL_CTX *ctx, X509 *x) {
if (x == NULL) {
- OPENSSL_PUT_ERROR(SSL, SSL_CTX_use_certificate,
- ERR_R_PASSED_NULL_PARAMETER);
+ OPENSSL_PUT_ERROR(SSL, ERR_R_PASSED_NULL_PARAMETER);
return 0;
}
@@ -324,32 +192,28 @@ int SSL_CTX_use_certificate(SSL_CTX *ctx, X509 *x) {
}
static int ssl_set_cert(CERT *c, X509 *x) {
- EVP_PKEY *pkey;
- int i;
-
- pkey = X509_get_pubkey(x);
+ EVP_PKEY *pkey = X509_get_pubkey(x);
if (pkey == NULL) {
- OPENSSL_PUT_ERROR(SSL, ssl_set_cert, SSL_R_X509_LIB);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_X509_LIB);
return 0;
}
- i = ssl_cert_type(pkey);
- if (i < 0) {
- OPENSSL_PUT_ERROR(SSL, ssl_set_cert, SSL_R_UNKNOWN_CERTIFICATE_TYPE);
+ if (!is_key_type_supported(pkey->type)) {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_UNKNOWN_CERTIFICATE_TYPE);
EVP_PKEY_free(pkey);
return 0;
}
- if (c->pkeys[i].privatekey != NULL) {
+ if (c->privatekey != NULL) {
/* Sanity-check that the private key and the certificate match, unless the
* key is opaque (in case of, say, a smartcard). */
- if (!EVP_PKEY_is_opaque(c->pkeys[i].privatekey) &&
- !X509_check_private_key(x, c->pkeys[i].privatekey)) {
+ if (!EVP_PKEY_is_opaque(c->privatekey) &&
+ !X509_check_private_key(x, c->privatekey)) {
/* don't fail for a cert/key mismatch, just free current private key
* (when switching to a different cert & key, first this function should
* be used, then ssl_set_pkey */
- EVP_PKEY_free(c->pkeys[i].privatekey);
- c->pkeys[i].privatekey = NULL;
+ EVP_PKEY_free(c->privatekey);
+ c->privatekey = NULL;
/* clear error queue */
ERR_clear_error();
}
@@ -357,63 +221,19 @@ static int ssl_set_cert(CERT *c, X509 *x) {
EVP_PKEY_free(pkey);
- X509_free(c->pkeys[i].x509);
- c->pkeys[i].x509 = X509_up_ref(x);
- c->key = &(c->pkeys[i]);
+ X509_free(c->x509);
+ c->x509 = X509_up_ref(x);
return 1;
}
-int SSL_CTX_use_certificate_file(SSL_CTX *ctx, const char *file, int type) {
- int reason_code;
- BIO *in;
- int ret = 0;
- X509 *x = NULL;
-
- in = BIO_new(BIO_s_file());
- if (in == NULL) {
- OPENSSL_PUT_ERROR(SSL, SSL_CTX_use_certificate_file, ERR_R_BUF_LIB);
- goto end;
- }
-
- if (BIO_read_filename(in, file) <= 0) {
- OPENSSL_PUT_ERROR(SSL, SSL_CTX_use_certificate_file, ERR_R_SYS_LIB);
- goto end;
- }
-
- if (type == SSL_FILETYPE_ASN1) {
- reason_code = ERR_R_ASN1_LIB;
- x = d2i_X509_bio(in, NULL);
- } else if (type == SSL_FILETYPE_PEM) {
- reason_code = ERR_R_PEM_LIB;
- x = PEM_read_bio_X509(in, NULL, ctx->default_passwd_callback,
- ctx->default_passwd_callback_userdata);
- } else {
- OPENSSL_PUT_ERROR(SSL, SSL_CTX_use_certificate_file,
- SSL_R_BAD_SSL_FILETYPE);
- goto end;
- }
-
- if (x == NULL) {
- OPENSSL_PUT_ERROR(SSL, SSL_CTX_use_certificate_file, reason_code);
- goto end;
- }
-
- ret = SSL_CTX_use_certificate(ctx, x);
-
-end:
- X509_free(x);
- BIO_free(in);
- return ret;
-}
-
int SSL_CTX_use_certificate_ASN1(SSL_CTX *ctx, int len, const uint8_t *d) {
X509 *x;
int ret;
x = d2i_X509(NULL, &d, (long)len);
if (x == NULL) {
- OPENSSL_PUT_ERROR(SSL, SSL_CTX_use_certificate_ASN1, ERR_R_ASN1_LIB);
+ OPENSSL_PUT_ERROR(SSL, ERR_R_ASN1_LIB);
return 0;
}
@@ -427,14 +247,13 @@ int SSL_CTX_use_RSAPrivateKey(SSL_CTX *ctx, RSA *rsa) {
EVP_PKEY *pkey;
if (rsa == NULL) {
- OPENSSL_PUT_ERROR(SSL, SSL_CTX_use_RSAPrivateKey,
- ERR_R_PASSED_NULL_PARAMETER);
+ OPENSSL_PUT_ERROR(SSL, ERR_R_PASSED_NULL_PARAMETER);
return 0;
}
pkey = EVP_PKEY_new();
if (pkey == NULL) {
- OPENSSL_PUT_ERROR(SSL, SSL_CTX_use_RSAPrivateKey, ERR_R_EVP_LIB);
+ OPENSSL_PUT_ERROR(SSL, ERR_R_EVP_LIB);
return 0;
}
@@ -446,113 +265,28 @@ int SSL_CTX_use_RSAPrivateKey(SSL_CTX *ctx, RSA *rsa) {
return ret;
}
-int SSL_CTX_use_RSAPrivateKey_file(SSL_CTX *ctx, const char *file, int type) {
- int reason_code, ret = 0;
- BIO *in;
- RSA *rsa = NULL;
-
- in = BIO_new(BIO_s_file());
- if (in == NULL) {
- OPENSSL_PUT_ERROR(SSL, SSL_CTX_use_RSAPrivateKey_file, ERR_R_BUF_LIB);
- goto end;
- }
-
- if (BIO_read_filename(in, file) <= 0) {
- OPENSSL_PUT_ERROR(SSL, SSL_CTX_use_RSAPrivateKey_file, ERR_R_SYS_LIB);
- goto end;
- }
-
- if (type == SSL_FILETYPE_ASN1) {
- reason_code = ERR_R_ASN1_LIB;
- rsa = d2i_RSAPrivateKey_bio(in, NULL);
- } else if (type == SSL_FILETYPE_PEM) {
- reason_code = ERR_R_PEM_LIB;
- rsa = PEM_read_bio_RSAPrivateKey(in, NULL, ctx->default_passwd_callback,
- ctx->default_passwd_callback_userdata);
- } else {
- OPENSSL_PUT_ERROR(SSL, SSL_CTX_use_RSAPrivateKey_file,
- SSL_R_BAD_SSL_FILETYPE);
- goto end;
- }
-
- if (rsa == NULL) {
- OPENSSL_PUT_ERROR(SSL, SSL_CTX_use_RSAPrivateKey_file, reason_code);
- goto end;
- }
- ret = SSL_CTX_use_RSAPrivateKey(ctx, rsa);
- RSA_free(rsa);
-
-end:
- BIO_free(in);
- return ret;
-}
-
-int SSL_CTX_use_RSAPrivateKey_ASN1(SSL_CTX *ctx, const uint8_t *d, long len) {
- int ret;
- const uint8_t *p;
- RSA *rsa;
-
- p = d;
- rsa = d2i_RSAPrivateKey(NULL, &p, (long)len);
+int SSL_CTX_use_RSAPrivateKey_ASN1(SSL_CTX *ctx, const uint8_t *der,
+ size_t der_len) {
+ RSA *rsa = RSA_private_key_from_bytes(der, der_len);
if (rsa == NULL) {
- OPENSSL_PUT_ERROR(SSL, SSL_CTX_use_RSAPrivateKey_ASN1, ERR_R_ASN1_LIB);
+ OPENSSL_PUT_ERROR(SSL, ERR_R_ASN1_LIB);
return 0;
}
- ret = SSL_CTX_use_RSAPrivateKey(ctx, rsa);
+ int ret = SSL_CTX_use_RSAPrivateKey(ctx, rsa);
RSA_free(rsa);
return ret;
}
int SSL_CTX_use_PrivateKey(SSL_CTX *ctx, EVP_PKEY *pkey) {
if (pkey == NULL) {
- OPENSSL_PUT_ERROR(SSL, SSL_CTX_use_PrivateKey, ERR_R_PASSED_NULL_PARAMETER);
+ OPENSSL_PUT_ERROR(SSL, ERR_R_PASSED_NULL_PARAMETER);
return 0;
}
return ssl_set_pkey(ctx->cert, pkey);
}
-int SSL_CTX_use_PrivateKey_file(SSL_CTX *ctx, const char *file, int type) {
- int reason_code, ret = 0;
- BIO *in;
- EVP_PKEY *pkey = NULL;
-
- in = BIO_new(BIO_s_file());
- if (in == NULL) {
- OPENSSL_PUT_ERROR(SSL, SSL_CTX_use_PrivateKey_file, ERR_R_BUF_LIB);
- goto end;
- }
-
- if (BIO_read_filename(in, file) <= 0) {
- OPENSSL_PUT_ERROR(SSL, SSL_CTX_use_PrivateKey_file, ERR_R_SYS_LIB);
- goto end;
- }
-
- if (type == SSL_FILETYPE_PEM) {
- reason_code = ERR_R_PEM_LIB;
- pkey = PEM_read_bio_PrivateKey(in, NULL, ctx->default_passwd_callback,
- ctx->default_passwd_callback_userdata);
- } else if (type == SSL_FILETYPE_ASN1) {
- reason_code = ERR_R_ASN1_LIB;
- pkey = d2i_PrivateKey_bio(in, NULL);
- } else {
- OPENSSL_PUT_ERROR(SSL, SSL_CTX_use_PrivateKey_file, SSL_R_BAD_SSL_FILETYPE);
- goto end;
- }
-
- if (pkey == NULL) {
- OPENSSL_PUT_ERROR(SSL, SSL_CTX_use_PrivateKey_file, reason_code);
- goto end;
- }
- ret = SSL_CTX_use_PrivateKey(ctx, pkey);
- EVP_PKEY_free(pkey);
-
-end:
- BIO_free(in);
- return ret;
-}
-
int SSL_CTX_use_PrivateKey_ASN1(int type, SSL_CTX *ctx, const uint8_t *d,
long len) {
int ret;
@@ -562,7 +296,7 @@ int SSL_CTX_use_PrivateKey_ASN1(int type, SSL_CTX *ctx, const uint8_t *d,
p = d;
pkey = d2i_PrivateKey(type, NULL, &p, (long)len);
if (pkey == NULL) {
- OPENSSL_PUT_ERROR(SSL, SSL_CTX_use_PrivateKey_ASN1, ERR_R_ASN1_LIB);
+ OPENSSL_PUT_ERROR(SSL, ERR_R_ASN1_LIB);
return 0;
}
@@ -571,76 +305,74 @@ int SSL_CTX_use_PrivateKey_ASN1(int type, SSL_CTX *ctx, const uint8_t *d,
return ret;
}
+void SSL_set_private_key_method(SSL *ssl,
+ const SSL_PRIVATE_KEY_METHOD *key_method) {
+ ssl->cert->key_method = key_method;
+}
-/* Read a file that contains our certificate in "PEM" format, possibly followed
- * by a sequence of CA certificates that should be sent to the peer in the
- * Certificate message. */
-int SSL_CTX_use_certificate_chain_file(SSL_CTX *ctx, const char *file) {
- BIO *in;
- int ret = 0;
- X509 *x = NULL;
-
- ERR_clear_error(); /* clear error stack for SSL_CTX_use_certificate() */
+int SSL_set_private_key_digest_prefs(SSL *ssl, const int *digest_nids,
+ size_t num_digests) {
+ OPENSSL_free(ssl->cert->digest_nids);
- in = BIO_new(BIO_s_file());
- if (in == NULL) {
- OPENSSL_PUT_ERROR(SSL, SSL_CTX_use_certificate_chain_file, ERR_R_BUF_LIB);
- goto end;
+ ssl->cert->num_digest_nids = 0;
+ ssl->cert->digest_nids = BUF_memdup(digest_nids, num_digests*sizeof(int));
+ if (ssl->cert->digest_nids == NULL) {
+ OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
+ return 0;
}
- if (BIO_read_filename(in, file) <= 0) {
- OPENSSL_PUT_ERROR(SSL, SSL_CTX_use_certificate_chain_file, ERR_R_SYS_LIB);
- goto end;
- }
+ ssl->cert->num_digest_nids = num_digests;
+ return 1;
+}
- x = PEM_read_bio_X509_AUX(in, NULL, ctx->default_passwd_callback,
- ctx->default_passwd_callback_userdata);
- if (x == NULL) {
- OPENSSL_PUT_ERROR(SSL, SSL_CTX_use_certificate_chain_file, ERR_R_PEM_LIB);
- goto end;
+int ssl_has_private_key(SSL *ssl) {
+ return ssl->cert->privatekey != NULL || ssl->cert->key_method != NULL;
+}
+
+int ssl_private_key_type(SSL *ssl) {
+ if (ssl->cert->key_method != NULL) {
+ return ssl->cert->key_method->type(ssl);
}
+ return EVP_PKEY_id(ssl->cert->privatekey);
+}
- ret = SSL_CTX_use_certificate(ctx, x);
+size_t ssl_private_key_max_signature_len(SSL *ssl) {
+ if (ssl->cert->key_method != NULL) {
+ return ssl->cert->key_method->max_signature_len(ssl);
+ }
+ return EVP_PKEY_size(ssl->cert->privatekey);
+}
- if (ERR_peek_error() != 0) {
- ret = 0; /* Key/certificate mismatch doesn't imply ret==0 ... */
+enum ssl_private_key_result_t ssl_private_key_sign(
+ SSL *ssl, uint8_t *out, size_t *out_len, size_t max_out, const EVP_MD *md,
+ const uint8_t *in, size_t in_len) {
+ if (ssl->cert->key_method != NULL) {
+ return ssl->cert->key_method->sign(ssl, out, out_len, max_out, md, in,
+ in_len);
}
- if (ret) {
- /* If we could set up our certificate, now proceed to the CA
- * certificates. */
- X509 *ca;
- int r;
- uint32_t err;
-
- SSL_CTX_clear_chain_certs(ctx);
-
- while ((ca = PEM_read_bio_X509(in, NULL, ctx->default_passwd_callback,
- ctx->default_passwd_callback_userdata)) !=
- NULL) {
- r = SSL_CTX_add0_chain_cert(ctx, ca);
- if (!r) {
- X509_free(ca);
- ret = 0;
- goto end;
- }
- /* Note that we must not free r if it was successfully added to the chain
- * (while we must free the main certificate, since its reference count is
- * increased by SSL_CTX_use_certificate). */
- }
+ enum ssl_private_key_result_t ret = ssl_private_key_failure;
+ EVP_PKEY_CTX *ctx = EVP_PKEY_CTX_new(ssl->cert->privatekey, NULL);
+ if (ctx == NULL) {
+ goto end;
+ }
- /* When the while loop ends, it's usually just EOF. */
- err = ERR_peek_last_error();
- if (ERR_GET_LIB(err) == ERR_LIB_PEM &&
- ERR_GET_REASON(err) == PEM_R_NO_START_LINE) {
- ERR_clear_error();
- } else {
- ret = 0; /* some real error */
- }
+ size_t len = max_out;
+ if (!EVP_PKEY_sign_init(ctx) ||
+ !EVP_PKEY_CTX_set_signature_md(ctx, md) ||
+ !EVP_PKEY_sign(ctx, out, &len, in, in_len)) {
+ goto end;
}
+ *out_len = len;
+ ret = ssl_private_key_success;
end:
- X509_free(x);
- BIO_free(in);
+ EVP_PKEY_CTX_free(ctx);
return ret;
}
+
+enum ssl_private_key_result_t ssl_private_key_sign_complete(
+ SSL *ssl, uint8_t *out, size_t *out_len, size_t max_out) {
+ /* Only custom keys may be asynchronous. */
+ return ssl->cert->key_method->sign_complete(ssl, out, out_len, max_out);
+}
diff --git a/src/ssl/ssl_sess.c b/src/ssl/ssl_session.c
index 9ab4585..345aca2 100644
--- a/src/ssl/ssl_sess.c
+++ b/src/ssl/ssl_session.c
@@ -133,6 +133,9 @@
* OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR
* OTHERWISE. */
+#include <openssl/ssl.h>
+
+#include <assert.h>
#include <stdio.h>
#include <string.h>
@@ -150,11 +153,111 @@
* that it needs to asynchronously fetch session information. */
static const char g_pending_session_magic = 0;
-static CRYPTO_EX_DATA_CLASS g_ex_data_class = CRYPTO_EX_DATA_CLASS_INIT;
+static CRYPTO_EX_DATA_CLASS g_ex_data_class =
+ CRYPTO_EX_DATA_CLASS_INIT_WITH_APP_DATA;
+
+static void SSL_SESSION_list_remove(SSL_CTX *ctx, SSL_SESSION *session);
+static void SSL_SESSION_list_add(SSL_CTX *ctx, SSL_SESSION *session);
+static int remove_session_lock(SSL_CTX *ctx, SSL_SESSION *session, int lock);
+
+SSL_SESSION *SSL_SESSION_new(void) {
+ SSL_SESSION *session = (SSL_SESSION *)OPENSSL_malloc(sizeof(SSL_SESSION));
+ if (session == NULL) {
+ OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
+ return 0;
+ }
+ memset(session, 0, sizeof(SSL_SESSION));
+
+ session->verify_result = 1; /* avoid 0 (= X509_V_OK) just in case */
+ session->references = 1;
+ session->timeout = SSL_DEFAULT_SESSION_TIMEOUT;
+ session->time = (unsigned long)time(NULL);
+ CRYPTO_new_ex_data(&g_ex_data_class, session, &session->ex_data);
+ return session;
+}
+
+SSL_SESSION *SSL_SESSION_up_ref(SSL_SESSION *session) {
+ if (session != NULL) {
+ CRYPTO_refcount_inc(&session->references);
+ }
+ return session;
+}
+
+void SSL_SESSION_free(SSL_SESSION *session) {
+ if (session == NULL ||
+ !CRYPTO_refcount_dec_and_test_zero(&session->references)) {
+ return;
+ }
+
+ CRYPTO_free_ex_data(&g_ex_data_class, session, &session->ex_data);
+
+ OPENSSL_cleanse(session->master_key, sizeof(session->master_key));
+ OPENSSL_cleanse(session->session_id, sizeof(session->session_id));
+ X509_free(session->peer);
+ sk_X509_pop_free(session->cert_chain, X509_free);
+ OPENSSL_free(session->tlsext_hostname);
+ OPENSSL_free(session->tlsext_tick);
+ OPENSSL_free(session->tlsext_signed_cert_timestamp_list);
+ OPENSSL_free(session->ocsp_response);
+ OPENSSL_free(session->psk_identity);
+ OPENSSL_cleanse(session, sizeof(*session));
+ OPENSSL_free(session);
+}
+
+const uint8_t *SSL_SESSION_get_id(const SSL_SESSION *session,
+ unsigned *out_len) {
+ if (out_len != NULL) {
+ *out_len = session->session_id_length;
+ }
+ return session->session_id;
+}
+
+long SSL_SESSION_get_timeout(const SSL_SESSION *session) {
+ return session->timeout;
+}
+
+long SSL_SESSION_get_time(const SSL_SESSION *session) {
+ return session->time;
+}
+
+uint32_t SSL_SESSION_get_key_exchange_info(const SSL_SESSION *session) {
+ return session->key_exchange_info;
+}
+
+X509 *SSL_SESSION_get0_peer(const SSL_SESSION *session) {
+ return session->peer;
+}
+
+long SSL_SESSION_set_time(SSL_SESSION *session, long time) {
+ if (session == NULL) {
+ return 0;
+ }
+
+ session->time = time;
+ return time;
+}
+
+long SSL_SESSION_set_timeout(SSL_SESSION *session, long timeout) {
+ if (session == NULL) {
+ return 0;
+ }
-static void SSL_SESSION_list_remove(SSL_CTX *ctx, SSL_SESSION *s);
-static void SSL_SESSION_list_add(SSL_CTX *ctx, SSL_SESSION *s);
-static int remove_session_lock(SSL_CTX *ctx, SSL_SESSION *c, int lck);
+ session->timeout = timeout;
+ return 1;
+}
+
+int SSL_SESSION_set1_id_context(SSL_SESSION *session, const uint8_t *sid_ctx,
+ unsigned sid_ctx_len) {
+ if (sid_ctx_len > SSL_MAX_SID_CTX_LENGTH) {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_SSL_SESSION_ID_CONTEXT_TOO_LONG);
+ return 0;
+ }
+
+ session->sid_ctx_length = sid_ctx_len;
+ memcpy(session->sid_ctx, sid_ctx, sid_ctx_len);
+
+ return 1;
+}
SSL_SESSION *SSL_magic_pending_session_ptr(void) {
return (SSL_SESSION *)&g_pending_session_magic;
@@ -182,37 +285,12 @@ int SSL_SESSION_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
return index;
}
-int SSL_SESSION_set_ex_data(SSL_SESSION *s, int idx, void *arg) {
- return CRYPTO_set_ex_data(&s->ex_data, idx, arg);
-}
-
-void *SSL_SESSION_get_ex_data(const SSL_SESSION *s, int idx) {
- return CRYPTO_get_ex_data(&s->ex_data, idx);
+int SSL_SESSION_set_ex_data(SSL_SESSION *session, int idx, void *arg) {
+ return CRYPTO_set_ex_data(&session->ex_data, idx, arg);
}
-SSL_SESSION *SSL_SESSION_new(void) {
- SSL_SESSION *ss;
-
- ss = (SSL_SESSION *)OPENSSL_malloc(sizeof(SSL_SESSION));
- if (ss == NULL) {
- OPENSSL_PUT_ERROR(SSL, SSL_SESSION_new, ERR_R_MALLOC_FAILURE);
- return 0;
- }
- memset(ss, 0, sizeof(SSL_SESSION));
-
- ss->verify_result = 1; /* avoid 0 (= X509_V_OK) just in case */
- ss->references = 1;
- ss->timeout = SSL_DEFAULT_SESSION_TIMEOUT;
- ss->time = (unsigned long)time(NULL);
- CRYPTO_new_ex_data(&g_ex_data_class, ss, &ss->ex_data);
- return ss;
-}
-
-const uint8_t *SSL_SESSION_get_id(const SSL_SESSION *s, unsigned int *len) {
- if (len) {
- *len = s->session_id_length;
- }
- return s->session_id;
+void *SSL_SESSION_get_ex_data(const SSL_SESSION *session, int idx) {
+ return CRYPTO_get_ex_data(&session->ex_data, idx);
}
/* Even with SSLv2, we have 16 bytes (128 bits) of session ID space.
@@ -225,9 +303,9 @@ const uint8_t *SSL_SESSION_get_id(const SSL_SESSION *s, unsigned int *len) {
* server. How you might store that many sessions is perhaps a more interesting
* question ... */
static int def_generate_session_id(const SSL *ssl, uint8_t *id,
- unsigned int *id_len) {
+ unsigned *id_len) {
static const unsigned kMaxAttempts = 10;
- unsigned int retry = 0;
+ unsigned retry = 0;
do {
if (!RAND_bytes(id, *id_len)) {
return 0;
@@ -257,8 +335,7 @@ int ssl_get_new_session(SSL *s, int session) {
GEN_SESSION_CB cb = def_generate_session_id;
if (s->mode & SSL_MODE_NO_SESSION_CREATION) {
- OPENSSL_PUT_ERROR(SSL, ssl_get_new_session,
- SSL_R_SESSION_MAY_NOT_BE_CREATED);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_SESSION_MAY_NOT_BE_CREATED);
return 0;
}
@@ -282,8 +359,7 @@ int ssl_get_new_session(SSL *s, int session) {
ss->ssl_version = s->version;
ss->session_id_length = SSL3_SSL_SESSION_ID_LENGTH;
} else {
- OPENSSL_PUT_ERROR(SSL, ssl_get_new_session,
- SSL_R_UNSUPPORTED_SSL_VERSION);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_UNSUPPORTED_SSL_VERSION);
SSL_SESSION_free(ss);
return 0;
}
@@ -305,8 +381,7 @@ int ssl_get_new_session(SSL *s, int session) {
tmp = ss->session_id_length;
if (!cb(s, ss->session_id, &tmp)) {
/* The callback failed */
- OPENSSL_PUT_ERROR(SSL, ssl_get_new_session,
- SSL_R_SSL_SESSION_ID_CALLBACK_FAILED);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_SSL_SESSION_ID_CALLBACK_FAILED);
SSL_SESSION_free(ss);
return 0;
}
@@ -315,8 +390,7 @@ int ssl_get_new_session(SSL *s, int session) {
* higher than it was. */
if (!tmp || tmp > ss->session_id_length) {
/* The callback set an illegal length */
- OPENSSL_PUT_ERROR(SSL, ssl_get_new_session,
- SSL_R_SSL_SESSION_ID_HAS_BAD_LENGTH);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_SSL_SESSION_ID_HAS_BAD_LENGTH);
SSL_SESSION_free(ss);
return 0;
}
@@ -324,8 +398,7 @@ int ssl_get_new_session(SSL *s, int session) {
ss->session_id_length = tmp;
/* Finally, check for a conflict */
if (SSL_has_matching_session_id(s, ss->session_id, ss->session_id_length)) {
- OPENSSL_PUT_ERROR(SSL, ssl_get_new_session,
- SSL_R_SSL_SESSION_ID_CONFLICT);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_SSL_SESSION_ID_CONFLICT);
SSL_SESSION_free(ss);
return 0;
}
@@ -334,7 +407,7 @@ int ssl_get_new_session(SSL *s, int session) {
if (s->tlsext_hostname) {
ss->tlsext_hostname = BUF_strdup(s->tlsext_hostname);
if (ss->tlsext_hostname == NULL) {
- OPENSSL_PUT_ERROR(SSL, ssl_get_new_session, ERR_R_INTERNAL_ERROR);
+ OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
SSL_SESSION_free(ss);
return 0;
}
@@ -344,7 +417,7 @@ int ssl_get_new_session(SSL *s, int session) {
}
if (s->sid_ctx_length > sizeof(ss->sid_ctx)) {
- OPENSSL_PUT_ERROR(SSL, ssl_get_new_session, ERR_R_INTERNAL_ERROR);
+ OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
SSL_SESSION_free(ss);
return 0;
}
@@ -358,121 +431,110 @@ int ssl_get_new_session(SSL *s, int session) {
return 1;
}
-/* ssl_get_prev attempts to find an SSL_SESSION to be used to resume this
- * connection. It is only called by servers.
- *
- * ctx: contains the early callback context, which is the result of a
- * shallow parse of the ClientHello.
- *
- * Returns:
- * -1: error
- * 0: a session may have been found.
- *
- * Side effects:
- * - If a session is found then s->session is pointed at it (after freeing an
- * existing session if need be) and s->verify_result is set from the session.
- * - Both for new and resumed sessions, s->tlsext_ticket_expected is set to 1
- * if the server should issue a new session ticket (to 0 otherwise). */
-int ssl_get_prev_session(SSL *s, const struct ssl_early_callback_ctx *ctx) {
- /* This is used only by servers. */
- SSL_SESSION *ret = NULL;
- int fatal = 0;
- int try_session_cache = 1;
- int r;
-
- if (ctx->session_id_len > SSL_MAX_SSL_SESSION_ID_LENGTH) {
- goto err;
- }
+/* ssl_lookup_session looks up |session_id| in the session cache and sets
+ * |*out_session| to an |SSL_SESSION| object if found. The caller takes
+ * ownership of the result. */
+static enum ssl_session_result_t ssl_lookup_session(
+ SSL *ssl, SSL_SESSION **out_session, const uint8_t *session_id,
+ size_t session_id_len) {
+ *out_session = NULL;
- if (ctx->session_id_len == 0) {
- try_session_cache = 0;
+ if (session_id_len == 0 || session_id_len > SSL_MAX_SSL_SESSION_ID_LENGTH) {
+ return ssl_session_success;
}
- r = tls1_process_ticket(s, ctx, &ret); /* sets s->tlsext_ticket_expected */
- switch (r) {
- case -1: /* Error during processing */
- fatal = 1;
- goto err;
-
- case 0: /* No ticket found */
- case 1: /* Zero length ticket found */
- break; /* Ok to carry on processing session id. */
-
- case 2: /* Ticket found but not decrypted. */
- case 3: /* Ticket decrypted, *ret has been set. */
- try_session_cache = 0;
- break;
-
- default:
- abort();
- }
-
- if (try_session_cache && ret == NULL &&
- !(s->initial_ctx->session_cache_mode &
+ SSL_SESSION *session;
+ /* Try the internal cache, if it exists. */
+ if (!(ssl->initial_ctx->session_cache_mode &
SSL_SESS_CACHE_NO_INTERNAL_LOOKUP)) {
SSL_SESSION data;
- data.ssl_version = s->version;
- data.session_id_length = ctx->session_id_len;
- if (ctx->session_id_len == 0) {
- return 0;
+ data.ssl_version = ssl->version;
+ data.session_id_length = session_id_len;
+ memcpy(data.session_id, session_id, session_id_len);
+
+ CRYPTO_MUTEX_lock_read(&ssl->initial_ctx->lock);
+ session = lh_SSL_SESSION_retrieve(ssl->initial_ctx->sessions, &data);
+ if (session != NULL) {
+ SSL_SESSION_up_ref(session);
}
- memcpy(data.session_id, ctx->session_id, ctx->session_id_len);
+ CRYPTO_MUTEX_unlock(&ssl->initial_ctx->lock);
- CRYPTO_MUTEX_lock_read(&s->initial_ctx->lock);
- ret = lh_SSL_SESSION_retrieve(s->initial_ctx->sessions, &data);
- CRYPTO_MUTEX_unlock(&s->initial_ctx->lock);
-
- if (ret != NULL) {
- SSL_SESSION_up_ref(ret);
+ if (session != NULL) {
+ *out_session = session;
+ return ssl_session_success;
}
}
- if (try_session_cache && ret == NULL &&
- s->initial_ctx->get_session_cb != NULL) {
- int copy = 1;
-
- ret = s->initial_ctx->get_session_cb(s, (uint8_t *)ctx->session_id,
- ctx->session_id_len, &copy);
- if (ret != NULL) {
- if (ret == SSL_magic_pending_session_ptr()) {
- /* This is a magic value which indicates that the callback needs to
- * unwind the stack and figure out the session asynchronously. */
- return PENDING_SESSION;
- }
-
- /* Increment reference count now if the session callback asks us to do so
- * (note that if the session structures returned by the callback are
- * shared between threads, it must handle the reference count itself
- * [i.e. copy == 0], or things won't be thread-safe). */
- if (copy) {
- SSL_SESSION_up_ref(ret);
- }
+ /* Fall back to the external cache, if it exists. */
+ if (ssl->initial_ctx->get_session_cb == NULL) {
+ return ssl_session_success;
+ }
+ int copy = 1;
+ session = ssl->initial_ctx->get_session_cb(ssl, (uint8_t *)session_id,
+ session_id_len, &copy);
+ if (session == NULL) {
+ return ssl_session_success;
+ }
+ if (session == SSL_magic_pending_session_ptr()) {
+ return ssl_session_retry;
+ }
- /* Add the externally cached session to the internal cache as well if and
- * only if we are supposed to. */
- if (!(s->initial_ctx->session_cache_mode &
- SSL_SESS_CACHE_NO_INTERNAL_STORE)) {
- /* The following should not return 1, otherwise, things are very
- * strange */
- SSL_CTX_add_session(s->initial_ctx, ret);
- }
- }
+ /* Increment reference count now if the session callback asks us to do so
+ * (note that if the session structures returned by the callback are shared
+ * between threads, it must handle the reference count itself [i.e. copy ==
+ * 0], or things won't be thread-safe). */
+ if (copy) {
+ SSL_SESSION_up_ref(session);
}
- if (ret == NULL) {
- goto err;
+ /* Add the externally cached session to the internal cache if necessary. */
+ if (!(ssl->initial_ctx->session_cache_mode &
+ SSL_SESS_CACHE_NO_INTERNAL_STORE)) {
+ SSL_CTX_add_session(ssl->initial_ctx, session);
}
- /* Now ret is non-NULL and we own one of its reference counts. */
+ *out_session = session;
+ return ssl_session_success;
+}
- if (ret->sid_ctx_length != s->sid_ctx_length ||
- memcmp(ret->sid_ctx, s->sid_ctx, ret->sid_ctx_length)) {
- /* We have the session requested by the client, but we don't want to use it
- * in this context. */
- goto err; /* treat like cache miss */
+enum ssl_session_result_t ssl_get_prev_session(
+ SSL *ssl, SSL_SESSION **out_session, int *out_send_ticket,
+ const struct ssl_early_callback_ctx *ctx) {
+ /* This is used only by servers. */
+ assert(ssl->server);
+ SSL_SESSION *session = NULL;
+ int send_ticket = 0;
+
+ /* If tickets are disabled, always behave as if no tickets are present. */
+ const uint8_t *ticket = NULL;
+ size_t ticket_len = 0;
+ const int tickets_supported =
+ !(SSL_get_options(ssl) & SSL_OP_NO_TICKET) &&
+ (ssl->version > SSL3_VERSION || ctx->extensions != NULL) &&
+ SSL_early_callback_ctx_extension_get(ctx, TLSEXT_TYPE_session_ticket,
+ &ticket, &ticket_len);
+ if (tickets_supported) {
+ if (!tls_process_ticket(ssl, &session, &send_ticket, ticket, ticket_len,
+ ctx->session_id, ctx->session_id_len)) {
+ return ssl_session_error;
+ }
+ } else {
+ /* The client does not support session tickets, so the session ID should be
+ * used instead. */
+ enum ssl_session_result_t lookup_ret = ssl_lookup_session(
+ ssl, &session, ctx->session_id, ctx->session_id_len);
+ if (lookup_ret != ssl_session_success) {
+ return lookup_ret;
+ }
}
- if ((s->verify_mode & SSL_VERIFY_PEER) && s->sid_ctx_length == 0) {
+ if (session == NULL ||
+ session->sid_ctx_length != ssl->sid_ctx_length ||
+ memcmp(session->sid_ctx, ssl->sid_ctx, ssl->sid_ctx_length) != 0) {
+ goto no_session;
+ }
+
+ if ((ssl->verify_mode & SSL_VERIFY_PEER) && ssl->sid_ctx_length == 0) {
/* We can't be sure if this session is being used out of context, which is
* especially important for SSL_VERIFY_PEER. The application should have
* used SSL[_CTX]_set_session_id_context.
@@ -481,83 +543,76 @@ int ssl_get_prev_session(SSL *s, const struct ssl_early_callback_ctx *ctx) {
* like a cache miss (otherwise it would be easy for applications to
* effectively disable the session cache by accident without anyone
* noticing). */
- OPENSSL_PUT_ERROR(SSL, ssl_get_prev_session,
- SSL_R_SESSION_ID_CONTEXT_UNINITIALIZED);
- fatal = 1;
- goto err;
+ OPENSSL_PUT_ERROR(SSL, SSL_R_SESSION_ID_CONTEXT_UNINITIALIZED);
+ goto fatal_error;
}
- if (ret->timeout < (long)(time(NULL) - ret->time)) {
- /* timeout */
- if (try_session_cache) {
- /* session was from the cache, so remove it */
- SSL_CTX_remove_session(s->initial_ctx, ret);
+ if (session->timeout < (long)(time(NULL) - session->time)) {
+ if (!tickets_supported) {
+ /* The session was from the cache, so remove it. */
+ SSL_CTX_remove_session(ssl->initial_ctx, session);
}
- goto err;
+ goto no_session;
}
- SSL_SESSION_free(s->session);
- s->session = ret;
- s->verify_result = s->session->verify_result;
- return 1;
+ *out_session = session;
+ *out_send_ticket = send_ticket;
+ return ssl_session_success;
-err:
- if (ret != NULL) {
- SSL_SESSION_free(ret);
- if (!try_session_cache) {
- /* The session was from a ticket, so we should
- * issue a ticket for the new session */
- s->tlsext_ticket_expected = 1;
- }
- }
- if (fatal) {
- return -1;
- }
- return 0;
+fatal_error:
+ SSL_SESSION_free(session);
+ return ssl_session_error;
+
+no_session:
+ *out_session = NULL;
+ *out_send_ticket = tickets_supported;
+ SSL_SESSION_free(session);
+ return ssl_session_success;
}
-int SSL_CTX_add_session(SSL_CTX *ctx, SSL_SESSION *c) {
+int SSL_CTX_add_session(SSL_CTX *ctx, SSL_SESSION *session) {
int ret = 0;
- SSL_SESSION *s;
+ SSL_SESSION *old_session;
- /* add just 1 reference count for the SSL_CTX's session cache even though it
+ /* Add just 1 reference count for the |SSL_CTX|'s session cache even though it
* has two ways of access: each session is in a doubly linked list and an
- * lhash */
- SSL_SESSION_up_ref(c);
- /* if session c is in already in cache, we take back the increment later */
+ * lhash. */
+ SSL_SESSION_up_ref(session);
+ /* If |session| is in already in cache, we take back the increment later. */
CRYPTO_MUTEX_lock_write(&ctx->lock);
- if (!lh_SSL_SESSION_insert(ctx->sessions, &s, c)) {
+ if (!lh_SSL_SESSION_insert(ctx->sessions, &old_session, session)) {
CRYPTO_MUTEX_unlock(&ctx->lock);
+ SSL_SESSION_free(session);
return 0;
}
- /* s != NULL iff we already had a session with the given PID. In this case, s
- * == c should hold (then we did not really modify ctx->sessions), or we're
- * in trouble. */
- if (s != NULL && s != c) {
+ /* |old_session| != NULL iff we already had a session with the given session
+ * ID. In this case, |old_session| == |session| should hold (then we did not
+ * really modify |ctx->sessions|), or we're in trouble. */
+ if (old_session != NULL && old_session != session) {
/* We *are* in trouble ... */
- SSL_SESSION_list_remove(ctx, s);
- SSL_SESSION_free(s);
+ SSL_SESSION_list_remove(ctx, old_session);
+ SSL_SESSION_free(old_session);
/* ... so pretend the other session did not exist in cache (we cannot
- * handle two SSL_SESSION structures with identical session ID in the same
+ * handle two |SSL_SESSION| structures with identical session ID in the same
* cache, which could happen e.g. when two threads concurrently obtain the
- * same session from an external cache) */
- s = NULL;
+ * same session from an external cache). */
+ old_session = NULL;
}
- /* Put at the head of the queue unless it is already in the cache */
- if (s == NULL) {
- SSL_SESSION_list_add(ctx, c);
+ /* Put at the head of the queue unless it is already in the cache. */
+ if (old_session == NULL) {
+ SSL_SESSION_list_add(ctx, session);
}
- if (s != NULL) {
- /* existing cache entry -- decrement previously incremented reference count
- * because it already takes into account the cache */
- SSL_SESSION_free(s); /* s == c */
+ if (old_session != NULL) {
+ /* Existing cache entry -- decrement previously incremented reference count
+ * because it already takes into account the cache. */
+ SSL_SESSION_free(old_session); /* |old_session| == |session| */
ret = 0;
} else {
- /* new cache entry -- remove old ones if cache has become too large */
+ /* New cache entry -- remove old ones if cache has become too large. */
ret = 1;
if (SSL_CTX_sess_get_cache_size(ctx) > 0) {
@@ -573,23 +628,23 @@ int SSL_CTX_add_session(SSL_CTX *ctx, SSL_SESSION *c) {
return ret;
}
-int SSL_CTX_remove_session(SSL_CTX *ctx, SSL_SESSION *c) {
- return remove_session_lock(ctx, c, 1);
+int SSL_CTX_remove_session(SSL_CTX *ctx, SSL_SESSION *session) {
+ return remove_session_lock(ctx, session, 1);
}
-static int remove_session_lock(SSL_CTX *ctx, SSL_SESSION *c, int lock) {
- SSL_SESSION *r;
+static int remove_session_lock(SSL_CTX *ctx, SSL_SESSION *session, int lock) {
int ret = 0;
- if (c != NULL && c->session_id_length != 0) {
+ if (session != NULL && session->session_id_length != 0) {
if (lock) {
CRYPTO_MUTEX_lock_write(&ctx->lock);
}
- r = lh_SSL_SESSION_retrieve(ctx->sessions, c);
- if (r == c) {
+ SSL_SESSION *found_session = lh_SSL_SESSION_retrieve(ctx->sessions,
+ session);
+ if (found_session == session) {
ret = 1;
- r = lh_SSL_SESSION_delete(ctx->sessions, c);
- SSL_SESSION_list_remove(ctx, c);
+ found_session = lh_SSL_SESSION_delete(ctx->sessions, session);
+ SSL_SESSION_list_remove(ctx, session);
}
if (lock) {
@@ -597,127 +652,48 @@ static int remove_session_lock(SSL_CTX *ctx, SSL_SESSION *c, int lock) {
}
if (ret) {
- r->not_resumable = 1;
+ found_session->not_resumable = 1;
if (ctx->remove_session_cb != NULL) {
- ctx->remove_session_cb(ctx, r);
+ ctx->remove_session_cb(ctx, found_session);
}
- SSL_SESSION_free(r);
+ SSL_SESSION_free(found_session);
}
}
return ret;
}
-SSL_SESSION *SSL_SESSION_up_ref(SSL_SESSION *session) {
- if (session) {
- CRYPTO_refcount_inc(&session->references);
- }
- return session;
-}
-
-void SSL_SESSION_free(SSL_SESSION *session) {
- if (session == NULL ||
- !CRYPTO_refcount_dec_and_test_zero(&session->references)) {
- return;
- }
-
- CRYPTO_free_ex_data(&g_ex_data_class, session, &session->ex_data);
-
- OPENSSL_cleanse(session->master_key, sizeof(session->master_key));
- OPENSSL_cleanse(session->session_id, sizeof(session->session_id));
- ssl_sess_cert_free(session->sess_cert);
- X509_free(session->peer);
- OPENSSL_free(session->tlsext_hostname);
- OPENSSL_free(session->tlsext_tick);
- OPENSSL_free(session->tlsext_signed_cert_timestamp_list);
- OPENSSL_free(session->ocsp_response);
- OPENSSL_free(session->psk_identity);
- OPENSSL_cleanse(session, sizeof(*session));
- OPENSSL_free(session);
-}
-
-int SSL_set_session(SSL *s, SSL_SESSION *session) {
- if (s->session == session) {
+int SSL_set_session(SSL *ssl, SSL_SESSION *session) {
+ if (ssl->session == session) {
return 1;
}
- SSL_SESSION_free(s->session);
- s->session = session;
+ SSL_SESSION_free(ssl->session);
+ ssl->session = session;
if (session != NULL) {
SSL_SESSION_up_ref(session);
- s->verify_result = session->verify_result;
+ ssl->verify_result = session->verify_result;
}
return 1;
}
-long SSL_SESSION_set_timeout(SSL_SESSION *s, long t) {
- if (s == NULL) {
+long SSL_CTX_set_timeout(SSL_CTX *ctx, long timeout) {
+ if (ctx == NULL) {
return 0;
}
- s->timeout = t;
- return 1;
+ long old_timeout = ctx->session_timeout;
+ ctx->session_timeout = timeout;
+ return old_timeout;
}
-long SSL_SESSION_get_timeout(const SSL_SESSION *s) {
- if (s == NULL) {
+long SSL_CTX_get_timeout(const SSL_CTX *ctx) {
+ if (ctx == NULL) {
return 0;
}
- return s->timeout;
-}
-
-long SSL_SESSION_get_time(const SSL_SESSION *s) {
- if (s == NULL) {
- return 0;
- }
-
- return s->time;
-}
-
-long SSL_SESSION_set_time(SSL_SESSION *s, long t) {
- if (s == NULL) {
- return 0;
- }
-
- s->time = t;
- return t;
-}
-
-X509 *SSL_SESSION_get0_peer(SSL_SESSION *s) { return s->peer; }
-
-int SSL_SESSION_set1_id_context(SSL_SESSION *s, const uint8_t *sid_ctx,
- unsigned int sid_ctx_len) {
- if (sid_ctx_len > SSL_MAX_SID_CTX_LENGTH) {
- OPENSSL_PUT_ERROR(SSL, SSL_SESSION_set1_id_context,
- SSL_R_SSL_SESSION_ID_CONTEXT_TOO_LONG);
- return 0;
- }
-
- s->sid_ctx_length = sid_ctx_len;
- memcpy(s->sid_ctx, sid_ctx, sid_ctx_len);
-
- return 1;
-}
-
-long SSL_CTX_set_timeout(SSL_CTX *s, long t) {
- long l;
- if (s == NULL) {
- return 0;
- }
-
- l = s->session_timeout;
- s->session_timeout = t;
- return l;
-}
-
-long SSL_CTX_get_timeout(const SSL_CTX *s) {
- if (s == NULL) {
- return 0;
- }
-
- return s->session_timeout;
+ return ctx->session_timeout;
}
typedef struct timeout_param_st {
@@ -726,25 +702,25 @@ typedef struct timeout_param_st {
LHASH_OF(SSL_SESSION) *cache;
} TIMEOUT_PARAM;
-static void timeout_doall_arg(SSL_SESSION *sess, void *void_param) {
+static void timeout_doall_arg(SSL_SESSION *session, void *void_param) {
TIMEOUT_PARAM *param = void_param;
if (param->time == 0 ||
- param->time > (sess->time + sess->timeout)) {
+ param->time > (session->time + session->timeout)) {
/* timeout */
/* The reason we don't call SSL_CTX_remove_session() is to
* save on locking overhead */
- (void) lh_SSL_SESSION_delete(param->cache, sess);
- SSL_SESSION_list_remove(param->ctx, sess);
- sess->not_resumable = 1;
+ (void) lh_SSL_SESSION_delete(param->cache, session);
+ SSL_SESSION_list_remove(param->ctx, session);
+ session->not_resumable = 1;
if (param->ctx->remove_session_cb != NULL) {
- param->ctx->remove_session_cb(param->ctx, sess);
+ param->ctx->remove_session_cb(param->ctx, session);
}
- SSL_SESSION_free(sess);
+ SSL_SESSION_free(session);
}
}
-void SSL_CTX_flush_sessions(SSL_CTX *ctx, long t) {
+void SSL_CTX_flush_sessions(SSL_CTX *ctx, long time) {
TIMEOUT_PARAM tp;
tp.ctx = ctx;
@@ -752,7 +728,7 @@ void SSL_CTX_flush_sessions(SSL_CTX *ctx, long t) {
if (tp.cache == NULL) {
return;
}
- tp.time = t;
+ tp.time = time;
CRYPTO_MUTEX_lock_write(&ctx->lock);
lh_SSL_SESSION_doall_arg(tp.cache, timeout_doall_arg, &tp);
CRYPTO_MUTEX_unlock(&ctx->lock);
@@ -769,80 +745,80 @@ int ssl_clear_bad_session(SSL *s) {
}
/* locked by SSL_CTX in the calling function */
-static void SSL_SESSION_list_remove(SSL_CTX *ctx, SSL_SESSION *s) {
- if (s->next == NULL || s->prev == NULL) {
+static void SSL_SESSION_list_remove(SSL_CTX *ctx, SSL_SESSION *session) {
+ if (session->next == NULL || session->prev == NULL) {
return;
}
- if (s->next == (SSL_SESSION *)&ctx->session_cache_tail) {
+ if (session->next == (SSL_SESSION *)&ctx->session_cache_tail) {
/* last element in list */
- if (s->prev == (SSL_SESSION *)&ctx->session_cache_head) {
+ if (session->prev == (SSL_SESSION *)&ctx->session_cache_head) {
/* only one element in list */
ctx->session_cache_head = NULL;
ctx->session_cache_tail = NULL;
} else {
- ctx->session_cache_tail = s->prev;
- s->prev->next = (SSL_SESSION *)&(ctx->session_cache_tail);
+ ctx->session_cache_tail = session->prev;
+ session->prev->next = (SSL_SESSION *)&(ctx->session_cache_tail);
}
} else {
- if (s->prev == (SSL_SESSION *)&ctx->session_cache_head) {
+ if (session->prev == (SSL_SESSION *)&ctx->session_cache_head) {
/* first element in list */
- ctx->session_cache_head = s->next;
- s->next->prev = (SSL_SESSION *)&(ctx->session_cache_head);
+ ctx->session_cache_head = session->next;
+ session->next->prev = (SSL_SESSION *)&(ctx->session_cache_head);
} else { /* middle of list */
- s->next->prev = s->prev;
- s->prev->next = s->next;
+ session->next->prev = session->prev;
+ session->prev->next = session->next;
}
}
- s->prev = s->next = NULL;
+ session->prev = session->next = NULL;
}
-static void SSL_SESSION_list_add(SSL_CTX *ctx, SSL_SESSION *s) {
- if (s->next != NULL && s->prev != NULL) {
- SSL_SESSION_list_remove(ctx, s);
+static void SSL_SESSION_list_add(SSL_CTX *ctx, SSL_SESSION *session) {
+ if (session->next != NULL && session->prev != NULL) {
+ SSL_SESSION_list_remove(ctx, session);
}
if (ctx->session_cache_head == NULL) {
- ctx->session_cache_head = s;
- ctx->session_cache_tail = s;
- s->prev = (SSL_SESSION *)&(ctx->session_cache_head);
- s->next = (SSL_SESSION *)&(ctx->session_cache_tail);
+ ctx->session_cache_head = session;
+ ctx->session_cache_tail = session;
+ session->prev = (SSL_SESSION *)&(ctx->session_cache_head);
+ session->next = (SSL_SESSION *)&(ctx->session_cache_tail);
} else {
- s->next = ctx->session_cache_head;
- s->next->prev = s;
- s->prev = (SSL_SESSION *)&(ctx->session_cache_head);
- ctx->session_cache_head = s;
+ session->next = ctx->session_cache_head;
+ session->next->prev = session;
+ session->prev = (SSL_SESSION *)&(ctx->session_cache_head);
+ ctx->session_cache_head = session;
}
}
void SSL_CTX_sess_set_new_cb(SSL_CTX *ctx,
- int (*cb)(struct ssl_st *ssl, SSL_SESSION *sess)) {
+ int (*cb)(SSL *ssl, SSL_SESSION *session)) {
ctx->new_session_cb = cb;
}
-int (*SSL_CTX_sess_get_new_cb(SSL_CTX *ctx))(SSL *ssl, SSL_SESSION *sess) {
+int (*SSL_CTX_sess_get_new_cb(SSL_CTX *ctx))(SSL *ssl, SSL_SESSION *session) {
return ctx->new_session_cb;
}
-void SSL_CTX_sess_set_remove_cb(SSL_CTX *ctx,
- void (*cb)(SSL_CTX *ctx, SSL_SESSION *sess)) {
+void SSL_CTX_sess_set_remove_cb(
+ SSL_CTX *ctx, void (*cb)(SSL_CTX *ctx, SSL_SESSION *session)) {
ctx->remove_session_cb = cb;
}
void (*SSL_CTX_sess_get_remove_cb(SSL_CTX *ctx))(SSL_CTX *ctx,
- SSL_SESSION *sess) {
+ SSL_SESSION *session) {
return ctx->remove_session_cb;
}
void SSL_CTX_sess_set_get_cb(SSL_CTX *ctx,
- SSL_SESSION *(*cb)(struct ssl_st *ssl,
- uint8_t *data, int len,
- int *copy)) {
+ SSL_SESSION *(*cb)(SSL *ssl,
+ uint8_t *id, int id_len,
+ int *out_copy)) {
ctx->get_session_cb = cb;
}
-SSL_SESSION *(*SSL_CTX_sess_get_get_cb(SSL_CTX *ctx))(SSL *ssl, uint8_t *data,
- int len, int *copy) {
+SSL_SESSION *(*SSL_CTX_sess_get_get_cb(SSL_CTX *ctx))(
+ SSL *ssl, uint8_t *id, int id_len, int *out_copy) {
return ctx->get_session_cb;
}
@@ -874,5 +850,3 @@ void SSL_CTX_set_channel_id_cb(SSL_CTX *ctx,
void (*SSL_CTX_get_channel_id_cb(SSL_CTX *ctx))(SSL *ssl, EVP_PKEY **pkey) {
return ctx->channel_id_cb;
}
-
-IMPLEMENT_PEM_rw(SSL_SESSION, SSL_SESSION, PEM_STRING_SSL_SESSION, SSL_SESSION)
diff --git a/src/ssl/ssl_stat.c b/src/ssl/ssl_stat.c
index fa5541b..5ad1e47 100644
--- a/src/ssl/ssl_stat.c
+++ b/src/ssl/ssl_stat.c
@@ -82,9 +82,11 @@
* OTHERWISE.
*/
-#include <stdio.h>
+#include <openssl/ssl.h>
+
#include "internal.h"
+
const char *SSL_state_string_long(const SSL *s) {
const char *str;
@@ -334,37 +336,6 @@ const char *SSL_state_string_long(const SSL *s) {
str = "SSLv3 read certificate verify B";
break;
- /* SSLv2/v3 compatibility states */
- /* client */
- case SSL23_ST_CW_CLNT_HELLO_A:
- str = "SSLv2/v3 write client hello A";
- break;
-
- case SSL23_ST_CW_CLNT_HELLO_B:
- str = "SSLv2/v3 write client hello B";
- break;
-
- case SSL23_ST_CR_SRVR_HELLO_A:
- str = "SSLv2/v3 read server hello A";
- break;
-
- case SSL23_ST_CR_SRVR_HELLO_B:
- str = "SSLv2/v3 read server hello B";
- break;
-
- /* server */
- case SSL23_ST_SR_CLNT_HELLO:
- str = "SSLv2/v3 read client hello";
- break;
-
- case SSL23_ST_SR_V2_CLNT_HELLO:
- str = "SSLv2/v3 read v2 client hello";
- break;
-
- case SSL23_ST_SR_SWITCH_VERSION:
- str = "SSLv2/v3 switch version";
- break;
-
/* DTLS */
case DTLS1_ST_CR_HELLO_VERIFY_REQUEST_A:
str = "DTLS1 read hello verify request A";
@@ -382,30 +353,6 @@ const char *SSL_state_string_long(const SSL *s) {
return str;
}
-const char *SSL_rstate_string_long(const SSL *s) {
- const char *str;
-
- switch (s->rstate) {
- case SSL_ST_READ_HEADER:
- str = "read header";
- break;
-
- case SSL_ST_READ_BODY:
- str = "read body";
- break;
-
- case SSL_ST_READ_DONE:
- str = "read done";
- break;
-
- default:
- str = "unknown";
- break;
- }
-
- return str;
-}
-
const char *SSL_state_string(const SSL *s) {
const char *str;
@@ -635,37 +582,6 @@ const char *SSL_state_string(const SSL *s) {
str = "3RCV_B";
break;
- /* SSLv2/v3 compatibility states */
- /* client */
- case SSL23_ST_CW_CLNT_HELLO_A:
- str = "23WCHA";
- break;
-
- case SSL23_ST_CW_CLNT_HELLO_B:
- str = "23WCHB";
- break;
-
- case SSL23_ST_CR_SRVR_HELLO_A:
- str = "23RSHA";
- break;
-
- case SSL23_ST_CR_SRVR_HELLO_B:
- str = "23RSHA";
- break;
-
- /* server */
- case SSL23_ST_SR_CLNT_HELLO:
- str = "23RCH_";
- break;
-
- case SSL23_ST_SR_V2_CLNT_HELLO:
- str = "23R2CH";
- break;
-
- case SSL23_ST_SR_SWITCH_VERSION:
- str = "23RSW_";
- break;
-
/* DTLS */
case DTLS1_ST_CR_HELLO_VERIFY_REQUEST_A:
str = "DRCHVA";
@@ -968,27 +884,3 @@ const char *SSL_alert_desc_string_long(int value) {
return str;
}
-
-const char *SSL_rstate_string(const SSL *s) {
- const char *str;
-
- switch (s->rstate) {
- case SSL_ST_READ_HEADER:
- str = "RH";
- break;
-
- case SSL_ST_READ_BODY:
- str = "RB";
- break;
-
- case SSL_ST_READ_DONE:
- str = "RD";
- break;
-
- default:
- str = "unknown";
- break;
- }
-
- return str;
-}
diff --git a/src/ssl/ssl_test.cc b/src/ssl/ssl_test.cc
index 9f2ddb9..810d3fa 100644
--- a/src/ssl/ssl_test.cc
+++ b/src/ssl/ssl_test.cc
@@ -24,6 +24,8 @@
#include <openssl/ssl.h>
#include "test/scoped_types.h"
+#include "../crypto/test/test_util.h"
+
struct ExpectedCipher {
unsigned long id;
@@ -212,6 +214,21 @@ static const char *kBadRules[] = {
NULL,
};
+static const char *kMustNotIncludeNull[] = {
+ "ALL",
+ "DEFAULT",
+ "ALL:!eNULL",
+ "ALL:!NULL",
+ "FIPS",
+ "SHA",
+ "SHA1",
+ "RSA",
+ "SSLv3",
+ "TLSv1",
+ "TLSv1.2",
+ NULL
+};
+
static void PrintCipherPreferenceList(ssl_cipher_preference_list_st *list) {
bool in_group = false;
for (size_t i = 0; i < sk_SSL_CIPHER_num(list->ciphers); i++) {
@@ -265,6 +282,24 @@ static bool TestCipherRule(CipherTest *t) {
return true;
}
+static bool TestRuleDoesNotIncludeNull(const char *rule) {
+ ScopedSSL_CTX ctx(SSL_CTX_new(SSLv23_server_method()));
+ if (!ctx) {
+ return false;
+ }
+ if (!SSL_CTX_set_cipher_list(ctx.get(), rule)) {
+ fprintf(stderr, "Error: cipher rule '%s' failed\n", rule);
+ return false;
+ }
+ for (size_t i = 0; i < sk_SSL_CIPHER_num(ctx->cipher_list->ciphers); i++) {
+ if (SSL_CIPHER_is_NULL(sk_SSL_CIPHER_value(ctx->cipher_list->ciphers, i))) {
+ fprintf(stderr, "Error: cipher rule '%s' includes NULL\n",rule);
+ return false;
+ }
+ }
+ return true;
+}
+
static bool TestCipherRules() {
for (size_t i = 0; kCipherTests[i].rule != NULL; i++) {
if (!TestCipherRule(&kCipherTests[i])) {
@@ -284,6 +319,12 @@ static bool TestCipherRules() {
ERR_clear_error();
}
+ for (size_t i = 0; kMustNotIncludeNull[i] != NULL; i++) {
+ if (!TestRuleDoesNotIncludeNull(kMustNotIncludeNull[i])) {
+ return false;
+ }
+ }
+
return true;
}
@@ -335,6 +376,104 @@ static const char kCustomSession[] =
"q+Topyzvx9USFgRvyuoxn0Hgb+R0A3j6SLRuyOdAi4gv7Y5oliynrSIEIAYGBgYG"
"BgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGrgMEAQevAwQBBLADBAEF";
+// kBoringSSLSession is a serialized SSL_SESSION generated from bssl client.
+static const char kBoringSSLSession[] =
+ "MIIRwQIBAQICAwMEAsAvBCDdoGxGK26mR+8lM0uq6+k9xYuxPnwAjpcF9n0Yli9R"
+ "kQQwbyshfWhdi5XQ1++7n2L1qqrcVlmHBPpr6yknT/u4pUrpQB5FZ7vqvNn8MdHf"
+ "9rWgoQYCBFXgs7uiBAICHCCjggR6MIIEdjCCA16gAwIBAgIIf+yfD7Y6UicwDQYJ"
+ "KoZIhvcNAQELBQAwSTELMAkGA1UEBhMCVVMxEzARBgNVBAoTCkdvb2dsZSBJbmMx"
+ "JTAjBgNVBAMTHEdvb2dsZSBJbnRlcm5ldCBBdXRob3JpdHkgRzIwHhcNMTUwODEy"
+ "MTQ1MzE1WhcNMTUxMTEwMDAwMDAwWjBoMQswCQYDVQQGEwJVUzETMBEGA1UECAwK"
+ "Q2FsaWZvcm5pYTEWMBQGA1UEBwwNTW91bnRhaW4gVmlldzETMBEGA1UECgwKR29v"
+ "Z2xlIEluYzEXMBUGA1UEAwwOd3d3Lmdvb2dsZS5jb20wggEiMA0GCSqGSIb3DQEB"
+ "AQUAA4IBDwAwggEKAoIBAQC0MeG5YGQ0t+IeJeoneP/PrhEaieibeKYkbKVLNZpo"
+ "PLuBinvhkXZo3DC133NpCBpy6ZktBwamqyixAyuk/NU6OjgXqwwxfQ7di1AInLIU"
+ "792c7hFyNXSUCG7At8Ifi3YwBX9Ba6u/1d6rWTGZJrdCq3QU11RkKYyTq2KT5mce"
+ "Tv9iGKqSkSTlp8puy/9SZ/3DbU3U+BuqCFqeSlz7zjwFmk35acdCilpJlVDDN5C/"
+ "RCh8/UKc8PaL+cxlt531qoTENvYrflBno14YEZlCBZsPiFeUSILpKEj3Ccwhy0eL"
+ "EucWQ72YZU8mUzXBoXGn0zA0crFl5ci/2sTBBGZsylNBAgMBAAGjggFBMIIBPTAd"
+ "BgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwGQYDVR0RBBIwEIIOd3d3Lmdv"
+ "b2dsZS5jb20waAYIKwYBBQUHAQEEXDBaMCsGCCsGAQUFBzAChh9odHRwOi8vcGtp"
+ "Lmdvb2dsZS5jb20vR0lBRzIuY3J0MCsGCCsGAQUFBzABhh9odHRwOi8vY2xpZW50"
+ "czEuZ29vZ2xlLmNvbS9vY3NwMB0GA1UdDgQWBBS/bzHxcE73Q4j3slC4BLbMtLjG"
+ "GjAMBgNVHRMBAf8EAjAAMB8GA1UdIwQYMBaAFErdBhYbvPZotXb1gba7Yhq6WoEv"
+ "MBcGA1UdIAQQMA4wDAYKKwYBBAHWeQIFATAwBgNVHR8EKTAnMCWgI6Ahhh9odHRw"
+ "Oi8vcGtpLmdvb2dsZS5jb20vR0lBRzIuY3JsMA0GCSqGSIb3DQEBCwUAA4IBAQAb"
+ "qdWPZEHk0X7iKPCTHL6S3w6q1eR67goxZGFSM1lk1hjwyu7XcLJuvALVV9uY3ovE"
+ "kQZSHwT+pyOPWQhsSjO+1GyjvCvK/CAwiUmBX+bQRGaqHsRcio7xSbdVcajQ3bXd"
+ "X+s0WdbOpn6MStKAiBVloPlSxEI8pxY6x/BBCnTIk/+DMB17uZlOjG3vbAnkDkP+"
+ "n0OTucD9sHV7EVj9XUxi51nOfNBCN/s7lpUjDS/NJ4k3iwOtbCPswiot8vLO779a"
+ "f07vR03r349Iz/KTzk95rlFtX0IU+KYNxFNsanIXZ+C9FYGRXkwhHcvFb4qMUB1y"
+ "TTlM80jBMOwyjZXmjRAhpAIEAKUDAgEUqQUCAwGJwKqBpwSBpOgebbmn9NRUtMWH"
+ "+eJpqA5JLMFSMCChOsvKey3toBaCNGU7HfAEiiXNuuAdCBoK262BjQc2YYfqFzqH"
+ "zuppopXCvhohx7j/tnCNZIMgLYt/O9SXK2RYI5z8FhCCHvB4CbD5G0LGl5EFP27s"
+ "Jb6S3aTTYPkQe8yZSlxevg6NDwmTogLO9F7UUkaYmVcMQhzssEE2ZRYNwSOU6KjE"
+ "0Yj+8fAiBtbQriIEIN2L8ZlpaVrdN5KFNdvcmOxJu81P8q53X55xQyGTnGWwsgMC"
+ "ARezggvvMIIEdjCCA16gAwIBAgIIf+yfD7Y6UicwDQYJKoZIhvcNAQELBQAwSTEL"
+ "MAkGA1UEBhMCVVMxEzARBgNVBAoTCkdvb2dsZSBJbmMxJTAjBgNVBAMTHEdvb2ds"
+ "ZSBJbnRlcm5ldCBBdXRob3JpdHkgRzIwHhcNMTUwODEyMTQ1MzE1WhcNMTUxMTEw"
+ "MDAwMDAwWjBoMQswCQYDVQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTEWMBQG"
+ "A1UEBwwNTW91bnRhaW4gVmlldzETMBEGA1UECgwKR29vZ2xlIEluYzEXMBUGA1UE"
+ "AwwOd3d3Lmdvb2dsZS5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB"
+ "AQC0MeG5YGQ0t+IeJeoneP/PrhEaieibeKYkbKVLNZpoPLuBinvhkXZo3DC133Np"
+ "CBpy6ZktBwamqyixAyuk/NU6OjgXqwwxfQ7di1AInLIU792c7hFyNXSUCG7At8If"
+ "i3YwBX9Ba6u/1d6rWTGZJrdCq3QU11RkKYyTq2KT5mceTv9iGKqSkSTlp8puy/9S"
+ "Z/3DbU3U+BuqCFqeSlz7zjwFmk35acdCilpJlVDDN5C/RCh8/UKc8PaL+cxlt531"
+ "qoTENvYrflBno14YEZlCBZsPiFeUSILpKEj3Ccwhy0eLEucWQ72YZU8mUzXBoXGn"
+ "0zA0crFl5ci/2sTBBGZsylNBAgMBAAGjggFBMIIBPTAdBgNVHSUEFjAUBggrBgEF"
+ "BQcDAQYIKwYBBQUHAwIwGQYDVR0RBBIwEIIOd3d3Lmdvb2dsZS5jb20waAYIKwYB"
+ "BQUHAQEEXDBaMCsGCCsGAQUFBzAChh9odHRwOi8vcGtpLmdvb2dsZS5jb20vR0lB"
+ "RzIuY3J0MCsGCCsGAQUFBzABhh9odHRwOi8vY2xpZW50czEuZ29vZ2xlLmNvbS9v"
+ "Y3NwMB0GA1UdDgQWBBS/bzHxcE73Q4j3slC4BLbMtLjGGjAMBgNVHRMBAf8EAjAA"
+ "MB8GA1UdIwQYMBaAFErdBhYbvPZotXb1gba7Yhq6WoEvMBcGA1UdIAQQMA4wDAYK"
+ "KwYBBAHWeQIFATAwBgNVHR8EKTAnMCWgI6Ahhh9odHRwOi8vcGtpLmdvb2dsZS5j"
+ "b20vR0lBRzIuY3JsMA0GCSqGSIb3DQEBCwUAA4IBAQAbqdWPZEHk0X7iKPCTHL6S"
+ "3w6q1eR67goxZGFSM1lk1hjwyu7XcLJuvALVV9uY3ovEkQZSHwT+pyOPWQhsSjO+"
+ "1GyjvCvK/CAwiUmBX+bQRGaqHsRcio7xSbdVcajQ3bXdX+s0WdbOpn6MStKAiBVl"
+ "oPlSxEI8pxY6x/BBCnTIk/+DMB17uZlOjG3vbAnkDkP+n0OTucD9sHV7EVj9XUxi"
+ "51nOfNBCN/s7lpUjDS/NJ4k3iwOtbCPswiot8vLO779af07vR03r349Iz/KTzk95"
+ "rlFtX0IU+KYNxFNsanIXZ+C9FYGRXkwhHcvFb4qMUB1yTTlM80jBMOwyjZXmjRAh"
+ "MIID8DCCAtigAwIBAgIDAjqDMA0GCSqGSIb3DQEBCwUAMEIxCzAJBgNVBAYTAlVT"
+ "MRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMRswGQYDVQQDExJHZW9UcnVzdCBHbG9i"
+ "YWwgQ0EwHhcNMTMwNDA1MTUxNTU2WhcNMTYxMjMxMjM1OTU5WjBJMQswCQYDVQQG"
+ "EwJVUzETMBEGA1UEChMKR29vZ2xlIEluYzElMCMGA1UEAxMcR29vZ2xlIEludGVy"
+ "bmV0IEF1dGhvcml0eSBHMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB"
+ "AJwqBHdc2FCROgajguDYUEi8iT/xGXAaiEZ+4I/F8YnOIe5a/mENtzJEiaB0C1NP"
+ "VaTOgmKV7utZX8bhBYASxF6UP7xbSDj0U/ck5vuR6RXEz/RTDfRK/J9U3n2+oGtv"
+ "h8DQUB8oMANA2ghzUWx//zo8pzcGjr1LEQTrfSTe5vn8MXH7lNVg8y5Kr0LSy+rE"
+ "ahqyzFPdFUuLH8gZYR/Nnag+YyuENWllhMgZxUYi+FOVvuOAShDGKuy6lyARxzmZ"
+ "EASg8GF6lSWMTlJ14rbtCMoU/M4iarNOz0YDl5cDfsCx3nuvRTPPuj5xt970JSXC"
+ "DTWJnZ37DhF5iR43xa+OcmkCAwEAAaOB5zCB5DAfBgNVHSMEGDAWgBTAephojYn7"
+ "qwVkDBF9qn1luMrMTjAdBgNVHQ4EFgQUSt0GFhu89mi1dvWBtrtiGrpagS8wDgYD"
+ "VR0PAQH/BAQDAgEGMC4GCCsGAQUFBwEBBCIwIDAeBggrBgEFBQcwAYYSaHR0cDov"
+ "L2cuc3ltY2QuY29tMBIGA1UdEwEB/wQIMAYBAf8CAQAwNQYDVR0fBC4wLDAqoCig"
+ "JoYkaHR0cDovL2cuc3ltY2IuY29tL2NybHMvZ3RnbG9iYWwuY3JsMBcGA1UdIAQQ"
+ "MA4wDAYKKwYBBAHWeQIFATANBgkqhkiG9w0BAQsFAAOCAQEAqvqpIM1qZ4PtXtR+"
+ "3h3Ef+AlBgDFJPupyC1tft6dgmUsgWM0Zj7pUsIItMsv91+ZOmqcUHqFBYx90SpI"
+ "hNMJbHzCzTWf84LuUt5oX+QAihcglvcpjZpNy6jehsgNb1aHA30DP9z6eX0hGfnI"
+ "Oi9RdozHQZJxjyXON/hKTAAj78Q1EK7gI4BzfE00LshukNYQHpmEcxpw8u1VDu4X"
+ "Bupn7jLrLN1nBz/2i8Jw3lsA5rsb0zYaImxssDVCbJAJPZPpZAkiDoUGn8JzIdPm"
+ "X4DkjYUiOnMDsWCOrmji9D6X52ASCWg23jrW4kOVWzeBkoEfu43XrVJkFleW2V40"
+ "fsg12DCCA30wggLmoAMCAQICAxK75jANBgkqhkiG9w0BAQUFADBOMQswCQYDVQQG"
+ "EwJVUzEQMA4GA1UEChMHRXF1aWZheDEtMCsGA1UECxMkRXF1aWZheCBTZWN1cmUg"
+ "Q2VydGlmaWNhdGUgQXV0aG9yaXR5MB4XDTAyMDUyMTA0MDAwMFoXDTE4MDgyMTA0"
+ "MDAwMFowQjELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUdlb1RydXN0IEluYy4xGzAZ"
+ "BgNVBAMTEkdlb1RydXN0IEdsb2JhbCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEP"
+ "ADCCAQoCggEBANrMGGMw/fQXIxpWflvfPGw45HG3eJHUvKHYTPioQ7YD6U0hBwiI"
+ "2lgvZjkpvQV4i5046AW3an5xpObEYKaw74DkiSgPniXW7YPzraaRx5jJQhg1FJ2t"
+ "mEaSLk/K8YdDwRaVVy1Q74ktgHpXrfLuX2vSAI25FPgUFTXZwEaje3LIkb/JVSvN"
+ "0Jc+nCZkzN/Ogxlxyk7m1NV7qRnNVd7I7NJeOFPlXE+MLf5QIzb8ZubLjqQ5GQC3"
+ "lQI5kQsO/jgu0R0FmvZNPm8PBx2vLB6PYDni+jZTEznUXiYr2z2oFL0y6xgDKFIE"
+ "ceWrMz3hOLsHNoRinHnqFjD0X8Ar6HFr5PkCAwEAAaOB8DCB7TAfBgNVHSMEGDAW"
+ "gBRI5mj5K9KylddH2CMgEE8zmJCf1DAdBgNVHQ4EFgQUwHqYaI2J+6sFZAwRfap9"
+ "ZbjKzE4wDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwOgYDVR0fBDMw"
+ "MTAvoC2gK4YpaHR0cDovL2NybC5nZW90cnVzdC5jb20vY3Jscy9zZWN1cmVjYS5j"
+ "cmwwTgYDVR0gBEcwRTBDBgRVHSAAMDswOQYIKwYBBQUHAgEWLWh0dHBzOi8vd3d3"
+ "Lmdlb3RydXN0LmNvbS9yZXNvdXJjZXMvcmVwb3NpdG9yeTANBgkqhkiG9w0BAQUF"
+ "AAOBgQB24RJuTksWEoYwBrKBCM/wCMfHcX5m7sLt1Dsf//DwyE7WQziwuTB9GNBV"
+ "g6JqyzYRnOhIZqNtf7gT1Ef+i1pcc/yu2RsyGTirlzQUqpbS66McFAhJtrvlke+D"
+ "NusdVm/K2rxzY5Dkf3s+Iss9B+1fOHSc4wNQTqGvmO5h8oQ/Eg==";
+
// kBadSessionExtraField is a custom serialized SSL_SESSION generated by replacing
// the final (optional) element of |kCustomSession| with tag number 30.
static const char kBadSessionExtraField[] =
@@ -418,6 +557,8 @@ static bool TestSSL_SESSIONEncoding(const char *input_b64) {
if (encoded_len != input.size() ||
memcmp(bssl::vector_data(&input), encoded.get(), input.size()) != 0) {
fprintf(stderr, "SSL_SESSION_to_bytes did not round-trip\n");
+ hexdump(stderr, "Before: ", input.data(), input.size());
+ hexdump(stderr, "After: ", encoded_raw, encoded_len);
return false;
}
@@ -549,12 +690,141 @@ static bool TestCipherGetRFCName(void) {
return true;
}
-int main(void) {
+// CreateSessionWithTicket returns a sample |SSL_SESSION| with the ticket
+// replaced for one of length |ticket_len| or nullptr on failure.
+static ScopedSSL_SESSION CreateSessionWithTicket(size_t ticket_len) {
+ std::vector<uint8_t> der;
+ if (!DecodeBase64(&der, kOpenSSLSession)) {
+ return nullptr;
+ }
+ ScopedSSL_SESSION session(SSL_SESSION_from_bytes(bssl::vector_data(&der),
+ der.size()));
+ if (!session) {
+ return nullptr;
+ }
+
+ // Swap out the ticket for a garbage one.
+ OPENSSL_free(session->tlsext_tick);
+ session->tlsext_tick = reinterpret_cast<uint8_t*>(OPENSSL_malloc(ticket_len));
+ if (session->tlsext_tick == nullptr) {
+ return nullptr;
+ }
+ memset(session->tlsext_tick, 'a', ticket_len);
+ session->tlsext_ticklen = ticket_len;
+ return session;
+}
+
+// GetClientHelloLen creates a client SSL connection with a ticket of length
+// |ticket_len| and records the ClientHello. It returns the length of the
+// ClientHello, not including the record header, on success and zero on error.
+static size_t GetClientHelloLen(size_t ticket_len) {
+ ScopedSSL_CTX ctx(SSL_CTX_new(TLS_method()));
+ ScopedSSL_SESSION session = CreateSessionWithTicket(ticket_len);
+ if (!ctx || !session) {
+ return 0;
+ }
+ ScopedSSL ssl(SSL_new(ctx.get()));
+ ScopedBIO bio(BIO_new(BIO_s_mem()));
+ if (!ssl || !bio || !SSL_set_session(ssl.get(), session.get())) {
+ return 0;
+ }
+ // Do not configure a reading BIO, but record what's written to a memory BIO.
+ SSL_set_bio(ssl.get(), nullptr /* rbio */, BIO_up_ref(bio.get()));
+ int ret = SSL_connect(ssl.get());
+ if (ret > 0) {
+ // SSL_connect should fail without a BIO to write to.
+ return 0;
+ }
+ ERR_clear_error();
+
+ const uint8_t *unused;
+ size_t client_hello_len;
+ if (!BIO_mem_contents(bio.get(), &unused, &client_hello_len) ||
+ client_hello_len <= SSL3_RT_HEADER_LENGTH) {
+ return 0;
+ }
+ return client_hello_len - SSL3_RT_HEADER_LENGTH;
+}
+
+struct PaddingTest {
+ size_t input_len, padded_len;
+};
+
+static const PaddingTest kPaddingTests[] = {
+ // ClientHellos of length below 0x100 do not require padding.
+ {0xfe, 0xfe},
+ {0xff, 0xff},
+ // ClientHellos of length 0x100 through 0x1fb are padded up to 0x200.
+ {0x100, 0x200},
+ {0x123, 0x200},
+ {0x1fb, 0x200},
+ // ClientHellos of length 0x1fc through 0x1ff get padded beyond 0x200. The
+ // padding extension takes a minimum of four bytes plus one required content
+ // byte. (To work around yet more server bugs, we avoid empty final
+ // extensions.)
+ {0x1fc, 0x201},
+ {0x1fd, 0x202},
+ {0x1fe, 0x203},
+ {0x1ff, 0x204},
+ // Finally, larger ClientHellos need no padding.
+ {0x200, 0x200},
+ {0x201, 0x201},
+};
+
+static bool TestPaddingExtension() {
+ // Sample a baseline length.
+ size_t base_len = GetClientHelloLen(1);
+ if (base_len == 0) {
+ return false;
+ }
+
+ for (const PaddingTest &test : kPaddingTests) {
+ if (base_len > test.input_len) {
+ fprintf(stderr, "Baseline ClientHello too long.\n");
+ return false;
+ }
+
+ size_t padded_len = GetClientHelloLen(1 + test.input_len - base_len);
+ if (padded_len != test.padded_len) {
+ fprintf(stderr, "%u-byte ClientHello padded to %u bytes, not %u.\n",
+ static_cast<unsigned>(test.input_len),
+ static_cast<unsigned>(padded_len),
+ static_cast<unsigned>(test.padded_len));
+ return false;
+ }
+ }
+ return true;
+}
+
+// Test that |SSL_get_client_CA_list| echoes back the configured parameter even
+// before configuring as a server.
+static bool TestClientCAList() {
+ ScopedSSL_CTX ctx(SSL_CTX_new(TLS_method()));
+ if (!ctx) {
+ return false;
+ }
+ ScopedSSL ssl(SSL_new(ctx.get()));
+ if (!ssl) {
+ return false;
+ }
+
+ STACK_OF(X509_NAME) *stack = sk_X509_NAME_new_null();
+ if (stack == nullptr) {
+ return false;
+ }
+ // |SSL_set_client_CA_list| takes ownership.
+ SSL_set_client_CA_list(ssl.get(), stack);
+
+ return SSL_get_client_CA_list(ssl.get()) == stack;
+}
+
+int main() {
SSL_library_init();
if (!TestCipherRules() ||
!TestSSL_SESSIONEncoding(kOpenSSLSession) ||
!TestSSL_SESSIONEncoding(kCustomSession) ||
+ !TestSSL_SESSIONEncoding(kBoringSSLSession) ||
!TestBadSSL_SESSIONEncoding(kBadSessionExtraField) ||
!TestBadSSL_SESSIONEncoding(kBadSessionVersion) ||
!TestBadSSL_SESSIONEncoding(kBadSessionTrailingData) ||
@@ -566,7 +836,9 @@ int main(void) {
!TestDefaultVersion(0, &DTLS_method) ||
!TestDefaultVersion(DTLS1_VERSION, &DTLSv1_method) ||
!TestDefaultVersion(DTLS1_2_VERSION, &DTLSv1_2_method) ||
- !TestCipherGetRFCName()) {
+ !TestCipherGetRFCName() ||
+ !TestPaddingExtension() ||
+ !TestClientCAList()) {
ERR_print_errors_fp(stderr);
return 1;
}
diff --git a/src/ssl/ssl_txt.c b/src/ssl/ssl_txt.c
index 2275f16..3ba0887 100644
--- a/src/ssl/ssl_txt.c
+++ b/src/ssl/ssl_txt.c
@@ -80,12 +80,14 @@
* OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR
* OTHERWISE. */
+#include <openssl/ssl.h>
+
#include <inttypes.h>
#include <stdio.h>
-#include <openssl/buf.h>
+#include <openssl/bio.h>
#include <openssl/err.h>
-#include <openssl/mem.h>
+#include <openssl/x509.h>
#include "internal.h"
@@ -96,7 +98,7 @@ int SSL_SESSION_print_fp(FILE *fp, const SSL_SESSION *x) {
b = BIO_new(BIO_s_file());
if (b == NULL) {
- OPENSSL_PUT_ERROR(SSL, SSL_SESSION_print_fp, ERR_R_BUF_LIB);
+ OPENSSL_PUT_ERROR(SSL, ERR_R_BUF_LIB);
return 0;
}
diff --git a/src/ssl/t1_enc.c b/src/ssl/t1_enc.c
index 6bd80c3..076f8bd 100644
--- a/src/ssl/t1_enc.c
+++ b/src/ssl/t1_enc.c
@@ -133,6 +133,8 @@
* OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR
* OTHERWISE. */
+#include <openssl/ssl.h>
+
#include <assert.h>
#include <stdio.h>
#include <string.h>
@@ -149,7 +151,7 @@
/* tls1_P_hash computes the TLS P_<hash> function as described in RFC 5246,
- * section 5. It writes |out_len| bytes to |out|, using |md| as the hash and
+ * section 5. It XORs |out_len| bytes to |out|, using |md| as the hash and
* |secret| as the secret. |seed1| through |seed3| are concatenated to form the
* seed parameter. It returns one on success and zero on failure. */
static int tls1_P_hash(uint8_t *out, size_t out_len, const EVP_MD *md,
@@ -188,26 +190,32 @@ static int tls1_P_hash(uint8_t *out, size_t out_len, const EVP_MD *md,
goto err;
}
- if (out_len > chunk) {
- unsigned len;
- if (!HMAC_Final(&ctx, out, &len)) {
- goto err;
- }
- assert(len == chunk);
- out += len;
- out_len -= len;
- /* Calculate the next A1 value. */
- if (!HMAC_Final(&ctx_tmp, A1, &A1_len)) {
- goto err;
- }
- } else {
- /* Last chunk. */
- if (!HMAC_Final(&ctx, A1, &A1_len)) {
- goto err;
- }
- memcpy(out, A1, out_len);
+ unsigned len;
+ uint8_t hmac[EVP_MAX_MD_SIZE];
+ if (!HMAC_Final(&ctx, hmac, &len)) {
+ goto err;
+ }
+ assert(len == chunk);
+
+ /* XOR the result into |out|. */
+ if (len > out_len) {
+ len = out_len;
+ }
+ unsigned i;
+ for (i = 0; i < len; i++) {
+ out[i] ^= hmac[i];
+ }
+ out += len;
+ out_len -= len;
+
+ if (out_len == 0) {
break;
}
+
+ /* Calculate the next A1 value. */
+ if (!HMAC_Final(&ctx_tmp, A1, &A1_len)) {
+ goto err;
+ }
}
ret = 1;
@@ -224,62 +232,36 @@ int tls1_prf(SSL *s, uint8_t *out, size_t out_len, const uint8_t *secret,
size_t secret_len, const char *label, size_t label_len,
const uint8_t *seed1, size_t seed1_len,
const uint8_t *seed2, size_t seed2_len) {
- size_t idx, len, count, i;
- const uint8_t *S1;
- uint32_t m;
- const EVP_MD *md;
- int ret = 0;
- uint8_t *tmp;
if (out_len == 0) {
return 1;
}
- /* Allocate a temporary buffer. */
- tmp = OPENSSL_malloc(out_len);
- if (tmp == NULL) {
- OPENSSL_PUT_ERROR(SSL, tls1_prf, ERR_R_MALLOC_FAILURE);
- return 0;
- }
+ memset(out, 0, out_len);
- /* Count number of digests and partition |secret| evenly. */
- count = 0;
- for (idx = 0; ssl_get_handshake_digest(&m, &md, idx); idx++) {
- if (m & ssl_get_algorithm2(s)) {
- count++;
+ uint32_t algorithm_prf = ssl_get_algorithm_prf(s);
+ if (algorithm_prf == SSL_HANDSHAKE_MAC_DEFAULT) {
+ /* If using the MD5/SHA1 PRF, |secret| is partitioned between SHA-1 and
+ * MD5, MD5 first. */
+ size_t secret_half = secret_len - (secret_len / 2);
+ if (!tls1_P_hash(out, out_len, EVP_md5(), secret, secret_half,
+ (const uint8_t *)label, label_len, seed1, seed1_len, seed2,
+ seed2_len)) {
+ return 0;
}
+
+ /* Note that, if |secret_len| is odd, the two halves share a byte. */
+ secret = secret + (secret_len - secret_half);
+ secret_len = secret_half;
}
- /* TODO(davidben): The only case where count isn't 1 is the old MD5/SHA-1
- * combination. The logic around multiple handshake digests can probably be
- * simplified. */
- assert(count == 1 || count == 2);
- len = secret_len / count;
- if (count == 1) {
- secret_len = 0;
- }
- S1 = secret;
- memset(out, 0, out_len);
- for (idx = 0; ssl_get_handshake_digest(&m, &md, idx); idx++) {
- if (m & ssl_get_algorithm2(s)) {
- /* If |count| is 2 and |secret_len| is odd, |secret| is partitioned into
- * two halves with an overlapping byte. */
- if (!tls1_P_hash(tmp, out_len, md, S1, len + (secret_len & 1),
- (const uint8_t *)label, label_len, seed1, seed1_len,
- seed2, seed2_len)) {
- goto err;
- }
- S1 += len;
- for (i = 0; i < out_len; i++) {
- out[i] ^= tmp[i];
- }
- }
+
+ if (!tls1_P_hash(out, out_len, ssl_get_handshake_digest(algorithm_prf),
+ secret, secret_len, (const uint8_t *)label, label_len,
+ seed1, seed1_len, seed2, seed2_len)) {
+ return 0;
}
- ret = 1;
-err:
- OPENSSL_cleanse(tmp, out_len);
- OPENSSL_free(tmp);
- return ret;
+ return 1;
}
static int tls1_generate_key_block(SSL *s, uint8_t *out, size_t out_len) {
@@ -317,7 +299,7 @@ int tls1_change_cipher_state(SSL *s, int which) {
iv_len = s->s3->tmp.new_fixed_iv_len;
if (aead == NULL) {
- OPENSSL_PUT_ERROR(SSL, tls1_change_cipher_state, ERR_R_INTERNAL_ERROR);
+ OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
return 0;
}
@@ -327,7 +309,7 @@ int tls1_change_cipher_state(SSL *s, int which) {
* suites) the key length reported by |EVP_AEAD_key_length| will
* include the MAC and IV key bytes. */
if (key_len < mac_secret_len + iv_len) {
- OPENSSL_PUT_ERROR(SSL, tls1_change_cipher_state, ERR_R_INTERNAL_ERROR);
+ OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
return 0;
}
key_len -= mac_secret_len + iv_len;
@@ -358,7 +340,7 @@ int tls1_change_cipher_state(SSL *s, int which) {
}
if (key_data - s->s3->tmp.key_block != s->s3->tmp.key_block_length) {
- OPENSSL_PUT_ERROR(SSL, tls1_change_cipher_state, ERR_R_INTERNAL_ERROR);
+ OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
return 0;
}
@@ -369,14 +351,26 @@ int tls1_change_cipher_state(SSL *s, int which) {
s->s3->tmp.new_cipher, key, key_len, mac_secret, mac_secret_len, iv,
iv_len);
return s->aead_read_ctx != NULL;
- } else {
- SSL_AEAD_CTX_free(s->aead_write_ctx);
- s->aead_write_ctx = SSL_AEAD_CTX_new(
- evp_aead_seal, ssl3_version_from_wire(s, s->version),
- s->s3->tmp.new_cipher, key, key_len, mac_secret, mac_secret_len, iv,
- iv_len);
- return s->aead_write_ctx != NULL;
}
+
+ SSL_AEAD_CTX_free(s->aead_write_ctx);
+ s->aead_write_ctx = SSL_AEAD_CTX_new(
+ evp_aead_seal, ssl3_version_from_wire(s, s->version),
+ s->s3->tmp.new_cipher, key, key_len, mac_secret, mac_secret_len, iv,
+ iv_len);
+ if (s->aead_write_ctx == NULL) {
+ return 0;
+ }
+
+ s->s3->need_record_splitting = 0;
+ if (!SSL_USE_EXPLICIT_IV(s) &&
+ (s->mode & SSL_MODE_CBC_RECORD_SPLITTING) != 0 &&
+ SSL_CIPHER_is_block_cipher(s->s3->tmp.new_cipher)) {
+ /* Enable 1/n-1 record-splitting to randomize the IV. See
+ * https://www.openssl.org/~bodo/tls-cbc.txt and the BEAST attack. */
+ s->s3->need_record_splitting = 1;
+ }
+ return 1;
}
int tls1_setup_key_block(SSL *s) {
@@ -406,14 +400,14 @@ int tls1_setup_key_block(SSL *s) {
* key length reported by |EVP_AEAD_key_length| will include the MAC key
* bytes and initial implicit IV. */
if (key_len < mac_secret_len + fixed_iv_len) {
- OPENSSL_PUT_ERROR(SSL, tls1_setup_key_block, ERR_R_INTERNAL_ERROR);
+ OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
return 0;
}
key_len -= mac_secret_len + fixed_iv_len;
} else {
/* The nonce is split into a fixed portion and a variable portion. */
if (variable_iv_len < fixed_iv_len) {
- OPENSSL_PUT_ERROR(SSL, tls1_setup_key_block, ERR_R_INTERNAL_ERROR);
+ OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
return 0;
}
variable_iv_len -= fixed_iv_len;
@@ -435,7 +429,7 @@ int tls1_setup_key_block(SSL *s) {
p = (uint8_t *)OPENSSL_malloc(key_block_len);
if (p == NULL) {
- OPENSSL_PUT_ERROR(SSL, tls1_setup_key_block, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
goto err;
}
@@ -446,60 +440,61 @@ int tls1_setup_key_block(SSL *s) {
goto err;
}
- if (!SSL_USE_EXPLICIT_IV(s) &&
- (s->mode & SSL_MODE_CBC_RECORD_SPLITTING) != 0) {
- /* enable vulnerability countermeasure for CBC ciphers with known-IV
- * problem (http://www.openssl.org/~bodo/tls-cbc.txt). */
- s->s3->need_record_splitting = 1;
-
- if (s->session->cipher != NULL &&
- s->session->cipher->algorithm_enc == SSL_RC4) {
- s->s3->need_record_splitting = 0;
- }
- }
-
ret = 1;
err:
return ret;
cipher_unavailable_err:
- OPENSSL_PUT_ERROR(SSL, tls1_setup_key_block,
- SSL_R_CIPHER_OR_HASH_UNAVAILABLE);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_CIPHER_OR_HASH_UNAVAILABLE);
return 0;
}
int tls1_cert_verify_mac(SSL *s, int md_nid, uint8_t *out) {
- unsigned int ret;
- EVP_MD_CTX ctx, *d = NULL;
- int i;
-
- if (s->s3->handshake_buffer &&
- !ssl3_digest_cached_records(s, free_handshake_buffer)) {
- return 0;
- }
-
- for (i = 0; i < SSL_MAX_DIGEST; i++) {
- if (s->s3->handshake_dgst[i] &&
- EVP_MD_CTX_type(s->s3->handshake_dgst[i]) == md_nid) {
- d = s->s3->handshake_dgst[i];
- break;
- }
- }
-
- if (!d) {
- OPENSSL_PUT_ERROR(SSL, tls1_cert_verify_mac, SSL_R_NO_REQUIRED_DIGEST);
+ const EVP_MD_CTX *ctx_template;
+ if (md_nid == NID_md5) {
+ ctx_template = &s->s3->handshake_md5;
+ } else if (md_nid == EVP_MD_CTX_type(&s->s3->handshake_hash)) {
+ ctx_template = &s->s3->handshake_hash;
+ } else {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_NO_REQUIRED_DIGEST);
return 0;
}
+ EVP_MD_CTX ctx;
EVP_MD_CTX_init(&ctx);
- if (!EVP_MD_CTX_copy_ex(&ctx, d)) {
+ if (!EVP_MD_CTX_copy_ex(&ctx, ctx_template)) {
EVP_MD_CTX_cleanup(&ctx);
return 0;
}
+ unsigned ret;
EVP_DigestFinal_ex(&ctx, out, &ret);
EVP_MD_CTX_cleanup(&ctx);
+ return ret;
+}
+
+static int append_digest(const EVP_MD_CTX *ctx, uint8_t *out, size_t *out_len,
+ size_t max_out) {
+ int ret = 0;
+ EVP_MD_CTX ctx_copy;
+ EVP_MD_CTX_init(&ctx_copy);
+
+ if (EVP_MD_CTX_size(ctx) > max_out) {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_BUFFER_TOO_SMALL);
+ goto err;
+ }
+ unsigned len;
+ if (!EVP_MD_CTX_copy_ex(&ctx_copy, ctx) ||
+ !EVP_DigestFinal_ex(&ctx_copy, out, &len)) {
+ goto err;
+ }
+ assert(len == EVP_MD_CTX_size(ctx));
+
+ *out_len = len;
+ ret = 1;
+err:
+ EVP_MD_CTX_cleanup(&ctx_copy);
return ret;
}
@@ -509,44 +504,19 @@ int tls1_cert_verify_mac(SSL *s, int md_nid, uint8_t *out) {
* underlying digests so can be called multiple times and prior to the final
* update etc. */
int tls1_handshake_digest(SSL *s, uint8_t *out, size_t out_len) {
- const EVP_MD *md;
- EVP_MD_CTX ctx;
- int err = 0, len = 0;
- size_t i;
- uint32_t mask;
-
- EVP_MD_CTX_init(&ctx);
-
- for (i = 0; ssl_get_handshake_digest(&mask, &md, i); i++) {
- size_t hash_size;
- unsigned int digest_len;
- EVP_MD_CTX *hdgst = s->s3->handshake_dgst[i];
-
- if ((mask & ssl_get_algorithm2(s)) == 0) {
- continue;
- }
-
- hash_size = EVP_MD_size(md);
- if (!hdgst ||
- hash_size > out_len ||
- !EVP_MD_CTX_copy_ex(&ctx, hdgst) ||
- !EVP_DigestFinal_ex(&ctx, out, &digest_len) ||
- digest_len != hash_size /* internal error */) {
- err = 1;
- break;
- }
-
- out += digest_len;
- out_len -= digest_len;
- len += digest_len;
+ size_t md5_len = 0;
+ if (EVP_MD_CTX_md(&s->s3->handshake_md5) != NULL &&
+ !append_digest(&s->s3->handshake_md5, out, &md5_len, out_len)) {
+ return -1;
}
- EVP_MD_CTX_cleanup(&ctx);
-
- if (err != 0) {
+ size_t len;
+ if (!append_digest(&s->s3->handshake_hash, out + md5_len, &len,
+ out_len - md5_len)) {
return -1;
}
- return len;
+
+ return (int)(md5_len + len);
}
int tls1_final_finish_mac(SSL *s, const char *str, int slen, uint8_t *out) {
@@ -555,14 +525,8 @@ int tls1_final_finish_mac(SSL *s, const char *str, int slen, uint8_t *out) {
int digests_len;
/* At this point, the handshake should have released the handshake buffer on
- * its own.
- * TODO(davidben): Apart from initialization, the handshake buffer should be
- * orthogonal to the handshake digest. https://crbug.com/492371 */
+ * its own. */
assert(s->s3->handshake_buffer == NULL);
- if (s->s3->handshake_buffer &&
- !ssl3_digest_cached_records(s, free_handshake_buffer)) {
- return 0;
- }
digests_len = tls1_handshake_digest(s, buf, sizeof(buf));
if (digests_len < 0) {
@@ -587,21 +551,7 @@ int tls1_generate_master_secret(SSL *s, uint8_t *out, const uint8_t *premaster,
size_t premaster_len) {
if (s->s3->tmp.extended_master_secret) {
uint8_t digests[2 * EVP_MAX_MD_SIZE];
- int digests_len;
-
- /* The master secret is based on the handshake hash just after sending the
- * ClientKeyExchange. However, we might have a client certificate to send,
- * in which case we might need different hashes for the verification and
- * thus still need the handshake buffer around. Keeping both a handshake
- * buffer *and* running hashes isn't yet supported so, when it comes to
- * calculating the Finished hash, we'll have to hash the handshake buffer
- * again. */
- if (s->s3->handshake_buffer &&
- !ssl3_digest_cached_records(s, dont_free_handshake_buffer)) {
- return 0;
- }
-
- digests_len = tls1_handshake_digest(s, digests, sizeof(digests));
+ int digests_len = tls1_handshake_digest(s, digests, sizeof(digests));
if (digests_len == -1) {
return 0;
}
@@ -630,22 +580,21 @@ int tls1_export_keying_material(SSL *s, uint8_t *out, size_t out_len,
const uint8_t *context, size_t context_len,
int use_context) {
if (!s->s3->have_version || s->version == SSL3_VERSION) {
- OPENSSL_PUT_ERROR(SSL, tls1_export_keying_material,
- ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
+ OPENSSL_PUT_ERROR(SSL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
return 0;
}
size_t seed_len = 2 * SSL3_RANDOM_SIZE;
if (use_context) {
if (context_len >= 1u << 16) {
- OPENSSL_PUT_ERROR(SSL, tls1_export_keying_material, ERR_R_OVERFLOW);
+ OPENSSL_PUT_ERROR(SSL, ERR_R_OVERFLOW);
return 0;
}
seed_len += 2 + context_len;
}
uint8_t *seed = OPENSSL_malloc(seed_len);
if (seed == NULL) {
- OPENSSL_PUT_ERROR(SSL, tls1_export_keying_material, ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
return 0;
}
diff --git a/src/ssl/t1_lib.c b/src/ssl/t1_lib.c
index 213a647..f30e8eb 100644
--- a/src/ssl/t1_lib.c
+++ b/src/ssl/t1_lib.c
@@ -106,12 +106,16 @@
* (eay@cryptsoft.com). This product includes software written by Tim
* Hudson (tjh@cryptsoft.com). */
+#include <openssl/ssl.h>
+
#include <assert.h>
+#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <openssl/bytestring.h>
+#include <openssl/digest.h>
#include <openssl/err.h>
#include <openssl/evp.h>
#include <openssl/hmac.h>
@@ -122,9 +126,6 @@
#include "internal.h"
-static int tls_decrypt_ticket(SSL *s, const uint8_t *tick, int ticklen,
- const uint8_t *sess_id, int sesslen,
- SSL_SESSION **psess);
static int ssl_check_clienthello_tlsext(SSL *s);
static int ssl_check_serverhello_tlsext(SSL *s);
@@ -213,8 +214,7 @@ static int tls1_check_duplicate_extensions(const CBS *cbs) {
extension_types =
(uint16_t *)OPENSSL_malloc(sizeof(uint16_t) * num_extensions);
if (extension_types == NULL) {
- OPENSSL_PUT_ERROR(SSL, tls1_check_duplicate_extensions,
- ERR_R_MALLOC_FAILURE);
+ OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE);
goto done;
}
@@ -338,24 +338,21 @@ char SSL_early_callback_ctx_extension_get(
struct tls_curve {
uint16_t curve_id;
int nid;
+ const char curve_name[8];
};
/* ECC curves from RFC4492. */
static const struct tls_curve tls_curves[] = {
- {21, NID_secp224r1},
- {23, NID_X9_62_prime256v1},
- {24, NID_secp384r1},
- {25, NID_secp521r1},
-};
-
-static const uint8_t ecformats_default[] = {
- TLSEXT_ECPOINTFORMAT_uncompressed,
+ {21, NID_secp224r1, "P-224"},
+ {23, NID_X9_62_prime256v1, "P-256"},
+ {24, NID_secp384r1, "P-384"},
+ {25, NID_secp521r1, "P-521"},
};
static const uint16_t eccurves_default[] = {
23, /* X9_62_prime256v1 */
24, /* secp384r1 */
-#if defined(ANDROID)
+#if defined(BORINGSSL_ANDROID_SYSTEM)
25, /* secp521r1 */
#endif
};
@@ -381,6 +378,16 @@ int tls1_ec_nid2curve_id(uint16_t *out_curve_id, int nid) {
return 0;
}
+const char* tls1_ec_curve_id2name(uint16_t curve_id) {
+ size_t i;
+ for (i = 0; i < sizeof(tls_curves) / sizeof(tls_curves[0]); i++) {
+ if (curve_id == tls_curves[i].curve_id) {
+ return tls_curves[i].curve_name;
+ }
+ }
+ return NULL;
+}
+
/* tls1_get_curvelist sets |*out_curve_ids| and |*out_curve_ids_len| to the
* list of allowed curve IDs. If |get_peer_curves| is non-zero, return the
* peer's curve list. Otherwise, return the preferred list. */
@@ -535,28 +542,6 @@ static int tls1_curve_params_from_ec_key(uint16_t *out_curve_id,
return 1;
}
-/* tls1_check_point_format returns one if |comp_id| is consistent with the
- * peer's point format preferences. */
-static int tls1_check_point_format(SSL *s, uint8_t comp_id) {
- uint8_t *p = s->s3->tmp.peer_ecpointformatlist;
- size_t plen = s->s3->tmp.peer_ecpointformatlist_length;
- size_t i;
-
- /* If point formats extension present check it, otherwise everything is
- * supported (see RFC4492). */
- if (p == NULL) {
- return 1;
- }
-
- for (i = 0; i < plen; i++) {
- if (comp_id == p[i]) {
- return 1;
- }
- }
-
- return 0;
-}
-
/* tls1_check_curve_id returns one if |curve_id| is consistent with both our
* and the peer's curve preferences. Note: if called as the client, only our
* preferences are checked; the peer (the server) does not send preferences. */
@@ -593,18 +578,6 @@ static int tls1_check_curve_id(SSL *s, uint16_t curve_id) {
return 1;
}
-static void tls1_get_formatlist(SSL *s, const uint8_t **pformats,
- size_t *pformatslen) {
- /* If we have a custom point format list use it otherwise use default */
- if (s->tlsext_ecpointformatlist) {
- *pformats = s->tlsext_ecpointformatlist;
- *pformatslen = s->tlsext_ecpointformatlist_length;
- } else {
- *pformats = ecformats_default;
- *pformatslen = sizeof(ecformats_default);
- }
-}
-
int tls1_check_ec_cert(SSL *s, X509 *x) {
int ret = 0;
EVP_PKEY *pkey = X509_get_pubkey(x);
@@ -615,7 +588,7 @@ int tls1_check_ec_cert(SSL *s, X509 *x) {
pkey->type != EVP_PKEY_EC ||
!tls1_curve_params_from_ec_key(&curve_id, &comp_id, pkey->pkey.ec) ||
!tls1_check_curve_id(s, curve_id) ||
- !tls1_check_point_format(s, comp_id)) {
+ comp_id != TLSEXT_ECPOINTFORMAT_uncompressed) {
goto done;
}
@@ -663,17 +636,8 @@ static const uint8_t tls12_sigalgs[] = {
};
size_t tls12_get_psigalgs(SSL *s, const uint8_t **psigs) {
- /* If server use client authentication sigalgs if not NULL */
- if (s->server && s->cert->client_sigalgs) {
- *psigs = s->cert->client_sigalgs;
- return s->cert->client_sigalgslen;
- } else if (s->cert->conf_sigalgs) {
- *psigs = s->cert->conf_sigalgs;
- return s->cert->conf_sigalgslen;
- } else {
- *psigs = tls12_sigalgs;
- return sizeof(tls12_sigalgs);
- }
+ *psigs = tls12_sigalgs;
+ return sizeof(tls12_sigalgs);
}
/* tls12_check_peer_sigalg parses a SignatureAndHashAlgorithm out of |cbs|. It
@@ -684,26 +648,26 @@ int tls12_check_peer_sigalg(const EVP_MD **out_md, int *out_alert, SSL *s,
CBS *cbs, EVP_PKEY *pkey) {
const uint8_t *sent_sigs;
size_t sent_sigslen, i;
- int sigalg = tls12_get_sigid(pkey);
+ int sigalg = tls12_get_sigid(pkey->type);
uint8_t hash, signature;
/* Should never happen */
if (sigalg == -1) {
- OPENSSL_PUT_ERROR(SSL, tls12_check_peer_sigalg, ERR_R_INTERNAL_ERROR);
+ OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
*out_alert = SSL_AD_INTERNAL_ERROR;
return 0;
}
if (!CBS_get_u8(cbs, &hash) ||
!CBS_get_u8(cbs, &signature)) {
- OPENSSL_PUT_ERROR(SSL, tls12_check_peer_sigalg, SSL_R_DECODE_ERROR);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR);
*out_alert = SSL_AD_DECODE_ERROR;
return 0;
}
/* Check key type is consistent with signature */
if (sigalg != signature) {
- OPENSSL_PUT_ERROR(SSL, tls12_check_peer_sigalg, SSL_R_WRONG_SIGNATURE_TYPE);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_WRONG_SIGNATURE_TYPE);
*out_alert = SSL_AD_ILLEGAL_PARAMETER;
return 0;
}
@@ -718,8 +682,8 @@ int tls12_check_peer_sigalg(const EVP_MD **out_md, int *out_alert, SSL *s,
}
if (s->server && (!tls1_check_curve_id(s, curve_id) ||
- !tls1_check_point_format(s, comp_id))) {
- OPENSSL_PUT_ERROR(SSL, tls12_check_peer_sigalg, SSL_R_WRONG_CURVE);
+ comp_id != TLSEXT_ECPOINTFORMAT_uncompressed)) {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_WRONG_CURVE);
*out_alert = SSL_AD_ILLEGAL_PARAMETER;
return 0;
}
@@ -735,14 +699,14 @@ int tls12_check_peer_sigalg(const EVP_MD **out_md, int *out_alert, SSL *s,
/* Allow fallback to SHA-1. */
if (i == sent_sigslen && hash != TLSEXT_hash_sha1) {
- OPENSSL_PUT_ERROR(SSL, tls12_check_peer_sigalg, SSL_R_WRONG_SIGNATURE_TYPE);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_WRONG_SIGNATURE_TYPE);
*out_alert = SSL_AD_ILLEGAL_PARAMETER;
return 0;
}
*out_md = tls12_get_hash(hash);
if (*out_md == NULL) {
- OPENSSL_PUT_ERROR(SSL, tls12_check_peer_sigalg, SSL_R_UNKNOWN_DIGEST);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_UNKNOWN_DIGEST);
*out_alert = SSL_AD_ILLEGAL_PARAMETER;
return 0;
}
@@ -799,1128 +763,1785 @@ void ssl_set_client_disabled(SSL *s) {
}
}
-/* header_len is the length of the ClientHello header written so far, used to
- * compute padding. It does not include the record header. Pass 0 if no padding
- * is to be done. */
-uint8_t *ssl_add_clienthello_tlsext(SSL *s, uint8_t *buf, uint8_t *limit,
- size_t header_len) {
- int extdatalen = 0;
- uint8_t *ret = buf;
- uint8_t *orig = buf;
- /* See if we support any ECC ciphersuites */
- int using_ecc = 0;
-
- if (s->version >= TLS1_VERSION || SSL_IS_DTLS(s)) {
- size_t i;
- uint32_t alg_k, alg_a;
- STACK_OF(SSL_CIPHER) *cipher_stack = SSL_get_ciphers(s);
-
- for (i = 0; i < sk_SSL_CIPHER_num(cipher_stack); i++) {
- const SSL_CIPHER *c = sk_SSL_CIPHER_value(cipher_stack, i);
-
- alg_k = c->algorithm_mkey;
- alg_a = c->algorithm_auth;
- if ((alg_k & SSL_kECDHE) || (alg_a & SSL_aECDSA)) {
- using_ecc = 1;
- break;
- }
- }
+/* tls_extension represents a TLS extension that is handled internally. The
+ * |init| function is called for each handshake, before any other functions of
+ * the extension. Then the add and parse callbacks are called as needed.
+ *
+ * The parse callbacks receive a |CBS| that contains the contents of the
+ * extension (i.e. not including the type and length bytes). If an extension is
+ * not received then the parse callbacks will be called with a NULL CBS so that
+ * they can do any processing needed to handle the absence of an extension.
+ *
+ * The add callbacks receive a |CBB| to which the extension can be appended but
+ * the function is responsible for appending the type and length bytes too.
+ *
+ * All callbacks return one for success and zero for error. If a parse function
+ * returns zero then a fatal alert with value |*out_alert| will be sent. If
+ * |*out_alert| isn't set, then a |decode_error| alert will be sent. */
+struct tls_extension {
+ uint16_t value;
+ void (*init)(SSL *ssl);
+
+ int (*add_clienthello)(SSL *ssl, CBB *out);
+ int (*parse_serverhello)(SSL *ssl, uint8_t *out_alert, CBS *contents);
+
+ int (*parse_clienthello)(SSL *ssl, uint8_t *out_alert, CBS *contents);
+ int (*add_serverhello)(SSL *ssl, CBB *out);
+};
+
+
+/* Server name indication (SNI).
+ *
+ * https://tools.ietf.org/html/rfc6066#section-3. */
+
+static void ext_sni_init(SSL *ssl) {
+ ssl->s3->tmp.should_ack_sni = 0;
+}
+
+static int ext_sni_add_clienthello(SSL *ssl, CBB *out) {
+ if (ssl->tlsext_hostname == NULL) {
+ return 1;
}
- /* don't add extensions for SSLv3 unless doing secure renegotiation */
- if (s->client_version == SSL3_VERSION && !s->s3->send_connection_binding) {
- return orig;
+ CBB contents, server_name_list, name;
+ if (!CBB_add_u16(out, TLSEXT_TYPE_server_name) ||
+ !CBB_add_u16_length_prefixed(out, &contents) ||
+ !CBB_add_u16_length_prefixed(&contents, &server_name_list) ||
+ !CBB_add_u8(&server_name_list, TLSEXT_NAMETYPE_host_name) ||
+ !CBB_add_u16_length_prefixed(&server_name_list, &name) ||
+ !CBB_add_bytes(&name, (const uint8_t *)ssl->tlsext_hostname,
+ strlen(ssl->tlsext_hostname)) ||
+ !CBB_flush(out)) {
+ return 0;
}
- ret += 2;
+ return 1;
+}
- if (ret >= limit) {
- return NULL; /* should never occur. */
+static int ext_sni_parse_serverhello(SSL *ssl, uint8_t *out_alert, CBS *contents) {
+ if (contents == NULL) {
+ return 1;
}
- if (s->tlsext_hostname != NULL) {
- /* Add TLS extension servername to the Client Hello message */
- unsigned long size_str;
- long lenmax;
+ if (CBS_len(contents) != 0) {
+ return 0;
+ }
- /* check for enough space.
- 4 for the servername type and entension length
- 2 for servernamelist length
- 1 for the hostname type
- 2 for hostname length
- + hostname length */
+ assert(ssl->tlsext_hostname != NULL);
- lenmax = limit - ret - 9;
- size_str = strlen(s->tlsext_hostname);
- if (lenmax < 0 || size_str > (unsigned long)lenmax) {
- return NULL;
+ if (!ssl->hit) {
+ assert(ssl->session->tlsext_hostname == NULL);
+ ssl->session->tlsext_hostname = BUF_strdup(ssl->tlsext_hostname);
+ if (!ssl->session->tlsext_hostname) {
+ *out_alert = SSL_AD_INTERNAL_ERROR;
+ return 0;
}
+ }
- /* extension type and length */
- s2n(TLSEXT_TYPE_server_name, ret);
- s2n(size_str + 5, ret);
+ return 1;
+}
- /* length of servername list */
- s2n(size_str + 3, ret);
+static int ext_sni_parse_clienthello(SSL *ssl, uint8_t *out_alert, CBS *contents) {
+ if (contents == NULL) {
+ return 1;
+ }
- /* hostname type, length and hostname */
- *(ret++) = (uint8_t)TLSEXT_NAMETYPE_host_name;
- s2n(size_str, ret);
- memcpy(ret, s->tlsext_hostname, size_str);
- ret += size_str;
+ /* The servername extension is treated as follows:
+ *
+ * - Only the hostname type is supported with a maximum length of 255.
+ * - The servername is rejected if too long or if it contains zeros, in
+ * which case an fatal alert is generated.
+ * - The servername field is maintained together with the session cache.
+ * - When a session is resumed, the servername callback is invoked in order
+ * to allow the application to position itself to the right context.
+ * - The servername is acknowledged if it is new for a session or when
+ * it is identical to a previously used for the same session.
+ * Applications can control the behaviour. They can at any time
+ * set a 'desirable' servername for a new SSL object. This can be the
+ * case for example with HTTPS when a Host: header field is received and
+ * a renegotiation is requested. In this case, a possible servername
+ * presented in the new client hello is only acknowledged if it matches
+ * the value of the Host: field.
+ * - Applications must use SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION
+ * if they provide for changing an explicit servername context for the
+ * session,
+ * i.e. when the session has been established with a servername extension.
+ */
+
+ CBS server_name_list;
+ char have_seen_host_name = 0;
+
+ if (!CBS_get_u16_length_prefixed(contents, &server_name_list) ||
+ CBS_len(&server_name_list) == 0 ||
+ CBS_len(contents) != 0) {
+ return 0;
}
- /* Add RI if renegotiating */
- if (s->s3->initial_handshake_complete) {
- int el;
+ /* Decode each ServerName in the extension. */
+ while (CBS_len(&server_name_list) > 0) {
+ uint8_t name_type;
+ CBS host_name;
- if (!ssl_add_clienthello_renegotiate_ext(s, 0, &el, 0)) {
- OPENSSL_PUT_ERROR(SSL, ssl_add_clienthello_tlsext, ERR_R_INTERNAL_ERROR);
- return NULL;
+ if (!CBS_get_u8(&server_name_list, &name_type) ||
+ !CBS_get_u16_length_prefixed(&server_name_list, &host_name)) {
+ return 0;
}
- if ((limit - ret - 4 - el) < 0) {
- return NULL;
+ /* Only host_name is supported. */
+ if (name_type != TLSEXT_NAMETYPE_host_name) {
+ continue;
}
- s2n(TLSEXT_TYPE_renegotiate, ret);
- s2n(el, ret);
-
- if (!ssl_add_clienthello_renegotiate_ext(s, ret, &el, el)) {
- OPENSSL_PUT_ERROR(SSL, ssl_add_clienthello_tlsext, ERR_R_INTERNAL_ERROR);
- return NULL;
+ if (have_seen_host_name) {
+ /* The ServerNameList MUST NOT contain more than one name of the same
+ * name_type. */
+ return 0;
}
- ret += el;
- }
+ have_seen_host_name = 1;
- /* Add extended master secret. */
- if (s->version != SSL3_VERSION) {
- if (limit - ret - 4 < 0) {
- return NULL;
- }
- s2n(TLSEXT_TYPE_extended_master_secret, ret);
- s2n(0, ret);
- }
-
- if (!(SSL_get_options(s) & SSL_OP_NO_TICKET)) {
- int ticklen = 0;
- /* Renegotiation does not participate in session resumption. However, still
- * advertise the extension to avoid potentially breaking servers which carry
- * over the state from the previous handshake, such as OpenSSL servers
- * without upstream's 3c3f0259238594d77264a78944d409f2127642c4. */
- if (!s->s3->initial_handshake_complete && s->session != NULL &&
- s->session->tlsext_tick != NULL) {
- ticklen = s->session->tlsext_ticklen;
+ if (CBS_len(&host_name) == 0 ||
+ CBS_len(&host_name) > TLSEXT_MAXLEN_host_name ||
+ CBS_contains_zero_byte(&host_name)) {
+ *out_alert = SSL_AD_UNRECOGNIZED_NAME;
+ return 0;
}
- /* Check for enough room 2 for extension type, 2 for len rest for
- * ticket. */
- if ((long)(limit - ret - 4 - ticklen) < 0) {
- return NULL;
- }
- s2n(TLSEXT_TYPE_session_ticket, ret);
- s2n(ticklen, ret);
- if (ticklen) {
- memcpy(ret, s->session->tlsext_tick, ticklen);
- ret += ticklen;
+ if (!ssl->hit) {
+ assert(ssl->session->tlsext_hostname == NULL);
+ if (ssl->session->tlsext_hostname) {
+ /* This should be impossible. */
+ return 0;
+ }
+
+ /* Copy the hostname as a string. */
+ if (!CBS_strdup(&host_name, &ssl->session->tlsext_hostname)) {
+ *out_alert = SSL_AD_INTERNAL_ERROR;
+ return 0;
+ }
+
+ ssl->s3->tmp.should_ack_sni = 1;
}
}
- if (ssl3_version_from_wire(s, s->client_version) >= TLS1_2_VERSION) {
- size_t salglen;
- const uint8_t *salg;
- salglen = tls12_get_psigalgs(s, &salg);
- if ((size_t)(limit - ret) < salglen + 6) {
- return NULL;
- }
- s2n(TLSEXT_TYPE_signature_algorithms, ret);
- s2n(salglen + 2, ret);
- s2n(salglen, ret);
- memcpy(ret, salg, salglen);
- ret += salglen;
- }
-
- if (s->ocsp_stapling_enabled) {
- /* The status_request extension is excessively extensible at every layer.
- * On the client, only support requesting OCSP responses with an empty
- * responder_id_list and no extensions. */
- if (limit - ret - 4 - 1 - 2 - 2 < 0) {
- return NULL;
- }
+ return 1;
+}
- s2n(TLSEXT_TYPE_status_request, ret);
- s2n(1 + 2 + 2, ret);
- /* status_type */
- *(ret++) = TLSEXT_STATUSTYPE_ocsp;
- /* responder_id_list - empty */
- s2n(0, ret);
- /* request_extensions - empty */
- s2n(0, ret);
- }
-
- if (s->ctx->next_proto_select_cb && !s->s3->initial_handshake_complete &&
- !SSL_IS_DTLS(s)) {
- /* The client advertises an emtpy extension to indicate its support for
- * Next Protocol Negotiation */
- if (limit - ret - 4 < 0) {
- return NULL;
- }
- s2n(TLSEXT_TYPE_next_proto_neg, ret);
- s2n(0, ret);
+static int ext_sni_add_serverhello(SSL *ssl, CBB *out) {
+ if (ssl->hit ||
+ !ssl->s3->tmp.should_ack_sni ||
+ ssl->session->tlsext_hostname == NULL) {
+ return 1;
}
- if (s->signed_cert_timestamps_enabled) {
- /* The client advertises an empty extension to indicate its support for
- * certificate timestamps. */
- if (limit - ret - 4 < 0) {
- return NULL;
- }
- s2n(TLSEXT_TYPE_certificate_timestamp, ret);
- s2n(0, ret);
+ if (!CBB_add_u16(out, TLSEXT_TYPE_server_name) ||
+ !CBB_add_u16(out, 0 /* length */)) {
+ return 0;
}
- if (s->alpn_client_proto_list && !s->s3->initial_handshake_complete) {
- if ((size_t)(limit - ret) < 6 + s->alpn_client_proto_list_len) {
- return NULL;
- }
- s2n(TLSEXT_TYPE_application_layer_protocol_negotiation, ret);
- s2n(2 + s->alpn_client_proto_list_len, ret);
- s2n(s->alpn_client_proto_list_len, ret);
- memcpy(ret, s->alpn_client_proto_list, s->alpn_client_proto_list_len);
- ret += s->alpn_client_proto_list_len;
+ return 1;
+}
+
+
+/* Renegotiation indication.
+ *
+ * https://tools.ietf.org/html/rfc5746 */
+
+static int ext_ri_add_clienthello(SSL *ssl, CBB *out) {
+ CBB contents, prev_finished;
+ if (!CBB_add_u16(out, TLSEXT_TYPE_renegotiate) ||
+ !CBB_add_u16_length_prefixed(out, &contents) ||
+ !CBB_add_u8_length_prefixed(&contents, &prev_finished) ||
+ !CBB_add_bytes(&prev_finished, ssl->s3->previous_client_finished,
+ ssl->s3->previous_client_finished_len) ||
+ !CBB_flush(out)) {
+ return 0;
}
- if (s->tlsext_channel_id_enabled && !SSL_IS_DTLS(s)) {
- /* The client advertises an emtpy extension to indicate its support for
- * Channel ID. */
- if (limit - ret - 4 < 0) {
- return NULL;
+ return 1;
+}
+
+static int ext_ri_parse_serverhello(SSL *ssl, uint8_t *out_alert,
+ CBS *contents) {
+ if (contents == NULL) {
+ /* No renegotiation extension received.
+ *
+ * Strictly speaking if we want to avoid an attack we should *always* see
+ * RI even on initial ServerHello because the client doesn't see any
+ * renegotiation during an attack. However this would mean we could not
+ * connect to any server which doesn't support RI.
+ *
+ * A lack of the extension is allowed if SSL_OP_LEGACY_SERVER_CONNECT is
+ * defined. */
+ if (ssl->options & SSL_OP_LEGACY_SERVER_CONNECT) {
+ return 1;
}
- if (s->ctx->tlsext_channel_id_enabled_new) {
- s2n(TLSEXT_TYPE_channel_id_new, ret);
+
+ *out_alert = SSL_AD_HANDSHAKE_FAILURE;
+ OPENSSL_PUT_ERROR(SSL, SSL_R_UNSAFE_LEGACY_RENEGOTIATION_DISABLED);
+ return 0;
+ }
+
+ const size_t expected_len = ssl->s3->previous_client_finished_len +
+ ssl->s3->previous_server_finished_len;
+
+ /* Check for logic errors */
+ assert(!expected_len || ssl->s3->previous_client_finished_len);
+ assert(!expected_len || ssl->s3->previous_server_finished_len);
+
+ /* Parse out the extension contents. */
+ CBS renegotiated_connection;
+ if (!CBS_get_u8_length_prefixed(contents, &renegotiated_connection) ||
+ CBS_len(contents) != 0) {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_RENEGOTIATION_ENCODING_ERR);
+ *out_alert = SSL_AD_ILLEGAL_PARAMETER;
+ return 0;
+ }
+
+ /* Check that the extension matches. */
+ if (CBS_len(&renegotiated_connection) != expected_len) {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_RENEGOTIATION_MISMATCH);
+ *out_alert = SSL_AD_HANDSHAKE_FAILURE;
+ return 0;
+ }
+
+ const uint8_t *d = CBS_data(&renegotiated_connection);
+ if (CRYPTO_memcmp(d, ssl->s3->previous_client_finished,
+ ssl->s3->previous_client_finished_len)) {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_RENEGOTIATION_MISMATCH);
+ *out_alert = SSL_AD_HANDSHAKE_FAILURE;
+ return 0;
+ }
+ d += ssl->s3->previous_client_finished_len;
+
+ if (CRYPTO_memcmp(d, ssl->s3->previous_server_finished,
+ ssl->s3->previous_server_finished_len)) {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_RENEGOTIATION_MISMATCH);
+ *out_alert = SSL_AD_ILLEGAL_PARAMETER;
+ return 0;
+ }
+ ssl->s3->send_connection_binding = 1;
+
+ return 1;
+}
+
+static int ext_ri_parse_clienthello(SSL *ssl, uint8_t *out_alert,
+ CBS *contents) {
+ /* Renegotiation isn't supported as a server so this function should never be
+ * called after the initial handshake. */
+ assert(!ssl->s3->initial_handshake_complete);
+
+ CBS fake_contents;
+ static const uint8_t kFakeExtension[] = {0};
+
+ if (contents == NULL) {
+ if (ssl->s3->send_connection_binding) {
+ /* The renegotiation SCSV was received so pretend that we received a
+ * renegotiation extension. */
+ CBS_init(&fake_contents, kFakeExtension, sizeof(kFakeExtension));
+ contents = &fake_contents;
+ /* We require that the renegotiation extension is at index zero of
+ * kExtensions. */
+ ssl->s3->tmp.extensions.received |= (1u << 0);
} else {
- s2n(TLSEXT_TYPE_channel_id, ret);
+ return 1;
}
- s2n(0, ret);
}
- if (SSL_get_srtp_profiles(s)) {
- int el;
+ CBS renegotiated_connection;
- ssl_add_clienthello_use_srtp_ext(s, 0, &el, 0);
+ if (!CBS_get_u8_length_prefixed(contents, &renegotiated_connection) ||
+ CBS_len(contents) != 0) {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_RENEGOTIATION_ENCODING_ERR);
+ return 0;
+ }
- if ((limit - ret - 4 - el) < 0) {
- return NULL;
- }
+ /* Check that the extension matches */
+ if (!CBS_mem_equal(&renegotiated_connection, ssl->s3->previous_client_finished,
+ ssl->s3->previous_client_finished_len)) {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_RENEGOTIATION_MISMATCH);
+ *out_alert = SSL_AD_HANDSHAKE_FAILURE;
+ return 0;
+ }
- s2n(TLSEXT_TYPE_use_srtp, ret);
- s2n(el, ret);
+ ssl->s3->send_connection_binding = 1;
- if (!ssl_add_clienthello_use_srtp_ext(s, ret, &el, el)) {
- OPENSSL_PUT_ERROR(SSL, ssl_add_clienthello_tlsext, ERR_R_INTERNAL_ERROR);
- return NULL;
- }
- ret += el;
+ return 1;
+}
+
+static int ext_ri_add_serverhello(SSL *ssl, CBB *out) {
+ CBB contents, prev_finished;
+ if (!CBB_add_u16(out, TLSEXT_TYPE_renegotiate) ||
+ !CBB_add_u16_length_prefixed(out, &contents) ||
+ !CBB_add_u8_length_prefixed(&contents, &prev_finished) ||
+ !CBB_add_bytes(&prev_finished, ssl->s3->previous_client_finished,
+ ssl->s3->previous_client_finished_len) ||
+ !CBB_add_bytes(&prev_finished, ssl->s3->previous_server_finished,
+ ssl->s3->previous_server_finished_len) ||
+ !CBB_flush(out)) {
+ return 0;
}
- if (using_ecc) {
- /* Add TLS extension ECPointFormats to the ClientHello message */
- long lenmax;
- const uint8_t *formats;
- const uint16_t *curves;
- size_t formats_len, curves_len, i;
+ return 1;
+}
- tls1_get_formatlist(s, &formats, &formats_len);
- lenmax = limit - ret - 5;
- if (lenmax < 0) {
- return NULL;
- }
- if (formats_len > (size_t)lenmax) {
- return NULL;
- }
- if (formats_len > 255) {
- OPENSSL_PUT_ERROR(SSL, ssl_add_clienthello_tlsext, ERR_R_INTERNAL_ERROR);
- return NULL;
- }
+/* Extended Master Secret.
+ *
+ * https://tools.ietf.org/html/draft-ietf-tls-session-hash-05 */
- s2n(TLSEXT_TYPE_ec_point_formats, ret);
- s2n(formats_len + 1, ret);
- *(ret++) = (uint8_t)formats_len;
- memcpy(ret, formats, formats_len);
- ret += formats_len;
+static void ext_ems_init(SSL *ssl) {
+ ssl->s3->tmp.extended_master_secret = 0;
+}
- /* Add TLS extension EllipticCurves to the ClientHello message */
- tls1_get_curvelist(s, 0, &curves, &curves_len);
+static int ext_ems_add_clienthello(SSL *ssl, CBB *out) {
+ if (ssl->version == SSL3_VERSION) {
+ return 1;
+ }
- lenmax = limit - ret - 6;
- if (lenmax < 0) {
- return NULL;
- }
- if (curves_len * 2 > (size_t)lenmax) {
- return NULL;
- }
- if (curves_len * 2 > 65532) {
- OPENSSL_PUT_ERROR(SSL, ssl_add_clienthello_tlsext, ERR_R_INTERNAL_ERROR);
- return NULL;
- }
+ if (!CBB_add_u16(out, TLSEXT_TYPE_extended_master_secret) ||
+ !CBB_add_u16(out, 0 /* length */)) {
+ return 0;
+ }
- s2n(TLSEXT_TYPE_elliptic_curves, ret);
- s2n((curves_len * 2) + 2, ret);
+ return 1;
+}
- s2n(curves_len * 2, ret);
- for (i = 0; i < curves_len; i++) {
- s2n(curves[i], ret);
- }
+static int ext_ems_parse_serverhello(SSL *ssl, uint8_t *out_alert,
+ CBS *contents) {
+ if (contents == NULL) {
+ return 1;
}
- if (header_len > 0) {
- size_t clienthello_minsize = 0;
- header_len += ret - orig;
- if (header_len > 0xff && header_len < 0x200) {
- /* Add padding to workaround bugs in F5 terminators. See
- * https://tools.ietf.org/html/draft-agl-tls-padding-03
- *
- * NB: because this code works out the length of all existing extensions
- * it MUST always appear last. */
- clienthello_minsize = 0x200;
- }
- if (s->fastradio_padding) {
- /* Pad the ClientHello record to 1024 bytes to fast forward the radio
- * into DCH (high data rate) state in 3G networks. Note that when
- * fastradio_padding is enabled, even if the header_len is less than 255
- * bytes, the padding will be applied regardless. This is slightly
- * different from the TLS padding extension suggested in
- * https://tools.ietf.org/html/draft-agl-tls-padding-03 */
- clienthello_minsize = 0x400;
- }
- if (header_len < clienthello_minsize) {
- size_t padding_len = clienthello_minsize - header_len;
- /* Extensions take at least four bytes to encode. Always include least
- * one byte of data if including the extension. WebSphere Application
- * Server 7.0 is intolerant to the last extension being zero-length. */
- if (padding_len >= 4 + 1) {
- padding_len -= 4;
- } else {
- padding_len = 1;
- }
+ if (ssl->version == SSL3_VERSION || CBS_len(contents) != 0) {
+ return 0;
+ }
- if (limit - ret - 4 - (long)padding_len < 0) {
- return NULL;
- }
+ ssl->s3->tmp.extended_master_secret = 1;
+ return 1;
+}
- s2n(TLSEXT_TYPE_padding, ret);
- s2n(padding_len, ret);
- memset(ret, 0, padding_len);
- ret += padding_len;
- }
+static int ext_ems_parse_clienthello(SSL *ssl, uint8_t *out_alert, CBS *contents) {
+ if (ssl->version == SSL3_VERSION || contents == NULL) {
+ return 1;
}
- extdatalen = ret - orig - 2;
- if (extdatalen == 0) {
- return orig;
+ if (CBS_len(contents) != 0) {
+ return 0;
}
- s2n(extdatalen, orig);
- return ret;
+ ssl->s3->tmp.extended_master_secret = 1;
+ return 1;
}
-uint8_t *ssl_add_serverhello_tlsext(SSL *s, uint8_t *buf, uint8_t *limit) {
- int extdatalen = 0;
- uint8_t *orig = buf;
- uint8_t *ret = buf;
- int next_proto_neg_seen;
- uint32_t alg_k = s->s3->tmp.new_cipher->algorithm_mkey;
- uint32_t alg_a = s->s3->tmp.new_cipher->algorithm_auth;
- int using_ecc = (alg_k & SSL_kECDHE) || (alg_a & SSL_aECDSA);
- using_ecc = using_ecc && (s->s3->tmp.peer_ecpointformatlist != NULL);
+static int ext_ems_add_serverhello(SSL *ssl, CBB *out) {
+ if (!ssl->s3->tmp.extended_master_secret) {
+ return 1;
+ }
- /* don't add extensions for SSLv3, unless doing secure renegotiation */
- if (s->version == SSL3_VERSION && !s->s3->send_connection_binding) {
- return orig;
+ if (!CBB_add_u16(out, TLSEXT_TYPE_extended_master_secret) ||
+ !CBB_add_u16(out, 0 /* length */)) {
+ return 0;
}
- ret += 2;
- if (ret >= limit) {
- return NULL; /* should never happen. */
+ return 1;
+}
+
+
+/* Session tickets.
+ *
+ * https://tools.ietf.org/html/rfc5077 */
+
+static int ext_ticket_add_clienthello(SSL *ssl, CBB *out) {
+ if (SSL_get_options(ssl) & SSL_OP_NO_TICKET) {
+ return 1;
}
- if (!s->hit && s->should_ack_sni && s->session->tlsext_hostname != NULL) {
- if ((long)(limit - ret - 4) < 0) {
- return NULL;
- }
+ const uint8_t *ticket_data = NULL;
+ int ticket_len = 0;
- s2n(TLSEXT_TYPE_server_name, ret);
- s2n(0, ret);
+ /* Renegotiation does not participate in session resumption. However, still
+ * advertise the extension to avoid potentially breaking servers which carry
+ * over the state from the previous handshake, such as OpenSSL servers
+ * without upstream's 3c3f0259238594d77264a78944d409f2127642c4. */
+ if (!ssl->s3->initial_handshake_complete &&
+ ssl->session != NULL &&
+ ssl->session->tlsext_tick != NULL) {
+ ticket_data = ssl->session->tlsext_tick;
+ ticket_len = ssl->session->tlsext_ticklen;
}
- if (s->s3->send_connection_binding) {
- int el;
+ CBB ticket;
+ if (!CBB_add_u16(out, TLSEXT_TYPE_session_ticket) ||
+ !CBB_add_u16_length_prefixed(out, &ticket) ||
+ !CBB_add_bytes(&ticket, ticket_data, ticket_len) ||
+ !CBB_flush(out)) {
+ return 0;
+ }
- if (!ssl_add_serverhello_renegotiate_ext(s, 0, &el, 0)) {
- OPENSSL_PUT_ERROR(SSL, ssl_add_serverhello_tlsext, ERR_R_INTERNAL_ERROR);
- return NULL;
- }
+ return 1;
+}
- if ((limit - ret - 4 - el) < 0) {
- return NULL;
- }
+static int ext_ticket_parse_serverhello(SSL *ssl, uint8_t *out_alert,
+ CBS *contents) {
+ ssl->tlsext_ticket_expected = 0;
- s2n(TLSEXT_TYPE_renegotiate, ret);
- s2n(el, ret);
+ if (contents == NULL) {
+ return 1;
+ }
- if (!ssl_add_serverhello_renegotiate_ext(s, ret, &el, el)) {
- OPENSSL_PUT_ERROR(SSL, ssl_add_serverhello_tlsext, ERR_R_INTERNAL_ERROR);
- return NULL;
- }
+ /* If |SSL_OP_NO_TICKET| is set then no extension will have been sent and
+ * this function should never be called, even if the server tries to send the
+ * extension. */
+ assert((SSL_get_options(ssl) & SSL_OP_NO_TICKET) == 0);
- ret += el;
+ if (CBS_len(contents) != 0) {
+ return 0;
}
- if (s->s3->tmp.extended_master_secret) {
- if ((long)(limit - ret - 4) < 0) {
- return NULL;
- }
+ ssl->tlsext_ticket_expected = 1;
+ return 1;
+}
+
+static int ext_ticket_parse_clienthello(SSL *ssl, uint8_t *out_alert, CBS *contents) {
+ /* This function isn't used because the ticket extension from the client is
+ * handled in ssl_sess.c. */
+ return 1;
+}
- s2n(TLSEXT_TYPE_extended_master_secret, ret);
- s2n(0, ret);
+static int ext_ticket_add_serverhello(SSL *ssl, CBB *out) {
+ if (!ssl->tlsext_ticket_expected) {
+ return 1;
}
- if (using_ecc) {
- const uint8_t *plist;
- size_t plistlen;
- /* Add TLS extension ECPointFormats to the ServerHello message */
- long lenmax;
+ /* If |SSL_OP_NO_TICKET| is set, |tlsext_ticket_expected| should never be
+ * true. */
+ assert((SSL_get_options(ssl) & SSL_OP_NO_TICKET) == 0);
- tls1_get_formatlist(s, &plist, &plistlen);
+ if (!CBB_add_u16(out, TLSEXT_TYPE_session_ticket) ||
+ !CBB_add_u16(out, 0 /* length */)) {
+ return 0;
+ }
- lenmax = limit - ret - 5;
- if (lenmax < 0) {
- return NULL;
- }
- if (plistlen > (size_t)lenmax) {
- return NULL;
- }
- if (plistlen > 255) {
- OPENSSL_PUT_ERROR(SSL, ssl_add_serverhello_tlsext, ERR_R_INTERNAL_ERROR);
- return NULL;
- }
+ return 1;
+}
- s2n(TLSEXT_TYPE_ec_point_formats, ret);
- s2n(plistlen + 1, ret);
- *(ret++) = (uint8_t)plistlen;
- memcpy(ret, plist, plistlen);
- ret += plistlen;
+
+/* Signature Algorithms.
+ *
+ * https://tools.ietf.org/html/rfc5246#section-7.4.1.4.1 */
+
+static int ext_sigalgs_add_clienthello(SSL *ssl, CBB *out) {
+ if (ssl3_version_from_wire(ssl, ssl->client_version) < TLS1_2_VERSION) {
+ return 1;
}
- /* Currently the server should not respond with a SupportedCurves extension */
- if (s->tlsext_ticket_expected && !(SSL_get_options(s) & SSL_OP_NO_TICKET)) {
- if ((long)(limit - ret - 4) < 0) {
- return NULL;
- }
- s2n(TLSEXT_TYPE_session_ticket, ret);
- s2n(0, ret);
+ const uint8_t *sigalgs_data;
+ const size_t sigalgs_len = tls12_get_psigalgs(ssl, &sigalgs_data);
+
+ CBB contents, sigalgs;
+ if (!CBB_add_u16(out, TLSEXT_TYPE_signature_algorithms) ||
+ !CBB_add_u16_length_prefixed(out, &contents) ||
+ !CBB_add_u16_length_prefixed(&contents, &sigalgs) ||
+ !CBB_add_bytes(&sigalgs, sigalgs_data, sigalgs_len) ||
+ !CBB_flush(out)) {
+ return 0;
}
- if (s->s3->tmp.certificate_status_expected) {
- if ((long)(limit - ret - 4) < 0) {
- return NULL;
- }
- s2n(TLSEXT_TYPE_status_request, ret);
- s2n(0, ret);
+ return 1;
+}
+
+static int ext_sigalgs_parse_serverhello(SSL *ssl, uint8_t *out_alert,
+ CBS *contents) {
+ if (contents != NULL) {
+ /* Servers MUST NOT send this extension. */
+ *out_alert = SSL_AD_UNSUPPORTED_EXTENSION;
+ OPENSSL_PUT_ERROR(SSL, SSL_R_SIGNATURE_ALGORITHMS_EXTENSION_SENT_BY_SERVER);
+ return 0;
}
- if (s->srtp_profile) {
- int el;
+ return 1;
+}
- ssl_add_serverhello_use_srtp_ext(s, 0, &el, 0);
+static int ext_sigalgs_parse_clienthello(SSL *ssl, uint8_t *out_alert,
+ CBS *contents) {
+ OPENSSL_free(ssl->cert->peer_sigalgs);
+ ssl->cert->peer_sigalgs = NULL;
+ ssl->cert->peer_sigalgslen = 0;
- if ((limit - ret - 4 - el) < 0) {
- return NULL;
- }
+ if (contents == NULL) {
+ return 1;
+ }
- s2n(TLSEXT_TYPE_use_srtp, ret);
- s2n(el, ret);
+ CBS supported_signature_algorithms;
+ if (!CBS_get_u16_length_prefixed(contents, &supported_signature_algorithms) ||
+ CBS_len(contents) != 0 ||
+ CBS_len(&supported_signature_algorithms) == 0 ||
+ !tls1_parse_peer_sigalgs(ssl, &supported_signature_algorithms)) {
+ return 0;
+ }
- if (!ssl_add_serverhello_use_srtp_ext(s, ret, &el, el)) {
- OPENSSL_PUT_ERROR(SSL, ssl_add_serverhello_tlsext, ERR_R_INTERNAL_ERROR);
- return NULL;
- }
- ret += el;
+ return 1;
+}
+
+static int ext_sigalgs_add_serverhello(SSL *ssl, CBB *out) {
+ /* Servers MUST NOT send this extension. */
+ return 1;
+}
+
+
+/* OCSP Stapling.
+ *
+ * https://tools.ietf.org/html/rfc6066#section-8 */
+
+static void ext_ocsp_init(SSL *ssl) {
+ ssl->s3->tmp.certificate_status_expected = 0;
+}
+
+static int ext_ocsp_add_clienthello(SSL *ssl, CBB *out) {
+ if (!ssl->ocsp_stapling_enabled) {
+ return 1;
+ }
+
+ CBB contents;
+ if (!CBB_add_u16(out, TLSEXT_TYPE_status_request) ||
+ !CBB_add_u16_length_prefixed(out, &contents) ||
+ !CBB_add_u8(&contents, TLSEXT_STATUSTYPE_ocsp) ||
+ !CBB_add_u16(&contents, 0 /* empty responder ID list */) ||
+ !CBB_add_u16(&contents, 0 /* empty request extensions */) ||
+ !CBB_flush(out)) {
+ return 0;
}
- next_proto_neg_seen = s->s3->next_proto_neg_seen;
- s->s3->next_proto_neg_seen = 0;
- if (next_proto_neg_seen && s->ctx->next_protos_advertised_cb) {
- const uint8_t *npa;
- unsigned int npalen;
- int r;
+ return 1;
+}
- r = s->ctx->next_protos_advertised_cb(
- s, &npa, &npalen, s->ctx->next_protos_advertised_cb_arg);
- if (r == SSL_TLSEXT_ERR_OK) {
- if ((long)(limit - ret - 4 - npalen) < 0) {
- return NULL;
- }
- s2n(TLSEXT_TYPE_next_proto_neg, ret);
- s2n(npalen, ret);
- memcpy(ret, npa, npalen);
- ret += npalen;
- s->s3->next_proto_neg_seen = 1;
- }
+static int ext_ocsp_parse_serverhello(SSL *ssl, uint8_t *out_alert,
+ CBS *contents) {
+ if (contents == NULL) {
+ return 1;
}
- if (s->s3->alpn_selected) {
- const uint8_t *selected = s->s3->alpn_selected;
- size_t len = s->s3->alpn_selected_len;
+ if (CBS_len(contents) != 0) {
+ return 0;
+ }
- if ((long)(limit - ret - 4 - 2 - 1 - len) < 0) {
- return NULL;
- }
- s2n(TLSEXT_TYPE_application_layer_protocol_negotiation, ret);
- s2n(3 + len, ret);
- s2n(1 + len, ret);
- *ret++ = len;
- memcpy(ret, selected, len);
- ret += len;
- }
-
- /* If the client advertised support for Channel ID, and we have it
- * enabled, then we want to echo it back. */
- if (s->s3->tlsext_channel_id_valid) {
- if (limit - ret - 4 < 0) {
- return NULL;
- }
- if (s->s3->tlsext_channel_id_new) {
- s2n(TLSEXT_TYPE_channel_id_new, ret);
- } else {
- s2n(TLSEXT_TYPE_channel_id, ret);
- }
- s2n(0, ret);
+ ssl->s3->tmp.certificate_status_expected = 1;
+ return 1;
+}
+
+static int ext_ocsp_parse_clienthello(SSL *ssl, uint8_t *out_alert,
+ CBS *contents) {
+ if (contents == NULL) {
+ return 1;
}
- extdatalen = ret - orig - 2;
- if (extdatalen == 0) {
- return orig;
+ uint8_t status_type;
+ if (!CBS_get_u8(contents, &status_type)) {
+ return 0;
}
- s2n(extdatalen, orig);
- return ret;
+ /* We cannot decide whether OCSP stapling will occur yet because the correct
+ * SSL_CTX might not have been selected. */
+ ssl->s3->tmp.ocsp_stapling_requested = status_type == TLSEXT_STATUSTYPE_ocsp;
+
+ return 1;
+}
+
+static int ext_ocsp_add_serverhello(SSL *ssl, CBB *out) {
+ /* The extension shouldn't be sent when resuming sessions. */
+ if (ssl->hit ||
+ !ssl->s3->tmp.ocsp_stapling_requested ||
+ ssl->ctx->ocsp_response_length == 0) {
+ return 1;
+ }
+
+ ssl->s3->tmp.certificate_status_expected = 1;
+
+ return CBB_add_u16(out, TLSEXT_TYPE_status_request) &&
+ CBB_add_u16(out, 0 /* length */);
}
-/* tls1_alpn_handle_client_hello is called to process the ALPN extension in a
- * ClientHello.
- * cbs: the contents of the extension, not including the type and length.
- * out_alert: a pointer to the alert value to send in the event of a zero
- * return.
+
+/* Next protocol negotiation.
*
- * returns: 1 on success. */
-static int tls1_alpn_handle_client_hello(SSL *s, CBS *cbs, int *out_alert) {
- CBS protocol_name_list, protocol_name_list_copy;
- const uint8_t *selected;
+ * https://htmlpreview.github.io/?https://github.com/agl/technotes/blob/master/nextprotoneg.html */
+
+static void ext_npn_init(SSL *ssl) {
+ ssl->s3->next_proto_neg_seen = 0;
+}
+
+static int ext_npn_add_clienthello(SSL *ssl, CBB *out) {
+ if (ssl->s3->initial_handshake_complete ||
+ ssl->ctx->next_proto_select_cb == NULL ||
+ SSL_IS_DTLS(ssl)) {
+ return 1;
+ }
+
+ if (!CBB_add_u16(out, TLSEXT_TYPE_next_proto_neg) ||
+ !CBB_add_u16(out, 0 /* length */)) {
+ return 0;
+ }
+
+ return 1;
+}
+
+static int ext_npn_parse_serverhello(SSL *ssl, uint8_t *out_alert,
+ CBS *contents) {
+ if (contents == NULL) {
+ return 1;
+ }
+
+ /* If any of these are false then we should never have sent the NPN
+ * extension in the ClientHello and thus this function should never have been
+ * called. */
+ assert(!ssl->s3->initial_handshake_complete);
+ assert(!SSL_IS_DTLS(ssl));
+ assert(ssl->ctx->next_proto_select_cb != NULL);
+
+ if (ssl->s3->alpn_selected != NULL) {
+ /* NPN and ALPN may not be negotiated in the same connection. */
+ *out_alert = SSL_AD_ILLEGAL_PARAMETER;
+ OPENSSL_PUT_ERROR(SSL, SSL_R_NEGOTIATED_BOTH_NPN_AND_ALPN);
+ return 0;
+ }
+
+ const uint8_t *const orig_contents = CBS_data(contents);
+ const size_t orig_len = CBS_len(contents);
+
+ while (CBS_len(contents) != 0) {
+ CBS proto;
+ if (!CBS_get_u8_length_prefixed(contents, &proto) ||
+ CBS_len(&proto) == 0) {
+ return 0;
+ }
+ }
+
+ uint8_t *selected;
uint8_t selected_len;
- int r;
+ if (ssl->ctx->next_proto_select_cb(
+ ssl, &selected, &selected_len, orig_contents, orig_len,
+ ssl->ctx->next_proto_select_cb_arg) != SSL_TLSEXT_ERR_OK) {
+ *out_alert = SSL_AD_INTERNAL_ERROR;
+ return 0;
+ }
+
+ OPENSSL_free(ssl->next_proto_negotiated);
+ ssl->next_proto_negotiated = BUF_memdup(selected, selected_len);
+ if (ssl->next_proto_negotiated == NULL) {
+ *out_alert = SSL_AD_INTERNAL_ERROR;
+ return 0;
+ }
+
+ ssl->next_proto_negotiated_len = selected_len;
+ ssl->s3->next_proto_neg_seen = 1;
+
+ return 1;
+}
+
+static int ext_npn_parse_clienthello(SSL *ssl, uint8_t *out_alert,
+ CBS *contents) {
+ if (contents != NULL && CBS_len(contents) != 0) {
+ return 0;
+ }
+
+ if (contents == NULL ||
+ ssl->s3->initial_handshake_complete ||
+ /* If the ALPN extension is seen before NPN, ignore it. (If ALPN is seen
+ * afterwards, parsing the ALPN extension will clear
+ * |next_proto_neg_seen|. */
+ ssl->s3->alpn_selected != NULL ||
+ ssl->ctx->next_protos_advertised_cb == NULL ||
+ SSL_IS_DTLS(ssl)) {
+ return 1;
+ }
+
+ ssl->s3->next_proto_neg_seen = 1;
+ return 1;
+}
+
+static int ext_npn_add_serverhello(SSL *ssl, CBB *out) {
+ /* |next_proto_neg_seen| might have been cleared when an ALPN extension was
+ * parsed. */
+ if (!ssl->s3->next_proto_neg_seen) {
+ return 1;
+ }
+
+ const uint8_t *npa;
+ unsigned npa_len;
+
+ if (ssl->ctx->next_protos_advertised_cb(
+ ssl, &npa, &npa_len, ssl->ctx->next_protos_advertised_cb_arg) !=
+ SSL_TLSEXT_ERR_OK) {
+ ssl->s3->next_proto_neg_seen = 0;
+ return 1;
+ }
+
+ CBB contents;
+ if (!CBB_add_u16(out, TLSEXT_TYPE_next_proto_neg) ||
+ !CBB_add_u16_length_prefixed(out, &contents) ||
+ !CBB_add_bytes(&contents, npa, npa_len) ||
+ !CBB_flush(out)) {
+ return 0;
+ }
+
+ return 1;
+}
+
+
+/* Signed certificate timestamps.
+ *
+ * https://tools.ietf.org/html/rfc6962#section-3.3.1 */
- if (s->ctx->alpn_select_cb == NULL) {
+static int ext_sct_add_clienthello(SSL *ssl, CBB *out) {
+ if (!ssl->signed_cert_timestamps_enabled) {
return 1;
}
- if (!CBS_get_u16_length_prefixed(cbs, &protocol_name_list) ||
- CBS_len(cbs) != 0 || CBS_len(&protocol_name_list) < 2) {
- goto parse_error;
+ if (!CBB_add_u16(out, TLSEXT_TYPE_certificate_timestamp) ||
+ !CBB_add_u16(out, 0 /* length */)) {
+ return 0;
+ }
+
+ return 1;
+}
+
+static int ext_sct_parse_serverhello(SSL *ssl, uint8_t *out_alert,
+ CBS *contents) {
+ if (contents == NULL) {
+ return 1;
+ }
+
+ /* If this is false then we should never have sent the SCT extension in the
+ * ClientHello and thus this function should never have been called. */
+ assert(ssl->signed_cert_timestamps_enabled);
+
+ if (CBS_len(contents) == 0) {
+ *out_alert = SSL_AD_DECODE_ERROR;
+ return 0;
+ }
+
+ /* Session resumption uses the original session information. */
+ if (!ssl->hit &&
+ !CBS_stow(contents, &ssl->session->tlsext_signed_cert_timestamp_list,
+ &ssl->session->tlsext_signed_cert_timestamp_list_length)) {
+ *out_alert = SSL_AD_INTERNAL_ERROR;
+ return 0;
+ }
+
+ return 1;
+}
+
+static int ext_sct_parse_clienthello(SSL *ssl, uint8_t *out_alert,
+ CBS *contents) {
+ return contents == NULL || CBS_len(contents) == 0;
+}
+
+static int ext_sct_add_serverhello(SSL *ssl, CBB *out) {
+ /* The extension shouldn't be sent when resuming sessions. */
+ if (ssl->hit ||
+ ssl->ctx->signed_cert_timestamp_list_length == 0) {
+ return 1;
+ }
+
+ CBB contents;
+ return CBB_add_u16(out, TLSEXT_TYPE_certificate_timestamp) &&
+ CBB_add_u16_length_prefixed(out, &contents) &&
+ CBB_add_bytes(&contents, ssl->ctx->signed_cert_timestamp_list,
+ ssl->ctx->signed_cert_timestamp_list_length) &&
+ CBB_flush(out);
+}
+
+
+/* Application-level Protocol Negotiation.
+ *
+ * https://tools.ietf.org/html/rfc7301 */
+
+static void ext_alpn_init(SSL *ssl) {
+ OPENSSL_free(ssl->s3->alpn_selected);
+ ssl->s3->alpn_selected = NULL;
+}
+
+static int ext_alpn_add_clienthello(SSL *ssl, CBB *out) {
+ if (ssl->alpn_client_proto_list == NULL ||
+ ssl->s3->initial_handshake_complete) {
+ return 1;
+ }
+
+ CBB contents, proto_list;
+ if (!CBB_add_u16(out, TLSEXT_TYPE_application_layer_protocol_negotiation) ||
+ !CBB_add_u16_length_prefixed(out, &contents) ||
+ !CBB_add_u16_length_prefixed(&contents, &proto_list) ||
+ !CBB_add_bytes(&proto_list, ssl->alpn_client_proto_list,
+ ssl->alpn_client_proto_list_len) ||
+ !CBB_flush(out)) {
+ return 0;
+ }
+
+ return 1;
+}
+
+static int ext_alpn_parse_serverhello(SSL *ssl, uint8_t *out_alert,
+ CBS *contents) {
+ if (contents == NULL) {
+ return 1;
+ }
+
+ assert(!ssl->s3->initial_handshake_complete);
+ assert(ssl->alpn_client_proto_list != NULL);
+
+ if (ssl->s3->next_proto_neg_seen) {
+ /* NPN and ALPN may not be negotiated in the same connection. */
+ *out_alert = SSL_AD_ILLEGAL_PARAMETER;
+ OPENSSL_PUT_ERROR(SSL, SSL_R_NEGOTIATED_BOTH_NPN_AND_ALPN);
+ return 0;
+ }
+
+ /* The extension data consists of a ProtocolNameList which must have
+ * exactly one ProtocolName. Each of these is length-prefixed. */
+ CBS protocol_name_list, protocol_name;
+ if (!CBS_get_u16_length_prefixed(contents, &protocol_name_list) ||
+ CBS_len(contents) != 0 ||
+ !CBS_get_u8_length_prefixed(&protocol_name_list, &protocol_name) ||
+ /* Empty protocol names are forbidden. */
+ CBS_len(&protocol_name) == 0 ||
+ CBS_len(&protocol_name_list) != 0) {
+ return 0;
+ }
+
+ if (!CBS_stow(&protocol_name, &ssl->s3->alpn_selected,
+ &ssl->s3->alpn_selected_len)) {
+ *out_alert = SSL_AD_INTERNAL_ERROR;
+ return 0;
+ }
+
+ return 1;
+}
+
+static int ext_alpn_parse_clienthello(SSL *ssl, uint8_t *out_alert,
+ CBS *contents) {
+ if (contents == NULL) {
+ return 1;
+ }
+
+ if (ssl->ctx->alpn_select_cb == NULL ||
+ ssl->s3->initial_handshake_complete) {
+ return 1;
+ }
+
+ /* ALPN takes precedence over NPN. */
+ ssl->s3->next_proto_neg_seen = 0;
+
+ CBS protocol_name_list;
+ if (!CBS_get_u16_length_prefixed(contents, &protocol_name_list) ||
+ CBS_len(contents) != 0 ||
+ CBS_len(&protocol_name_list) < 2) {
+ return 0;
}
/* Validate the protocol list. */
- protocol_name_list_copy = protocol_name_list;
+ CBS protocol_name_list_copy = protocol_name_list;
while (CBS_len(&protocol_name_list_copy) > 0) {
CBS protocol_name;
- if (!CBS_get_u8_length_prefixed(&protocol_name_list_copy, &protocol_name)) {
- goto parse_error;
+ if (!CBS_get_u8_length_prefixed(&protocol_name_list_copy, &protocol_name) ||
+ /* Empty protocol names are forbidden. */
+ CBS_len(&protocol_name) == 0) {
+ return 0;
}
}
- r = s->ctx->alpn_select_cb(
- s, &selected, &selected_len, CBS_data(&protocol_name_list),
- CBS_len(&protocol_name_list), s->ctx->alpn_select_cb_arg);
- if (r == SSL_TLSEXT_ERR_OK) {
- OPENSSL_free(s->s3->alpn_selected);
- s->s3->alpn_selected = BUF_memdup(selected, selected_len);
- if (!s->s3->alpn_selected) {
+ const uint8_t *selected;
+ uint8_t selected_len;
+ if (ssl->ctx->alpn_select_cb(
+ ssl, &selected, &selected_len, CBS_data(&protocol_name_list),
+ CBS_len(&protocol_name_list),
+ ssl->ctx->alpn_select_cb_arg) == SSL_TLSEXT_ERR_OK) {
+ OPENSSL_free(ssl->s3->alpn_selected);
+ ssl->s3->alpn_selected = BUF_memdup(selected, selected_len);
+ if (ssl->s3->alpn_selected == NULL) {
*out_alert = SSL_AD_INTERNAL_ERROR;
return 0;
}
- s->s3->alpn_selected_len = selected_len;
+ ssl->s3->alpn_selected_len = selected_len;
}
return 1;
+}
-parse_error:
- *out_alert = SSL_AD_DECODE_ERROR;
- return 0;
+static int ext_alpn_add_serverhello(SSL *ssl, CBB *out) {
+ if (ssl->s3->alpn_selected == NULL) {
+ return 1;
+ }
+
+ CBB contents, proto_list, proto;
+ if (!CBB_add_u16(out, TLSEXT_TYPE_application_layer_protocol_negotiation) ||
+ !CBB_add_u16_length_prefixed(out, &contents) ||
+ !CBB_add_u16_length_prefixed(&contents, &proto_list) ||
+ !CBB_add_u8_length_prefixed(&proto_list, &proto) ||
+ !CBB_add_bytes(&proto, ssl->s3->alpn_selected, ssl->s3->alpn_selected_len) ||
+ !CBB_flush(out)) {
+ return 0;
+ }
+
+ return 1;
}
-static int ssl_scan_clienthello_tlsext(SSL *s, CBS *cbs, int *out_alert) {
- int renegotiate_seen = 0;
- CBS extensions;
- s->should_ack_sni = 0;
- s->srtp_profile = NULL;
- s->s3->next_proto_neg_seen = 0;
- s->s3->tmp.certificate_status_expected = 0;
- s->s3->tmp.extended_master_secret = 0;
+/* Channel ID.
+ *
+ * https://tools.ietf.org/html/draft-balfanz-tls-channelid-01 */
+
+static void ext_channel_id_init(SSL *ssl) {
+ ssl->s3->tlsext_channel_id_valid = 0;
+}
+
+static int ext_channel_id_add_clienthello(SSL *ssl, CBB *out) {
+ if (!ssl->tlsext_channel_id_enabled ||
+ SSL_IS_DTLS(ssl)) {
+ return 1;
+ }
+
+ if (!CBB_add_u16(out, TLSEXT_TYPE_channel_id) ||
+ !CBB_add_u16(out, 0 /* length */)) {
+ return 0;
+ }
- OPENSSL_free(s->s3->alpn_selected);
- s->s3->alpn_selected = NULL;
+ return 1;
+}
- /* Clear any signature algorithms extension received */
- OPENSSL_free(s->cert->peer_sigalgs);
- s->cert->peer_sigalgs = NULL;
- s->cert->peer_sigalgslen = 0;
+static int ext_channel_id_parse_serverhello(SSL *ssl, uint8_t *out_alert,
+ CBS *contents) {
+ if (contents == NULL) {
+ return 1;
+ }
- /* Clear any shared signature algorithms */
- OPENSSL_free(s->cert->shared_sigalgs);
- s->cert->shared_sigalgs = NULL;
- s->cert->shared_sigalgslen = 0;
+ assert(!SSL_IS_DTLS(ssl));
+ assert(ssl->tlsext_channel_id_enabled);
- /* Clear ECC extensions */
- OPENSSL_free(s->s3->tmp.peer_ecpointformatlist);
- s->s3->tmp.peer_ecpointformatlist = NULL;
- s->s3->tmp.peer_ecpointformatlist_length = 0;
+ if (CBS_len(contents) != 0) {
+ return 0;
+ }
- OPENSSL_free(s->s3->tmp.peer_ellipticcurvelist);
- s->s3->tmp.peer_ellipticcurvelist = NULL;
- s->s3->tmp.peer_ellipticcurvelist_length = 0;
+ ssl->s3->tlsext_channel_id_valid = 1;
+ return 1;
+}
- /* There may be no extensions. */
- if (CBS_len(cbs) == 0) {
- goto ri_check;
+static int ext_channel_id_parse_clienthello(SSL *ssl, uint8_t *out_alert,
+ CBS *contents) {
+ if (contents == NULL ||
+ !ssl->tlsext_channel_id_enabled ||
+ SSL_IS_DTLS(ssl)) {
+ return 1;
}
- /* Decode the extensions block and check it is valid. */
- if (!CBS_get_u16_length_prefixed(cbs, &extensions) ||
- !tls1_check_duplicate_extensions(&extensions)) {
- *out_alert = SSL_AD_DECODE_ERROR;
+ if (CBS_len(contents) != 0) {
return 0;
}
- while (CBS_len(&extensions) != 0) {
- uint16_t type;
- CBS extension;
+ ssl->s3->tlsext_channel_id_valid = 1;
+ return 1;
+}
- /* Decode the next extension. */
- if (!CBS_get_u16(&extensions, &type) ||
- !CBS_get_u16_length_prefixed(&extensions, &extension)) {
- *out_alert = SSL_AD_DECODE_ERROR;
+static int ext_channel_id_add_serverhello(SSL *ssl, CBB *out) {
+ if (!ssl->s3->tlsext_channel_id_valid) {
+ return 1;
+ }
+
+ if (!CBB_add_u16(out, TLSEXT_TYPE_channel_id) ||
+ !CBB_add_u16(out, 0 /* length */)) {
+ return 0;
+ }
+
+ return 1;
+}
+
+
+/* Secure Real-time Transport Protocol (SRTP) extension.
+ *
+ * https://tools.ietf.org/html/rfc5764 */
+
+
+static void ext_srtp_init(SSL *ssl) {
+ ssl->srtp_profile = NULL;
+}
+
+static int ext_srtp_add_clienthello(SSL *ssl, CBB *out) {
+ STACK_OF(SRTP_PROTECTION_PROFILE) *profiles = SSL_get_srtp_profiles(ssl);
+ if (profiles == NULL) {
+ return 1;
+ }
+ const size_t num_profiles = sk_SRTP_PROTECTION_PROFILE_num(profiles);
+ if (num_profiles == 0) {
+ return 1;
+ }
+
+ CBB contents, profile_ids;
+ if (!CBB_add_u16(out, TLSEXT_TYPE_srtp) ||
+ !CBB_add_u16_length_prefixed(out, &contents) ||
+ !CBB_add_u16_length_prefixed(&contents, &profile_ids)) {
+ return 0;
+ }
+
+ size_t i;
+ for (i = 0; i < num_profiles; i++) {
+ if (!CBB_add_u16(&profile_ids,
+ sk_SRTP_PROTECTION_PROFILE_value(profiles, i)->id)) {
return 0;
}
+ }
- /* The servername extension is treated as follows:
-
- - Only the hostname type is supported with a maximum length of 255.
- - The servername is rejected if too long or if it contains zeros, in
- which case an fatal alert is generated.
- - The servername field is maintained together with the session cache.
- - When a session is resumed, the servername call back invoked in order
- to allow the application to position itself to the right context.
- - The servername is acknowledged if it is new for a session or when
- it is identical to a previously used for the same session.
- Applications can control the behaviour. They can at any time
- set a 'desirable' servername for a new SSL object. This can be the
- case for example with HTTPS when a Host: header field is received and
- a renegotiation is requested. In this case, a possible servername
- presented in the new client hello is only acknowledged if it matches
- the value of the Host: field.
- - Applications must use SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION
- if they provide for changing an explicit servername context for the
- session,
- i.e. when the session has been established with a servername extension.
- - On session reconnect, the servername extension may be absent. */
-
- if (type == TLSEXT_TYPE_server_name) {
- CBS server_name_list;
- char have_seen_host_name = 0;
-
- if (!CBS_get_u16_length_prefixed(&extension, &server_name_list) ||
- CBS_len(&server_name_list) < 1 || CBS_len(&extension) != 0) {
- *out_alert = SSL_AD_DECODE_ERROR;
- return 0;
- }
+ if (!CBB_add_u8(&contents, 0 /* empty use_mki value */) ||
+ !CBB_flush(out)) {
+ return 0;
+ }
- /* Decode each ServerName in the extension. */
- while (CBS_len(&server_name_list) > 0) {
- uint8_t name_type;
- CBS host_name;
+ return 1;
+}
- /* Decode the NameType. */
- if (!CBS_get_u8(&server_name_list, &name_type)) {
- *out_alert = SSL_AD_DECODE_ERROR;
- return 0;
- }
+static int ext_srtp_parse_serverhello(SSL *ssl, uint8_t *out_alert,
+ CBS *contents) {
+ if (contents == NULL) {
+ return 1;
+ }
- /* Only host_name is supported. */
- if (name_type != TLSEXT_NAMETYPE_host_name) {
- continue;
- }
+ /* The extension consists of a u16-prefixed profile ID list containing a
+ * single uint16_t profile ID, then followed by a u8-prefixed srtp_mki field.
+ *
+ * See https://tools.ietf.org/html/rfc5764#section-4.1.1 */
+ CBS profile_ids, srtp_mki;
+ uint16_t profile_id;
+ if (!CBS_get_u16_length_prefixed(contents, &profile_ids) ||
+ !CBS_get_u16(&profile_ids, &profile_id) ||
+ CBS_len(&profile_ids) != 0 ||
+ !CBS_get_u8_length_prefixed(contents, &srtp_mki) ||
+ CBS_len(contents) != 0) {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_SRTP_PROTECTION_PROFILE_LIST);
+ return 0;
+ }
- if (have_seen_host_name) {
- /* The ServerNameList MUST NOT contain more than one name of the same
- * name_type. */
- *out_alert = SSL_AD_DECODE_ERROR;
- return 0;
- }
+ if (CBS_len(&srtp_mki) != 0) {
+ /* Must be no MKI, since we never offer one. */
+ OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_SRTP_MKI_VALUE);
+ *out_alert = SSL_AD_ILLEGAL_PARAMETER;
+ return 0;
+ }
- have_seen_host_name = 1;
+ STACK_OF(SRTP_PROTECTION_PROFILE) *profiles = SSL_get_srtp_profiles(ssl);
- if (!CBS_get_u16_length_prefixed(&server_name_list, &host_name) ||
- CBS_len(&host_name) < 1) {
- *out_alert = SSL_AD_DECODE_ERROR;
- return 0;
- }
+ /* Check to see if the server gave us something we support (and presumably
+ * offered). */
+ size_t i;
+ for (i = 0; i < sk_SRTP_PROTECTION_PROFILE_num(profiles); i++) {
+ const SRTP_PROTECTION_PROFILE *profile =
+ sk_SRTP_PROTECTION_PROFILE_value(profiles, i);
- if (CBS_len(&host_name) > TLSEXT_MAXLEN_host_name ||
- CBS_contains_zero_byte(&host_name)) {
- *out_alert = SSL_AD_UNRECOGNIZED_NAME;
- return 0;
- }
+ if (profile->id == profile_id) {
+ ssl->srtp_profile = profile;
+ return 1;
+ }
+ }
- if (!s->hit) {
- assert(s->session->tlsext_hostname == NULL);
- if (s->session->tlsext_hostname) {
- /* This should be impossible. */
- *out_alert = SSL_AD_DECODE_ERROR;
- return 0;
- }
-
- /* Copy the hostname as a string. */
- if (!CBS_strdup(&host_name, &s->session->tlsext_hostname)) {
- *out_alert = SSL_AD_INTERNAL_ERROR;
- return 0;
- }
-
- s->should_ack_sni = 1;
- }
- }
- } else if (type == TLSEXT_TYPE_ec_point_formats) {
- CBS ec_point_format_list;
+ OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_SRTP_PROTECTION_PROFILE_LIST);
+ *out_alert = SSL_AD_ILLEGAL_PARAMETER;
+ return 0;
+}
- if (!CBS_get_u8_length_prefixed(&extension, &ec_point_format_list) ||
- CBS_len(&extension) != 0) {
- *out_alert = SSL_AD_DECODE_ERROR;
- return 0;
- }
+static int ext_srtp_parse_clienthello(SSL *ssl, uint8_t *out_alert,
+ CBS *contents) {
+ if (contents == NULL) {
+ return 1;
+ }
- if (!CBS_stow(&ec_point_format_list, &s->s3->tmp.peer_ecpointformatlist,
- &s->s3->tmp.peer_ecpointformatlist_length)) {
- *out_alert = SSL_AD_INTERNAL_ERROR;
- return 0;
- }
- } else if (type == TLSEXT_TYPE_elliptic_curves) {
- CBS elliptic_curve_list;
- size_t i, num_curves;
-
- if (!CBS_get_u16_length_prefixed(&extension, &elliptic_curve_list) ||
- CBS_len(&elliptic_curve_list) == 0 ||
- (CBS_len(&elliptic_curve_list) & 1) != 0 ||
- CBS_len(&extension) != 0) {
- *out_alert = SSL_AD_DECODE_ERROR;
- return 0;
- }
+ CBS profile_ids, srtp_mki;
+ if (!CBS_get_u16_length_prefixed(contents, &profile_ids) ||
+ CBS_len(&profile_ids) < 2 ||
+ !CBS_get_u8_length_prefixed(contents, &srtp_mki) ||
+ CBS_len(contents) != 0) {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_SRTP_PROTECTION_PROFILE_LIST);
+ return 0;
+ }
+ /* Discard the MKI value for now. */
- OPENSSL_free(s->s3->tmp.peer_ellipticcurvelist);
- s->s3->tmp.peer_ellipticcurvelist_length = 0;
+ const STACK_OF(SRTP_PROTECTION_PROFILE) *server_profiles =
+ SSL_get_srtp_profiles(ssl);
- s->s3->tmp.peer_ellipticcurvelist =
- (uint16_t *)OPENSSL_malloc(CBS_len(&elliptic_curve_list));
+ /* Pick the server's most preferred profile. */
+ size_t i;
+ for (i = 0; i < sk_SRTP_PROTECTION_PROFILE_num(server_profiles); i++) {
+ const SRTP_PROTECTION_PROFILE *server_profile =
+ sk_SRTP_PROTECTION_PROFILE_value(server_profiles, i);
- if (s->s3->tmp.peer_ellipticcurvelist == NULL) {
- *out_alert = SSL_AD_INTERNAL_ERROR;
+ CBS profile_ids_tmp;
+ CBS_init(&profile_ids_tmp, CBS_data(&profile_ids), CBS_len(&profile_ids));
+
+ while (CBS_len(&profile_ids_tmp) > 0) {
+ uint16_t profile_id;
+ if (!CBS_get_u16(&profile_ids_tmp, &profile_id)) {
return 0;
}
- num_curves = CBS_len(&elliptic_curve_list) / 2;
- for (i = 0; i < num_curves; i++) {
- if (!CBS_get_u16(&elliptic_curve_list,
- &s->s3->tmp.peer_ellipticcurvelist[i])) {
- *out_alert = SSL_AD_INTERNAL_ERROR;
- return 0;
- }
+ if (server_profile->id == profile_id) {
+ ssl->srtp_profile = server_profile;
+ return 1;
}
+ }
+ }
- if (CBS_len(&elliptic_curve_list) != 0) {
- *out_alert = SSL_AD_INTERNAL_ERROR;
- return 0;
- }
+ return 1;
+}
- s->s3->tmp.peer_ellipticcurvelist_length = num_curves;
- } else if (type == TLSEXT_TYPE_renegotiate) {
- if (!ssl_parse_clienthello_renegotiate_ext(s, &extension, out_alert)) {
- return 0;
- }
- renegotiate_seen = 1;
- } else if (type == TLSEXT_TYPE_signature_algorithms) {
- CBS supported_signature_algorithms;
+static int ext_srtp_add_serverhello(SSL *ssl, CBB *out) {
+ if (ssl->srtp_profile == NULL) {
+ return 1;
+ }
- if (!CBS_get_u16_length_prefixed(&extension,
- &supported_signature_algorithms) ||
- CBS_len(&extension) != 0) {
- *out_alert = SSL_AD_DECODE_ERROR;
- return 0;
- }
+ CBB contents, profile_ids;
+ if (!CBB_add_u16(out, TLSEXT_TYPE_srtp) ||
+ !CBB_add_u16_length_prefixed(out, &contents) ||
+ !CBB_add_u16_length_prefixed(&contents, &profile_ids) ||
+ !CBB_add_u16(&profile_ids, ssl->srtp_profile->id) ||
+ !CBB_add_u8(&contents, 0 /* empty MKI */) ||
+ !CBB_flush(out)) {
+ return 0;
+ }
- /* Ensure the signature algorithms are non-empty. It contains a list of
- * SignatureAndHashAlgorithms which are two bytes each. */
- if (CBS_len(&supported_signature_algorithms) == 0 ||
- (CBS_len(&supported_signature_algorithms) % 2) != 0) {
- *out_alert = SSL_AD_DECODE_ERROR;
- return 0;
- }
+ return 1;
+}
- if (!tls1_process_sigalgs(s, &supported_signature_algorithms)) {
- *out_alert = SSL_AD_DECODE_ERROR;
- return 0;
- }
- /* If sigalgs received and no shared algorithms fatal error. */
- if (s->cert->peer_sigalgs && !s->cert->shared_sigalgs) {
- OPENSSL_PUT_ERROR(SSL, ssl_scan_clienthello_tlsext,
- SSL_R_NO_SHARED_SIGATURE_ALGORITHMS);
- *out_alert = SSL_AD_ILLEGAL_PARAMETER;
- return 0;
- }
- } else if (type == TLSEXT_TYPE_next_proto_neg &&
- !s->s3->initial_handshake_complete &&
- s->s3->alpn_selected == NULL && !SSL_IS_DTLS(s)) {
- /* The extension must be empty. */
- if (CBS_len(&extension) != 0) {
- *out_alert = SSL_AD_DECODE_ERROR;
- return 0;
- }
- s->s3->next_proto_neg_seen = 1;
- } else if (type == TLSEXT_TYPE_application_layer_protocol_negotiation &&
- s->ctx->alpn_select_cb && !s->s3->initial_handshake_complete) {
- if (!tls1_alpn_handle_client_hello(s, &extension, out_alert)) {
- return 0;
- }
- /* ALPN takes precedence over NPN. */
- s->s3->next_proto_neg_seen = 0;
- } else if (type == TLSEXT_TYPE_channel_id && s->tlsext_channel_id_enabled &&
- !SSL_IS_DTLS(s)) {
- /* The extension must be empty. */
- if (CBS_len(&extension) != 0) {
- *out_alert = SSL_AD_DECODE_ERROR;
- return 0;
- }
- s->s3->tlsext_channel_id_valid = 1;
- } else if (type == TLSEXT_TYPE_channel_id_new &&
- s->tlsext_channel_id_enabled && !SSL_IS_DTLS(s)) {
- /* The extension must be empty. */
- if (CBS_len(&extension) != 0) {
- *out_alert = SSL_AD_DECODE_ERROR;
- return 0;
- }
+/* EC point formats.
+ *
+ * https://tools.ietf.org/html/rfc4492#section-5.1.2 */
- s->s3->tlsext_channel_id_valid = 1;
- s->s3->tlsext_channel_id_new = 1;
- } else if (type == TLSEXT_TYPE_use_srtp) {
- if (!ssl_parse_clienthello_use_srtp_ext(s, &extension, out_alert)) {
- return 0;
- }
- } else if (type == TLSEXT_TYPE_extended_master_secret &&
- s->version != SSL3_VERSION) {
- if (CBS_len(&extension) != 0) {
- *out_alert = SSL_AD_DECODE_ERROR;
- return 0;
- }
+static int ssl_any_ec_cipher_suites_enabled(const SSL *ssl) {
+ if (ssl->version < TLS1_VERSION && !SSL_IS_DTLS(ssl)) {
+ return 0;
+ }
+
+ const STACK_OF(SSL_CIPHER) *cipher_stack = SSL_get_ciphers(ssl);
+
+ size_t i;
+ for (i = 0; i < sk_SSL_CIPHER_num(cipher_stack); i++) {
+ const SSL_CIPHER *cipher = sk_SSL_CIPHER_value(cipher_stack, i);
- s->s3->tmp.extended_master_secret = 1;
+ const uint32_t alg_k = cipher->algorithm_mkey;
+ const uint32_t alg_a = cipher->algorithm_auth;
+ if ((alg_k & SSL_kECDHE) || (alg_a & SSL_aECDSA)) {
+ return 1;
}
}
-ri_check:
- /* Need RI if renegotiating */
+ return 0;
+}
- if (!renegotiate_seen && s->s3->initial_handshake_complete &&
- !(s->options & SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION)) {
- *out_alert = SSL_AD_HANDSHAKE_FAILURE;
- OPENSSL_PUT_ERROR(SSL, ssl_scan_clienthello_tlsext,
- SSL_R_UNSAFE_LEGACY_RENEGOTIATION_DISABLED);
+static int ext_ec_point_add_extension(SSL *ssl, CBB *out) {
+ CBB contents, formats;
+ if (!CBB_add_u16(out, TLSEXT_TYPE_ec_point_formats) ||
+ !CBB_add_u16_length_prefixed(out, &contents) ||
+ !CBB_add_u8_length_prefixed(&contents, &formats) ||
+ !CBB_add_u8(&formats, TLSEXT_ECPOINTFORMAT_uncompressed) ||
+ !CBB_flush(out)) {
return 0;
}
return 1;
}
-int ssl_parse_clienthello_tlsext(SSL *s, CBS *cbs) {
- int alert = -1;
- if (ssl_scan_clienthello_tlsext(s, cbs, &alert) <= 0) {
- ssl3_send_alert(s, SSL3_AL_FATAL, alert);
+static int ext_ec_point_add_clienthello(SSL *ssl, CBB *out) {
+ if (!ssl_any_ec_cipher_suites_enabled(ssl)) {
+ return 1;
+ }
+
+ return ext_ec_point_add_extension(ssl, out);
+}
+
+static int ext_ec_point_parse_serverhello(SSL *ssl, uint8_t *out_alert,
+ CBS *contents) {
+ if (contents == NULL) {
+ return 1;
+ }
+
+ CBS ec_point_format_list;
+ if (!CBS_get_u8_length_prefixed(contents, &ec_point_format_list) ||
+ CBS_len(contents) != 0) {
return 0;
}
- if (ssl_check_clienthello_tlsext(s) <= 0) {
- OPENSSL_PUT_ERROR(SSL, ssl_parse_clienthello_tlsext,
- SSL_R_CLIENTHELLO_TLSEXT);
+ /* Per RFC 4492, section 5.1.2, implementations MUST support the uncompressed
+ * point format. */
+ if (memchr(CBS_data(&ec_point_format_list), TLSEXT_ECPOINTFORMAT_uncompressed,
+ CBS_len(&ec_point_format_list)) == NULL) {
+ *out_alert = SSL_AD_ILLEGAL_PARAMETER;
return 0;
}
return 1;
}
-/* ssl_next_proto_validate validates a Next Protocol Negotiation block. No
- * elements of zero length are allowed and the set of elements must exactly
- * fill the length of the block. */
-static char ssl_next_proto_validate(const CBS *cbs) {
- CBS copy = *cbs;
+static int ext_ec_point_parse_clienthello(SSL *ssl, uint8_t *out_alert,
+ CBS *contents) {
+ return ext_ec_point_parse_serverhello(ssl, out_alert, contents);
+}
+
+static int ext_ec_point_add_serverhello(SSL *ssl, CBB *out) {
+ const uint32_t alg_k = ssl->s3->tmp.new_cipher->algorithm_mkey;
+ const uint32_t alg_a = ssl->s3->tmp.new_cipher->algorithm_auth;
+ const int using_ecc = (alg_k & SSL_kECDHE) || (alg_a & SSL_aECDSA);
- while (CBS_len(&copy) != 0) {
- CBS proto;
- if (!CBS_get_u8_length_prefixed(&copy, &proto) || CBS_len(&proto) == 0) {
+ if (!using_ecc) {
+ return 1;
+ }
+
+ return ext_ec_point_add_extension(ssl, out);
+}
+
+
+/* EC supported curves.
+ *
+ * https://tools.ietf.org/html/rfc4492#section-5.1.2 */
+
+static void ext_ec_curves_init(SSL *ssl) {
+ OPENSSL_free(ssl->s3->tmp.peer_ellipticcurvelist);
+ ssl->s3->tmp.peer_ellipticcurvelist = NULL;
+ ssl->s3->tmp.peer_ellipticcurvelist_length = 0;
+}
+
+static int ext_ec_curves_add_clienthello(SSL *ssl, CBB *out) {
+ if (!ssl_any_ec_cipher_suites_enabled(ssl)) {
+ return 1;
+ }
+
+ CBB contents, curves_bytes;
+ if (!CBB_add_u16(out, TLSEXT_TYPE_elliptic_curves) ||
+ !CBB_add_u16_length_prefixed(out, &contents) ||
+ !CBB_add_u16_length_prefixed(&contents, &curves_bytes)) {
+ return 0;
+ }
+
+ const uint16_t *curves;
+ size_t curves_len;
+ tls1_get_curvelist(ssl, 0, &curves, &curves_len);
+
+ size_t i;
+ for (i = 0; i < curves_len; i++) {
+ if (!CBB_add_u16(&curves_bytes, curves[i])) {
return 0;
}
}
+ return CBB_flush(out);
+}
+
+static int ext_ec_curves_parse_serverhello(SSL *ssl, uint8_t *out_alert,
+ CBS *contents) {
+ /* This extension is not expected to be echoed by servers and is ignored. */
return 1;
}
-static int ssl_scan_serverhello_tlsext(SSL *s, CBS *cbs, int *out_alert) {
- int tlsext_servername = 0;
- int renegotiate_seen = 0;
- CBS extensions;
+static int ext_ec_curves_parse_clienthello(SSL *ssl, uint8_t *out_alert,
+ CBS *contents) {
+ if (contents == NULL) {
+ return 1;
+ }
- /* TODO(davidben): Move all of these to some per-handshake state that gets
- * systematically reset on a new handshake; perhaps allocate it fresh each
- * time so it's not even kept around post-handshake. */
- s->s3->next_proto_neg_seen = 0;
- s->tlsext_ticket_expected = 0;
- s->s3->tmp.certificate_status_expected = 0;
- s->s3->tmp.extended_master_secret = 0;
- s->srtp_profile = NULL;
+ CBS elliptic_curve_list;
+ if (!CBS_get_u16_length_prefixed(contents, &elliptic_curve_list) ||
+ CBS_len(&elliptic_curve_list) == 0 ||
+ (CBS_len(&elliptic_curve_list) & 1) != 0 ||
+ CBS_len(contents) != 0) {
+ return 0;
+ }
- OPENSSL_free(s->s3->alpn_selected);
- s->s3->alpn_selected = NULL;
+ ssl->s3->tmp.peer_ellipticcurvelist =
+ (uint16_t *)OPENSSL_malloc(CBS_len(&elliptic_curve_list));
- /* Clear ECC extensions */
- OPENSSL_free(s->s3->tmp.peer_ecpointformatlist);
- s->s3->tmp.peer_ecpointformatlist = NULL;
- s->s3->tmp.peer_ecpointformatlist_length = 0;
+ if (ssl->s3->tmp.peer_ellipticcurvelist == NULL) {
+ *out_alert = SSL_AD_INTERNAL_ERROR;
+ return 0;
+ }
- /* There may be no extensions. */
- if (CBS_len(cbs) == 0) {
- goto ri_check;
+ const size_t num_curves = CBS_len(&elliptic_curve_list) / 2;
+ size_t i;
+ for (i = 0; i < num_curves; i++) {
+ if (!CBS_get_u16(&elliptic_curve_list,
+ &ssl->s3->tmp.peer_ellipticcurvelist[i])) {
+ goto err;
+ }
}
- /* Decode the extensions block and check it is valid. */
- if (!CBS_get_u16_length_prefixed(cbs, &extensions) ||
- !tls1_check_duplicate_extensions(&extensions)) {
- *out_alert = SSL_AD_DECODE_ERROR;
- return 0;
+ assert(CBS_len(&elliptic_curve_list) == 0);
+ ssl->s3->tmp.peer_ellipticcurvelist_length = num_curves;
+
+ return 1;
+
+err:
+ OPENSSL_free(ssl->s3->tmp.peer_ellipticcurvelist);
+ ssl->s3->tmp.peer_ellipticcurvelist = NULL;
+ *out_alert = SSL_AD_INTERNAL_ERROR;
+ return 0;
+}
+
+static int ext_ec_curves_add_serverhello(SSL *ssl, CBB *out) {
+ /* Servers don't echo this extension. */
+ return 1;
+}
+
+
+/* kExtensions contains all the supported extensions. */
+static const struct tls_extension kExtensions[] = {
+ {
+ /* The renegotiation extension must always be at index zero because the
+ * |received| and |sent| bitsets need to be tweaked when the "extension" is
+ * sent as an SCSV. */
+ TLSEXT_TYPE_renegotiate,
+ NULL,
+ ext_ri_add_clienthello,
+ ext_ri_parse_serverhello,
+ ext_ri_parse_clienthello,
+ ext_ri_add_serverhello,
+ },
+ {
+ TLSEXT_TYPE_server_name,
+ ext_sni_init,
+ ext_sni_add_clienthello,
+ ext_sni_parse_serverhello,
+ ext_sni_parse_clienthello,
+ ext_sni_add_serverhello,
+ },
+ {
+ TLSEXT_TYPE_extended_master_secret,
+ ext_ems_init,
+ ext_ems_add_clienthello,
+ ext_ems_parse_serverhello,
+ ext_ems_parse_clienthello,
+ ext_ems_add_serverhello,
+ },
+ {
+ TLSEXT_TYPE_session_ticket,
+ NULL,
+ ext_ticket_add_clienthello,
+ ext_ticket_parse_serverhello,
+ ext_ticket_parse_clienthello,
+ ext_ticket_add_serverhello,
+ },
+ {
+ TLSEXT_TYPE_signature_algorithms,
+ NULL,
+ ext_sigalgs_add_clienthello,
+ ext_sigalgs_parse_serverhello,
+ ext_sigalgs_parse_clienthello,
+ ext_sigalgs_add_serverhello,
+ },
+ {
+ TLSEXT_TYPE_status_request,
+ ext_ocsp_init,
+ ext_ocsp_add_clienthello,
+ ext_ocsp_parse_serverhello,
+ ext_ocsp_parse_clienthello,
+ ext_ocsp_add_serverhello,
+ },
+ {
+ TLSEXT_TYPE_next_proto_neg,
+ ext_npn_init,
+ ext_npn_add_clienthello,
+ ext_npn_parse_serverhello,
+ ext_npn_parse_clienthello,
+ ext_npn_add_serverhello,
+ },
+ {
+ TLSEXT_TYPE_certificate_timestamp,
+ NULL,
+ ext_sct_add_clienthello,
+ ext_sct_parse_serverhello,
+ ext_sct_parse_clienthello,
+ ext_sct_add_serverhello,
+ },
+ {
+ TLSEXT_TYPE_application_layer_protocol_negotiation,
+ ext_alpn_init,
+ ext_alpn_add_clienthello,
+ ext_alpn_parse_serverhello,
+ ext_alpn_parse_clienthello,
+ ext_alpn_add_serverhello,
+ },
+ {
+ TLSEXT_TYPE_channel_id,
+ ext_channel_id_init,
+ ext_channel_id_add_clienthello,
+ ext_channel_id_parse_serverhello,
+ ext_channel_id_parse_clienthello,
+ ext_channel_id_add_serverhello,
+ },
+ {
+ TLSEXT_TYPE_srtp,
+ ext_srtp_init,
+ ext_srtp_add_clienthello,
+ ext_srtp_parse_serverhello,
+ ext_srtp_parse_clienthello,
+ ext_srtp_add_serverhello,
+ },
+ {
+ TLSEXT_TYPE_ec_point_formats,
+ NULL,
+ ext_ec_point_add_clienthello,
+ ext_ec_point_parse_serverhello,
+ ext_ec_point_parse_clienthello,
+ ext_ec_point_add_serverhello,
+ },
+ {
+ TLSEXT_TYPE_elliptic_curves,
+ ext_ec_curves_init,
+ ext_ec_curves_add_clienthello,
+ ext_ec_curves_parse_serverhello,
+ ext_ec_curves_parse_clienthello,
+ ext_ec_curves_add_serverhello,
+ },
+};
+
+#define kNumExtensions (sizeof(kExtensions) / sizeof(struct tls_extension))
+
+OPENSSL_COMPILE_ASSERT(kNumExtensions <=
+ sizeof(((SSL *)NULL)->s3->tmp.extensions.sent) * 8,
+ too_many_extensions_for_sent_bitset);
+OPENSSL_COMPILE_ASSERT(kNumExtensions <=
+ sizeof(((SSL *)NULL)->s3->tmp.extensions.received) *
+ 8,
+ too_many_extensions_for_received_bitset);
+
+static const struct tls_extension *tls_extension_find(uint32_t *out_index,
+ uint16_t value) {
+ unsigned i;
+ for (i = 0; i < kNumExtensions; i++) {
+ if (kExtensions[i].value == value) {
+ *out_index = i;
+ return &kExtensions[i];
+ }
}
- while (CBS_len(&extensions) != 0) {
- uint16_t type;
- CBS extension;
+ return NULL;
+}
- /* Decode the next extension. */
- if (!CBS_get_u16(&extensions, &type) ||
- !CBS_get_u16_length_prefixed(&extensions, &extension)) {
- *out_alert = SSL_AD_DECODE_ERROR;
- return 0;
+int SSL_extension_supported(unsigned extension_value) {
+ uint32_t index;
+ return extension_value == TLSEXT_TYPE_padding ||
+ tls_extension_find(&index, extension_value) != NULL;
+}
+
+/* header_len is the length of the ClientHello header written so far, used to
+ * compute padding. It does not include the record header. Pass 0 if no padding
+ * is to be done. */
+uint8_t *ssl_add_clienthello_tlsext(SSL *s, uint8_t *const buf,
+ uint8_t *const limit, size_t header_len) {
+ /* don't add extensions for SSLv3 unless doing secure renegotiation */
+ if (s->client_version == SSL3_VERSION && !s->s3->send_connection_binding) {
+ return buf;
+ }
+
+ CBB cbb, extensions;
+ CBB_zero(&cbb);
+ if (!CBB_init_fixed(&cbb, buf, limit - buf) ||
+ !CBB_add_u16_length_prefixed(&cbb, &extensions)) {
+ goto err;
+ }
+
+ s->s3->tmp.extensions.sent = 0;
+ s->s3->tmp.custom_extensions.sent = 0;
+
+ size_t i;
+ for (i = 0; i < kNumExtensions; i++) {
+ if (kExtensions[i].init != NULL) {
+ kExtensions[i].init(s);
}
+ }
- if (type == TLSEXT_TYPE_server_name) {
- /* The extension must be empty. */
- if (CBS_len(&extension) != 0) {
- *out_alert = SSL_AD_DECODE_ERROR;
- return 0;
+ for (i = 0; i < kNumExtensions; i++) {
+ const size_t len_before = CBB_len(&extensions);
+ if (!kExtensions[i].add_clienthello(s, &extensions)) {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_ERROR_ADDING_EXTENSION);
+ ERR_add_error_dataf("extension: %u", (unsigned)kExtensions[i].value);
+ goto err;
+ }
+
+ if (CBB_len(&extensions) != len_before) {
+ s->s3->tmp.extensions.sent |= (1u << i);
+ }
+ }
+
+ if (!custom_ext_add_clienthello(s, &extensions)) {
+ goto err;
+ }
+
+ if (header_len > 0) {
+ header_len += CBB_len(&extensions);
+ if (header_len > 0xff && header_len < 0x200) {
+ /* Add padding to workaround bugs in F5 terminators. See
+ * https://tools.ietf.org/html/draft-agl-tls-padding-03
+ *
+ * NB: because this code works out the length of all existing extensions
+ * it MUST always appear last. */
+ size_t padding_len = 0x200 - header_len;
+ /* Extensions take at least four bytes to encode. Always include least
+ * one byte of data if including the extension. WebSphere Application
+ * Server 7.0 is intolerant to the last extension being zero-length. */
+ if (padding_len >= 4 + 1) {
+ padding_len -= 4;
+ } else {
+ padding_len = 1;
}
- /* We must have sent it in ClientHello. */
- if (s->tlsext_hostname == NULL) {
- *out_alert = SSL_AD_UNSUPPORTED_EXTENSION;
- return 0;
+ uint8_t *padding_bytes;
+ if (!CBB_add_u16(&extensions, TLSEXT_TYPE_padding) ||
+ !CBB_add_u16(&extensions, padding_len) ||
+ !CBB_add_space(&extensions, &padding_bytes, padding_len)) {
+ goto err;
}
- tlsext_servername = 1;
- } else if (type == TLSEXT_TYPE_ec_point_formats) {
- CBS ec_point_format_list;
+ memset(padding_bytes, 0, padding_len);
+ }
+ }
+
+ if (!CBB_flush(&cbb)) {
+ goto err;
+ }
+
+ uint8_t *ret = buf;
+ const size_t cbb_len = CBB_len(&cbb);
+ /* If only two bytes have been written then the extensions are actually empty
+ * and those two bytes are the zero length. In that case, we don't bother
+ * sending the extensions length. */
+ if (cbb_len > 2) {
+ ret += cbb_len;
+ }
+
+ CBB_cleanup(&cbb);
+ return ret;
+
+err:
+ CBB_cleanup(&cbb);
+ OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
+ return NULL;
+}
+
+uint8_t *ssl_add_serverhello_tlsext(SSL *s, uint8_t *const buf,
+ uint8_t *const limit) {
+ /* don't add extensions for SSLv3, unless doing secure renegotiation */
+ if (s->version == SSL3_VERSION && !s->s3->send_connection_binding) {
+ return buf;
+ }
+
+ CBB cbb, extensions;
+ CBB_zero(&cbb);
+ if (!CBB_init_fixed(&cbb, buf, limit - buf) ||
+ !CBB_add_u16_length_prefixed(&cbb, &extensions)) {
+ goto err;
+ }
+
+ unsigned i;
+ for (i = 0; i < kNumExtensions; i++) {
+ if (!(s->s3->tmp.extensions.received & (1u << i))) {
+ /* Don't send extensions that were not received. */
+ continue;
+ }
+
+ if (!kExtensions[i].add_serverhello(s, &extensions)) {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_ERROR_ADDING_EXTENSION);
+ ERR_add_error_dataf("extension: %u", (unsigned)kExtensions[i].value);
+ goto err;
+ }
+ }
+
+ if (!custom_ext_add_serverhello(s, &extensions)) {
+ goto err;
+ }
+
+ if (!CBB_flush(&cbb)) {
+ goto err;
+ }
+
+ uint8_t *ret = buf;
+ const size_t cbb_len = CBB_len(&cbb);
+ /* If only two bytes have been written then the extensions are actually empty
+ * and those two bytes are the zero length. In that case, we don't bother
+ * sending the extensions length. */
+ if (cbb_len > 2) {
+ ret += cbb_len;
+ }
+
+ CBB_cleanup(&cbb);
+ return ret;
+
+err:
+ CBB_cleanup(&cbb);
+ OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
+ return NULL;
+}
+
+static int ssl_scan_clienthello_tlsext(SSL *s, CBS *cbs, int *out_alert) {
+ size_t i;
+ for (i = 0; i < kNumExtensions; i++) {
+ if (kExtensions[i].init != NULL) {
+ kExtensions[i].init(s);
+ }
+ }
+
+ s->s3->tmp.extensions.received = 0;
+ s->s3->tmp.custom_extensions.received = 0;
+ /* The renegotiation extension must always be at index zero because the
+ * |received| and |sent| bitsets need to be tweaked when the "extension" is
+ * sent as an SCSV. */
+ assert(kExtensions[0].value == TLSEXT_TYPE_renegotiate);
- if (!CBS_get_u8_length_prefixed(&extension, &ec_point_format_list) ||
- CBS_len(&extension) != 0) {
+ /* There may be no extensions. */
+ if (CBS_len(cbs) != 0) {
+ /* Decode the extensions block and check it is valid. */
+ CBS extensions;
+ if (!CBS_get_u16_length_prefixed(cbs, &extensions) ||
+ !tls1_check_duplicate_extensions(&extensions)) {
+ *out_alert = SSL_AD_DECODE_ERROR;
+ return 0;
+ }
+
+ while (CBS_len(&extensions) != 0) {
+ uint16_t type;
+ CBS extension;
+
+ /* Decode the next extension. */
+ if (!CBS_get_u16(&extensions, &type) ||
+ !CBS_get_u16_length_prefixed(&extensions, &extension)) {
*out_alert = SSL_AD_DECODE_ERROR;
return 0;
}
- if (!CBS_stow(&ec_point_format_list, &s->s3->tmp.peer_ecpointformatlist,
- &s->s3->tmp.peer_ecpointformatlist_length)) {
- *out_alert = SSL_AD_INTERNAL_ERROR;
- return 0;
- }
- } else if (type == TLSEXT_TYPE_session_ticket) {
- if ((SSL_get_options(s) & SSL_OP_NO_TICKET) || CBS_len(&extension) > 0) {
- *out_alert = SSL_AD_UNSUPPORTED_EXTENSION;
- return 0;
+ unsigned ext_index;
+ const struct tls_extension *const ext =
+ tls_extension_find(&ext_index, type);
+
+ if (ext == NULL) {
+ if (!custom_ext_parse_clienthello(s, out_alert, type, &extension)) {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_ERROR_PARSING_EXTENSION);
+ return 0;
+ }
+ continue;
}
- s->tlsext_ticket_expected = 1;
- } else if (type == TLSEXT_TYPE_status_request) {
- /* The extension MUST be empty and may only sent if we've requested a
- * status request message. */
- if (CBS_len(&extension) != 0) {
- *out_alert = SSL_AD_DECODE_ERROR;
+ s->s3->tmp.extensions.received |= (1u << ext_index);
+ uint8_t alert = SSL_AD_DECODE_ERROR;
+ if (!ext->parse_clienthello(s, &alert, &extension)) {
+ *out_alert = alert;
+ OPENSSL_PUT_ERROR(SSL, SSL_R_ERROR_PARSING_EXTENSION);
+ ERR_add_error_dataf("extension: %u", (unsigned)type);
return 0;
}
+ }
+ }
- if (!s->ocsp_stapling_enabled) {
- *out_alert = SSL_AD_UNSUPPORTED_EXTENSION;
+ for (i = 0; i < kNumExtensions; i++) {
+ if (!(s->s3->tmp.extensions.received & (1u << i))) {
+ /* Extension wasn't observed so call the callback with a NULL
+ * parameter. */
+ uint8_t alert = SSL_AD_DECODE_ERROR;
+ if (!kExtensions[i].parse_clienthello(s, &alert, NULL)) {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_MISSING_EXTENSION);
+ ERR_add_error_dataf("extension: %u", (unsigned)kExtensions[i].value);
+ *out_alert = alert;
return 0;
}
+ }
+ }
- /* Set a flag to expect a CertificateStatus message */
- s->s3->tmp.certificate_status_expected = 1;
- } else if (type == TLSEXT_TYPE_next_proto_neg &&
- !s->s3->initial_handshake_complete && !SSL_IS_DTLS(s)) {
- uint8_t *selected;
- uint8_t selected_len;
+ return 1;
+}
- /* We must have requested it. */
- if (s->ctx->next_proto_select_cb == NULL) {
- *out_alert = SSL_AD_UNSUPPORTED_EXTENSION;
- return 0;
- }
+int ssl_parse_clienthello_tlsext(SSL *s, CBS *cbs) {
+ int alert = -1;
+ if (ssl_scan_clienthello_tlsext(s, cbs, &alert) <= 0) {
+ ssl3_send_alert(s, SSL3_AL_FATAL, alert);
+ return 0;
+ }
- /* The data must be valid. */
- if (!ssl_next_proto_validate(&extension)) {
- *out_alert = SSL_AD_DECODE_ERROR;
- return 0;
- }
+ if (ssl_check_clienthello_tlsext(s) <= 0) {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_CLIENTHELLO_TLSEXT);
+ return 0;
+ }
- if (s->ctx->next_proto_select_cb(
- s, &selected, &selected_len, CBS_data(&extension),
- CBS_len(&extension),
- s->ctx->next_proto_select_cb_arg) != SSL_TLSEXT_ERR_OK) {
- *out_alert = SSL_AD_INTERNAL_ERROR;
- return 0;
- }
+ return 1;
+}
- s->next_proto_negotiated = BUF_memdup(selected, selected_len);
- if (s->next_proto_negotiated == NULL) {
- *out_alert = SSL_AD_INTERNAL_ERROR;
- return 0;
- }
+static int ssl_scan_serverhello_tlsext(SSL *s, CBS *cbs, int *out_alert) {
+ uint32_t received = 0;
+ assert(kNumExtensions <= sizeof(received) * 8);
+
+ if (CBS_len(cbs) != 0) {
+ /* Decode the extensions block and check it is valid. */
+ CBS extensions;
+ if (!CBS_get_u16_length_prefixed(cbs, &extensions) ||
+ !tls1_check_duplicate_extensions(&extensions)) {
+ *out_alert = SSL_AD_DECODE_ERROR;
+ return 0;
+ }
- s->next_proto_negotiated_len = selected_len;
- s->s3->next_proto_neg_seen = 1;
- } else if (type == TLSEXT_TYPE_application_layer_protocol_negotiation &&
- !s->s3->initial_handshake_complete) {
- CBS protocol_name_list, protocol_name;
- /* We must have requested it. */
- if (s->alpn_client_proto_list == NULL) {
- *out_alert = SSL_AD_UNSUPPORTED_EXTENSION;
- return 0;
- }
+ while (CBS_len(&extensions) != 0) {
+ uint16_t type;
+ CBS extension;
- /* The extension data consists of a ProtocolNameList which must have
- * exactly one ProtocolName. Each of these is length-prefixed. */
- if (!CBS_get_u16_length_prefixed(&extension, &protocol_name_list) ||
- CBS_len(&extension) != 0 ||
- !CBS_get_u8_length_prefixed(&protocol_name_list, &protocol_name) ||
- CBS_len(&protocol_name_list) != 0) {
+ /* Decode the next extension. */
+ if (!CBS_get_u16(&extensions, &type) ||
+ !CBS_get_u16_length_prefixed(&extensions, &extension)) {
*out_alert = SSL_AD_DECODE_ERROR;
return 0;
}
- if (!CBS_stow(&protocol_name, &s->s3->alpn_selected,
- &s->s3->alpn_selected_len)) {
- *out_alert = SSL_AD_INTERNAL_ERROR;
- return 0;
- }
- } else if (type == TLSEXT_TYPE_channel_id && !SSL_IS_DTLS(s)) {
- if (CBS_len(&extension) != 0) {
- *out_alert = SSL_AD_DECODE_ERROR;
- return 0;
- }
+ unsigned ext_index;
+ const struct tls_extension *const ext =
+ tls_extension_find(&ext_index, type);
- s->s3->tlsext_channel_id_valid = 1;
- } else if (type == TLSEXT_TYPE_channel_id_new && !SSL_IS_DTLS(s)) {
- if (CBS_len(&extension) != 0) {
- *out_alert = SSL_AD_DECODE_ERROR;
- return 0;
+ if (ext == NULL) {
+ if (!custom_ext_parse_serverhello(s, out_alert, type, &extension)) {
+ return 0;
+ }
+ continue;
}
- s->s3->tlsext_channel_id_valid = 1;
- s->s3->tlsext_channel_id_new = 1;
- } else if (type == TLSEXT_TYPE_certificate_timestamp) {
- if (CBS_len(&extension) == 0) {
+ if (!(s->s3->tmp.extensions.sent & (1u << ext_index))) {
+ /* If the extension was never sent then it is illegal. */
+ OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_EXTENSION);
+ ERR_add_error_dataf("extension :%u", (unsigned)type);
*out_alert = SSL_AD_DECODE_ERROR;
return 0;
}
- /* Session resumption uses the original session information. */
- if (!s->hit &&
- !CBS_stow(&extension, &s->session->tlsext_signed_cert_timestamp_list,
- &s->session->tlsext_signed_cert_timestamp_list_length)) {
- *out_alert = SSL_AD_INTERNAL_ERROR;
- return 0;
- }
- } else if (type == TLSEXT_TYPE_renegotiate) {
- if (!ssl_parse_serverhello_renegotiate_ext(s, &extension, out_alert)) {
- return 0;
- }
+ received |= (1u << ext_index);
- renegotiate_seen = 1;
- } else if (type == TLSEXT_TYPE_use_srtp) {
- if (!ssl_parse_serverhello_use_srtp_ext(s, &extension, out_alert)) {
+ uint8_t alert = SSL_AD_DECODE_ERROR;
+ if (!ext->parse_serverhello(s, &alert, &extension)) {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_ERROR_PARSING_EXTENSION);
+ ERR_add_error_dataf("extension: %u", (unsigned)type);
+ *out_alert = alert;
return 0;
}
- } else if (type == TLSEXT_TYPE_extended_master_secret) {
- if (/* It is invalid for the server to select EMS and
- SSLv3. */
- s->version == SSL3_VERSION || CBS_len(&extension) != 0) {
- *out_alert = SSL_AD_DECODE_ERROR;
- return 0;
- }
-
- s->s3->tmp.extended_master_secret = 1;
}
}
- if (!s->hit && tlsext_servername == 1 && s->tlsext_hostname) {
- if (s->session->tlsext_hostname == NULL) {
- s->session->tlsext_hostname = BUF_strdup(s->tlsext_hostname);
- if (!s->session->tlsext_hostname) {
- *out_alert = SSL_AD_UNRECOGNIZED_NAME;
+ size_t i;
+ for (i = 0; i < kNumExtensions; i++) {
+ if (!(received & (1u << i))) {
+ /* Extension wasn't observed so call the callback with a NULL
+ * parameter. */
+ uint8_t alert = SSL_AD_DECODE_ERROR;
+ if (!kExtensions[i].parse_serverhello(s, &alert, NULL)) {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_MISSING_EXTENSION);
+ ERR_add_error_dataf("extension: %u", (unsigned)kExtensions[i].value);
+ *out_alert = alert;
return 0;
}
- } else {
- *out_alert = SSL_AD_DECODE_ERROR;
- return 0;
}
}
-ri_check:
- /* Determine if we need to see RI. Strictly speaking if we want to avoid an
- * attack we should *always* see RI even on initial server hello because the
- * client doesn't see any renegotiation during an attack. However this would
- * mean we could not connect to any server which doesn't support RI so for
- * the immediate future tolerate RI absence on initial connect only. */
- if (!renegotiate_seen && !(s->options & SSL_OP_LEGACY_SERVER_CONNECT) &&
- !(s->options & SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION)) {
- *out_alert = SSL_AD_HANDSHAKE_FAILURE;
- OPENSSL_PUT_ERROR(SSL, ssl_scan_serverhello_tlsext,
- SSL_R_UNSAFE_LEGACY_RENEGOTIATION_DISABLED);
- return 0;
- }
-
return 1;
}
-int ssl_prepare_clienthello_tlsext(SSL *s) { return 1; }
-
-int ssl_prepare_serverhello_tlsext(SSL *s) { return 1; }
-
static int ssl_check_clienthello_tlsext(SSL *s) {
int ret = SSL_TLSEXT_ERR_NOACK;
int al = SSL_AD_UNRECOGNIZED_NAME;
@@ -1947,7 +2568,7 @@ static int ssl_check_clienthello_tlsext(SSL *s) {
return 1;
case SSL_TLSEXT_ERR_NOACK:
- s->should_ack_sni = 0;
+ s->s3->tmp.should_ack_sni = 0;
return 1;
default:
@@ -1956,22 +2577,9 @@ static int ssl_check_clienthello_tlsext(SSL *s) {
}
static int ssl_check_serverhello_tlsext(SSL *s) {
- int ret = SSL_TLSEXT_ERR_NOACK;
+ int ret = SSL_TLSEXT_ERR_OK;
int al = SSL_AD_UNRECOGNIZED_NAME;
- /* If we are client and using an elliptic curve cryptography cipher suite,
- * then if server returns an EC point formats lists extension it must contain
- * uncompressed. */
- uint32_t alg_k = s->s3->tmp.new_cipher->algorithm_mkey;
- uint32_t alg_a = s->s3->tmp.new_cipher->algorithm_auth;
- if (((alg_k & SSL_kECDHE) || (alg_a & SSL_aECDSA)) &&
- !tls1_check_point_format(s, TLSEXT_ECPOINTFORMAT_uncompressed)) {
- OPENSSL_PUT_ERROR(SSL, ssl_check_serverhello_tlsext,
- SSL_R_TLS_INVALID_ECPOINTFORMAT_LIST);
- return -1;
- }
- ret = SSL_TLSEXT_ERR_OK;
-
if (s->ctx != NULL && s->ctx->tlsext_servername_callback != 0) {
ret = s->ctx->tlsext_servername_callback(s, &al,
s->ctx->tlsext_servername_arg);
@@ -2007,203 +2615,131 @@ int ssl_parse_serverhello_tlsext(SSL *s, CBS *cbs) {
}
if (ssl_check_serverhello_tlsext(s) <= 0) {
- OPENSSL_PUT_ERROR(SSL, ssl_parse_serverhello_tlsext,
- SSL_R_SERVERHELLO_TLSEXT);
+ OPENSSL_PUT_ERROR(SSL, SSL_R_SERVERHELLO_TLSEXT);
return 0;
}
return 1;
}
-/* Since the server cache lookup is done early on in the processing of the
- * ClientHello, and other operations depend on the result, we need to handle
- * any TLS session ticket extension at the same time.
- *
- * ctx: contains the early callback context, which is the result of a
- * shallow parse of the ClientHello.
- * ret: (output) on return, if a ticket was decrypted, then this is set to
- * point to the resulting session.
- *
- * Returns:
- * -1: fatal error, either from parsing or decrypting the ticket.
- * 0: no ticket was found (or was ignored, based on settings).
- * 1: a zero length extension was found, indicating that the client supports
- * session tickets but doesn't currently have one to offer.
- * 2: a ticket was offered but couldn't be decrypted because of a non-fatal
- * error.
- * 3: a ticket was successfully decrypted and *ret was set.
- *
- * Side effects:
- * Sets s->tlsext_ticket_expected to 1 if the server will have to issue
- * a new session ticket to the client because the client indicated support
- * but the client either doesn't have a session ticket or we couldn't use
- * the one it gave us, or if s->ctx->tlsext_ticket_key_cb asked to renew
- * the client's ticket. Otherwise, s->tlsext_ticket_expected is set to 0.
- */
-int tls1_process_ticket(SSL *s, const struct ssl_early_callback_ctx *ctx,
- SSL_SESSION **ret) {
- *ret = NULL;
- s->tlsext_ticket_expected = 0;
- const uint8_t *data;
- size_t len;
- int r;
-
- /* If tickets disabled behave as if no ticket present to permit stateful
- * resumption. */
- if ((SSL_get_options(s) & SSL_OP_NO_TICKET) ||
- (s->version <= SSL3_VERSION && !ctx->extensions) ||
- !SSL_early_callback_ctx_extension_get(ctx, TLSEXT_TYPE_session_ticket,
- &data, &len)) {
- return 0;
- }
-
- if (len == 0) {
- /* The client will accept a ticket but doesn't currently have one. */
- s->tlsext_ticket_expected = 1;
- return 1;
- }
-
- r = tls_decrypt_ticket(s, data, len, ctx->session_id, ctx->session_id_len,
- ret);
- switch (r) {
- case 2: /* ticket couldn't be decrypted */
- s->tlsext_ticket_expected = 1;
- return 2;
+int tls_process_ticket(SSL *ssl, SSL_SESSION **out_session,
+ int *out_send_ticket, const uint8_t *ticket,
+ size_t ticket_len, const uint8_t *session_id,
+ size_t session_id_len) {
+ int ret = 1; /* Most errors are non-fatal. */
+ SSL_CTX *ssl_ctx = ssl->initial_ctx;
+ uint8_t *plaintext = NULL;
- case 3: /* ticket was decrypted */
- return r;
+ HMAC_CTX hmac_ctx;
+ HMAC_CTX_init(&hmac_ctx);
+ EVP_CIPHER_CTX cipher_ctx;
+ EVP_CIPHER_CTX_init(&cipher_ctx);
- case 4: /* ticket decrypted but need to renew */
- s->tlsext_ticket_expected = 1;
- return 3;
+ *out_send_ticket = 0;
+ *out_session = NULL;
- default: /* fatal error */
- return -1;
+ if (session_id_len > SSL_MAX_SSL_SESSION_ID_LENGTH) {
+ goto done;
}
-}
-/* tls_decrypt_ticket attempts to decrypt a session ticket.
- *
- * etick: points to the body of the session ticket extension.
- * eticklen: the length of the session tickets extenion.
- * sess_id: points at the session ID.
- * sesslen: the length of the session ID.
- * psess: (output) on return, if a ticket was decrypted, then this is set to
- * point to the resulting session.
- *
- * Returns:
- * -1: fatal error, either from parsing or decrypting the ticket.
- * 2: the ticket couldn't be decrypted.
- * 3: a ticket was successfully decrypted and *psess was set.
- * 4: same as 3, but the ticket needs to be renewed. */
-static int tls_decrypt_ticket(SSL *s, const uint8_t *etick, int eticklen,
- const uint8_t *sess_id, int sesslen,
- SSL_SESSION **psess) {
- SSL_SESSION *sess;
- uint8_t *sdec;
- const uint8_t *p;
- int slen, mlen, renew_ticket = 0;
- uint8_t tick_hmac[EVP_MAX_MD_SIZE];
- HMAC_CTX hctx;
- EVP_CIPHER_CTX ctx;
- SSL_CTX *tctx = s->initial_ctx;
+ if (ticket_len == 0) {
+ /* The client will accept a ticket but doesn't currently have one. */
+ *out_send_ticket = 1;
+ goto done;
+ }
/* Ensure there is room for the key name and the largest IV
* |tlsext_ticket_key_cb| may try to consume. The real limit may be lower, but
* the maximum IV length should be well under the minimum size for the
* session material and HMAC. */
- if (eticklen < 16 + EVP_MAX_IV_LENGTH) {
- return 2;
- }
-
- /* Initialize session ticket encryption and HMAC contexts */
- HMAC_CTX_init(&hctx);
- EVP_CIPHER_CTX_init(&ctx);
- if (tctx->tlsext_ticket_key_cb) {
- uint8_t *nctick = (uint8_t *)etick;
- int rv = tctx->tlsext_ticket_key_cb(s, nctick, nctick + 16, &ctx, &hctx,
- 0 /* decrypt */);
- if (rv < 0) {
- return -1;
+ if (ticket_len < SSL_TICKET_KEY_NAME_LEN + EVP_MAX_IV_LENGTH) {
+ goto done;
+ }
+ const uint8_t *iv = ticket + SSL_TICKET_KEY_NAME_LEN;
+
+ if (ssl_ctx->tlsext_ticket_key_cb != NULL) {
+ int cb_ret = ssl_ctx->tlsext_ticket_key_cb(ssl, (uint8_t*)ticket /* name */,
+ (uint8_t*)iv, &cipher_ctx, &hmac_ctx,
+ 0 /* decrypt */);
+ if (cb_ret < 0) {
+ ret = 0;
+ goto done;
}
- if (rv == 0) {
- return 2;
+ if (cb_ret == 0) {
+ goto done;
}
- if (rv == 2) {
- renew_ticket = 1;
+ if (cb_ret == 2) {
+ *out_send_ticket = 1;
}
} else {
- /* Check key name matches */
- if (memcmp(etick, tctx->tlsext_tick_key_name, 16)) {
- return 2;
+ /* Check the key name matches. */
+ if (memcmp(ticket, ssl_ctx->tlsext_tick_key_name,
+ SSL_TICKET_KEY_NAME_LEN) != 0) {
+ goto done;
}
- if (!HMAC_Init_ex(&hctx, tctx->tlsext_tick_hmac_key, 16, tlsext_tick_md(),
+ if (!HMAC_Init_ex(&hmac_ctx, ssl_ctx->tlsext_tick_hmac_key,
+ sizeof(ssl_ctx->tlsext_tick_hmac_key), tlsext_tick_md(),
NULL) ||
- !EVP_DecryptInit_ex(&ctx, EVP_aes_128_cbc(), NULL,
- tctx->tlsext_tick_aes_key, etick + 16)) {
- HMAC_CTX_cleanup(&hctx);
- EVP_CIPHER_CTX_cleanup(&ctx);
- return -1;
+ !EVP_DecryptInit_ex(&cipher_ctx, EVP_aes_128_cbc(), NULL,
+ ssl_ctx->tlsext_tick_aes_key, iv)) {
+ ret = 0;
+ goto done;
}
}
+ size_t iv_len = EVP_CIPHER_CTX_iv_length(&cipher_ctx);
- /* First, check the MAC. The MAC is at the end of the ticket. */
- mlen = HMAC_size(&hctx);
- if ((size_t) eticklen < 16 + EVP_CIPHER_CTX_iv_length(&ctx) + 1 + mlen) {
+ /* Check the MAC at the end of the ticket. */
+ uint8_t mac[EVP_MAX_MD_SIZE];
+ size_t mac_len = HMAC_size(&hmac_ctx);
+ if (ticket_len < SSL_TICKET_KEY_NAME_LEN + iv_len + 1 + mac_len) {
/* The ticket must be large enough for key name, IV, data, and MAC. */
- HMAC_CTX_cleanup(&hctx);
- EVP_CIPHER_CTX_cleanup(&ctx);
- return 2;
- }
- eticklen -= mlen;
- /* Check HMAC of encrypted ticket */
- HMAC_Update(&hctx, etick, eticklen);
- HMAC_Final(&hctx, tick_hmac, NULL);
- HMAC_CTX_cleanup(&hctx);
- if (CRYPTO_memcmp(tick_hmac, etick + eticklen, mlen)) {
- EVP_CIPHER_CTX_cleanup(&ctx);
- return 2;
- }
-
- /* Attempt to decrypt session data */
- /* Move p after IV to start of encrypted ticket, update length */
- p = etick + 16 + EVP_CIPHER_CTX_iv_length(&ctx);
- eticklen -= 16 + EVP_CIPHER_CTX_iv_length(&ctx);
- sdec = OPENSSL_malloc(eticklen);
- if (!sdec) {
- EVP_CIPHER_CTX_cleanup(&ctx);
- return -1;
+ goto done;
}
- EVP_DecryptUpdate(&ctx, sdec, &slen, p, eticklen);
- if (EVP_DecryptFinal_ex(&ctx, sdec + slen, &mlen) <= 0) {
- EVP_CIPHER_CTX_cleanup(&ctx);
- OPENSSL_free(sdec);
- return 2;
- }
- slen += mlen;
- EVP_CIPHER_CTX_cleanup(&ctx);
- p = sdec;
-
- sess = SSL_SESSION_from_bytes(sdec, slen);
- OPENSSL_free(sdec);
- if (sess) {
- /* The session ID, if non-empty, is used by some clients to detect that the
- * ticket has been accepted. So we copy it to the session structure. If it
- * is empty set length to zero as required by standard. */
- if (sesslen) {
- memcpy(sess->session_id, sess_id, sesslen);
- }
- sess->session_id_length = sesslen;
- *psess = sess;
- if (renew_ticket) {
- return 4;
- }
- return 3;
+ HMAC_Update(&hmac_ctx, ticket, ticket_len - mac_len);
+ HMAC_Final(&hmac_ctx, mac, NULL);
+ if (CRYPTO_memcmp(mac, ticket + (ticket_len - mac_len), mac_len) != 0) {
+ goto done;
+ }
+
+ /* Decrypt the session data. */
+ const uint8_t *ciphertext = ticket + SSL_TICKET_KEY_NAME_LEN + iv_len;
+ size_t ciphertext_len = ticket_len - SSL_TICKET_KEY_NAME_LEN - iv_len -
+ mac_len;
+ plaintext = OPENSSL_malloc(ciphertext_len);
+ if (plaintext == NULL) {
+ ret = 0;
+ goto done;
+ }
+ if (ciphertext_len >= INT_MAX) {
+ goto done;
+ }
+ int len1, len2;
+ if (!EVP_DecryptUpdate(&cipher_ctx, plaintext, &len1, ciphertext,
+ (int)ciphertext_len) ||
+ !EVP_DecryptFinal_ex(&cipher_ctx, plaintext + len1, &len2)) {
+ ERR_clear_error(); /* Don't leave an error on the queue. */
+ goto done;
+ }
+
+ /* Decode the session. */
+ SSL_SESSION *session = SSL_SESSION_from_bytes(plaintext, len1 + len2);
+ if (session == NULL) {
+ ERR_clear_error(); /* Don't leave an error on the queue. */
+ goto done;
}
- ERR_clear_error();
- /* For session parse failure, indicate that we need to send a new ticket. */
- return 2;
+ /* Copy the client's session ID into the new session, to denote the ticket has
+ * been accepted. */
+ memcpy(session->session_id, session_id, session_id_len);
+ session->session_id_length = session_id_len;
+
+ *out_session = session;
+
+done:
+ OPENSSL_free(plaintext);
+ HMAC_CTX_cleanup(&hmac_ctx);
+ EVP_CIPHER_CTX_cleanup(&cipher_ctx);
+ return ret;
}
/* Tables to translate from NIDs to TLS v1.2 ids */
@@ -2233,18 +2769,12 @@ static int tls12_find_id(int nid, const tls12_lookup *table, size_t tlen) {
return -1;
}
-static int tls12_find_nid(int id, const tls12_lookup *table, size_t tlen) {
- size_t i;
- for (i = 0; i < tlen; i++) {
- if (table[i].id == id) {
- return table[i].nid;
- }
- }
-
- return NID_undef;
+int tls12_get_sigid(int pkey_type) {
+ return tls12_find_id(pkey_type, tls12_sig,
+ sizeof(tls12_sig) / sizeof(tls12_lookup));
}
-int tls12_get_sigandhash(uint8_t *p, const EVP_PKEY *pk, const EVP_MD *md) {
+int tls12_get_sigandhash(SSL *ssl, uint8_t *p, const EVP_MD *md) {
int sig_id, md_id;
if (!md) {
@@ -2257,7 +2787,7 @@ int tls12_get_sigandhash(uint8_t *p, const EVP_PKEY *pk, const EVP_MD *md) {
return 0;
}
- sig_id = tls12_get_sigid(pk);
+ sig_id = tls12_get_sigid(ssl_private_key_type(ssl));
if (sig_id == -1) {
return 0;
}
@@ -2267,11 +2797,6 @@ int tls12_get_sigandhash(uint8_t *p, const EVP_PKEY *pk, const EVP_MD *md) {
return 1;
}
-int tls12_get_sigid(const EVP_PKEY *pk) {
- return tls12_find_id(pk->type, tls12_sig,
- sizeof(tls12_sig) / sizeof(tls12_lookup));
-}
-
const EVP_MD *tls12_get_hash(uint8_t hash_alg) {
switch (hash_alg) {
case TLSEXT_hash_md5:
@@ -2312,256 +2837,129 @@ static int tls12_get_pkey_type(uint8_t sig_alg) {
}
}
-/* Convert TLS 1.2 signature algorithm extension values into NIDs */
-static void tls1_lookup_sigalg(int *phash_nid, int *psign_nid,
- int *psignhash_nid, const uint8_t *data) {
- int sign_nid = 0, hash_nid = 0;
- if (!phash_nid && !psign_nid && !psignhash_nid) {
- return;
- }
-
- if (phash_nid || psignhash_nid) {
- hash_nid = tls12_find_nid(data[0], tls12_md,
- sizeof(tls12_md) / sizeof(tls12_lookup));
- if (phash_nid) {
- *phash_nid = hash_nid;
- }
- }
-
- if (psign_nid || psignhash_nid) {
- sign_nid = tls12_find_nid(data[1], tls12_sig,
- sizeof(tls12_sig) / sizeof(tls12_lookup));
- if (psign_nid) {
- *psign_nid = sign_nid;
- }
- }
-
- if (psignhash_nid) {
- if (sign_nid && hash_nid) {
- OBJ_find_sigid_by_algs(psignhash_nid, hash_nid, sign_nid);
- } else {
- *psignhash_nid = NID_undef;
- }
- }
-}
-
-/* Given preference and allowed sigalgs set shared sigalgs */
-static int tls12_do_shared_sigalgs(TLS_SIGALGS *shsig, const uint8_t *pref,
- size_t preflen, const uint8_t *allow,
- size_t allowlen) {
- const uint8_t *ptmp, *atmp;
- size_t i, j, nmatch = 0;
-
- for (i = 0, ptmp = pref; i < preflen; i += 2, ptmp += 2) {
- /* Skip disabled hashes or signature algorithms */
- if (tls12_get_hash(ptmp[0]) == NULL ||
- tls12_get_pkey_type(ptmp[1]) == -1) {
- continue;
- }
-
- for (j = 0, atmp = allow; j < allowlen; j += 2, atmp += 2) {
- if (ptmp[0] == atmp[0] && ptmp[1] == atmp[1]) {
- nmatch++;
- if (shsig) {
- shsig->rhash = ptmp[0];
- shsig->rsign = ptmp[1];
- tls1_lookup_sigalg(&shsig->hash_nid, &shsig->sign_nid,
- &shsig->signandhash_nid, ptmp);
- shsig++;
- }
-
- break;
- }
- }
- }
-
- return nmatch;
-}
-
-/* Set shared signature algorithms for SSL structures */
-static int tls1_set_shared_sigalgs(SSL *s) {
- const uint8_t *pref, *allow, *conf;
- size_t preflen, allowlen, conflen;
- size_t nmatch;
- TLS_SIGALGS *salgs = NULL;
- CERT *c = s->cert;
+OPENSSL_COMPILE_ASSERT(sizeof(TLS_SIGALGS) == 2,
+ sizeof_tls_sigalgs_is_not_two);
- OPENSSL_free(c->shared_sigalgs);
- c->shared_sigalgs = NULL;
- c->shared_sigalgslen = 0;
-
- /* If client use client signature algorithms if not NULL */
- if (!s->server && c->client_sigalgs) {
- conf = c->client_sigalgs;
- conflen = c->client_sigalgslen;
- } else if (c->conf_sigalgs) {
- conf = c->conf_sigalgs;
- conflen = c->conf_sigalgslen;
- } else {
- conflen = tls12_get_psigalgs(s, &conf);
+int tls1_parse_peer_sigalgs(SSL *ssl, const CBS *in_sigalgs) {
+ /* Extension ignored for inappropriate versions */
+ if (!SSL_USE_SIGALGS(ssl)) {
+ return 1;
}
- if (s->options & SSL_OP_CIPHER_SERVER_PREFERENCE) {
- pref = conf;
- preflen = conflen;
- allow = c->peer_sigalgs;
- allowlen = c->peer_sigalgslen;
- } else {
- allow = conf;
- allowlen = conflen;
- pref = c->peer_sigalgs;
- preflen = c->peer_sigalgslen;
- }
+ CERT *const cert = ssl->cert;
+ OPENSSL_free(cert->peer_sigalgs);
+ cert->peer_sigalgs = NULL;
+ cert->peer_sigalgslen = 0;
- nmatch = tls12_do_shared_sigalgs(NULL, pref, preflen, allow, allowlen);
- if (!nmatch) {
- return 1;
- }
+ size_t num_sigalgs = CBS_len(in_sigalgs);
- salgs = OPENSSL_malloc(nmatch * sizeof(TLS_SIGALGS));
- if (!salgs) {
+ if (num_sigalgs % 2 != 0) {
return 0;
}
+ num_sigalgs /= 2;
- nmatch = tls12_do_shared_sigalgs(salgs, pref, preflen, allow, allowlen);
- c->shared_sigalgs = salgs;
- c->shared_sigalgslen = nmatch;
- return 1;
-}
-
-/* Set preferred digest for each key type */
-int tls1_process_sigalgs(SSL *s, const CBS *sigalgs) {
- CERT *c = s->cert;
-
- /* Extension ignored for inappropriate versions */
- if (!SSL_USE_SIGALGS(s)) {
+ /* supported_signature_algorithms in the certificate request is
+ * allowed to be empty. */
+ if (num_sigalgs == 0) {
return 1;
}
- if (CBS_len(sigalgs) % 2 != 0 ||
- !CBS_stow(sigalgs, &c->peer_sigalgs, &c->peer_sigalgslen) ||
- !tls1_set_shared_sigalgs(s)) {
+ /* This multiplication doesn't overflow because sizeof(TLS_SIGALGS) is two
+ * (statically asserted above) and we just divided |num_sigalgs| by two. */
+ cert->peer_sigalgs = OPENSSL_malloc(num_sigalgs * sizeof(TLS_SIGALGS));
+ if (cert->peer_sigalgs == NULL) {
return 0;
}
+ cert->peer_sigalgslen = num_sigalgs;
- return 1;
-}
+ CBS sigalgs;
+ CBS_init(&sigalgs, CBS_data(in_sigalgs), CBS_len(in_sigalgs));
-const EVP_MD *tls1_choose_signing_digest(SSL *s, EVP_PKEY *pkey) {
- CERT *c = s->cert;
- int type = EVP_PKEY_id(pkey);
size_t i;
-
- /* Select the first shared digest supported by our key. */
- for (i = 0; i < c->shared_sigalgslen; i++) {
- const EVP_MD *md = tls12_get_hash(c->shared_sigalgs[i].rhash);
- if (md == NULL ||
- tls12_get_pkey_type(c->shared_sigalgs[i].rsign) != type ||
- !EVP_PKEY_supports_digest(pkey, md)) {
- continue;
- }
- return md;
- }
-
- /* If no suitable digest may be found, default to SHA-1. */
- return EVP_sha1();
-}
-
-int SSL_get_sigalgs(SSL *s, int idx, int *psign, int *phash, int *psignhash,
- uint8_t *rsig, uint8_t *rhash) {
- const uint8_t *psig = s->cert->peer_sigalgs;
-
- if (psig == NULL) {
- return 0;
- }
-
- if (idx >= 0) {
- idx <<= 1;
- if (idx >= (int)s->cert->peer_sigalgslen) {
+ for (i = 0; i < num_sigalgs; i++) {
+ TLS_SIGALGS *const sigalg = &cert->peer_sigalgs[i];
+ if (!CBS_get_u8(&sigalgs, &sigalg->rhash) ||
+ !CBS_get_u8(&sigalgs, &sigalg->rsign)) {
return 0;
}
- psig += idx;
- if (rhash) {
- *rhash = psig[0];
- }
- if (rsig) {
- *rsig = psig[1];
- }
- tls1_lookup_sigalg(phash, psign, psignhash, psig);
}
- return s->cert->peer_sigalgslen / 2;
+ return 1;
}
-int SSL_get_shared_sigalgs(SSL *s, int idx, int *psign, int *phash,
- int *psignhash, uint8_t *rsig, uint8_t *rhash) {
- TLS_SIGALGS *shsigalgs = s->cert->shared_sigalgs;
-
- if (!shsigalgs || idx >= (int)s->cert->shared_sigalgslen) {
- return 0;
- }
+const EVP_MD *tls1_choose_signing_digest(SSL *ssl) {
+ CERT *cert = ssl->cert;
+ int type = ssl_private_key_type(ssl);
+ size_t i, j;
+
+ static const int kDefaultDigestList[] = {NID_sha256, NID_sha384, NID_sha512,
+ NID_sha224, NID_sha1};
+
+ const int *digest_nids = kDefaultDigestList;
+ size_t num_digest_nids =
+ sizeof(kDefaultDigestList) / sizeof(kDefaultDigestList[0]);
+ if (cert->digest_nids != NULL) {
+ digest_nids = cert->digest_nids;
+ num_digest_nids = cert->num_digest_nids;
+ }
+
+ for (i = 0; i < num_digest_nids; i++) {
+ const int digest_nid = digest_nids[i];
+ for (j = 0; j < cert->peer_sigalgslen; j++) {
+ const EVP_MD *md = tls12_get_hash(cert->peer_sigalgs[j].rhash);
+ if (md == NULL ||
+ digest_nid != EVP_MD_type(md) ||
+ tls12_get_pkey_type(cert->peer_sigalgs[j].rsign) != type) {
+ continue;
+ }
- shsigalgs += idx;
- if (phash) {
- *phash = shsigalgs->hash_nid;
- }
- if (psign) {
- *psign = shsigalgs->sign_nid;
- }
- if (psignhash) {
- *psignhash = shsigalgs->signandhash_nid;
- }
- if (rsig) {
- *rsig = shsigalgs->rsign;
- }
- if (rhash) {
- *rhash = shsigalgs->rhash;
+ return md;
+ }
}
- return s->cert->shared_sigalgslen;
+ /* If no suitable digest may be found, default to SHA-1. */
+ return EVP_sha1();
}
-/* tls1_channel_id_hash calculates the signed data for a Channel ID on the
- * given SSL connection and writes it to |md|. */
-int tls1_channel_id_hash(EVP_MD_CTX *md, SSL *s) {
+int tls1_channel_id_hash(SSL *ssl, uint8_t *out, size_t *out_len) {
+ int ret = 0;
EVP_MD_CTX ctx;
- uint8_t temp_digest[EVP_MAX_MD_SIZE];
- unsigned temp_digest_len;
- int i;
- static const char kClientIDMagic[] = "TLS Channel ID signature";
- if (s->s3->handshake_buffer &&
- !ssl3_digest_cached_records(s, free_handshake_buffer)) {
- return 0;
+ EVP_MD_CTX_init(&ctx);
+ if (!EVP_DigestInit_ex(&ctx, EVP_sha256(), NULL)) {
+ goto err;
}
- EVP_DigestUpdate(md, kClientIDMagic, sizeof(kClientIDMagic));
+ static const char kClientIDMagic[] = "TLS Channel ID signature";
+ EVP_DigestUpdate(&ctx, kClientIDMagic, sizeof(kClientIDMagic));
- if (s->hit && s->s3->tlsext_channel_id_new) {
+ if (ssl->hit) {
static const char kResumptionMagic[] = "Resumption";
- EVP_DigestUpdate(md, kResumptionMagic, sizeof(kResumptionMagic));
- if (s->session->original_handshake_hash_len == 0) {
- return 0;
+ EVP_DigestUpdate(&ctx, kResumptionMagic, sizeof(kResumptionMagic));
+ if (ssl->session->original_handshake_hash_len == 0) {
+ OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR);
+ goto err;
}
- EVP_DigestUpdate(md, s->session->original_handshake_hash,
- s->session->original_handshake_hash_len);
+ EVP_DigestUpdate(&ctx, ssl->session->original_handshake_hash,
+ ssl->session->original_handshake_hash_len);
}
- EVP_MD_CTX_init(&ctx);
- for (i = 0; i < SSL_MAX_DIGEST; i++) {
- if (s->s3->handshake_dgst[i] == NULL) {
- continue;
- }
- if (!EVP_MD_CTX_copy_ex(&ctx, s->s3->handshake_dgst[i])) {
- EVP_MD_CTX_cleanup(&ctx);
- return 0;
- }
- EVP_DigestFinal_ex(&ctx, temp_digest, &temp_digest_len);
- EVP_DigestUpdate(md, temp_digest, temp_digest_len);
+ uint8_t handshake_hash[EVP_MAX_MD_SIZE];
+ int handshake_hash_len = tls1_handshake_digest(ssl, handshake_hash,
+ sizeof(handshake_hash));
+ if (handshake_hash_len < 0) {
+ goto err;
}
- EVP_MD_CTX_cleanup(&ctx);
+ EVP_DigestUpdate(&ctx, handshake_hash, (size_t)handshake_hash_len);
+ unsigned len_u;
+ EVP_DigestFinal_ex(&ctx, out, &len_u);
+ *out_len = len_u;
- return 1;
+ ret = 1;
+
+err:
+ EVP_MD_CTX_cleanup(&ctx);
+ return ret;
}
/* tls1_record_handshake_hashes_for_channel_id records the current handshake
@@ -2575,12 +2973,6 @@ int tls1_record_handshake_hashes_for_channel_id(SSL *s) {
return -1;
}
- /* It only makes sense to call this function if Channel IDs have been
- * negotiated. */
- if (!s->s3->tlsext_channel_id_new) {
- return -1;
- }
-
digest_len =
tls1_handshake_digest(s, s->session->original_handshake_hash,
sizeof(s->session->original_handshake_hash));
@@ -2592,48 +2984,3 @@ int tls1_record_handshake_hashes_for_channel_id(SSL *s) {
return 1;
}
-
-int tls1_set_sigalgs(CERT *c, const int *psig_nids, size_t salglen,
- int client) {
- uint8_t *sigalgs, *sptr;
- int rhash, rsign;
- size_t i;
-
- if (salglen & 1) {
- return 0;
- }
-
- sigalgs = OPENSSL_malloc(salglen);
- if (sigalgs == NULL) {
- return 0;
- }
-
- for (i = 0, sptr = sigalgs; i < salglen; i += 2) {
- rhash = tls12_find_id(*psig_nids++, tls12_md,
- sizeof(tls12_md) / sizeof(tls12_lookup));
- rsign = tls12_find_id(*psig_nids++, tls12_sig,
- sizeof(tls12_sig) / sizeof(tls12_lookup));
-
- if (rhash == -1 || rsign == -1) {
- goto err;
- }
- *sptr++ = rhash;
- *sptr++ = rsign;
- }
-
- if (client) {
- OPENSSL_free(c->client_sigalgs);
- c->client_sigalgs = sigalgs;
- c->client_sigalgslen = salglen;
- } else {
- OPENSSL_free(c->conf_sigalgs);
- c->conf_sigalgs = sigalgs;
- c->conf_sigalgslen = salglen;
- }
-
- return 1;
-
-err:
- OPENSSL_free(sigalgs);
- return 0;
-}
diff --git a/src/ssl/t1_reneg.c b/src/ssl/t1_reneg.c
deleted file mode 100644
index d0009c1..0000000
--- a/src/ssl/t1_reneg.c
+++ /dev/null
@@ -1,246 +0,0 @@
-/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
- * All rights reserved.
- *
- * This package is an SSL implementation written
- * by Eric Young (eay@cryptsoft.com).
- * The implementation was written so as to conform with Netscapes SSL.
- *
- * This library is free for commercial and non-commercial use as long as
- * the following conditions are aheared to. The following conditions
- * apply to all code found in this distribution, be it the RC4, RSA,
- * lhash, DES, etc., code; not just the SSL code. The SSL documentation
- * included with this distribution is covered by the same copyright terms
- * except that the holder is Tim Hudson (tjh@cryptsoft.com).
- *
- * Copyright remains Eric Young's, and as such any Copyright notices in
- * the code are not to be removed.
- * If this package is used in a product, Eric Young should be given attribution
- * as the author of the parts of the library used.
- * This can be in the form of a textual message at program startup or
- * in documentation (online or textual) provided with the package.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * "This product includes cryptographic software written by
- * Eric Young (eay@cryptsoft.com)"
- * The word 'cryptographic' can be left out if the rouines from the library
- * being used are not cryptographic related :-).
- * 4. If you include any Windows specific code (or a derivative thereof) from
- * the apps directory (application code) you must include an acknowledgement:
- * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
- *
- * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * The licence and distribution terms for any publically available version or
- * derivative of this code cannot be changed. i.e. this code cannot simply be
- * copied and put under another distribution licence
- * [including the GNU Public Licence.]
- */
-/* ====================================================================
- * Copyright (c) 1998-2009 The OpenSSL Project. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in
- * the documentation and/or other materials provided with the
- * distribution.
- *
- * 3. All advertising materials mentioning features or use of this
- * software must display the following acknowledgment:
- * "This product includes software developed by the OpenSSL Project
- * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
- *
- * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
- * endorse or promote products derived from this software without
- * prior written permission. For written permission, please contact
- * openssl-core@openssl.org.
- *
- * 5. Products derived from this software may not be called "OpenSSL"
- * nor may "OpenSSL" appear in their names without prior written
- * permission of the OpenSSL Project.
- *
- * 6. Redistributions of any form whatsoever must retain the following
- * acknowledgment:
- * "This product includes software developed by the OpenSSL Project
- * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
- *
- * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
- * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
- * OF THE POSSIBILITY OF SUCH DAMAGE.
- * ====================================================================
- *
- * This product includes cryptographic software written by Eric Young
- * (eay@cryptsoft.com). This product includes software written by Tim
- * Hudson (tjh@cryptsoft.com). */
-
-#include <assert.h>
-#include <stdio.h>
-#include <string.h>
-
-#include <openssl/bytestring.h>
-#include <openssl/err.h>
-
-#include "internal.h"
-
-
-/* Add the client's renegotiation binding */
-int ssl_add_clienthello_renegotiate_ext(SSL *s, unsigned char *p, int *len,
- int maxlen) {
- if (p) {
- if (s->s3->previous_client_finished_len + 1 > maxlen) {
- OPENSSL_PUT_ERROR(SSL, ssl_add_clienthello_renegotiate_ext,
- SSL_R_RENEGOTIATE_EXT_TOO_LONG);
- return 0;
- }
-
- /* Length byte */
- *p = s->s3->previous_client_finished_len;
- p++;
-
- memcpy(p, s->s3->previous_client_finished,
- s->s3->previous_client_finished_len);
- }
-
- *len = s->s3->previous_client_finished_len + 1;
-
- return 1;
-}
-
-/* Parse the client's renegotiation binding and abort if it's not right */
-int ssl_parse_clienthello_renegotiate_ext(SSL *s, CBS *cbs, int *out_alert) {
- CBS renegotiated_connection;
-
- if (!CBS_get_u8_length_prefixed(cbs, &renegotiated_connection) ||
- CBS_len(cbs) != 0) {
- OPENSSL_PUT_ERROR(SSL, ssl_parse_clienthello_renegotiate_ext,
- SSL_R_RENEGOTIATION_ENCODING_ERR);
- *out_alert = SSL_AD_DECODE_ERROR;
- return 0;
- }
-
- /* Check that the extension matches */
- if (!CBS_mem_equal(&renegotiated_connection, s->s3->previous_client_finished,
- s->s3->previous_client_finished_len)) {
- OPENSSL_PUT_ERROR(SSL, ssl_parse_clienthello_renegotiate_ext,
- SSL_R_RENEGOTIATION_MISMATCH);
- *out_alert = SSL_AD_HANDSHAKE_FAILURE;
- return 0;
- }
-
- s->s3->send_connection_binding = 1;
-
- return 1;
-}
-
-/* Add the server's renegotiation binding */
-int ssl_add_serverhello_renegotiate_ext(SSL *s, unsigned char *p, int *len,
- int maxlen) {
- if (p) {
- if (s->s3->previous_client_finished_len +
- s->s3->previous_server_finished_len + 1 > maxlen) {
- OPENSSL_PUT_ERROR(SSL, ssl_add_serverhello_renegotiate_ext,
- SSL_R_RENEGOTIATE_EXT_TOO_LONG);
- return 0;
- }
-
- /* Length byte */
- *p = s->s3->previous_client_finished_len +
- s->s3->previous_server_finished_len;
- p++;
-
- memcpy(p, s->s3->previous_client_finished,
- s->s3->previous_client_finished_len);
- p += s->s3->previous_client_finished_len;
-
- memcpy(p, s->s3->previous_server_finished,
- s->s3->previous_server_finished_len);
- }
-
- *len = s->s3->previous_client_finished_len +
- s->s3->previous_server_finished_len + 1;
-
- return 1;
-}
-
-/* Parse the server's renegotiation binding and abort if it's not right */
-int ssl_parse_serverhello_renegotiate_ext(SSL *s, CBS *cbs, int *out_alert) {
- int expected_len =
- s->s3->previous_client_finished_len + s->s3->previous_server_finished_len;
- CBS renegotiated_connection;
- const uint8_t *d;
-
- /* Check for logic errors */
- assert(!expected_len || s->s3->previous_client_finished_len);
- assert(!expected_len || s->s3->previous_server_finished_len);
-
- /* Parse out the extension contents. */
- if (!CBS_get_u8_length_prefixed(cbs, &renegotiated_connection) ||
- CBS_len(cbs) != 0) {
- OPENSSL_PUT_ERROR(SSL, ssl_parse_serverhello_renegotiate_ext,
- SSL_R_RENEGOTIATION_ENCODING_ERR);
- *out_alert = SSL_AD_ILLEGAL_PARAMETER;
- return 0;
- }
-
- /* Check that the extension matches. */
- if (CBS_len(&renegotiated_connection) != expected_len) {
- OPENSSL_PUT_ERROR(SSL, ssl_parse_serverhello_renegotiate_ext,
- SSL_R_RENEGOTIATION_MISMATCH);
- *out_alert = SSL_AD_HANDSHAKE_FAILURE;
- return 0;
- }
-
- d = CBS_data(&renegotiated_connection);
- if (memcmp(d, s->s3->previous_client_finished,
- s->s3->previous_client_finished_len)) {
- OPENSSL_PUT_ERROR(SSL, ssl_parse_serverhello_renegotiate_ext,
- SSL_R_RENEGOTIATION_MISMATCH);
- *out_alert = SSL_AD_HANDSHAKE_FAILURE;
- return 0;
- }
- d += s->s3->previous_client_finished_len;
-
- if (memcmp(d, s->s3->previous_server_finished,
- s->s3->previous_server_finished_len)) {
- OPENSSL_PUT_ERROR(SSL, ssl_parse_serverhello_renegotiate_ext,
- SSL_R_RENEGOTIATION_MISMATCH);
- *out_alert = SSL_AD_ILLEGAL_PARAMETER;
- return 0;
- }
- s->s3->send_connection_binding = 1;
-
- return 1;
-}
diff --git a/src/ssl/test/bssl_shim.cc b/src/ssl/test/bssl_shim.cc
index 3b95d7e..edae67b 100644
--- a/src/ssl/test/bssl_shim.cc
+++ b/src/ssl/test/bssl_shim.cc
@@ -38,10 +38,14 @@
#include <openssl/bio.h>
#include <openssl/buf.h>
#include <openssl/bytestring.h>
+#include <openssl/cipher.h>
#include <openssl/err.h>
+#include <openssl/hmac.h>
+#include <openssl/rand.h>
#include <openssl/ssl.h>
#include <memory>
+#include <string>
#include <vector>
#include "../../crypto/test/scoped_types.h"
@@ -90,10 +94,17 @@ struct TestState {
ScopedSSL_SESSION pending_session;
bool early_callback_called = false;
bool handshake_done = false;
+ // private_key is the underlying private key used when testing custom keys.
+ ScopedEVP_PKEY private_key;
+ std::vector<uint8_t> signature;
+ // signature_retries is the number of times an asynchronous sign operation has
+ // been retried.
+ unsigned signature_retries = 0;
+ bool got_new_session = false;
};
static void TestStateExFree(void *parent, void *ptr, CRYPTO_EX_DATA *ad,
- int index, long argl, void *argp) {
+ int index, long argl, void *argp) {
delete ((TestState *)ptr);
}
@@ -129,18 +140,137 @@ static ScopedEVP_PKEY LoadPrivateKey(const std::string &file) {
return pkey;
}
+static int AsyncPrivateKeyType(SSL *ssl) {
+ return EVP_PKEY_id(GetTestState(ssl)->private_key.get());
+}
+
+static size_t AsyncPrivateKeyMaxSignatureLen(SSL *ssl) {
+ return EVP_PKEY_size(GetTestState(ssl)->private_key.get());
+}
+
+static ssl_private_key_result_t AsyncPrivateKeySign(
+ SSL *ssl, uint8_t *out, size_t *out_len, size_t max_out,
+ const EVP_MD *md, const uint8_t *in, size_t in_len) {
+ TestState *test_state = GetTestState(ssl);
+ if (!test_state->signature.empty()) {
+ fprintf(stderr, "AsyncPrivateKeySign called with operation pending.\n");
+ abort();
+ }
+
+ ScopedEVP_PKEY_CTX ctx(EVP_PKEY_CTX_new(test_state->private_key.get(),
+ nullptr));
+ if (!ctx) {
+ return ssl_private_key_failure;
+ }
+
+ // Write the signature into |test_state|.
+ size_t len = 0;
+ if (!EVP_PKEY_sign_init(ctx.get()) ||
+ !EVP_PKEY_CTX_set_signature_md(ctx.get(), md) ||
+ !EVP_PKEY_sign(ctx.get(), nullptr, &len, in, in_len)) {
+ return ssl_private_key_failure;
+ }
+ test_state->signature.resize(len);
+ if (!EVP_PKEY_sign(ctx.get(), bssl::vector_data(&test_state->signature), &len,
+ in, in_len)) {
+ return ssl_private_key_failure;
+ }
+ test_state->signature.resize(len);
+
+ // The signature will be released asynchronously in |AsyncPrivateKeySignComplete|.
+ return ssl_private_key_retry;
+}
+
+static ssl_private_key_result_t AsyncPrivateKeySignComplete(
+ SSL *ssl, uint8_t *out, size_t *out_len, size_t max_out) {
+ TestState *test_state = GetTestState(ssl);
+ if (test_state->signature.empty()) {
+ fprintf(stderr,
+ "AsyncPrivateKeySignComplete called without operation pending.\n");
+ abort();
+ }
+
+ if (test_state->signature_retries < 2) {
+ // Only return the signature on the second attempt, to test both incomplete
+ // |sign| and |sign_complete|.
+ return ssl_private_key_retry;
+ }
+
+ if (max_out < test_state->signature.size()) {
+ fprintf(stderr, "Output buffer too small.\n");
+ return ssl_private_key_failure;
+ }
+ memcpy(out, bssl::vector_data(&test_state->signature),
+ test_state->signature.size());
+ *out_len = test_state->signature.size();
+
+ test_state->signature.clear();
+ test_state->signature_retries = 0;
+ return ssl_private_key_success;
+}
+
+static const SSL_PRIVATE_KEY_METHOD g_async_private_key_method = {
+ AsyncPrivateKeyType,
+ AsyncPrivateKeyMaxSignatureLen,
+ AsyncPrivateKeySign,
+ AsyncPrivateKeySignComplete,
+};
+
+template<typename T>
+struct Free {
+ void operator()(T *buf) {
+ free(buf);
+ }
+};
+
static bool InstallCertificate(SSL *ssl) {
const TestConfig *config = GetConfigPtr(ssl);
- if (!config->key_file.empty() &&
- !SSL_use_PrivateKey_file(ssl, config->key_file.c_str(),
- SSL_FILETYPE_PEM)) {
- return false;
+ TestState *test_state = GetTestState(ssl);
+
+ if (!config->digest_prefs.empty()) {
+ std::unique_ptr<char, Free<char>> digest_prefs(
+ strdup(config->digest_prefs.c_str()));
+ std::vector<int> digest_list;
+
+ for (;;) {
+ char *token =
+ strtok(digest_list.empty() ? digest_prefs.get() : nullptr, ",");
+ if (token == nullptr) {
+ break;
+ }
+
+ digest_list.push_back(EVP_MD_type(EVP_get_digestbyname(token)));
+ }
+
+ if (!SSL_set_private_key_digest_prefs(ssl, digest_list.data(),
+ digest_list.size())) {
+ return false;
+ }
+ }
+
+ if (!config->key_file.empty()) {
+ if (config->use_async_private_key) {
+ test_state->private_key = LoadPrivateKey(config->key_file.c_str());
+ if (!test_state->private_key) {
+ return false;
+ }
+ SSL_set_private_key_method(ssl, &g_async_private_key_method);
+ } else if (!SSL_use_PrivateKey_file(ssl, config->key_file.c_str(),
+ SSL_FILETYPE_PEM)) {
+ return false;
+ }
}
if (!config->cert_file.empty() &&
!SSL_use_certificate_file(ssl, config->cert_file.c_str(),
SSL_FILETYPE_PEM)) {
return false;
}
+ if (!config->ocsp_response.empty() &&
+ !SSL_CTX_set_ocsp_response(ssl->ctx,
+ (const uint8_t *)config->ocsp_response.data(),
+ config->ocsp_response.size())) {
+ return false;
+ }
return true;
}
@@ -196,10 +326,29 @@ static int SelectCertificateCallback(const struct ssl_early_callback_ctx *ctx) {
return 1;
}
-static int SkipVerify(int preverify_ok, X509_STORE_CTX *store_ctx) {
+static int VerifySucceed(X509_STORE_CTX *store_ctx, void *arg) {
+ SSL* ssl = (SSL*)X509_STORE_CTX_get_ex_data(store_ctx,
+ SSL_get_ex_data_X509_STORE_CTX_idx());
+ const TestConfig *config = GetConfigPtr(ssl);
+
+ if (!config->expected_ocsp_response.empty()) {
+ const uint8_t *data;
+ size_t len;
+ SSL_get0_ocsp_response(ssl, &data, &len);
+ if (len == 0) {
+ fprintf(stderr, "OCSP response not available in verify callback\n");
+ return 0;
+ }
+ }
+
return 1;
}
+static int VerifyFail(X509_STORE_CTX *store_ctx, void *arg) {
+ store_ctx->error = X509_V_ERR_APPLICATION_VERIFICATION;
+ return 0;
+}
+
static int NextProtosAdvertisedCallback(SSL *ssl, const uint8_t **out,
unsigned int *out_len, void *arg) {
const TestConfig *config = GetConfigPtr(ssl);
@@ -341,6 +490,94 @@ static void InfoCallback(const SSL *ssl, int type, int val) {
}
}
+static int NewSessionCallback(SSL *ssl, SSL_SESSION *session) {
+ GetTestState(ssl)->got_new_session = true;
+ // BoringSSL passes a reference to |session|.
+ SSL_SESSION_free(session);
+ return 1;
+}
+
+static int TicketKeyCallback(SSL *ssl, uint8_t *key_name, uint8_t *iv,
+ EVP_CIPHER_CTX *ctx, HMAC_CTX *hmac_ctx,
+ int encrypt) {
+ // This is just test code, so use the all-zeros key.
+ static const uint8_t kZeros[16] = {0};
+
+ if (encrypt) {
+ memcpy(key_name, kZeros, sizeof(kZeros));
+ RAND_bytes(iv, 16);
+ } else if (memcmp(key_name, kZeros, 16) != 0) {
+ return 0;
+ }
+
+ if (!HMAC_Init_ex(hmac_ctx, kZeros, sizeof(kZeros), EVP_sha256(), NULL) ||
+ !EVP_CipherInit_ex(ctx, EVP_aes_128_cbc(), NULL, kZeros, iv, encrypt)) {
+ return -1;
+ }
+
+ if (!encrypt) {
+ return GetConfigPtr(ssl)->renew_ticket ? 2 : 1;
+ }
+ return 1;
+}
+
+// kCustomExtensionValue is the extension value that the custom extension
+// callbacks will add.
+static const uint16_t kCustomExtensionValue = 1234;
+static void *const kCustomExtensionAddArg =
+ reinterpret_cast<void *>(kCustomExtensionValue);
+static void *const kCustomExtensionParseArg =
+ reinterpret_cast<void *>(kCustomExtensionValue + 1);
+static const char kCustomExtensionContents[] = "custom extension";
+
+static int CustomExtensionAddCallback(SSL *ssl, unsigned extension_value,
+ const uint8_t **out, size_t *out_len,
+ int *out_alert_value, void *add_arg) {
+ if (extension_value != kCustomExtensionValue ||
+ add_arg != kCustomExtensionAddArg) {
+ abort();
+ }
+
+ if (GetConfigPtr(ssl)->custom_extension_skip) {
+ return 0;
+ }
+ if (GetConfigPtr(ssl)->custom_extension_fail_add) {
+ return -1;
+ }
+
+ *out = reinterpret_cast<const uint8_t*>(kCustomExtensionContents);
+ *out_len = sizeof(kCustomExtensionContents) - 1;
+
+ return 1;
+}
+
+static void CustomExtensionFreeCallback(SSL *ssl, unsigned extension_value,
+ const uint8_t *out, void *add_arg) {
+ if (extension_value != kCustomExtensionValue ||
+ add_arg != kCustomExtensionAddArg ||
+ out != reinterpret_cast<const uint8_t *>(kCustomExtensionContents)) {
+ abort();
+ }
+}
+
+static int CustomExtensionParseCallback(SSL *ssl, unsigned extension_value,
+ const uint8_t *contents,
+ size_t contents_len,
+ int *out_alert_value, void *parse_arg) {
+ if (extension_value != kCustomExtensionValue ||
+ parse_arg != kCustomExtensionParseArg) {
+ abort();
+ }
+
+ if (contents_len != sizeof(kCustomExtensionContents) - 1 ||
+ memcmp(contents, kCustomExtensionContents, contents_len) != 0) {
+ *out_alert_value = SSL_AD_DECODE_ERROR;
+ return 0;
+ }
+
+ return 1;
+}
+
// Connect returns a new socket connected to localhost on |port| or -1 on
// error.
static int Connect(uint16_t port) {
@@ -406,7 +643,23 @@ static ScopedSSL_CTX SetupCtx(const TestConfig *config) {
return nullptr;
}
- if (!SSL_CTX_set_cipher_list(ssl_ctx.get(), "ALL")) {
+ std::string cipher_list = "ALL";
+ if (!config->cipher.empty()) {
+ cipher_list = config->cipher;
+ SSL_CTX_set_options(ssl_ctx.get(), SSL_OP_CIPHER_SERVER_PREFERENCE);
+ }
+ if (!SSL_CTX_set_cipher_list(ssl_ctx.get(), cipher_list.c_str())) {
+ return nullptr;
+ }
+
+ if (!config->cipher_tls10.empty() &&
+ !SSL_CTX_set_cipher_list_tls10(ssl_ctx.get(),
+ config->cipher_tls10.c_str())) {
+ return nullptr;
+ }
+ if (!config->cipher_tls11.empty() &&
+ !SSL_CTX_set_cipher_list_tls11(ssl_ctx.get(),
+ config->cipher_tls11.c_str())) {
return nullptr;
}
@@ -438,12 +691,46 @@ static ScopedSSL_CTX SetupCtx(const TestConfig *config) {
SSL_CTX_set_alpn_select_cb(ssl_ctx.get(), AlpnSelectCallback, NULL);
}
- ssl_ctx->tlsext_channel_id_enabled_new = 1;
+ SSL_CTX_enable_tls_channel_id(ssl_ctx.get());
SSL_CTX_set_channel_id_cb(ssl_ctx.get(), ChannelIdCallback);
ssl_ctx->current_time_cb = CurrentTimeCallback;
SSL_CTX_set_info_callback(ssl_ctx.get(), InfoCallback);
+ SSL_CTX_sess_set_new_cb(ssl_ctx.get(), NewSessionCallback);
+
+ if (config->use_ticket_callback) {
+ SSL_CTX_set_tlsext_ticket_key_cb(ssl_ctx.get(), TicketKeyCallback);
+ }
+
+ if (config->enable_client_custom_extension &&
+ !SSL_CTX_add_client_custom_ext(
+ ssl_ctx.get(), kCustomExtensionValue, CustomExtensionAddCallback,
+ CustomExtensionFreeCallback, kCustomExtensionAddArg,
+ CustomExtensionParseCallback, kCustomExtensionParseArg)) {
+ return nullptr;
+ }
+
+ if (config->enable_server_custom_extension &&
+ !SSL_CTX_add_server_custom_ext(
+ ssl_ctx.get(), kCustomExtensionValue, CustomExtensionAddCallback,
+ CustomExtensionFreeCallback, kCustomExtensionAddArg,
+ CustomExtensionParseCallback, kCustomExtensionParseArg)) {
+ return nullptr;
+ }
+
+ if (config->verify_fail) {
+ SSL_CTX_set_cert_verify_callback(ssl_ctx.get(), VerifyFail, NULL);
+ } else {
+ SSL_CTX_set_cert_verify_callback(ssl_ctx.get(), VerifySucceed, NULL);
+ }
+
+ if (!config->signed_cert_timestamps.empty() &&
+ !SSL_CTX_set_signed_cert_timestamp_list(
+ ssl_ctx.get(), (const uint8_t *)config->signed_cert_timestamps.data(),
+ config->signed_cert_timestamps.size())) {
+ return nullptr;
+ }
return ssl_ctx;
}
@@ -500,6 +787,9 @@ static bool RetryAsync(SSL *ssl, int ret) {
case SSL_ERROR_PENDING_CERTIFICATE:
// The handshake will resume without a second call to the early callback.
return InstallCertificate(ssl);
+ case SSL_ERROR_WANT_PRIVATE_KEY_OPERATION:
+ test_state->signature_retries++;
+ return true;
default:
return false;
}
@@ -531,6 +821,177 @@ static int WriteAll(SSL *ssl, const uint8_t *in, size_t in_len) {
return ret;
}
+// DoShutdown calls |SSL_shutdown|, resolving any asynchronous operations. It
+// returns the result of the final |SSL_shutdown| call.
+static int DoShutdown(SSL *ssl) {
+ const TestConfig *config = GetConfigPtr(ssl);
+ int ret;
+ do {
+ ret = SSL_shutdown(ssl);
+ } while (config->async && RetryAsync(ssl, ret));
+ return ret;
+}
+
+// CheckHandshakeProperties checks, immediately after |ssl| completes its
+// initial handshake (or False Starts), whether all the properties are
+// consistent with the test configuration and invariants.
+static bool CheckHandshakeProperties(SSL *ssl, bool is_resume) {
+ const TestConfig *config = GetConfigPtr(ssl);
+
+ if (SSL_get_current_cipher(ssl) == nullptr) {
+ fprintf(stderr, "null cipher after handshake\n");
+ return false;
+ }
+
+ if (is_resume &&
+ (!!SSL_session_reused(ssl) == config->expect_session_miss)) {
+ fprintf(stderr, "session was%s reused\n",
+ SSL_session_reused(ssl) ? "" : " not");
+ return false;
+ }
+
+ bool expect_handshake_done = is_resume || !config->false_start;
+ if (expect_handshake_done != GetTestState(ssl)->handshake_done) {
+ fprintf(stderr, "handshake was%s completed\n",
+ GetTestState(ssl)->handshake_done ? "" : " not");
+ return false;
+ }
+
+ if (expect_handshake_done && !config->is_server) {
+ bool expect_new_session =
+ !config->expect_no_session &&
+ (!SSL_session_reused(ssl) || config->expect_ticket_renewal);
+ if (expect_new_session != GetTestState(ssl)->got_new_session) {
+ fprintf(stderr,
+ "new session was%s established, but we expected the opposite\n",
+ GetTestState(ssl)->got_new_session ? "" : " not");
+ return false;
+ }
+ }
+
+ if (config->is_server && !GetTestState(ssl)->early_callback_called) {
+ fprintf(stderr, "early callback not called\n");
+ return false;
+ }
+
+ if (!config->expected_server_name.empty()) {
+ const char *server_name =
+ SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name);
+ if (server_name != config->expected_server_name) {
+ fprintf(stderr, "servername mismatch (got %s; want %s)\n",
+ server_name, config->expected_server_name.c_str());
+ return false;
+ }
+ }
+
+ if (!config->expected_certificate_types.empty()) {
+ const uint8_t *certificate_types;
+ size_t certificate_types_len =
+ SSL_get0_certificate_types(ssl, &certificate_types);
+ if (certificate_types_len != config->expected_certificate_types.size() ||
+ memcmp(certificate_types,
+ config->expected_certificate_types.data(),
+ certificate_types_len) != 0) {
+ fprintf(stderr, "certificate types mismatch\n");
+ return false;
+ }
+ }
+
+ if (!config->expected_next_proto.empty()) {
+ const uint8_t *next_proto;
+ unsigned next_proto_len;
+ SSL_get0_next_proto_negotiated(ssl, &next_proto, &next_proto_len);
+ if (next_proto_len != config->expected_next_proto.size() ||
+ memcmp(next_proto, config->expected_next_proto.data(),
+ next_proto_len) != 0) {
+ fprintf(stderr, "negotiated next proto mismatch\n");
+ return false;
+ }
+ }
+
+ if (!config->expected_alpn.empty()) {
+ const uint8_t *alpn_proto;
+ unsigned alpn_proto_len;
+ SSL_get0_alpn_selected(ssl, &alpn_proto, &alpn_proto_len);
+ if (alpn_proto_len != config->expected_alpn.size() ||
+ memcmp(alpn_proto, config->expected_alpn.data(),
+ alpn_proto_len) != 0) {
+ fprintf(stderr, "negotiated alpn proto mismatch\n");
+ return false;
+ }
+ }
+
+ if (!config->expected_channel_id.empty()) {
+ uint8_t channel_id[64];
+ if (!SSL_get_tls_channel_id(ssl, channel_id, sizeof(channel_id))) {
+ fprintf(stderr, "no channel id negotiated\n");
+ return false;
+ }
+ if (config->expected_channel_id.size() != 64 ||
+ memcmp(config->expected_channel_id.data(),
+ channel_id, 64) != 0) {
+ fprintf(stderr, "channel id mismatch\n");
+ return false;
+ }
+ }
+
+ if (config->expect_extended_master_secret) {
+ if (!ssl->session->extended_master_secret) {
+ fprintf(stderr, "No EMS for session when expected");
+ return false;
+ }
+ }
+
+ if (!config->expected_ocsp_response.empty()) {
+ const uint8_t *data;
+ size_t len;
+ SSL_get0_ocsp_response(ssl, &data, &len);
+ if (config->expected_ocsp_response.size() != len ||
+ memcmp(config->expected_ocsp_response.data(), data, len) != 0) {
+ fprintf(stderr, "OCSP response mismatch\n");
+ return false;
+ }
+ }
+
+ if (!config->expected_signed_cert_timestamps.empty()) {
+ const uint8_t *data;
+ size_t len;
+ SSL_get0_signed_cert_timestamp_list(ssl, &data, &len);
+ if (config->expected_signed_cert_timestamps.size() != len ||
+ memcmp(config->expected_signed_cert_timestamps.data(),
+ data, len) != 0) {
+ fprintf(stderr, "SCT list mismatch\n");
+ return false;
+ }
+ }
+
+ if (config->expect_verify_result) {
+ int expected_verify_result = config->verify_fail ?
+ X509_V_ERR_APPLICATION_VERIFICATION :
+ X509_V_OK;
+
+ if (SSL_get_verify_result(ssl) != expected_verify_result) {
+ fprintf(stderr, "Wrong certificate verification result\n");
+ return false;
+ }
+ }
+
+ if (!config->is_server) {
+ /* Clients should expect a peer certificate chain iff this was not a PSK
+ * cipher suite. */
+ if (config->psk.empty()) {
+ if (SSL_get_peer_cert_chain(ssl) == nullptr) {
+ fprintf(stderr, "Missing peer certificate chain!\n");
+ return false;
+ }
+ } else if (SSL_get_peer_cert_chain(ssl) != nullptr) {
+ fprintf(stderr, "Unexpected peer certificate chain!\n");
+ return false;
+ }
+ }
+ return true;
+}
+
// DoExchange runs a test SSL exchange against the peer. On success, it returns
// true and sets |*out_session| to the negotiated SSL session. If the test is a
// resumption attempt, |is_resume| is true and |session| is the session from the
@@ -562,7 +1023,10 @@ static bool DoExchange(ScopedSSL_SESSION *out_session, SSL_CTX *ssl_ctx,
}
if (config->require_any_client_certificate) {
SSL_set_verify(ssl.get(), SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
- SkipVerify);
+ NULL);
+ }
+ if (config->verify_peer) {
+ SSL_set_verify(ssl.get(), SSL_VERIFY_PEER, NULL);
}
if (config->false_start) {
SSL_set_mode(ssl.get(), SSL_MODE_ENABLE_FALSE_START);
@@ -588,8 +1052,8 @@ static bool DoExchange(ScopedSSL_SESSION *out_session, SSL_CTX *ssl_ctx,
if (config->tls_d5_bug) {
SSL_set_options(ssl.get(), SSL_OP_TLS_D5_BUG);
}
- if (config->allow_unsafe_legacy_renegotiation) {
- SSL_set_options(ssl.get(), SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION);
+ if (config->microsoft_big_sslv3_buffer) {
+ SSL_set_options(ssl.get(), SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER);
}
if (config->no_legacy_server_connect) {
SSL_clear_options(ssl.get(), SSL_OP_LEGACY_SERVER_CONNECT);
@@ -637,7 +1101,6 @@ static bool DoExchange(ScopedSSL_SESSION *out_session, SSL_CTX *ssl_ctx,
!SSL_enable_signed_cert_timestamps(ssl.get())) {
return false;
}
- SSL_enable_fastradio_padding(ssl.get(), config->fastradio_padding);
if (config->min_version != 0) {
SSL_set_min_version(ssl.get(), (uint16_t)config->min_version);
}
@@ -651,14 +1114,13 @@ static bool DoExchange(ScopedSSL_SESSION *out_session, SSL_CTX *ssl_ctx,
if (config->install_ddos_callback) {
SSL_CTX_set_dos_protection_cb(ssl_ctx, DDoSCallback);
}
- if (!config->cipher.empty() &&
- !SSL_set_cipher_list(ssl.get(), config->cipher.c_str())) {
- return false;
- }
if (!config->reject_peer_renegotiations) {
/* Renegotiations are disabled by default. */
SSL_set_reject_peer_renegotiations(ssl.get(), 0);
}
+ if (!config->check_close_notify) {
+ SSL_set_quiet_shutdown(ssl.get(), 1);
+ }
int sock = Connect(config->port);
if (sock == -1) {
@@ -719,139 +1181,14 @@ static bool DoExchange(ScopedSSL_SESSION *out_session, SSL_CTX *ssl_ctx,
ret = SSL_connect(ssl.get());
}
} while (config->async && RetryAsync(ssl.get(), ret));
- if (ret != 1) {
- return false;
- }
-
- if (SSL_get_current_cipher(ssl.get()) == nullptr) {
- fprintf(stderr, "null cipher after handshake\n");
- return false;
- }
-
- if (is_resume &&
- (!!SSL_session_reused(ssl.get()) == config->expect_session_miss)) {
- fprintf(stderr, "session was%s reused\n",
- SSL_session_reused(ssl.get()) ? "" : " not");
- return false;
- }
-
- bool expect_handshake_done = is_resume || !config->false_start;
- if (expect_handshake_done != GetTestState(ssl.get())->handshake_done) {
- fprintf(stderr, "handshake was%s completed\n",
- GetTestState(ssl.get())->handshake_done ? "" : " not");
- return false;
- }
-
- if (config->is_server && !GetTestState(ssl.get())->early_callback_called) {
- fprintf(stderr, "early callback not called\n");
+ if (ret != 1 ||
+ !CheckHandshakeProperties(ssl.get(), is_resume)) {
return false;
}
- if (!config->expected_server_name.empty()) {
- const char *server_name =
- SSL_get_servername(ssl.get(), TLSEXT_NAMETYPE_host_name);
- if (server_name != config->expected_server_name) {
- fprintf(stderr, "servername mismatch (got %s; want %s)\n",
- server_name, config->expected_server_name.c_str());
- return false;
- }
- }
-
- if (!config->expected_certificate_types.empty()) {
- uint8_t *certificate_types;
- int num_certificate_types =
- SSL_get0_certificate_types(ssl.get(), &certificate_types);
- if (num_certificate_types !=
- (int)config->expected_certificate_types.size() ||
- memcmp(certificate_types,
- config->expected_certificate_types.data(),
- num_certificate_types) != 0) {
- fprintf(stderr, "certificate types mismatch\n");
- return false;
- }
- }
-
- if (!config->expected_next_proto.empty()) {
- const uint8_t *next_proto;
- unsigned next_proto_len;
- SSL_get0_next_proto_negotiated(ssl.get(), &next_proto, &next_proto_len);
- if (next_proto_len != config->expected_next_proto.size() ||
- memcmp(next_proto, config->expected_next_proto.data(),
- next_proto_len) != 0) {
- fprintf(stderr, "negotiated next proto mismatch\n");
- return false;
- }
- }
-
- if (!config->expected_alpn.empty()) {
- const uint8_t *alpn_proto;
- unsigned alpn_proto_len;
- SSL_get0_alpn_selected(ssl.get(), &alpn_proto, &alpn_proto_len);
- if (alpn_proto_len != config->expected_alpn.size() ||
- memcmp(alpn_proto, config->expected_alpn.data(),
- alpn_proto_len) != 0) {
- fprintf(stderr, "negotiated alpn proto mismatch\n");
- return false;
- }
- }
-
- if (!config->expected_channel_id.empty()) {
- uint8_t channel_id[64];
- if (!SSL_get_tls_channel_id(ssl.get(), channel_id, sizeof(channel_id))) {
- fprintf(stderr, "no channel id negotiated\n");
- return false;
- }
- if (config->expected_channel_id.size() != 64 ||
- memcmp(config->expected_channel_id.data(),
- channel_id, 64) != 0) {
- fprintf(stderr, "channel id mismatch\n");
- return false;
- }
- }
-
- if (config->expect_extended_master_secret) {
- if (!ssl->session->extended_master_secret) {
- fprintf(stderr, "No EMS for session when expected");
- return false;
- }
- }
-
- if (!config->expected_ocsp_response.empty()) {
- const uint8_t *data;
- size_t len;
- SSL_get0_ocsp_response(ssl.get(), &data, &len);
- if (config->expected_ocsp_response.size() != len ||
- memcmp(config->expected_ocsp_response.data(), data, len) != 0) {
- fprintf(stderr, "OCSP response mismatch\n");
- return false;
- }
- }
-
- if (!config->expected_signed_cert_timestamps.empty()) {
- const uint8_t *data;
- size_t len;
- SSL_get0_signed_cert_timestamp_list(ssl.get(), &data, &len);
- if (config->expected_signed_cert_timestamps.size() != len ||
- memcmp(config->expected_signed_cert_timestamps.data(),
- data, len) != 0) {
- fprintf(stderr, "SCT list mismatch\n");
- return false;
- }
- }
-
- if (!config->is_server) {
- /* Clients should expect a peer certificate chain iff this was not a PSK
- * cipher suite. */
- if (config->psk.empty()) {
- if (SSL_get_peer_cert_chain(ssl.get()) == nullptr) {
- fprintf(stderr, "Missing peer certificate chain!\n");
- return false;
- }
- } else if (SSL_get_peer_cert_chain(ssl.get()) != nullptr) {
- fprintf(stderr, "Unexpected peer certificate chain!\n");
- return false;
- }
- }
+ // Reset the state to assert later that the callback isn't called in
+ // renegotations.
+ GetTestState(ssl.get())->got_new_session = false;
}
if (config->export_keying_material > 0) {
@@ -897,18 +1234,19 @@ static bool DoExchange(ScopedSSL_SESSION *out_session, SSL_CTX *ssl_ctx,
}
// This mode writes a number of different record sizes in an attempt to
// trip up the CBC record splitting code.
- uint8_t buf[32769];
- memset(buf, 0x42, sizeof(buf));
+ static const size_t kBufLen = 32769;
+ std::unique_ptr<uint8_t[]> buf(new uint8_t[kBufLen]);
+ memset(buf.get(), 0x42, kBufLen);
static const size_t kRecordSizes[] = {
0, 1, 255, 256, 257, 16383, 16384, 16385, 32767, 32768, 32769};
for (size_t i = 0; i < sizeof(kRecordSizes) / sizeof(kRecordSizes[0]);
i++) {
const size_t len = kRecordSizes[i];
- if (len > sizeof(buf)) {
+ if (len > kBufLen) {
fprintf(stderr, "Bad kRecordSizes value.\n");
return false;
}
- if (WriteAll(ssl.get(), buf, len) < 0) {
+ if (WriteAll(ssl.get(), buf.get(), len) < 0) {
return false;
}
}
@@ -919,53 +1257,82 @@ static bool DoExchange(ScopedSSL_SESSION *out_session, SSL_CTX *ssl_ctx,
return false;
}
}
- for (;;) {
- uint8_t buf[512];
- int n = DoRead(ssl.get(), buf, sizeof(buf));
- int err = SSL_get_error(ssl.get(), n);
- if (err == SSL_ERROR_ZERO_RETURN ||
- (n == 0 && err == SSL_ERROR_SYSCALL)) {
- if (n != 0) {
- fprintf(stderr, "Invalid SSL_get_error output\n");
+ if (!config->shim_shuts_down) {
+ for (;;) {
+ static const size_t kBufLen = 16384;
+ std::unique_ptr<uint8_t[]> buf(new uint8_t[kBufLen]);
+
+ // Read only 512 bytes at a time in TLS to ensure records may be
+ // returned in multiple reads.
+ int n = DoRead(ssl.get(), buf.get(), config->is_dtls ? kBufLen : 512);
+ int err = SSL_get_error(ssl.get(), n);
+ if (err == SSL_ERROR_ZERO_RETURN ||
+ (n == 0 && err == SSL_ERROR_SYSCALL)) {
+ if (n != 0) {
+ fprintf(stderr, "Invalid SSL_get_error output\n");
+ return false;
+ }
+ // Stop on either clean or unclean shutdown.
+ break;
+ } else if (err != SSL_ERROR_NONE) {
+ if (n > 0) {
+ fprintf(stderr, "Invalid SSL_get_error output\n");
+ return false;
+ }
return false;
}
- // Accept shutdowns with or without close_notify.
- // TODO(davidben): Write tests which distinguish these two cases.
- break;
- } else if (err != SSL_ERROR_NONE) {
- if (n > 0) {
+ // Successfully read data.
+ if (n <= 0) {
fprintf(stderr, "Invalid SSL_get_error output\n");
return false;
}
- return false;
- }
- // Successfully read data.
- if (n <= 0) {
- fprintf(stderr, "Invalid SSL_get_error output\n");
- return false;
- }
- // After a successful read, with or without False Start, the handshake
- // must be complete.
- if (!GetTestState(ssl.get())->handshake_done) {
- fprintf(stderr, "handshake was not completed after SSL_read\n");
- return false;
- }
+ // After a successful read, with or without False Start, the handshake
+ // must be complete.
+ if (!GetTestState(ssl.get())->handshake_done) {
+ fprintf(stderr, "handshake was not completed after SSL_read\n");
+ return false;
+ }
- for (int i = 0; i < n; i++) {
- buf[i] ^= 0xff;
- }
- if (WriteAll(ssl.get(), buf, n) < 0) {
- return false;
+ for (int i = 0; i < n; i++) {
+ buf[i] ^= 0xff;
+ }
+ if (WriteAll(ssl.get(), buf.get(), n) < 0) {
+ return false;
+ }
}
}
}
+ if (!config->is_server && !config->false_start &&
+ !config->implicit_handshake &&
+ GetTestState(ssl.get())->got_new_session) {
+ fprintf(stderr, "new session was established after the handshake\n");
+ return false;
+ }
+
if (out_session) {
out_session->reset(SSL_get1_session(ssl.get()));
}
- SSL_shutdown(ssl.get());
+ ret = DoShutdown(ssl.get());
+
+ if (config->shim_shuts_down && config->check_close_notify) {
+ // We initiate shutdown, so |SSL_shutdown| will return in two stages. First
+ // it returns zero when our close_notify is sent, then one when the peer's
+ // is received.
+ if (ret != 0) {
+ fprintf(stderr, "Unexpected SSL_shutdown result: %d != 0\n", ret);
+ return false;
+ }
+ ret = DoShutdown(ssl.get());
+ }
+
+ if (ret != 1) {
+ fprintf(stderr, "Unexpected SSL_shutdown result: %d != 1\n", ret);
+ return false;
+ }
+
return true;
}
diff --git a/src/ssl/test/runner/cipher_suites.go b/src/ssl/test/runner/cipher_suites.go
index 70c7262..ffc056d 100644
--- a/src/ssl/test/runner/cipher_suites.go
+++ b/src/ssl/test/runner/cipher_suites.go
@@ -102,7 +102,6 @@ var cipherSuites = []*cipherSuite{
{TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384, 32, 48, 16, ecdheECDSAKA, suiteECDHE | suiteECDSA | suiteTLS12 | suiteSHA384, cipherAES, macSHA384, nil},
{TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, 32, 20, 16, ecdheRSAKA, suiteECDHE, cipherAES, macSHA1, nil},
{TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, 32, 20, 16, ecdheECDSAKA, suiteECDHE | suiteECDSA, cipherAES, macSHA1, nil},
- {TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 32, 0, 0, dheRSAKA, suiteTLS12, nil, nil, aeadCHACHA20POLY1305},
{TLS_DHE_RSA_WITH_AES_128_GCM_SHA256, 16, 0, 4, dheRSAKA, suiteTLS12, nil, nil, aeadAESGCM},
{TLS_DHE_RSA_WITH_AES_256_GCM_SHA384, 32, 0, 4, dheRSAKA, suiteTLS12 | suiteSHA384, nil, nil, aeadAESGCM},
{TLS_DHE_RSA_WITH_AES_128_CBC_SHA256, 16, 32, 16, dheRSAKA, suiteTLS12, cipherAES, macSHA256, nil},
@@ -120,12 +119,18 @@ var cipherSuites = []*cipherSuite{
{TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, 24, 20, 8, ecdheRSAKA, suiteECDHE, cipher3DES, macSHA1, nil},
{TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA, 24, 20, 8, dheRSAKA, 0, cipher3DES, macSHA1, nil},
{TLS_RSA_WITH_3DES_EDE_CBC_SHA, 24, 20, 8, rsaKA, 0, cipher3DES, macSHA1, nil},
- {TLS_ECDHE_PSK_WITH_AES_128_GCM_SHA256, 16, 0, 4, ecdhePSKKA, suiteECDHE | suiteTLS12 | suitePSK, nil, nil, aeadAESGCM},
{TLS_PSK_WITH_RC4_128_SHA, 16, 20, 0, pskKA, suiteNoDTLS | suitePSK, cipherRC4, macSHA1, nil},
{TLS_PSK_WITH_AES_128_CBC_SHA, 16, 20, 16, pskKA, suitePSK, cipherAES, macSHA1, nil},
{TLS_PSK_WITH_AES_256_CBC_SHA, 32, 20, 16, pskKA, suitePSK, cipherAES, macSHA1, nil},
{TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA, 16, 20, 16, ecdhePSKKA, suiteECDHE | suitePSK, cipherAES, macSHA1, nil},
{TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA, 32, 20, 16, ecdhePSKKA, suiteECDHE | suitePSK, cipherAES, macSHA1, nil},
+ {TLS_RSA_WITH_NULL_SHA, 0, 20, 0, rsaKA, suiteNoDTLS, cipherNull, macSHA1, nil},
+}
+
+type nullCipher struct{}
+
+func cipherNull(key, iv []byte, isRead bool) interface{} {
+ return nullCipher{}
}
func cipherRC4(key, iv []byte, isRead bool) interface{} {
@@ -370,6 +375,7 @@ func mutualCipherSuite(have []uint16, want uint16) *cipherSuite {
// A list of the possible cipher suite ids. Taken from
// http://www.iana.org/assignments/tls-parameters/tls-parameters.xml
const (
+ TLS_RSA_WITH_NULL_SHA uint16 = 0x0002
TLS_RSA_WITH_RC4_128_MD5 uint16 = 0x0004
TLS_RSA_WITH_RC4_128_SHA uint16 = 0x0005
TLS_RSA_WITH_3DES_EDE_CBC_SHA uint16 = 0x000a
@@ -406,13 +412,12 @@ const (
TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 uint16 = 0xc030
TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA uint16 = 0xc035
TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA uint16 = 0xc036
+ renegotiationSCSV uint16 = 0x00ff
fallbackSCSV uint16 = 0x5600
)
// Additional cipher suite IDs, not IANA-assigned.
const (
- TLS_ECDHE_PSK_WITH_AES_128_GCM_SHA256 uint16 = 0xcafe
TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 uint16 = 0xcc13
TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 uint16 = 0xcc14
- TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256 uint16 = 0xcc15
)
diff --git a/src/ssl/test/runner/common.go b/src/ssl/test/runner/common.go
index edebba1..77be9f6 100644
--- a/src/ssl/test/runner/common.go
+++ b/src/ssl/test/runner/common.go
@@ -82,6 +82,7 @@ const (
extensionSignedCertificateTimestamp uint16 = 18
extensionExtendedMasterSecret uint16 = 23
extensionSessionTicket uint16 = 35
+ extensionCustom uint16 = 1234 // not IANA assigned
extensionNextProtoNeg uint16 = 13172 // not IANA assigned
extensionRenegotiationInfo uint16 = 0xff01
extensionChannelID uint16 = 30032 // not IANA assigned
@@ -188,7 +189,9 @@ type ConnectionState struct {
VerifiedChains [][]*x509.Certificate // verified chains built from PeerCertificates
ChannelID *ecdsa.PublicKey // the channel ID for this connection
SRTPProtectionProfile uint16 // the negotiated DTLS-SRTP protection profile
- TLSUnique []byte
+ TLSUnique []byte // the tls-unique channel binding
+ SCTList []byte // signed certificate timestamp list
+ ClientCertSignatureHash uint8 // TLS id of the hash used by the client to sign the handshake
}
// ClientAuthType declares the policy the server will follow for
@@ -214,6 +217,8 @@ type ClientSessionState struct {
handshakeHash []byte // Handshake hash for Channel ID purposes.
serverCertificates []*x509.Certificate // Certificate chain presented by the server
extendedMasterSecret bool // Whether an extended master secret was used to generate the session
+ sctList []byte
+ ocspResponse []byte
}
// ClientSessionCache is a cache of ClientSessionState objects that can be used
@@ -399,6 +404,10 @@ type ProtocolBugs struct {
// ServerKeyExchange message should be invalid.
InvalidSKXSignature bool
+ // InvalidCertVerifySignature specifies that the signature in a
+ // CertificateVerify message should be invalid.
+ InvalidCertVerifySignature bool
+
// InvalidSKXCurve causes the curve ID in the ServerKeyExchange message
// to be wrong.
InvalidSKXCurve bool
@@ -476,6 +485,10 @@ type ProtocolBugs struct {
// TLS_FALLBACK_SCSV in the ClientHello.
SendFallbackSCSV bool
+ // SendRenegotiationSCSV causes the client to include the renegotiation
+ // SCSV in the ClientHello.
+ SendRenegotiationSCSV bool
+
// MaxHandshakeRecordLength, if non-zero, is the maximum size of a
// handshake record. Handshake messages will be split into multiple
// records at the specified size, except that the client_version will
@@ -535,11 +548,14 @@ type ProtocolBugs struct {
// must specify in the server_name extension.
ExpectServerName string
- // SwapNPNAndALPN switches the relative order between NPN and
- // ALPN on the server. This is to test that server preference
- // of ALPN works regardless of their relative order.
+ // SwapNPNAndALPN switches the relative order between NPN and ALPN in
+ // both ClientHello and ServerHello.
SwapNPNAndALPN bool
+ // ALPNProtocol, if not nil, sets the ALPN protocol that a server will
+ // return.
+ ALPNProtocol *string
+
// AllowSessionVersionMismatch causes the server to resume sessions
// regardless of the version associated with the session.
AllowSessionVersionMismatch bool
@@ -572,11 +588,15 @@ type ProtocolBugs struct {
// didn't support the renegotiation info extension.
NoRenegotiationInfo bool
- // SequenceNumberIncrement, if non-zero, causes outgoing sequence
- // numbers in DTLS to increment by that value rather by 1. This is to
- // stress the replay bitmap window by simulating extreme packet loss and
- // retransmit at the record layer.
- SequenceNumberIncrement uint64
+ // RequireRenegotiationInfo, if true, causes the client to return an
+ // error if the server doesn't reply with the renegotiation extension.
+ RequireRenegotiationInfo bool
+
+ // SequenceNumberMapping, if non-nil, is the mapping function to apply
+ // to the sequence number of outgoing packets. For both TLS and DTLS,
+ // the two most-significant bytes in the resulting sequence number are
+ // ignored so that the DTLS epoch cannot be changed.
+ SequenceNumberMapping func(uint64) uint64
// RSAEphemeralKey, if true, causes the server to send a
// ServerKeyExchange message containing an ephemeral key (as in
@@ -609,10 +629,6 @@ type ProtocolBugs struct {
// across a renego.
RequireSameRenegoClientVersion bool
- // RequireFastradioPadding, if true, requires that ClientHello messages
- // be at least 1000 bytes long.
- RequireFastradioPadding bool
-
// ExpectInitialRecordVersion, if non-zero, is the expected
// version of the records before the version is determined.
ExpectInitialRecordVersion uint16
@@ -626,7 +642,11 @@ type ProtocolBugs struct {
// the server believes it has actually negotiated.
SendCipherSuite uint16
- // AppDataAfterChangeCipherSpec, if not null, causes application data to
+ // AppDataBeforeHandshake, if not nil, causes application data to be
+ // sent immediately before the first handshake message.
+ AppDataBeforeHandshake []byte
+
+ // AppDataAfterChangeCipherSpec, if not nil, causes application data to
// be sent immediately after ChangeCipherSpec.
AppDataAfterChangeCipherSpec []byte
@@ -668,17 +688,10 @@ type ProtocolBugs struct {
// handshake fragments in DTLS to have the wrong message length.
FragmentMessageLengthMismatch bool
- // SplitFragmentHeader, if true, causes the handshake fragments in DTLS
- // to be split across two records.
- SplitFragmentHeader bool
-
- // SplitFragmentBody, if true, causes the handshake bodies in DTLS to be
- // split across two records.
- //
- // TODO(davidben): There's one final split to test: when the header and
- // body are split across two records. But those are (incorrectly)
- // accepted right now.
- SplitFragmentBody bool
+ // SplitFragments, if non-zero, causes the handshake fragments in DTLS
+ // to be split across two records. The value of |SplitFragments| is the
+ // number of bytes in the first fragment.
+ SplitFragments int
// SendEmptyFragments, if true, causes handshakes to include empty
// fragments in DTLS.
@@ -705,10 +718,6 @@ type ProtocolBugs struct {
// preferences to be ignored.
IgnorePeerCurvePreferences bool
- // SendWarningAlerts, if non-zero, causes every record to be prefaced by
- // a warning alert.
- SendWarningAlerts alert
-
// BadFinished, if true, causes the Finished hash to be broken.
BadFinished bool
@@ -727,6 +736,43 @@ type ProtocolBugs struct {
// EnableAllCiphersInDTLS, if true, causes RC4 to be enabled in DTLS.
EnableAllCiphersInDTLS bool
+
+ // EmptyCertificateList, if true, causes the server to send an empty
+ // certificate list in the Certificate message.
+ EmptyCertificateList bool
+
+ // ExpectNewTicket, if true, causes the client to abort if it does not
+ // receive a new ticket.
+ ExpectNewTicket bool
+
+ // RequireClientHelloSize, if not zero, is the required length in bytes
+ // of the ClientHello /record/. This is checked by the server.
+ RequireClientHelloSize int
+
+ // CustomExtension, if not empty, contains the contents of an extension
+ // that will be added to client/server hellos.
+ CustomExtension string
+
+ // ExpectedCustomExtension, if not nil, contains the expected contents
+ // of a custom extension.
+ ExpectedCustomExtension *string
+
+ // NoCloseNotify, if true, causes the close_notify alert to be skipped
+ // on connection shutdown.
+ NoCloseNotify bool
+
+ // ExpectCloseNotify, if true, requires a close_notify from the peer on
+ // shutdown. Records from the peer received after close_notify is sent
+ // are not discard.
+ ExpectCloseNotify bool
+
+ // SendLargeRecords, if true, allows outgoing records to be sent
+ // arbitrarily large.
+ SendLargeRecords bool
+
+ // NegotiateALPNAndNPN, if true, causes the server to negotiate both
+ // ALPN and NPN in the same connetion.
+ NegotiateALPNAndNPN bool
}
func (c *Config) serverInit() {
diff --git a/src/ssl/test/runner/conn.go b/src/ssl/test/runner/conn.go
index adbc1c3..39bdfda 100644
--- a/src/ssl/test/runner/conn.go
+++ b/src/ssl/test/runner/conn.go
@@ -12,6 +12,7 @@ import (
"crypto/ecdsa"
"crypto/subtle"
"crypto/x509"
+ "encoding/binary"
"errors"
"fmt"
"io"
@@ -39,6 +40,7 @@ type Conn struct {
extendedMasterSecret bool // whether this session used an extended master secret
cipherSuite *cipherSuite
ocspResponse []byte // stapled OCSP response
+ sctList []byte // signed certificate timestamp list
peerCertificates []*x509.Certificate
// verifiedChains contains the certificate chains that we built, as
// opposed to the ones presented by the server.
@@ -48,6 +50,11 @@ type Conn struct {
// firstFinished contains the first Finished hash sent during the
// handshake. This is the "tls-unique" channel binding value.
firstFinished [12]byte
+ // clientCertSignatureHash contains the TLS hash id for the hash that
+ // was used by the client to sign the handshake with a client
+ // certificate. This is only set by a server and is zero if no client
+ // certificates were used.
+ clientCertSignatureHash uint8
clientRandom, serverRandom [32]byte
masterSecret [48]byte
@@ -87,6 +94,8 @@ func (c *Conn) init() {
c.out.isDTLS = c.isDTLS
c.in.config = c.config
c.out.config = c.config
+
+ c.out.updateOutSeq()
}
// Access to net.Conn methods.
@@ -134,6 +143,7 @@ type halfConn struct {
cipher interface{} // cipher algorithm
mac macFunction
seq [8]byte // 64-bit sequence number
+ outSeq [8]byte // Mapped sequence number
bfree *block // list of free blocks
nextCipher interface{} // next encryption state
@@ -189,10 +199,6 @@ func (hc *halfConn) incSeq(isOutgoing bool) {
if hc.isDTLS {
// Increment up to the epoch in DTLS.
limit = 2
-
- if isOutgoing && hc.config.Bugs.SequenceNumberIncrement != 0 {
- increment = hc.config.Bugs.SequenceNumberIncrement
- }
}
for i := 7; i >= limit; i-- {
increment += uint64(hc.seq[i])
@@ -206,6 +212,8 @@ func (hc *halfConn) incSeq(isOutgoing bool) {
if increment != 0 {
panic("TLS: sequence number wraparound")
}
+
+ hc.updateOutSeq()
}
// incNextSeq increments the starting sequence number for the next epoch.
@@ -241,6 +249,22 @@ func (hc *halfConn) incEpoch() {
hc.seq[i] = 0
}
}
+
+ hc.updateOutSeq()
+}
+
+func (hc *halfConn) updateOutSeq() {
+ if hc.config.Bugs.SequenceNumberMapping != nil {
+ seqU64 := binary.BigEndian.Uint64(hc.seq[:])
+ seqU64 = hc.config.Bugs.SequenceNumberMapping(seqU64)
+ binary.BigEndian.PutUint64(hc.outSeq[:], seqU64)
+
+ // The DTLS epoch cannot be changed.
+ copy(hc.outSeq[:2], hc.seq[:2])
+ return
+ }
+
+ copy(hc.outSeq[:], hc.seq[:])
}
func (hc *halfConn) recordHeaderLen() int {
@@ -397,6 +421,8 @@ func (hc *halfConn) decrypt(b *block) (ok bool, prefixLen int, alertValue alert)
//
// However, our behavior matches OpenSSL, so we leak
// only as much as they do.
+ case nullCipher:
+ break
default:
panic("unknown cipher type")
}
@@ -460,7 +486,7 @@ func (hc *halfConn) encrypt(b *block, explicitIVLen int) (bool, alert) {
// mac
if hc.mac != nil {
- mac := hc.mac.MAC(hc.outDigestBuf, hc.seq[0:], b.data[:3], b.data[recordHeaderLen-2:recordHeaderLen], b.data[recordHeaderLen+explicitIVLen:])
+ mac := hc.mac.MAC(hc.outDigestBuf, hc.outSeq[0:], b.data[:3], b.data[recordHeaderLen-2:recordHeaderLen], b.data[recordHeaderLen+explicitIVLen:])
n := len(b.data)
b.resize(n + len(mac))
@@ -478,7 +504,7 @@ func (hc *halfConn) encrypt(b *block, explicitIVLen int) (bool, alert) {
case *tlsAead:
payloadLen := len(b.data) - recordHeaderLen - explicitIVLen
b.resize(len(b.data) + c.Overhead())
- nonce := hc.seq[:]
+ nonce := hc.outSeq[:]
if c.explicitNonce {
nonce = b.data[recordHeaderLen : recordHeaderLen+explicitIVLen]
}
@@ -486,7 +512,7 @@ func (hc *halfConn) encrypt(b *block, explicitIVLen int) (bool, alert) {
payload = payload[:payloadLen]
var additionalData [13]byte
- copy(additionalData[:], hc.seq[:])
+ copy(additionalData[:], hc.outSeq[:])
copy(additionalData[8:], b.data[:3])
additionalData[11] = byte(payloadLen >> 8)
additionalData[12] = byte(payloadLen)
@@ -502,6 +528,8 @@ func (hc *halfConn) encrypt(b *block, explicitIVLen int) (bool, alert) {
b.resize(recordHeaderLen + explicitIVLen + len(prefix) + len(finalBlock))
c.CryptBlocks(b.data[recordHeaderLen+explicitIVLen:], prefix)
c.CryptBlocks(b.data[recordHeaderLen+explicitIVLen+len(prefix):], finalBlock)
+ case nullCipher:
+ break
default:
panic("unknown cipher type")
}
@@ -630,10 +658,10 @@ func (c *Conn) doReadRecord(want recordType) (recordType, *block, error) {
if err := b.readFromUntil(c.conn, recordHeaderLen); err != nil {
// RFC suggests that EOF without an alertCloseNotify is
// an error, but popular web sites seem to do this,
- // so we can't make it an error.
- // if err == io.EOF {
- // err = io.ErrUnexpectedEOF
- // }
+ // so we can't make it an error, outside of tests.
+ if err == io.EOF && c.config.Bugs.ExpectCloseNotify {
+ err = io.ErrUnexpectedEOF
+ }
if e, ok := err.(net.Error); !ok || !e.Temporary() {
c.in.setErrorLocked(err)
}
@@ -722,6 +750,10 @@ func (c *Conn) readRecord(want recordType) error {
c.sendAlert(alertInternalError)
return c.in.setErrorLocked(errors.New("tls: application data record requested before handshake complete"))
}
+ case recordTypeAlert:
+ // Looking for a close_notify. Note: unlike a real
+ // implementation, this is not tolerant of additional records.
+ // See the documentation for ExpectCloseNotify.
}
Again:
@@ -784,7 +816,7 @@ Again:
// A client might need to process a HelloRequest from
// the server, thus receiving a handshake message when
// application data is expected is ok.
- if !c.isClient {
+ if !c.isClient || want != recordTypeApplicationData {
return c.in.setErrorLocked(c.sendAlert(alertNoRenegotiation))
}
}
@@ -799,13 +831,8 @@ Again:
// sendAlert sends a TLS alert message.
// c.out.Mutex <= L.
-func (c *Conn) sendAlertLocked(err alert) error {
- switch err {
- case alertNoRenegotiation, alertCloseNotify:
- c.tmp[0] = alertLevelWarning
- default:
- c.tmp[0] = alertLevelError
- }
+func (c *Conn) sendAlertLocked(level byte, err alert) error {
+ c.tmp[0] = level
c.tmp[1] = byte(err)
if c.config.Bugs.FragmentAlert {
c.writeRecord(recordTypeAlert, c.tmp[0:1])
@@ -813,8 +840,8 @@ func (c *Conn) sendAlertLocked(err alert) error {
} else {
c.writeRecord(recordTypeAlert, c.tmp[0:2])
}
- // closeNotify is a special case in that it isn't an error:
- if err != alertCloseNotify {
+ // Error alerts are fatal to the connection.
+ if level == alertLevelError {
return c.out.setErrorLocked(&net.OpError{Op: "local error", Err: err})
}
return nil
@@ -823,9 +850,17 @@ func (c *Conn) sendAlertLocked(err alert) error {
// sendAlert sends a TLS alert message.
// L < c.out.Mutex.
func (c *Conn) sendAlert(err alert) error {
+ level := byte(alertLevelError)
+ if err == alertNoRenegotiation || err == alertCloseNotify {
+ level = alertLevelWarning
+ }
+ return c.SendAlert(level, err)
+}
+
+func (c *Conn) SendAlert(level byte, err alert) error {
c.out.Lock()
defer c.out.Unlock()
- return c.sendAlertLocked(err)
+ return c.sendAlertLocked(level, err)
}
// writeV2Record writes a record for a V2ClientHello.
@@ -841,13 +876,6 @@ func (c *Conn) writeV2Record(data []byte) (n int, err error) {
// to the connection and updates the record layer state.
// c.out.Mutex <= L.
func (c *Conn) writeRecord(typ recordType, data []byte) (n int, err error) {
- if typ != recordTypeAlert && c.config.Bugs.SendWarningAlerts != 0 {
- alert := make([]byte, 2)
- alert[0] = alertLevelWarning
- alert[1] = byte(c.config.Bugs.SendWarningAlerts)
- c.writeRecord(recordTypeAlert, alert)
- }
-
if c.isDTLS {
return c.dtlsWriteRecord(typ, data)
}
@@ -856,9 +884,9 @@ func (c *Conn) writeRecord(typ recordType, data []byte) (n int, err error) {
b := c.out.newBlock()
first := true
isClientHello := typ == recordTypeHandshake && len(data) > 0 && data[0] == typeClientHello
- for len(data) > 0 {
+ for len(data) > 0 || first {
m := len(data)
- if m > maxPlaintext {
+ if m > maxPlaintext && !c.config.Bugs.SendLargeRecords {
m = maxPlaintext
}
if typ == recordTypeHandshake && c.config.Bugs.MaxHandshakeRecordLength > 0 && m > c.config.Bugs.MaxHandshakeRecordLength {
@@ -1038,6 +1066,9 @@ func (c *Conn) readHandshake() (interface{}, error) {
// sequence number expectations but otherwise ignores them.
func (c *Conn) skipPacket(packet []byte) error {
for len(packet) > 0 {
+ if len(packet) < 13 {
+ return errors.New("tls: bad packet")
+ }
// Dropped packets are completely ignored save to update
// expected sequence numbers for this and the next epoch. (We
// don't assert on the contents of the packets both for
@@ -1057,6 +1088,9 @@ func (c *Conn) skipPacket(packet []byte) error {
}
c.in.incNextSeq()
}
+ if len(packet) < 13+int(length) {
+ return errors.New("tls: bad packet")
+ }
packet = packet[13+length:]
}
return nil
@@ -1113,7 +1147,7 @@ func (c *Conn) Write(b []byte) (int, error) {
}
if c.config.Bugs.SendSpuriousAlert != 0 {
- c.sendAlertLocked(c.config.Bugs.SendSpuriousAlert)
+ c.sendAlertLocked(alertLevelError, c.config.Bugs.SendSpuriousAlert)
}
// SSL 3.0 and TLS 1.0 are susceptible to a chosen-plaintext
@@ -1240,10 +1274,22 @@ func (c *Conn) Close() error {
c.handshakeMutex.Lock()
defer c.handshakeMutex.Unlock()
- if c.handshakeComplete {
+ if c.handshakeComplete && !c.config.Bugs.NoCloseNotify {
alertErr = c.sendAlert(alertCloseNotify)
}
+ // Consume a close_notify from the peer if one hasn't been received
+ // already. This avoids the peer from failing |SSL_shutdown| due to a
+ // write failing.
+ if c.handshakeComplete && alertErr == nil && c.config.Bugs.ExpectCloseNotify {
+ for c.in.error() == nil {
+ c.readRecord(recordTypeAlert)
+ }
+ if c.in.error() != io.EOF {
+ alertErr = c.in.error()
+ }
+ }
+
if err := c.conn.Close(); err != nil {
return err
}
@@ -1273,6 +1319,9 @@ func (c *Conn) Handshake() error {
})
c.conn.Write([]byte{alertLevelError, byte(alertInternalError)})
}
+ if data := c.config.Bugs.AppDataBeforeHandshake; data != nil {
+ c.writeRecord(recordTypeApplicationData, data)
+ }
if c.isClient {
c.handshakeErr = c.clientHandshake()
} else {
@@ -1304,6 +1353,8 @@ func (c *Conn) ConnectionState() ConnectionState {
state.ChannelID = c.channelID
state.SRTPProtectionProfile = c.srtpProtectionProfile
state.TLSUnique = c.firstFinished[:]
+ state.SCTList = c.sctList
+ state.ClientCertSignatureHash = c.clientCertSignatureHash
}
return state
diff --git a/src/ssl/test/runner/dtls.go b/src/ssl/test/runner/dtls.go
index 50f7786..5c59dea 100644
--- a/src/ssl/test/runner/dtls.go
+++ b/src/ssl/test/runner/dtls.go
@@ -216,13 +216,10 @@ func (c *Conn) dtlsFlushHandshake() error {
// Pack handshake fragments into records.
var records [][]byte
for _, fragment := range fragments {
- if c.config.Bugs.SplitFragmentHeader {
- records = append(records, fragment[:2])
- records = append(records, fragment[2:])
- } else if c.config.Bugs.SplitFragmentBody {
- if len(fragment) > 12 {
- records = append(records, fragment[:13])
- records = append(records, fragment[13:])
+ if n := c.config.Bugs.SplitFragments; n > 0 {
+ if len(fragment) > n {
+ records = append(records, fragment[:n])
+ records = append(records, fragment[n:])
} else {
records = append(records, fragment)
}
@@ -301,13 +298,13 @@ func (c *Conn) dtlsSealRecord(typ recordType, data []byte) (b *block, err error)
b.data[1] = byte(vers >> 8)
b.data[2] = byte(vers)
// DTLS records include an explicit sequence number.
- copy(b.data[3:11], c.out.seq[0:])
+ copy(b.data[3:11], c.out.outSeq[0:])
b.data[11] = byte(len(data) >> 8)
b.data[12] = byte(len(data))
if explicitIVLen > 0 {
explicitIV := b.data[recordHeaderLen : recordHeaderLen+explicitIVLen]
if explicitIVIsSeq {
- copy(explicitIV, c.out.seq[:])
+ copy(explicitIV, c.out.outSeq[:])
} else {
if _, err = io.ReadFull(c.config.rand(), explicitIV); err != nil {
return
diff --git a/src/ssl/test/runner/handshake_client.go b/src/ssl/test/runner/handshake_client.go
index a950313..a3ce686 100644
--- a/src/ssl/test/runner/handshake_client.go
+++ b/src/ssl/test/runner/handshake_client.go
@@ -45,7 +45,7 @@ func (c *Conn) clientHandshake() error {
nextProtosLength := 0
for _, proto := range c.config.NextProtos {
- if l := len(proto); l == 0 || l > 255 {
+ if l := len(proto); l > 255 {
return errors.New("tls: invalid NextProtos value")
} else {
nextProtosLength += 1 + l
@@ -61,6 +61,7 @@ func (c *Conn) clientHandshake() error {
compressionMethods: []uint8{compressionNone},
random: make([]byte, 32),
ocspStapling: true,
+ sctListSupported: true,
serverName: c.config.ServerName,
supportedCurves: c.config.curvePreferences(),
supportedPoints: []uint8{pointFormatUncompressed},
@@ -73,6 +74,7 @@ func (c *Conn) clientHandshake() error {
extendedMasterSecret: c.config.maxVersion() >= VersionTLS10,
srtpProtectionProfiles: c.config.SRTPProtectionProfiles,
srtpMasterKeyIdentifier: c.config.Bugs.SRTPMasterKeyIdentifer,
+ customExtension: c.config.Bugs.CustomExtension,
}
if c.config.Bugs.SendClientVersion != 0 {
@@ -123,6 +125,10 @@ NextCipherSuite:
}
}
+ if c.config.Bugs.SendRenegotiationSCSV {
+ hello.cipherSuites = append(hello.cipherSuites, renegotiationSCSV)
+ }
+
if c.config.Bugs.SendFallbackSCSV {
hello.cipherSuites = append(hello.cipherSuites, fallbackSCSV)
}
@@ -272,6 +278,10 @@ NextCipherSuite:
return fmt.Errorf("tls: server selected an unsupported cipher suite")
}
+ if c.config.Bugs.RequireRenegotiationInfo && serverHello.secureRenegotiation == nil {
+ return errors.New("tls: renegotiation extension missing")
+ }
+
if len(c.clientVerify) > 0 && !c.config.Bugs.NoRenegotiationInfo {
var expectedRenegInfo []byte
expectedRenegInfo = append(expectedRenegInfo, c.clientVerify...)
@@ -282,6 +292,12 @@ NextCipherSuite:
}
}
+ if expected := c.config.Bugs.ExpectedCustomExtension; expected != nil {
+ if serverHello.customExtension != *expected {
+ return fmt.Errorf("tls: bad custom extension contents %q", serverHello.customExtension)
+ }
+ }
+
hs := &clientHandshakeState{
c: c,
serverHello: serverHello,
@@ -356,6 +372,7 @@ NextCipherSuite:
copy(c.clientRandom[:], hs.hello.random)
copy(c.serverRandom[:], hs.serverHello.random)
copy(c.masterSecret[:], hs.masterSecret)
+
return nil
}
@@ -607,6 +624,9 @@ func (hs *clientHandshakeState) doFullHandshake() error {
c.sendAlert(alertInternalError)
return err
}
+ if c.config.Bugs.InvalidCertVerifySignature {
+ digest[0] ^= 0x80
+ }
switch key := c.config.Certificates[0].PrivateKey.(type) {
case *ecdsa.PrivateKey:
@@ -730,13 +750,28 @@ func (hs *clientHandshakeState) processServerHello() (bool, error) {
return false, errors.New("tls: server resumed session on renegotiation")
}
+ if hs.serverHello.sctList != nil {
+ return false, errors.New("tls: server sent SCT extension on session resumption")
+ }
+
+ if hs.serverHello.ocspStapling {
+ return false, errors.New("tls: server sent OCSP extension on session resumption")
+ }
+
// Restore masterSecret and peerCerts from previous state
hs.masterSecret = hs.session.masterSecret
c.peerCertificates = hs.session.serverCertificates
c.extendedMasterSecret = hs.session.extendedMasterSecret
+ c.sctList = hs.session.sctList
+ c.ocspResponse = hs.session.ocspResponse
hs.finishedHash.discardHandshakeBuffer()
return true, nil
}
+
+ if hs.serverHello.sctList != nil {
+ c.sctList = hs.serverHello.sctList
+ }
+
return false, nil
}
@@ -783,9 +818,14 @@ func (hs *clientHandshakeState) readSessionTicket() error {
masterSecret: hs.masterSecret,
handshakeHash: hs.finishedHash.server.Sum(nil),
serverCertificates: c.peerCertificates,
+ sctList: c.sctList,
+ ocspResponse: c.ocspResponse,
}
if !hs.serverHello.ticketSupported {
+ if c.config.Bugs.ExpectNewTicket {
+ return errors.New("tls: expected new ticket")
+ }
if hs.session == nil && len(hs.serverHello.sessionId) > 0 {
session.sessionId = hs.serverHello.sessionId
hs.session = session
diff --git a/src/ssl/test/runner/handshake_messages.go b/src/ssl/test/runner/handshake_messages.go
index ce214fd..da85e7a 100644
--- a/src/ssl/test/runner/handshake_messages.go
+++ b/src/ssl/test/runner/handshake_messages.go
@@ -32,6 +32,7 @@ type clientHelloMsg struct {
srtpProtectionProfiles []uint16
srtpMasterKeyIdentifier string
sctListSupported bool
+ customExtension string
}
func (m *clientHelloMsg) equal(i interface{}) bool {
@@ -65,7 +66,8 @@ func (m *clientHelloMsg) equal(i interface{}) bool {
m.extendedMasterSecret == m1.extendedMasterSecret &&
eqUint16s(m.srtpProtectionProfiles, m1.srtpProtectionProfiles) &&
m.srtpMasterKeyIdentifier == m1.srtpMasterKeyIdentifier &&
- m.sctListSupported == m1.sctListSupported
+ m.sctListSupported == m1.sctListSupported &&
+ m.customExtension == m1.customExtension
}
func (m *clientHelloMsg) marshal() []byte {
@@ -119,7 +121,7 @@ func (m *clientHelloMsg) marshal() []byte {
if len(m.alpnProtocols) > 0 {
extensionsLength += 2
for _, s := range m.alpnProtocols {
- if l := len(s); l == 0 || l > 255 {
+ if l := len(s); l > 255 {
panic("invalid ALPN protocol")
}
extensionsLength++
@@ -138,6 +140,10 @@ func (m *clientHelloMsg) marshal() []byte {
if m.sctListSupported {
numExtensions++
}
+ if l := len(m.customExtension); l > 0 {
+ extensionsLength += l
+ numExtensions++
+ }
if numExtensions > 0 {
extensionsLength += 4 * numExtensions
length += 2 + extensionsLength
@@ -376,6 +382,14 @@ func (m *clientHelloMsg) marshal() []byte {
z[1] = byte(extensionSignedCertificateTimestamp & 0xff)
z = z[4:]
}
+ if l := len(m.customExtension); l > 0 {
+ z[0] = byte(extensionCustom >> 8)
+ z[1] = byte(extensionCustom & 0xff)
+ z[2] = byte(l >> 8)
+ z[3] = byte(l & 0xff)
+ copy(z[4:], []byte(m.customExtension))
+ z = z[4+l:]
+ }
m.raw = x
@@ -443,6 +457,7 @@ func (m *clientHelloMsg) unmarshal(data []byte) bool {
m.signatureAndHashes = nil
m.alpnProtocols = nil
m.extendedMasterSecret = false
+ m.customExtension = ""
if len(data) == 0 {
// ClientHello is optionally followed by extension data
@@ -604,6 +619,8 @@ func (m *clientHelloMsg) unmarshal(data []byte) bool {
return false
}
m.sctListSupported = true
+ case extensionCustom:
+ m.customExtension = string(data[:length])
}
data = data[length:]
}
@@ -625,40 +642,15 @@ type serverHelloMsg struct {
ticketSupported bool
secureRenegotiation []byte
alpnProtocol string
+ alpnProtocolEmpty bool
duplicateExtension bool
channelIDRequested bool
extendedMasterSecret bool
srtpProtectionProfile uint16
srtpMasterKeyIdentifier string
sctList []byte
-}
-
-func (m *serverHelloMsg) equal(i interface{}) bool {
- m1, ok := i.(*serverHelloMsg)
- if !ok {
- return false
- }
-
- return bytes.Equal(m.raw, m1.raw) &&
- m.isDTLS == m1.isDTLS &&
- m.vers == m1.vers &&
- bytes.Equal(m.random, m1.random) &&
- bytes.Equal(m.sessionId, m1.sessionId) &&
- m.cipherSuite == m1.cipherSuite &&
- m.compressionMethod == m1.compressionMethod &&
- m.nextProtoNeg == m1.nextProtoNeg &&
- eqStrings(m.nextProtos, m1.nextProtos) &&
- m.ocspStapling == m1.ocspStapling &&
- m.ticketSupported == m1.ticketSupported &&
- bytes.Equal(m.secureRenegotiation, m1.secureRenegotiation) &&
- (m.secureRenegotiation == nil) == (m1.secureRenegotiation == nil) &&
- m.alpnProtocol == m1.alpnProtocol &&
- m.duplicateExtension == m1.duplicateExtension &&
- m.channelIDRequested == m1.channelIDRequested &&
- m.extendedMasterSecret == m1.extendedMasterSecret &&
- m.srtpProtectionProfile == m1.srtpProtectionProfile &&
- m.srtpMasterKeyIdentifier == m1.srtpMasterKeyIdentifier &&
- bytes.Equal(m.sctList, m1.sctList)
+ customExtension string
+ npnLast bool
}
func (m *serverHelloMsg) marshal() []byte {
@@ -695,7 +687,7 @@ func (m *serverHelloMsg) marshal() []byte {
if m.channelIDRequested {
numExtensions++
}
- if alpnLen := len(m.alpnProtocol); alpnLen > 0 {
+ if alpnLen := len(m.alpnProtocol); alpnLen > 0 || m.alpnProtocolEmpty {
if alpnLen >= 256 {
panic("invalid ALPN protocol")
}
@@ -713,6 +705,10 @@ func (m *serverHelloMsg) marshal() []byte {
extensionsLength += len(m.sctList)
numExtensions++
}
+ if l := len(m.customExtension); l > 0 {
+ extensionsLength += l
+ numExtensions++
+ }
if numExtensions > 0 {
extensionsLength += 4 * numExtensions
@@ -747,7 +743,7 @@ func (m *serverHelloMsg) marshal() []byte {
z[1] = 0xff
z = z[4:]
}
- if m.nextProtoNeg {
+ if m.nextProtoNeg && !m.npnLast {
z[0] = byte(extensionNextProtoNeg >> 8)
z[1] = byte(extensionNextProtoNeg & 0xff)
z[2] = byte(nextProtoLen >> 8)
@@ -784,7 +780,7 @@ func (m *serverHelloMsg) marshal() []byte {
copy(z, m.secureRenegotiation)
z = z[len(m.secureRenegotiation):]
}
- if alpnLen := len(m.alpnProtocol); alpnLen > 0 {
+ if alpnLen := len(m.alpnProtocol); alpnLen > 0 || m.alpnProtocolEmpty {
z[0] = byte(extensionALPN >> 8)
z[1] = byte(extensionALPN & 0xff)
l := 2 + 1 + alpnLen
@@ -838,6 +834,31 @@ func (m *serverHelloMsg) marshal() []byte {
copy(z[4:], m.sctList)
z = z[4+l:]
}
+ if l := len(m.customExtension); l > 0 {
+ z[0] = byte(extensionCustom >> 8)
+ z[1] = byte(extensionCustom & 0xff)
+ z[2] = byte(l >> 8)
+ z[3] = byte(l & 0xff)
+ copy(z[4:], []byte(m.customExtension))
+ z = z[4+l:]
+ }
+ if m.nextProtoNeg && m.npnLast {
+ z[0] = byte(extensionNextProtoNeg >> 8)
+ z[1] = byte(extensionNextProtoNeg & 0xff)
+ z[2] = byte(nextProtoLen >> 8)
+ z[3] = byte(nextProtoLen)
+ z = z[4:]
+
+ for _, v := range m.nextProtos {
+ l := len(v)
+ if l > 255 {
+ l = 255
+ }
+ z[0] = byte(l)
+ copy(z[1:], []byte(v[0:l]))
+ z = z[1+l:]
+ }
+ }
m.raw = x
@@ -869,7 +890,9 @@ func (m *serverHelloMsg) unmarshal(data []byte) bool {
m.ocspStapling = false
m.ticketSupported = false
m.alpnProtocol = ""
+ m.alpnProtocolEmpty = false
m.extendedMasterSecret = false
+ m.customExtension = ""
if len(data) == 0 {
// ServerHello is optionally followed by extension data
@@ -940,6 +963,7 @@ func (m *serverHelloMsg) unmarshal(data []byte) bool {
}
d = d[1:]
m.alpnProtocol = string(d)
+ m.alpnProtocolEmpty = len(d) == 0
case extensionChannelID:
if length > 0 {
return false
@@ -965,14 +989,9 @@ func (m *serverHelloMsg) unmarshal(data []byte) bool {
}
m.srtpMasterKeyIdentifier = string(d[1:])
case extensionSignedCertificateTimestamp:
- if length < 2 {
- return false
- }
- l := int(data[0])<<8 | int(data[1])
- if l != len(data)-2 {
- return false
- }
- m.sctList = data[2:length]
+ m.sctList = data[:length]
+ case extensionCustom:
+ m.customExtension = string(data[:length])
}
data = data[length:]
}
@@ -985,16 +1004,6 @@ type certificateMsg struct {
certificates [][]byte
}
-func (m *certificateMsg) equal(i interface{}) bool {
- m1, ok := i.(*certificateMsg)
- if !ok {
- return false
- }
-
- return bytes.Equal(m.raw, m1.raw) &&
- eqByteSlices(m.certificates, m1.certificates)
-}
-
func (m *certificateMsg) marshal() (x []byte) {
if m.raw != nil {
return m.raw
@@ -1072,16 +1081,6 @@ type serverKeyExchangeMsg struct {
key []byte
}
-func (m *serverKeyExchangeMsg) equal(i interface{}) bool {
- m1, ok := i.(*serverKeyExchangeMsg)
- if !ok {
- return false
- }
-
- return bytes.Equal(m.raw, m1.raw) &&
- bytes.Equal(m.key, m1.key)
-}
-
func (m *serverKeyExchangeMsg) marshal() []byte {
if m.raw != nil {
return m.raw
@@ -1113,17 +1112,6 @@ type certificateStatusMsg struct {
response []byte
}
-func (m *certificateStatusMsg) equal(i interface{}) bool {
- m1, ok := i.(*certificateStatusMsg)
- if !ok {
- return false
- }
-
- return bytes.Equal(m.raw, m1.raw) &&
- m.statusType == m1.statusType &&
- bytes.Equal(m.response, m1.response)
-}
-
func (m *certificateStatusMsg) marshal() []byte {
if m.raw != nil {
return m.raw
@@ -1175,11 +1163,6 @@ func (m *certificateStatusMsg) unmarshal(data []byte) bool {
type serverHelloDoneMsg struct{}
-func (m *serverHelloDoneMsg) equal(i interface{}) bool {
- _, ok := i.(*serverHelloDoneMsg)
- return ok
-}
-
func (m *serverHelloDoneMsg) marshal() []byte {
x := make([]byte, 4)
x[0] = typeServerHelloDone
@@ -1195,16 +1178,6 @@ type clientKeyExchangeMsg struct {
ciphertext []byte
}
-func (m *clientKeyExchangeMsg) equal(i interface{}) bool {
- m1, ok := i.(*clientKeyExchangeMsg)
- if !ok {
- return false
- }
-
- return bytes.Equal(m.raw, m1.raw) &&
- bytes.Equal(m.ciphertext, m1.ciphertext)
-}
-
func (m *clientKeyExchangeMsg) marshal() []byte {
if m.raw != nil {
return m.raw
@@ -1239,16 +1212,6 @@ type finishedMsg struct {
verifyData []byte
}
-func (m *finishedMsg) equal(i interface{}) bool {
- m1, ok := i.(*finishedMsg)
- if !ok {
- return false
- }
-
- return bytes.Equal(m.raw, m1.raw) &&
- bytes.Equal(m.verifyData, m1.verifyData)
-}
-
func (m *finishedMsg) marshal() (x []byte) {
if m.raw != nil {
return m.raw
@@ -1276,16 +1239,6 @@ type nextProtoMsg struct {
proto string
}
-func (m *nextProtoMsg) equal(i interface{}) bool {
- m1, ok := i.(*nextProtoMsg)
- if !ok {
- return false
- }
-
- return bytes.Equal(m.raw, m1.raw) &&
- m.proto == m1.proto
-}
-
func (m *nextProtoMsg) marshal() []byte {
if m.raw != nil {
return m.raw
@@ -1353,18 +1306,6 @@ type certificateRequestMsg struct {
certificateAuthorities [][]byte
}
-func (m *certificateRequestMsg) equal(i interface{}) bool {
- m1, ok := i.(*certificateRequestMsg)
- if !ok {
- return false
- }
-
- return bytes.Equal(m.raw, m1.raw) &&
- bytes.Equal(m.certificateTypes, m1.certificateTypes) &&
- eqByteSlices(m.certificateAuthorities, m1.certificateAuthorities) &&
- eqSignatureAndHashes(m.signatureAndHashes, m1.signatureAndHashes)
-}
-
func (m *certificateRequestMsg) marshal() (x []byte) {
if m.raw != nil {
return m.raw
@@ -1507,19 +1448,6 @@ type certificateVerifyMsg struct {
signature []byte
}
-func (m *certificateVerifyMsg) equal(i interface{}) bool {
- m1, ok := i.(*certificateVerifyMsg)
- if !ok {
- return false
- }
-
- return bytes.Equal(m.raw, m1.raw) &&
- m.hasSignatureAndHash == m1.hasSignatureAndHash &&
- m.signatureAndHash.hash == m1.signatureAndHash.hash &&
- m.signatureAndHash.signature == m1.signatureAndHash.signature &&
- bytes.Equal(m.signature, m1.signature)
-}
-
func (m *certificateVerifyMsg) marshal() (x []byte) {
if m.raw != nil {
return m.raw
@@ -1589,16 +1517,6 @@ type newSessionTicketMsg struct {
ticket []byte
}
-func (m *newSessionTicketMsg) equal(i interface{}) bool {
- m1, ok := i.(*newSessionTicketMsg)
- if !ok {
- return false
- }
-
- return bytes.Equal(m.raw, m1.raw) &&
- bytes.Equal(m.ticket, m1.ticket)
-}
-
func (m *newSessionTicketMsg) marshal() (x []byte) {
if m.raw != nil {
return m.raw
@@ -1651,19 +1569,6 @@ type v2ClientHelloMsg struct {
challenge []byte
}
-func (m *v2ClientHelloMsg) equal(i interface{}) bool {
- m1, ok := i.(*v2ClientHelloMsg)
- if !ok {
- return false
- }
-
- return bytes.Equal(m.raw, m1.raw) &&
- m.vers == m1.vers &&
- eqUint16s(m.cipherSuites, m1.cipherSuites) &&
- bytes.Equal(m.sessionId, m1.sessionId) &&
- bytes.Equal(m.challenge, m1.challenge)
-}
-
func (m *v2ClientHelloMsg) marshal() []byte {
if m.raw != nil {
return m.raw
@@ -1703,17 +1608,6 @@ type helloVerifyRequestMsg struct {
cookie []byte
}
-func (m *helloVerifyRequestMsg) equal(i interface{}) bool {
- m1, ok := i.(*helloVerifyRequestMsg)
- if !ok {
- return false
- }
-
- return bytes.Equal(m.raw, m1.raw) &&
- m.vers == m1.vers &&
- bytes.Equal(m.cookie, m1.cookie)
-}
-
func (m *helloVerifyRequestMsg) marshal() []byte {
if m.raw != nil {
return m.raw
@@ -1755,16 +1649,6 @@ type encryptedExtensionsMsg struct {
channelID []byte
}
-func (m *encryptedExtensionsMsg) equal(i interface{}) bool {
- m1, ok := i.(*encryptedExtensionsMsg)
- if !ok {
- return false
- }
-
- return bytes.Equal(m.raw, m1.raw) &&
- bytes.Equal(m.channelID, m1.channelID)
-}
-
func (m *encryptedExtensionsMsg) marshal() []byte {
if m.raw != nil {
return m.raw
diff --git a/src/ssl/test/runner/handshake_server.go b/src/ssl/test/runner/handshake_server.go
index 85cc0d2..068dff9 100644
--- a/src/ssl/test/runner/handshake_server.go
+++ b/src/ssl/test/runner/handshake_server.go
@@ -139,8 +139,8 @@ func (hs *serverHandshakeState) readClientHello() (isResume bool, err error) {
c.sendAlert(alertUnexpectedMessage)
return false, unexpectedMessageError(hs.clientHello, msg)
}
- if config.Bugs.RequireFastradioPadding && len(hs.clientHello.raw) < 1000 {
- return false, errors.New("tls: ClientHello record size should be larger than 1000 bytes when padding enabled.")
+ if size := config.Bugs.RequireClientHelloSize; size != 0 && len(hs.clientHello.raw) != size {
+ return false, fmt.Errorf("tls: ClientHello record size is %d, but expected %d", len(hs.clientHello.raw), size)
}
if c.isDTLS && !config.Bugs.SkipHelloVerifyRequest {
@@ -210,8 +210,11 @@ func (hs *serverHandshakeState) readClientHello() (isResume bool, err error) {
}
c.haveVers = true
- hs.hello = new(serverHelloMsg)
- hs.hello.isDTLS = c.isDTLS
+ hs.hello = &serverHelloMsg{
+ isDTLS: c.isDTLS,
+ customExtension: config.Bugs.CustomExtension,
+ npnLast: config.Bugs.SwapNPNAndALPN,
+ }
supportedCurve := false
preferredCurves := config.curvePreferences()
@@ -285,12 +288,18 @@ Curves:
}
if len(hs.clientHello.alpnProtocols) > 0 {
- if selectedProto, fallback := mutualProtocol(hs.clientHello.alpnProtocols, c.config.NextProtos); !fallback {
+ if proto := c.config.Bugs.ALPNProtocol; proto != nil {
+ hs.hello.alpnProtocol = *proto
+ hs.hello.alpnProtocolEmpty = len(*proto) == 0
+ c.clientProtocol = *proto
+ c.usedALPN = true
+ } else if selectedProto, fallback := mutualProtocol(hs.clientHello.alpnProtocols, c.config.NextProtos); !fallback {
hs.hello.alpnProtocol = selectedProto
c.clientProtocol = selectedProto
c.usedALPN = true
}
- } else {
+ }
+ if len(hs.clientHello.alpnProtocols) == 0 || c.config.Bugs.NegotiateALPNAndNPN {
// Although sending an empty NPN extension is reasonable, Firefox has
// had a bug around this. Best to send nothing at all if
// config.NextProtos is empty. See
@@ -335,6 +344,12 @@ Curves:
hs.hello.srtpProtectionProfile = c.config.Bugs.SendSRTPProtectionProfile
}
+ if expected := c.config.Bugs.ExpectedCustomExtension; expected != nil {
+ if hs.clientHello.customExtension != *expected {
+ return false, fmt.Errorf("tls: bad custom extension contents %q", hs.clientHello.customExtension)
+ }
+ }
+
_, hs.ecdsaOk = hs.cert.PrivateKey.(*ecdsa.PrivateKey)
// For test purposes, check that the peer never offers a session when
@@ -516,7 +531,9 @@ func (hs *serverHandshakeState) doFullHandshake() error {
if !isPSK {
certMsg := new(certificateMsg)
- certMsg.certificates = hs.cert.Certificate
+ if !config.Bugs.EmptyCertificateList {
+ certMsg.certificates = hs.cert.Certificate
+ }
if !config.Bugs.UnauthenticatedECDH {
certMsgBytes := certMsg.marshal()
if config.Bugs.WrongCertificateMessageType {
@@ -668,6 +685,7 @@ func (hs *serverHandshakeState) doFullHandshake() error {
if !isSupportedSignatureAndHash(signatureAndHash, config.signatureAndHashesForServer()) {
return errors.New("tls: unsupported hash function for client certificate")
}
+ c.clientCertSignatureHash = signatureAndHash.hash
} else {
// Before TLS 1.2 the signature algorithm was implicit
// from the key type, and only one hash per signature
diff --git a/src/ssl/test/runner/runner.go b/src/ssl/test/runner/runner.go
index 94c1d32..269a955 100644
--- a/src/ssl/test/runner/runner.go
+++ b/src/ssl/test/runner/runner.go
@@ -32,6 +32,10 @@ var (
mallocTestDebug = flag.Bool("malloc-test-debug", false, "If true, ask bssl_shim to abort rather than fail a malloc. This can be used with a specific value for --malloc-test to identity the malloc failing that is causing problems.")
jsonOutput = flag.String("json-output", "", "The file to output JSON results to.")
pipe = flag.Bool("pipe", false, "If true, print status output suitable for piping into another program.")
+ testToRun = flag.String("test", "", "The name of a test to run, or empty to run all tests")
+ numWorkers = flag.Int("num-workers", runtime.NumCPU(), "The number of workers to run in parallel.")
+ shimPath = flag.String("shim-path", "../../../build/ssl/test/bssl_shim", "The location of the shim binary.")
+ resourceDir = flag.String("resource-dir", ".", "The directory in which to find certificate and key files.")
)
const (
@@ -54,21 +58,21 @@ var testSCTList = []byte{5, 6, 7, 8}
func initCertificates() {
var err error
- rsaCertificate, err = LoadX509KeyPair(rsaCertificateFile, rsaKeyFile)
+ rsaCertificate, err = LoadX509KeyPair(path.Join(*resourceDir, rsaCertificateFile), path.Join(*resourceDir, rsaKeyFile))
if err != nil {
panic(err)
}
rsaCertificate.OCSPStaple = testOCSPResponse
rsaCertificate.SignedCertificateTimestampList = testSCTList
- ecdsaCertificate, err = LoadX509KeyPair(ecdsaCertificateFile, ecdsaKeyFile)
+ ecdsaCertificate, err = LoadX509KeyPair(path.Join(*resourceDir, ecdsaCertificateFile), path.Join(*resourceDir, ecdsaKeyFile))
if err != nil {
panic(err)
}
ecdsaCertificate.OCSPStaple = testOCSPResponse
ecdsaCertificate.SignedCertificateTimestampList = testSCTList
- channelIDPEMBlock, err := ioutil.ReadFile(channelIDKeyFile)
+ channelIDPEMBlock, err := ioutil.ReadFile(path.Join(*resourceDir, channelIDKeyFile))
if err != nil {
panic(err)
}
@@ -151,9 +155,21 @@ type testCase struct {
// expectedSRTPProtectionProfile is the DTLS-SRTP profile that
// should be negotiated. If zero, none should be negotiated.
expectedSRTPProtectionProfile uint16
+ // expectedOCSPResponse, if not nil, is the expected OCSP response to be received.
+ expectedOCSPResponse []uint8
+ // expectedSCTList, if not nil, is the expected SCT list to be received.
+ expectedSCTList []uint8
+ // expectedClientCertSignatureHash, if not zero, is the TLS id of the
+ // hash function that the client should have used when signing the
+ // handshake with a client certificate.
+ expectedClientCertSignatureHash uint8
// messageLen is the length, in bytes, of the test message that will be
// sent.
messageLen int
+ // messageCount is the number of test messages that will be sent.
+ messageCount int
+ // digestPrefs is the list of digest preferences from the client.
+ digestPrefs string
// certFile is the path to the certificate to use for the server.
certFile string
// keyFile is the path to the private key to use for the server.
@@ -174,12 +190,19 @@ type testCase struct {
// newSessionsOnResume, if true, will cause resumeConfig to
// use a different session resumption context.
newSessionsOnResume bool
+ // noSessionCache, if true, will cause the server to run without a
+ // session cache.
+ noSessionCache bool
// sendPrefix sends a prefix on the socket before actually performing a
// handshake.
sendPrefix string
// shimWritesFirst controls whether the shim sends an initial "hello"
// message before doing a roundtrip with the runner.
shimWritesFirst bool
+ // shimShutsDown, if true, runs a test where the shim shuts down the
+ // connection immediately after the handshake rather than echoing
+ // messages from the runner.
+ shimShutsDown bool
// renegotiate indicates the the connection should be renegotiated
// during the exchange.
renegotiate bool
@@ -204,941 +227,20 @@ type testCase struct {
// testTLSUnique, if true, causes the shim to send the tls-unique value
// which will be compared against the expected value.
testTLSUnique bool
+ // sendEmptyRecords is the number of consecutive empty records to send
+ // before and after the test message.
+ sendEmptyRecords int
+ // sendWarningAlerts is the number of consecutive warning alerts to send
+ // before and after the test message.
+ sendWarningAlerts int
+ // expectMessageDropped, if true, means the test message is expected to
+ // be dropped by the client rather than echoed back.
+ expectMessageDropped bool
}
-var testCases = []testCase{
- {
- name: "BadRSASignature",
- config: Config{
- CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
- Bugs: ProtocolBugs{
- InvalidSKXSignature: true,
- },
- },
- shouldFail: true,
- expectedError: ":BAD_SIGNATURE:",
- },
- {
- name: "BadECDSASignature",
- config: Config{
- CipherSuites: []uint16{TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256},
- Bugs: ProtocolBugs{
- InvalidSKXSignature: true,
- },
- Certificates: []Certificate{getECDSACertificate()},
- },
- shouldFail: true,
- expectedError: ":BAD_SIGNATURE:",
- },
- {
- name: "BadECDSACurve",
- config: Config{
- CipherSuites: []uint16{TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256},
- Bugs: ProtocolBugs{
- InvalidSKXCurve: true,
- },
- Certificates: []Certificate{getECDSACertificate()},
- },
- shouldFail: true,
- expectedError: ":WRONG_CURVE:",
- },
- {
- testType: serverTest,
- name: "BadRSAVersion",
- config: Config{
- CipherSuites: []uint16{TLS_RSA_WITH_RC4_128_SHA},
- Bugs: ProtocolBugs{
- RsaClientKeyExchangeVersion: VersionTLS11,
- },
- },
- shouldFail: true,
- expectedError: ":DECRYPTION_FAILED_OR_BAD_RECORD_MAC:",
- },
- {
- name: "NoFallbackSCSV",
- config: Config{
- Bugs: ProtocolBugs{
- FailIfNotFallbackSCSV: true,
- },
- },
- shouldFail: true,
- expectedLocalError: "no fallback SCSV found",
- },
- {
- name: "SendFallbackSCSV",
- config: Config{
- Bugs: ProtocolBugs{
- FailIfNotFallbackSCSV: true,
- },
- },
- flags: []string{"-fallback-scsv"},
- },
- {
- name: "ClientCertificateTypes",
- config: Config{
- ClientAuth: RequestClientCert,
- ClientCertificateTypes: []byte{
- CertTypeDSSSign,
- CertTypeRSASign,
- CertTypeECDSASign,
- },
- },
- flags: []string{
- "-expect-certificate-types",
- base64.StdEncoding.EncodeToString([]byte{
- CertTypeDSSSign,
- CertTypeRSASign,
- CertTypeECDSASign,
- }),
- },
- },
- {
- name: "NoClientCertificate",
- config: Config{
- ClientAuth: RequireAnyClientCert,
- },
- shouldFail: true,
- expectedLocalError: "client didn't provide a certificate",
- },
- {
- name: "UnauthenticatedECDH",
- config: Config{
- CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
- Bugs: ProtocolBugs{
- UnauthenticatedECDH: true,
- },
- },
- shouldFail: true,
- expectedError: ":UNEXPECTED_MESSAGE:",
- },
- {
- name: "SkipCertificateStatus",
- config: Config{
- CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
- Bugs: ProtocolBugs{
- SkipCertificateStatus: true,
- },
- },
- flags: []string{
- "-enable-ocsp-stapling",
- },
- },
- {
- name: "SkipServerKeyExchange",
- config: Config{
- CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
- Bugs: ProtocolBugs{
- SkipServerKeyExchange: true,
- },
- },
- shouldFail: true,
- expectedError: ":UNEXPECTED_MESSAGE:",
- },
- {
- name: "SkipChangeCipherSpec-Client",
- config: Config{
- Bugs: ProtocolBugs{
- SkipChangeCipherSpec: true,
- },
- },
- shouldFail: true,
- expectedError: ":HANDSHAKE_RECORD_BEFORE_CCS:",
- },
- {
- testType: serverTest,
- name: "SkipChangeCipherSpec-Server",
- config: Config{
- Bugs: ProtocolBugs{
- SkipChangeCipherSpec: true,
- },
- },
- shouldFail: true,
- expectedError: ":HANDSHAKE_RECORD_BEFORE_CCS:",
- },
- {
- testType: serverTest,
- name: "SkipChangeCipherSpec-Server-NPN",
- config: Config{
- NextProtos: []string{"bar"},
- Bugs: ProtocolBugs{
- SkipChangeCipherSpec: true,
- },
- },
- flags: []string{
- "-advertise-npn", "\x03foo\x03bar\x03baz",
- },
- shouldFail: true,
- expectedError: ":HANDSHAKE_RECORD_BEFORE_CCS:",
- },
- {
- name: "FragmentAcrossChangeCipherSpec-Client",
- config: Config{
- Bugs: ProtocolBugs{
- FragmentAcrossChangeCipherSpec: true,
- },
- },
- shouldFail: true,
- expectedError: ":HANDSHAKE_RECORD_BEFORE_CCS:",
- },
- {
- testType: serverTest,
- name: "FragmentAcrossChangeCipherSpec-Server",
- config: Config{
- Bugs: ProtocolBugs{
- FragmentAcrossChangeCipherSpec: true,
- },
- },
- shouldFail: true,
- expectedError: ":HANDSHAKE_RECORD_BEFORE_CCS:",
- },
- {
- testType: serverTest,
- name: "FragmentAcrossChangeCipherSpec-Server-NPN",
- config: Config{
- NextProtos: []string{"bar"},
- Bugs: ProtocolBugs{
- FragmentAcrossChangeCipherSpec: true,
- },
- },
- flags: []string{
- "-advertise-npn", "\x03foo\x03bar\x03baz",
- },
- shouldFail: true,
- expectedError: ":HANDSHAKE_RECORD_BEFORE_CCS:",
- },
- {
- testType: serverTest,
- name: "Alert",
- config: Config{
- Bugs: ProtocolBugs{
- SendSpuriousAlert: alertRecordOverflow,
- },
- },
- shouldFail: true,
- expectedError: ":TLSV1_ALERT_RECORD_OVERFLOW:",
- },
- {
- protocol: dtls,
- testType: serverTest,
- name: "Alert-DTLS",
- config: Config{
- Bugs: ProtocolBugs{
- SendSpuriousAlert: alertRecordOverflow,
- },
- },
- shouldFail: true,
- expectedError: ":TLSV1_ALERT_RECORD_OVERFLOW:",
- },
- {
- testType: serverTest,
- name: "FragmentAlert",
- config: Config{
- Bugs: ProtocolBugs{
- FragmentAlert: true,
- SendSpuriousAlert: alertRecordOverflow,
- },
- },
- shouldFail: true,
- expectedError: ":BAD_ALERT:",
- },
- {
- protocol: dtls,
- testType: serverTest,
- name: "FragmentAlert-DTLS",
- config: Config{
- Bugs: ProtocolBugs{
- FragmentAlert: true,
- SendSpuriousAlert: alertRecordOverflow,
- },
- },
- shouldFail: true,
- expectedError: ":BAD_ALERT:",
- },
- {
- testType: serverTest,
- name: "EarlyChangeCipherSpec-server-1",
- config: Config{
- Bugs: ProtocolBugs{
- EarlyChangeCipherSpec: 1,
- },
- },
- shouldFail: true,
- expectedError: ":CCS_RECEIVED_EARLY:",
- },
- {
- testType: serverTest,
- name: "EarlyChangeCipherSpec-server-2",
- config: Config{
- Bugs: ProtocolBugs{
- EarlyChangeCipherSpec: 2,
- },
- },
- shouldFail: true,
- expectedError: ":CCS_RECEIVED_EARLY:",
- },
- {
- name: "SkipNewSessionTicket",
- config: Config{
- Bugs: ProtocolBugs{
- SkipNewSessionTicket: true,
- },
- },
- shouldFail: true,
- expectedError: ":CCS_RECEIVED_EARLY:",
- },
- {
- testType: serverTest,
- name: "FallbackSCSV",
- config: Config{
- MaxVersion: VersionTLS11,
- Bugs: ProtocolBugs{
- SendFallbackSCSV: true,
- },
- },
- shouldFail: true,
- expectedError: ":INAPPROPRIATE_FALLBACK:",
- },
- {
- testType: serverTest,
- name: "FallbackSCSV-VersionMatch",
- config: Config{
- Bugs: ProtocolBugs{
- SendFallbackSCSV: true,
- },
- },
- },
- {
- testType: serverTest,
- name: "FragmentedClientVersion",
- config: Config{
- Bugs: ProtocolBugs{
- MaxHandshakeRecordLength: 1,
- FragmentClientVersion: true,
- },
- },
- expectedVersion: VersionTLS12,
- },
- {
- testType: serverTest,
- name: "MinorVersionTolerance",
- config: Config{
- Bugs: ProtocolBugs{
- SendClientVersion: 0x03ff,
- },
- },
- expectedVersion: VersionTLS12,
- },
- {
- testType: serverTest,
- name: "MajorVersionTolerance",
- config: Config{
- Bugs: ProtocolBugs{
- SendClientVersion: 0x0400,
- },
- },
- expectedVersion: VersionTLS12,
- },
- {
- testType: serverTest,
- name: "VersionTooLow",
- config: Config{
- Bugs: ProtocolBugs{
- SendClientVersion: 0x0200,
- },
- },
- shouldFail: true,
- expectedError: ":UNSUPPORTED_PROTOCOL:",
- },
- {
- testType: serverTest,
- name: "HttpGET",
- sendPrefix: "GET / HTTP/1.0\n",
- shouldFail: true,
- expectedError: ":HTTP_REQUEST:",
- },
- {
- testType: serverTest,
- name: "HttpPOST",
- sendPrefix: "POST / HTTP/1.0\n",
- shouldFail: true,
- expectedError: ":HTTP_REQUEST:",
- },
- {
- testType: serverTest,
- name: "HttpHEAD",
- sendPrefix: "HEAD / HTTP/1.0\n",
- shouldFail: true,
- expectedError: ":HTTP_REQUEST:",
- },
- {
- testType: serverTest,
- name: "HttpPUT",
- sendPrefix: "PUT / HTTP/1.0\n",
- shouldFail: true,
- expectedError: ":HTTP_REQUEST:",
- },
- {
- testType: serverTest,
- name: "HttpCONNECT",
- sendPrefix: "CONNECT www.google.com:443 HTTP/1.0\n",
- shouldFail: true,
- expectedError: ":HTTPS_PROXY_REQUEST:",
- },
- {
- testType: serverTest,
- name: "Garbage",
- sendPrefix: "blah",
- shouldFail: true,
- expectedError: ":UNKNOWN_PROTOCOL:",
- },
- {
- name: "SkipCipherVersionCheck",
- config: Config{
- CipherSuites: []uint16{TLS_RSA_WITH_AES_128_GCM_SHA256},
- MaxVersion: VersionTLS11,
- Bugs: ProtocolBugs{
- SkipCipherVersionCheck: true,
- },
- },
- shouldFail: true,
- expectedError: ":WRONG_CIPHER_RETURNED:",
- },
- {
- name: "RSAEphemeralKey",
- config: Config{
- CipherSuites: []uint16{TLS_RSA_WITH_AES_128_CBC_SHA},
- Bugs: ProtocolBugs{
- RSAEphemeralKey: true,
- },
- },
- shouldFail: true,
- expectedError: ":UNEXPECTED_MESSAGE:",
- },
- {
- name: "DisableEverything",
- flags: []string{"-no-tls12", "-no-tls11", "-no-tls1", "-no-ssl3"},
- shouldFail: true,
- expectedError: ":WRONG_SSL_VERSION:",
- },
- {
- protocol: dtls,
- name: "DisableEverything-DTLS",
- flags: []string{"-no-tls12", "-no-tls1"},
- shouldFail: true,
- expectedError: ":WRONG_SSL_VERSION:",
- },
- {
- name: "NoSharedCipher",
- config: Config{
- CipherSuites: []uint16{},
- },
- shouldFail: true,
- expectedError: ":HANDSHAKE_FAILURE_ON_CLIENT_HELLO:",
- },
- {
- protocol: dtls,
- testType: serverTest,
- name: "MTU",
- config: Config{
- Bugs: ProtocolBugs{
- MaxPacketLength: 256,
- },
- },
- flags: []string{"-mtu", "256"},
- },
- {
- protocol: dtls,
- testType: serverTest,
- name: "MTUExceeded",
- config: Config{
- Bugs: ProtocolBugs{
- MaxPacketLength: 255,
- },
- },
- flags: []string{"-mtu", "256"},
- shouldFail: true,
- expectedLocalError: "dtls: exceeded maximum packet length",
- },
- {
- name: "CertMismatchRSA",
- config: Config{
- CipherSuites: []uint16{TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256},
- Certificates: []Certificate{getECDSACertificate()},
- Bugs: ProtocolBugs{
- SendCipherSuite: TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
- },
- },
- shouldFail: true,
- expectedError: ":WRONG_CERTIFICATE_TYPE:",
- },
- {
- name: "CertMismatchECDSA",
- config: Config{
- CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
- Certificates: []Certificate{getRSACertificate()},
- Bugs: ProtocolBugs{
- SendCipherSuite: TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
- },
- },
- shouldFail: true,
- expectedError: ":WRONG_CERTIFICATE_TYPE:",
- },
- {
- name: "TLSFatalBadPackets",
- damageFirstWrite: true,
- shouldFail: true,
- expectedError: ":DECRYPTION_FAILED_OR_BAD_RECORD_MAC:",
- },
- {
- protocol: dtls,
- name: "DTLSIgnoreBadPackets",
- damageFirstWrite: true,
- },
- {
- protocol: dtls,
- name: "DTLSIgnoreBadPackets-Async",
- damageFirstWrite: true,
- flags: []string{"-async"},
- },
- {
- name: "AppDataAfterChangeCipherSpec",
- config: Config{
- Bugs: ProtocolBugs{
- AppDataAfterChangeCipherSpec: []byte("TEST MESSAGE"),
- },
- },
- shouldFail: true,
- expectedError: ":DATA_BETWEEN_CCS_AND_FINISHED:",
- },
- {
- protocol: dtls,
- name: "AppDataAfterChangeCipherSpec-DTLS",
- config: Config{
- Bugs: ProtocolBugs{
- AppDataAfterChangeCipherSpec: []byte("TEST MESSAGE"),
- },
- },
- // BoringSSL's DTLS implementation will drop the out-of-order
- // application data.
- },
- {
- name: "AlertAfterChangeCipherSpec",
- config: Config{
- Bugs: ProtocolBugs{
- AlertAfterChangeCipherSpec: alertRecordOverflow,
- },
- },
- shouldFail: true,
- expectedError: ":TLSV1_ALERT_RECORD_OVERFLOW:",
- },
- {
- protocol: dtls,
- name: "AlertAfterChangeCipherSpec-DTLS",
- config: Config{
- Bugs: ProtocolBugs{
- AlertAfterChangeCipherSpec: alertRecordOverflow,
- },
- },
- shouldFail: true,
- expectedError: ":TLSV1_ALERT_RECORD_OVERFLOW:",
- },
- {
- protocol: dtls,
- name: "ReorderHandshakeFragments-Small-DTLS",
- config: Config{
- Bugs: ProtocolBugs{
- ReorderHandshakeFragments: true,
- // Small enough that every handshake message is
- // fragmented.
- MaxHandshakeRecordLength: 2,
- },
- },
- },
- {
- protocol: dtls,
- name: "ReorderHandshakeFragments-Large-DTLS",
- config: Config{
- Bugs: ProtocolBugs{
- ReorderHandshakeFragments: true,
- // Large enough that no handshake message is
- // fragmented.
- MaxHandshakeRecordLength: 2048,
- },
- },
- },
- {
- protocol: dtls,
- name: "MixCompleteMessageWithFragments-DTLS",
- config: Config{
- Bugs: ProtocolBugs{
- ReorderHandshakeFragments: true,
- MixCompleteMessageWithFragments: true,
- MaxHandshakeRecordLength: 2,
- },
- },
- },
- {
- name: "SendInvalidRecordType",
- config: Config{
- Bugs: ProtocolBugs{
- SendInvalidRecordType: true,
- },
- },
- shouldFail: true,
- expectedError: ":UNEXPECTED_RECORD:",
- },
- {
- protocol: dtls,
- name: "SendInvalidRecordType-DTLS",
- config: Config{
- Bugs: ProtocolBugs{
- SendInvalidRecordType: true,
- },
- },
- shouldFail: true,
- expectedError: ":UNEXPECTED_RECORD:",
- },
- {
- name: "FalseStart-SkipServerSecondLeg",
- config: Config{
- CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
- NextProtos: []string{"foo"},
- Bugs: ProtocolBugs{
- SkipNewSessionTicket: true,
- SkipChangeCipherSpec: true,
- SkipFinished: true,
- ExpectFalseStart: true,
- },
- },
- flags: []string{
- "-false-start",
- "-handshake-never-done",
- "-advertise-alpn", "\x03foo",
- },
- shimWritesFirst: true,
- shouldFail: true,
- expectedError: ":UNEXPECTED_RECORD:",
- },
- {
- name: "FalseStart-SkipServerSecondLeg-Implicit",
- config: Config{
- CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
- NextProtos: []string{"foo"},
- Bugs: ProtocolBugs{
- SkipNewSessionTicket: true,
- SkipChangeCipherSpec: true,
- SkipFinished: true,
- },
- },
- flags: []string{
- "-implicit-handshake",
- "-false-start",
- "-handshake-never-done",
- "-advertise-alpn", "\x03foo",
- },
- shouldFail: true,
- expectedError: ":UNEXPECTED_RECORD:",
- },
- {
- testType: serverTest,
- name: "FailEarlyCallback",
- flags: []string{"-fail-early-callback"},
- shouldFail: true,
- expectedError: ":CONNECTION_REJECTED:",
- expectedLocalError: "remote error: access denied",
- },
- {
- name: "WrongMessageType",
- config: Config{
- Bugs: ProtocolBugs{
- WrongCertificateMessageType: true,
- },
- },
- shouldFail: true,
- expectedError: ":UNEXPECTED_MESSAGE:",
- expectedLocalError: "remote error: unexpected message",
- },
- {
- protocol: dtls,
- name: "WrongMessageType-DTLS",
- config: Config{
- Bugs: ProtocolBugs{
- WrongCertificateMessageType: true,
- },
- },
- shouldFail: true,
- expectedError: ":UNEXPECTED_MESSAGE:",
- expectedLocalError: "remote error: unexpected message",
- },
- {
- protocol: dtls,
- name: "FragmentMessageTypeMismatch-DTLS",
- config: Config{
- Bugs: ProtocolBugs{
- MaxHandshakeRecordLength: 2,
- FragmentMessageTypeMismatch: true,
- },
- },
- shouldFail: true,
- expectedError: ":FRAGMENT_MISMATCH:",
- },
- {
- protocol: dtls,
- name: "FragmentMessageLengthMismatch-DTLS",
- config: Config{
- Bugs: ProtocolBugs{
- MaxHandshakeRecordLength: 2,
- FragmentMessageLengthMismatch: true,
- },
- },
- shouldFail: true,
- expectedError: ":FRAGMENT_MISMATCH:",
- },
- {
- protocol: dtls,
- name: "SplitFragmentHeader-DTLS",
- config: Config{
- Bugs: ProtocolBugs{
- SplitFragmentHeader: true,
- },
- },
- shouldFail: true,
- expectedError: ":UNEXPECTED_MESSAGE:",
- },
- {
- protocol: dtls,
- name: "SplitFragmentBody-DTLS",
- config: Config{
- Bugs: ProtocolBugs{
- SplitFragmentBody: true,
- },
- },
- shouldFail: true,
- expectedError: ":UNEXPECTED_MESSAGE:",
- },
- {
- protocol: dtls,
- name: "SendEmptyFragments-DTLS",
- config: Config{
- Bugs: ProtocolBugs{
- SendEmptyFragments: true,
- },
- },
- },
- {
- name: "UnsupportedCipherSuite",
- config: Config{
- CipherSuites: []uint16{TLS_RSA_WITH_RC4_128_SHA},
- Bugs: ProtocolBugs{
- IgnorePeerCipherPreferences: true,
- },
- },
- flags: []string{"-cipher", "DEFAULT:!RC4"},
- shouldFail: true,
- expectedError: ":WRONG_CIPHER_RETURNED:",
- },
- {
- name: "UnsupportedCurve",
- config: Config{
- CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
- // BoringSSL implements P-224 but doesn't enable it by
- // default.
- CurvePreferences: []CurveID{CurveP224},
- Bugs: ProtocolBugs{
- IgnorePeerCurvePreferences: true,
- },
- },
- shouldFail: true,
- expectedError: ":WRONG_CURVE:",
- },
- {
- name: "SendWarningAlerts",
- config: Config{
- Bugs: ProtocolBugs{
- SendWarningAlerts: alertAccessDenied,
- },
- },
- },
- {
- protocol: dtls,
- name: "SendWarningAlerts-DTLS",
- config: Config{
- Bugs: ProtocolBugs{
- SendWarningAlerts: alertAccessDenied,
- },
- },
- },
- {
- name: "BadFinished",
- config: Config{
- Bugs: ProtocolBugs{
- BadFinished: true,
- },
- },
- shouldFail: true,
- expectedError: ":DIGEST_CHECK_FAILED:",
- },
- {
- name: "FalseStart-BadFinished",
- config: Config{
- CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
- NextProtos: []string{"foo"},
- Bugs: ProtocolBugs{
- BadFinished: true,
- ExpectFalseStart: true,
- },
- },
- flags: []string{
- "-false-start",
- "-handshake-never-done",
- "-advertise-alpn", "\x03foo",
- },
- shimWritesFirst: true,
- shouldFail: true,
- expectedError: ":DIGEST_CHECK_FAILED:",
- },
- {
- name: "NoFalseStart-NoALPN",
- config: Config{
- CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
- Bugs: ProtocolBugs{
- ExpectFalseStart: true,
- AlertBeforeFalseStartTest: alertAccessDenied,
- },
- },
- flags: []string{
- "-false-start",
- },
- shimWritesFirst: true,
- shouldFail: true,
- expectedError: ":TLSV1_ALERT_ACCESS_DENIED:",
- expectedLocalError: "tls: peer did not false start: EOF",
- },
- {
- name: "NoFalseStart-NoAEAD",
- config: Config{
- CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA},
- NextProtos: []string{"foo"},
- Bugs: ProtocolBugs{
- ExpectFalseStart: true,
- AlertBeforeFalseStartTest: alertAccessDenied,
- },
- },
- flags: []string{
- "-false-start",
- "-advertise-alpn", "\x03foo",
- },
- shimWritesFirst: true,
- shouldFail: true,
- expectedError: ":TLSV1_ALERT_ACCESS_DENIED:",
- expectedLocalError: "tls: peer did not false start: EOF",
- },
- {
- name: "NoFalseStart-RSA",
- config: Config{
- CipherSuites: []uint16{TLS_RSA_WITH_AES_128_GCM_SHA256},
- NextProtos: []string{"foo"},
- Bugs: ProtocolBugs{
- ExpectFalseStart: true,
- AlertBeforeFalseStartTest: alertAccessDenied,
- },
- },
- flags: []string{
- "-false-start",
- "-advertise-alpn", "\x03foo",
- },
- shimWritesFirst: true,
- shouldFail: true,
- expectedError: ":TLSV1_ALERT_ACCESS_DENIED:",
- expectedLocalError: "tls: peer did not false start: EOF",
- },
- {
- name: "NoFalseStart-DHE_RSA",
- config: Config{
- CipherSuites: []uint16{TLS_DHE_RSA_WITH_AES_128_GCM_SHA256},
- NextProtos: []string{"foo"},
- Bugs: ProtocolBugs{
- ExpectFalseStart: true,
- AlertBeforeFalseStartTest: alertAccessDenied,
- },
- },
- flags: []string{
- "-false-start",
- "-advertise-alpn", "\x03foo",
- },
- shimWritesFirst: true,
- shouldFail: true,
- expectedError: ":TLSV1_ALERT_ACCESS_DENIED:",
- expectedLocalError: "tls: peer did not false start: EOF",
- },
- {
- testType: serverTest,
- name: "NoSupportedCurves",
- config: Config{
- CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
- Bugs: ProtocolBugs{
- NoSupportedCurves: true,
- },
- },
- },
- {
- testType: serverTest,
- name: "NoCommonCurves",
- config: Config{
- CipherSuites: []uint16{
- TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
- TLS_DHE_RSA_WITH_AES_128_GCM_SHA256,
- },
- CurvePreferences: []CurveID{CurveP224},
- },
- expectedCipher: TLS_DHE_RSA_WITH_AES_128_GCM_SHA256,
- },
- {
- protocol: dtls,
- name: "SendSplitAlert-Sync",
- config: Config{
- Bugs: ProtocolBugs{
- SendSplitAlert: true,
- },
- },
- },
- {
- protocol: dtls,
- name: "SendSplitAlert-Async",
- config: Config{
- Bugs: ProtocolBugs{
- SendSplitAlert: true,
- },
- },
- flags: []string{"-async"},
- },
- {
- protocol: dtls,
- name: "PackDTLSHandshake",
- config: Config{
- Bugs: ProtocolBugs{
- MaxHandshakeRecordLength: 2,
- PackHandshakeFragments: 20,
- PackHandshakeRecords: 200,
- },
- },
- },
- {
- testType: serverTest,
- protocol: dtls,
- name: "NoRC4-DTLS",
- config: Config{
- CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_RC4_128_SHA},
- Bugs: ProtocolBugs{
- EnableAllCiphersInDTLS: true,
- },
- },
- shouldFail: true,
- expectedError: ":NO_SHARED_CIPHER:",
- },
-}
+var testCases []testCase
-func doExchange(test *testCase, config *Config, conn net.Conn, messageLen int, isResume bool) error {
+func doExchange(test *testCase, config *Config, conn net.Conn, isResume bool) error {
var connDebug *recordingConn
var connDamage *damageAdaptor
if *flagDebug {
@@ -1183,6 +285,7 @@ func doExchange(test *testCase, config *Config, conn net.Conn, messageLen int, i
tlsConn = Client(conn, config)
}
}
+ defer tlsConn.Close()
if err := tlsConn.Handshake(); err != nil {
return err
@@ -1235,6 +338,18 @@ func doExchange(test *testCase, config *Config, conn net.Conn, messageLen int, i
return fmt.Errorf("SRTP profile mismatch: got %d, wanted %d", p, test.expectedSRTPProtectionProfile)
}
+ if test.expectedOCSPResponse != nil && !bytes.Equal(test.expectedOCSPResponse, tlsConn.OCSPResponse()) {
+ return fmt.Errorf("OCSP Response mismatch")
+ }
+
+ if test.expectedSCTList != nil && !bytes.Equal(test.expectedSCTList, connState.SCTList) {
+ return fmt.Errorf("SCT list mismatch")
+ }
+
+ if expected := test.expectedClientCertSignatureHash; expected != 0 && expected != connState.ClientCertSignatureHash {
+ return fmt.Errorf("expected client to sign handshake with hash %d, but got %d", expected, connState.ClientCertSignatureHash)
+ }
+
if test.exportKeyingMaterial > 0 {
actual := make([]byte, test.exportKeyingMaterial)
if _, err := io.ReadFull(tlsConn, actual); err != nil {
@@ -1271,6 +386,14 @@ func doExchange(test *testCase, config *Config, conn net.Conn, messageLen int, i
}
}
+ for i := 0; i < test.sendEmptyRecords; i++ {
+ tlsConn.Write(nil)
+ }
+
+ for i := 0; i < test.sendWarningAlerts; i++ {
+ tlsConn.SendAlert(alertLevelWarning, alertUnexpectedMessage)
+ }
+
if test.renegotiate {
if test.renegotiateCiphers != nil {
config.CipherSuites = test.renegotiateCiphers
@@ -1288,6 +411,7 @@ func doExchange(test *testCase, config *Config, conn net.Conn, messageLen int, i
connDamage.setDamage(false)
}
+ messageLen := test.messageLen
if messageLen < 0 {
if test.protocol == dtls {
return fmt.Errorf("messageLen < 0 not supported for DTLS tests")
@@ -1296,37 +420,57 @@ func doExchange(test *testCase, config *Config, conn net.Conn, messageLen int, i
_, err := io.Copy(ioutil.Discard, tlsConn)
return err
}
-
if messageLen == 0 {
messageLen = 32
}
- testMessage := make([]byte, messageLen)
- for i := range testMessage {
- testMessage[i] = 0x42
+
+ messageCount := test.messageCount
+ if messageCount == 0 {
+ messageCount = 1
}
- tlsConn.Write(testMessage)
- buf := make([]byte, len(testMessage))
- if test.protocol == dtls {
- bufTmp := make([]byte, len(buf)+1)
- n, err := tlsConn.Read(bufTmp)
- if err != nil {
- return err
+ for j := 0; j < messageCount; j++ {
+ testMessage := make([]byte, messageLen)
+ for i := range testMessage {
+ testMessage[i] = 0x42 ^ byte(j)
}
- if n != len(buf) {
- return fmt.Errorf("bad reply; length mismatch (%d vs %d)", n, len(buf))
+ tlsConn.Write(testMessage)
+
+ for i := 0; i < test.sendEmptyRecords; i++ {
+ tlsConn.Write(nil)
}
- copy(buf, bufTmp)
- } else {
- _, err := io.ReadFull(tlsConn, buf)
- if err != nil {
- return err
+
+ for i := 0; i < test.sendWarningAlerts; i++ {
+ tlsConn.SendAlert(alertLevelWarning, alertUnexpectedMessage)
+ }
+
+ if test.shimShutsDown || test.expectMessageDropped {
+ // The shim will not respond.
+ continue
+ }
+
+ buf := make([]byte, len(testMessage))
+ if test.protocol == dtls {
+ bufTmp := make([]byte, len(buf)+1)
+ n, err := tlsConn.Read(bufTmp)
+ if err != nil {
+ return err
+ }
+ if n != len(buf) {
+ return fmt.Errorf("bad reply; length mismatch (%d vs %d)", n, len(buf))
+ }
+ copy(buf, bufTmp)
+ } else {
+ _, err := io.ReadFull(tlsConn, buf)
+ if err != nil {
+ return err
+ }
}
- }
- for i, v := range buf {
- if v != testMessage[i]^0xff {
- return fmt.Errorf("bad reply contents at byte %d", i)
+ for i, v := range buf {
+ if v != testMessage[i]^0xff {
+ return fmt.Errorf("bad reply contents at byte %d", i)
+ }
}
}
@@ -1382,7 +526,7 @@ func acceptOrWait(listener net.Listener, waitChan chan error) (net.Conn, error)
}
}
-func runTest(test *testCase, buildDir string, mallocNumToFail int64) error {
+func runTest(test *testCase, shimPath string, mallocNumToFail int64) error {
if !test.shouldFail && (len(test.expectedError) > 0 || len(test.expectedLocalError) > 0) {
panic("Error expected without shouldFail in " + test.name)
}
@@ -1391,6 +535,10 @@ func runTest(test *testCase, buildDir string, mallocNumToFail int64) error {
panic("expectResumeRejected without resumeSession in " + test.name)
}
+ if test.testType != clientTest && test.expectedClientCertSignatureHash != 0 {
+ panic("expectedClientCertSignatureHash non-zero with serverTest in " + test.name)
+ }
+
listener, err := net.ListenTCP("tcp4", &net.TCPAddr{IP: net.IP{127, 0, 0, 1}})
if err != nil {
panic(err)
@@ -1401,26 +549,30 @@ func runTest(test *testCase, buildDir string, mallocNumToFail int64) error {
}
}()
- shim_path := path.Join(buildDir, "ssl/test/bssl_shim")
flags := []string{"-port", strconv.Itoa(listener.Addr().(*net.TCPAddr).Port)}
if test.testType == serverTest {
flags = append(flags, "-server")
flags = append(flags, "-key-file")
if test.keyFile == "" {
- flags = append(flags, rsaKeyFile)
+ flags = append(flags, path.Join(*resourceDir, rsaKeyFile))
} else {
- flags = append(flags, test.keyFile)
+ flags = append(flags, path.Join(*resourceDir, test.keyFile))
}
flags = append(flags, "-cert-file")
if test.certFile == "" {
- flags = append(flags, rsaCertificateFile)
+ flags = append(flags, path.Join(*resourceDir, rsaCertificateFile))
} else {
- flags = append(flags, test.certFile)
+ flags = append(flags, path.Join(*resourceDir, test.certFile))
}
}
+ if test.digestPrefs != "" {
+ flags = append(flags, "-digest-prefs")
+ flags = append(flags, test.digestPrefs)
+ }
+
if test.protocol == dtls {
flags = append(flags, "-dtls")
}
@@ -1433,6 +585,10 @@ func runTest(test *testCase, buildDir string, mallocNumToFail int64) error {
flags = append(flags, "-shim-writes-first")
}
+ if test.shimShutsDown {
+ flags = append(flags, "-shim-shuts-down")
+ }
+
if test.exportKeyingMaterial > 0 {
flags = append(flags, "-export-keying-material", strconv.Itoa(test.exportKeyingMaterial))
flags = append(flags, "-export-label", test.exportLabel)
@@ -1453,11 +609,11 @@ func runTest(test *testCase, buildDir string, mallocNumToFail int64) error {
var shim *exec.Cmd
if *useValgrind {
- shim = valgrindOf(false, shim_path, flags...)
+ shim = valgrindOf(false, shimPath, flags...)
} else if *useGDB {
- shim = gdbOf(shim_path, flags...)
+ shim = gdbOf(shimPath, flags...)
} else {
- shim = exec.Command(shim_path, flags...)
+ shim = exec.Command(shimPath, flags...)
}
shim.Stdin = os.Stdin
var stdoutBuf, stderrBuf bytes.Buffer
@@ -1467,7 +623,7 @@ func runTest(test *testCase, buildDir string, mallocNumToFail int64) error {
shim.Env = os.Environ()
shim.Env = append(shim.Env, "MALLOC_NUMBER_TO_FAIL="+strconv.FormatInt(mallocNumToFail, 10))
if *mallocTestDebug {
- shim.Env = append(shim.Env, "MALLOC_ABORT_ON_FAIL=1")
+ shim.Env = append(shim.Env, "MALLOC_BREAK_ON_FAIL=1")
}
shim.Env = append(shim.Env, "_MALLOC_CHECK=1")
}
@@ -1479,8 +635,10 @@ func runTest(test *testCase, buildDir string, mallocNumToFail int64) error {
go func() { waitChan <- shim.Wait() }()
config := test.config
- config.ClientSessionCache = NewLRUClientSessionCache(1)
- config.ServerSessionCache = NewLRUServerSessionCache(1)
+ if !test.noSessionCache {
+ config.ClientSessionCache = NewLRUClientSessionCache(1)
+ config.ServerSessionCache = NewLRUServerSessionCache(1)
+ }
if test.testType == clientTest {
if len(config.Certificates) == 0 {
config.Certificates = []Certificate{getRSACertificate()}
@@ -1495,7 +653,7 @@ func runTest(test *testCase, buildDir string, mallocNumToFail int64) error {
conn, err := acceptOrWait(listener, waitChan)
if err == nil {
- err = doExchange(test, &config, conn, test.messageLen, false /* not a resumption */)
+ err = doExchange(test, &config, conn, false /* not a resumption */)
conn.Close()
}
@@ -1509,7 +667,12 @@ func runTest(test *testCase, buildDir string, mallocNumToFail int64) error {
if len(resumeConfig.Certificates) == 0 {
resumeConfig.Certificates = []Certificate{getRSACertificate()}
}
- if !test.newSessionsOnResume {
+ if test.newSessionsOnResume {
+ if !test.noSessionCache {
+ resumeConfig.ClientSessionCache = NewLRUClientSessionCache(1)
+ resumeConfig.ServerSessionCache = NewLRUServerSessionCache(1)
+ }
+ } else {
resumeConfig.SessionTicketKey = config.SessionTicketKey
resumeConfig.ClientSessionCache = config.ClientSessionCache
resumeConfig.ServerSessionCache = config.ServerSessionCache
@@ -1520,7 +683,7 @@ func runTest(test *testCase, buildDir string, mallocNumToFail int64) error {
var connResume net.Conn
connResume, err = acceptOrWait(listener, waitChan)
if err == nil {
- err = doExchange(test, &resumeConfig, connResume, test.messageLen, true /* resumption */)
+ err = doExchange(test, &resumeConfig, connResume, true /* resumption */)
connResume.Close()
}
}
@@ -1606,7 +769,6 @@ var testCipherSuites = []struct {
{"DHE-RSA-AES256-GCM", TLS_DHE_RSA_WITH_AES_256_GCM_SHA384},
{"DHE-RSA-AES256-SHA", TLS_DHE_RSA_WITH_AES_256_CBC_SHA},
{"DHE-RSA-AES256-SHA256", TLS_DHE_RSA_WITH_AES_256_CBC_SHA256},
- {"DHE-RSA-CHACHA20-POLY1305", TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256},
{"ECDHE-ECDSA-AES128-GCM", TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256},
{"ECDHE-ECDSA-AES128-SHA", TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA},
{"ECDHE-ECDSA-AES128-SHA256", TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256},
@@ -1630,6 +792,7 @@ var testCipherSuites = []struct {
{"PSK-RC4-SHA", TLS_PSK_WITH_RC4_128_SHA},
{"RC4-MD5", TLS_RSA_WITH_RC4_128_MD5},
{"RC4-SHA", TLS_RSA_WITH_RC4_128_SHA},
+ {"NULL-SHA", TLS_RSA_WITH_NULL_SHA},
}
func hasComponent(suiteName, component string) bool {
@@ -1644,7 +807,7 @@ func isTLS12Only(suiteName string) bool {
}
func isDTLSCipher(suiteName string) bool {
- return !hasComponent(suiteName, "RC4")
+ return !hasComponent(suiteName, "RC4") && !hasComponent(suiteName, "NULL")
}
func bigFromHex(hex string) *big.Int {
@@ -1655,6 +818,1152 @@ func bigFromHex(hex string) *big.Int {
return ret
}
+func addBasicTests() {
+ basicTests := []testCase{
+ {
+ name: "BadRSASignature",
+ config: Config{
+ CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
+ Bugs: ProtocolBugs{
+ InvalidSKXSignature: true,
+ },
+ },
+ shouldFail: true,
+ expectedError: ":BAD_SIGNATURE:",
+ },
+ {
+ name: "BadECDSASignature",
+ config: Config{
+ CipherSuites: []uint16{TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256},
+ Bugs: ProtocolBugs{
+ InvalidSKXSignature: true,
+ },
+ Certificates: []Certificate{getECDSACertificate()},
+ },
+ shouldFail: true,
+ expectedError: ":BAD_SIGNATURE:",
+ },
+ {
+ testType: serverTest,
+ name: "BadRSASignature-ClientAuth",
+ config: Config{
+ Bugs: ProtocolBugs{
+ InvalidCertVerifySignature: true,
+ },
+ Certificates: []Certificate{getRSACertificate()},
+ },
+ shouldFail: true,
+ expectedError: ":BAD_SIGNATURE:",
+ flags: []string{"-require-any-client-certificate"},
+ },
+ {
+ testType: serverTest,
+ name: "BadECDSASignature-ClientAuth",
+ config: Config{
+ Bugs: ProtocolBugs{
+ InvalidCertVerifySignature: true,
+ },
+ Certificates: []Certificate{getECDSACertificate()},
+ },
+ shouldFail: true,
+ expectedError: ":BAD_SIGNATURE:",
+ flags: []string{"-require-any-client-certificate"},
+ },
+ {
+ name: "BadECDSACurve",
+ config: Config{
+ CipherSuites: []uint16{TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256},
+ Bugs: ProtocolBugs{
+ InvalidSKXCurve: true,
+ },
+ Certificates: []Certificate{getECDSACertificate()},
+ },
+ shouldFail: true,
+ expectedError: ":WRONG_CURVE:",
+ },
+ {
+ testType: serverTest,
+ name: "BadRSAVersion",
+ config: Config{
+ CipherSuites: []uint16{TLS_RSA_WITH_RC4_128_SHA},
+ Bugs: ProtocolBugs{
+ RsaClientKeyExchangeVersion: VersionTLS11,
+ },
+ },
+ shouldFail: true,
+ expectedError: ":DECRYPTION_FAILED_OR_BAD_RECORD_MAC:",
+ },
+ {
+ name: "NoFallbackSCSV",
+ config: Config{
+ Bugs: ProtocolBugs{
+ FailIfNotFallbackSCSV: true,
+ },
+ },
+ shouldFail: true,
+ expectedLocalError: "no fallback SCSV found",
+ },
+ {
+ name: "SendFallbackSCSV",
+ config: Config{
+ Bugs: ProtocolBugs{
+ FailIfNotFallbackSCSV: true,
+ },
+ },
+ flags: []string{"-fallback-scsv"},
+ },
+ {
+ name: "ClientCertificateTypes",
+ config: Config{
+ ClientAuth: RequestClientCert,
+ ClientCertificateTypes: []byte{
+ CertTypeDSSSign,
+ CertTypeRSASign,
+ CertTypeECDSASign,
+ },
+ },
+ flags: []string{
+ "-expect-certificate-types",
+ base64.StdEncoding.EncodeToString([]byte{
+ CertTypeDSSSign,
+ CertTypeRSASign,
+ CertTypeECDSASign,
+ }),
+ },
+ },
+ {
+ name: "NoClientCertificate",
+ config: Config{
+ ClientAuth: RequireAnyClientCert,
+ },
+ shouldFail: true,
+ expectedLocalError: "client didn't provide a certificate",
+ },
+ {
+ name: "UnauthenticatedECDH",
+ config: Config{
+ CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
+ Bugs: ProtocolBugs{
+ UnauthenticatedECDH: true,
+ },
+ },
+ shouldFail: true,
+ expectedError: ":UNEXPECTED_MESSAGE:",
+ },
+ {
+ name: "SkipCertificateStatus",
+ config: Config{
+ CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
+ Bugs: ProtocolBugs{
+ SkipCertificateStatus: true,
+ },
+ },
+ flags: []string{
+ "-enable-ocsp-stapling",
+ },
+ },
+ {
+ name: "SkipServerKeyExchange",
+ config: Config{
+ CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
+ Bugs: ProtocolBugs{
+ SkipServerKeyExchange: true,
+ },
+ },
+ shouldFail: true,
+ expectedError: ":UNEXPECTED_MESSAGE:",
+ },
+ {
+ name: "SkipChangeCipherSpec-Client",
+ config: Config{
+ Bugs: ProtocolBugs{
+ SkipChangeCipherSpec: true,
+ },
+ },
+ shouldFail: true,
+ expectedError: ":HANDSHAKE_RECORD_BEFORE_CCS:",
+ },
+ {
+ testType: serverTest,
+ name: "SkipChangeCipherSpec-Server",
+ config: Config{
+ Bugs: ProtocolBugs{
+ SkipChangeCipherSpec: true,
+ },
+ },
+ shouldFail: true,
+ expectedError: ":HANDSHAKE_RECORD_BEFORE_CCS:",
+ },
+ {
+ testType: serverTest,
+ name: "SkipChangeCipherSpec-Server-NPN",
+ config: Config{
+ NextProtos: []string{"bar"},
+ Bugs: ProtocolBugs{
+ SkipChangeCipherSpec: true,
+ },
+ },
+ flags: []string{
+ "-advertise-npn", "\x03foo\x03bar\x03baz",
+ },
+ shouldFail: true,
+ expectedError: ":HANDSHAKE_RECORD_BEFORE_CCS:",
+ },
+ {
+ name: "FragmentAcrossChangeCipherSpec-Client",
+ config: Config{
+ Bugs: ProtocolBugs{
+ FragmentAcrossChangeCipherSpec: true,
+ },
+ },
+ shouldFail: true,
+ expectedError: ":HANDSHAKE_RECORD_BEFORE_CCS:",
+ },
+ {
+ testType: serverTest,
+ name: "FragmentAcrossChangeCipherSpec-Server",
+ config: Config{
+ Bugs: ProtocolBugs{
+ FragmentAcrossChangeCipherSpec: true,
+ },
+ },
+ shouldFail: true,
+ expectedError: ":HANDSHAKE_RECORD_BEFORE_CCS:",
+ },
+ {
+ testType: serverTest,
+ name: "FragmentAcrossChangeCipherSpec-Server-NPN",
+ config: Config{
+ NextProtos: []string{"bar"},
+ Bugs: ProtocolBugs{
+ FragmentAcrossChangeCipherSpec: true,
+ },
+ },
+ flags: []string{
+ "-advertise-npn", "\x03foo\x03bar\x03baz",
+ },
+ shouldFail: true,
+ expectedError: ":HANDSHAKE_RECORD_BEFORE_CCS:",
+ },
+ {
+ testType: serverTest,
+ name: "Alert",
+ config: Config{
+ Bugs: ProtocolBugs{
+ SendSpuriousAlert: alertRecordOverflow,
+ },
+ },
+ shouldFail: true,
+ expectedError: ":TLSV1_ALERT_RECORD_OVERFLOW:",
+ },
+ {
+ protocol: dtls,
+ testType: serverTest,
+ name: "Alert-DTLS",
+ config: Config{
+ Bugs: ProtocolBugs{
+ SendSpuriousAlert: alertRecordOverflow,
+ },
+ },
+ shouldFail: true,
+ expectedError: ":TLSV1_ALERT_RECORD_OVERFLOW:",
+ },
+ {
+ testType: serverTest,
+ name: "FragmentAlert",
+ config: Config{
+ Bugs: ProtocolBugs{
+ FragmentAlert: true,
+ SendSpuriousAlert: alertRecordOverflow,
+ },
+ },
+ shouldFail: true,
+ expectedError: ":BAD_ALERT:",
+ },
+ {
+ protocol: dtls,
+ testType: serverTest,
+ name: "FragmentAlert-DTLS",
+ config: Config{
+ Bugs: ProtocolBugs{
+ FragmentAlert: true,
+ SendSpuriousAlert: alertRecordOverflow,
+ },
+ },
+ shouldFail: true,
+ expectedError: ":BAD_ALERT:",
+ },
+ {
+ testType: serverTest,
+ name: "EarlyChangeCipherSpec-server-1",
+ config: Config{
+ Bugs: ProtocolBugs{
+ EarlyChangeCipherSpec: 1,
+ },
+ },
+ shouldFail: true,
+ expectedError: ":CCS_RECEIVED_EARLY:",
+ },
+ {
+ testType: serverTest,
+ name: "EarlyChangeCipherSpec-server-2",
+ config: Config{
+ Bugs: ProtocolBugs{
+ EarlyChangeCipherSpec: 2,
+ },
+ },
+ shouldFail: true,
+ expectedError: ":CCS_RECEIVED_EARLY:",
+ },
+ {
+ name: "SkipNewSessionTicket",
+ config: Config{
+ Bugs: ProtocolBugs{
+ SkipNewSessionTicket: true,
+ },
+ },
+ shouldFail: true,
+ expectedError: ":CCS_RECEIVED_EARLY:",
+ },
+ {
+ testType: serverTest,
+ name: "FallbackSCSV",
+ config: Config{
+ MaxVersion: VersionTLS11,
+ Bugs: ProtocolBugs{
+ SendFallbackSCSV: true,
+ },
+ },
+ shouldFail: true,
+ expectedError: ":INAPPROPRIATE_FALLBACK:",
+ },
+ {
+ testType: serverTest,
+ name: "FallbackSCSV-VersionMatch",
+ config: Config{
+ Bugs: ProtocolBugs{
+ SendFallbackSCSV: true,
+ },
+ },
+ },
+ {
+ testType: serverTest,
+ name: "FragmentedClientVersion",
+ config: Config{
+ Bugs: ProtocolBugs{
+ MaxHandshakeRecordLength: 1,
+ FragmentClientVersion: true,
+ },
+ },
+ expectedVersion: VersionTLS12,
+ },
+ {
+ testType: serverTest,
+ name: "MinorVersionTolerance",
+ config: Config{
+ Bugs: ProtocolBugs{
+ SendClientVersion: 0x03ff,
+ },
+ },
+ expectedVersion: VersionTLS12,
+ },
+ {
+ testType: serverTest,
+ name: "MajorVersionTolerance",
+ config: Config{
+ Bugs: ProtocolBugs{
+ SendClientVersion: 0x0400,
+ },
+ },
+ expectedVersion: VersionTLS12,
+ },
+ {
+ testType: serverTest,
+ name: "VersionTooLow",
+ config: Config{
+ Bugs: ProtocolBugs{
+ SendClientVersion: 0x0200,
+ },
+ },
+ shouldFail: true,
+ expectedError: ":UNSUPPORTED_PROTOCOL:",
+ },
+ {
+ testType: serverTest,
+ name: "HttpGET",
+ sendPrefix: "GET / HTTP/1.0\n",
+ shouldFail: true,
+ expectedError: ":HTTP_REQUEST:",
+ },
+ {
+ testType: serverTest,
+ name: "HttpPOST",
+ sendPrefix: "POST / HTTP/1.0\n",
+ shouldFail: true,
+ expectedError: ":HTTP_REQUEST:",
+ },
+ {
+ testType: serverTest,
+ name: "HttpHEAD",
+ sendPrefix: "HEAD / HTTP/1.0\n",
+ shouldFail: true,
+ expectedError: ":HTTP_REQUEST:",
+ },
+ {
+ testType: serverTest,
+ name: "HttpPUT",
+ sendPrefix: "PUT / HTTP/1.0\n",
+ shouldFail: true,
+ expectedError: ":HTTP_REQUEST:",
+ },
+ {
+ testType: serverTest,
+ name: "HttpCONNECT",
+ sendPrefix: "CONNECT www.google.com:443 HTTP/1.0\n",
+ shouldFail: true,
+ expectedError: ":HTTPS_PROXY_REQUEST:",
+ },
+ {
+ testType: serverTest,
+ name: "Garbage",
+ sendPrefix: "blah",
+ shouldFail: true,
+ expectedError: ":WRONG_VERSION_NUMBER:",
+ },
+ {
+ name: "SkipCipherVersionCheck",
+ config: Config{
+ CipherSuites: []uint16{TLS_RSA_WITH_AES_128_GCM_SHA256},
+ MaxVersion: VersionTLS11,
+ Bugs: ProtocolBugs{
+ SkipCipherVersionCheck: true,
+ },
+ },
+ shouldFail: true,
+ expectedError: ":WRONG_CIPHER_RETURNED:",
+ },
+ {
+ name: "RSAEphemeralKey",
+ config: Config{
+ CipherSuites: []uint16{TLS_RSA_WITH_AES_128_CBC_SHA},
+ Bugs: ProtocolBugs{
+ RSAEphemeralKey: true,
+ },
+ },
+ shouldFail: true,
+ expectedError: ":UNEXPECTED_MESSAGE:",
+ },
+ {
+ name: "DisableEverything",
+ flags: []string{"-no-tls12", "-no-tls11", "-no-tls1", "-no-ssl3"},
+ shouldFail: true,
+ expectedError: ":WRONG_SSL_VERSION:",
+ },
+ {
+ protocol: dtls,
+ name: "DisableEverything-DTLS",
+ flags: []string{"-no-tls12", "-no-tls1"},
+ shouldFail: true,
+ expectedError: ":WRONG_SSL_VERSION:",
+ },
+ {
+ name: "NoSharedCipher",
+ config: Config{
+ CipherSuites: []uint16{},
+ },
+ shouldFail: true,
+ expectedError: ":HANDSHAKE_FAILURE_ON_CLIENT_HELLO:",
+ },
+ {
+ protocol: dtls,
+ testType: serverTest,
+ name: "MTU",
+ config: Config{
+ Bugs: ProtocolBugs{
+ MaxPacketLength: 256,
+ },
+ },
+ flags: []string{"-mtu", "256"},
+ },
+ {
+ protocol: dtls,
+ testType: serverTest,
+ name: "MTUExceeded",
+ config: Config{
+ Bugs: ProtocolBugs{
+ MaxPacketLength: 255,
+ },
+ },
+ flags: []string{"-mtu", "256"},
+ shouldFail: true,
+ expectedLocalError: "dtls: exceeded maximum packet length",
+ },
+ {
+ name: "CertMismatchRSA",
+ config: Config{
+ CipherSuites: []uint16{TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256},
+ Certificates: []Certificate{getECDSACertificate()},
+ Bugs: ProtocolBugs{
+ SendCipherSuite: TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
+ },
+ },
+ shouldFail: true,
+ expectedError: ":WRONG_CERTIFICATE_TYPE:",
+ },
+ {
+ name: "CertMismatchECDSA",
+ config: Config{
+ CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
+ Certificates: []Certificate{getRSACertificate()},
+ Bugs: ProtocolBugs{
+ SendCipherSuite: TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
+ },
+ },
+ shouldFail: true,
+ expectedError: ":WRONG_CERTIFICATE_TYPE:",
+ },
+ {
+ name: "EmptyCertificateList",
+ config: Config{
+ CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
+ Bugs: ProtocolBugs{
+ EmptyCertificateList: true,
+ },
+ },
+ shouldFail: true,
+ expectedError: ":DECODE_ERROR:",
+ },
+ {
+ name: "TLSFatalBadPackets",
+ damageFirstWrite: true,
+ shouldFail: true,
+ expectedError: ":DECRYPTION_FAILED_OR_BAD_RECORD_MAC:",
+ },
+ {
+ protocol: dtls,
+ name: "DTLSIgnoreBadPackets",
+ damageFirstWrite: true,
+ },
+ {
+ protocol: dtls,
+ name: "DTLSIgnoreBadPackets-Async",
+ damageFirstWrite: true,
+ flags: []string{"-async"},
+ },
+ {
+ name: "AppDataBeforeHandshake",
+ config: Config{
+ Bugs: ProtocolBugs{
+ AppDataBeforeHandshake: []byte("TEST MESSAGE"),
+ },
+ },
+ shouldFail: true,
+ expectedError: ":UNEXPECTED_RECORD:",
+ },
+ {
+ name: "AppDataBeforeHandshake-Empty",
+ config: Config{
+ Bugs: ProtocolBugs{
+ AppDataBeforeHandshake: []byte{},
+ },
+ },
+ shouldFail: true,
+ expectedError: ":UNEXPECTED_RECORD:",
+ },
+ {
+ protocol: dtls,
+ name: "AppDataBeforeHandshake-DTLS",
+ config: Config{
+ Bugs: ProtocolBugs{
+ AppDataBeforeHandshake: []byte("TEST MESSAGE"),
+ },
+ },
+ shouldFail: true,
+ expectedError: ":UNEXPECTED_RECORD:",
+ },
+ {
+ protocol: dtls,
+ name: "AppDataBeforeHandshake-DTLS-Empty",
+ config: Config{
+ Bugs: ProtocolBugs{
+ AppDataBeforeHandshake: []byte{},
+ },
+ },
+ shouldFail: true,
+ expectedError: ":UNEXPECTED_RECORD:",
+ },
+ {
+ name: "AppDataAfterChangeCipherSpec",
+ config: Config{
+ Bugs: ProtocolBugs{
+ AppDataAfterChangeCipherSpec: []byte("TEST MESSAGE"),
+ },
+ },
+ shouldFail: true,
+ expectedError: ":DATA_BETWEEN_CCS_AND_FINISHED:",
+ },
+ {
+ name: "AppDataAfterChangeCipherSpec-Empty",
+ config: Config{
+ Bugs: ProtocolBugs{
+ AppDataAfterChangeCipherSpec: []byte{},
+ },
+ },
+ shouldFail: true,
+ expectedError: ":DATA_BETWEEN_CCS_AND_FINISHED:",
+ },
+ {
+ protocol: dtls,
+ name: "AppDataAfterChangeCipherSpec-DTLS",
+ config: Config{
+ Bugs: ProtocolBugs{
+ AppDataAfterChangeCipherSpec: []byte("TEST MESSAGE"),
+ },
+ },
+ // BoringSSL's DTLS implementation will drop the out-of-order
+ // application data.
+ },
+ {
+ protocol: dtls,
+ name: "AppDataAfterChangeCipherSpec-DTLS-Empty",
+ config: Config{
+ Bugs: ProtocolBugs{
+ AppDataAfterChangeCipherSpec: []byte{},
+ },
+ },
+ // BoringSSL's DTLS implementation will drop the out-of-order
+ // application data.
+ },
+ {
+ name: "AlertAfterChangeCipherSpec",
+ config: Config{
+ Bugs: ProtocolBugs{
+ AlertAfterChangeCipherSpec: alertRecordOverflow,
+ },
+ },
+ shouldFail: true,
+ expectedError: ":TLSV1_ALERT_RECORD_OVERFLOW:",
+ },
+ {
+ protocol: dtls,
+ name: "AlertAfterChangeCipherSpec-DTLS",
+ config: Config{
+ Bugs: ProtocolBugs{
+ AlertAfterChangeCipherSpec: alertRecordOverflow,
+ },
+ },
+ shouldFail: true,
+ expectedError: ":TLSV1_ALERT_RECORD_OVERFLOW:",
+ },
+ {
+ protocol: dtls,
+ name: "ReorderHandshakeFragments-Small-DTLS",
+ config: Config{
+ Bugs: ProtocolBugs{
+ ReorderHandshakeFragments: true,
+ // Small enough that every handshake message is
+ // fragmented.
+ MaxHandshakeRecordLength: 2,
+ },
+ },
+ },
+ {
+ protocol: dtls,
+ name: "ReorderHandshakeFragments-Large-DTLS",
+ config: Config{
+ Bugs: ProtocolBugs{
+ ReorderHandshakeFragments: true,
+ // Large enough that no handshake message is
+ // fragmented.
+ MaxHandshakeRecordLength: 2048,
+ },
+ },
+ },
+ {
+ protocol: dtls,
+ name: "MixCompleteMessageWithFragments-DTLS",
+ config: Config{
+ Bugs: ProtocolBugs{
+ ReorderHandshakeFragments: true,
+ MixCompleteMessageWithFragments: true,
+ MaxHandshakeRecordLength: 2,
+ },
+ },
+ },
+ {
+ name: "SendInvalidRecordType",
+ config: Config{
+ Bugs: ProtocolBugs{
+ SendInvalidRecordType: true,
+ },
+ },
+ shouldFail: true,
+ expectedError: ":UNEXPECTED_RECORD:",
+ },
+ {
+ protocol: dtls,
+ name: "SendInvalidRecordType-DTLS",
+ config: Config{
+ Bugs: ProtocolBugs{
+ SendInvalidRecordType: true,
+ },
+ },
+ shouldFail: true,
+ expectedError: ":UNEXPECTED_RECORD:",
+ },
+ {
+ name: "FalseStart-SkipServerSecondLeg",
+ config: Config{
+ CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
+ NextProtos: []string{"foo"},
+ Bugs: ProtocolBugs{
+ SkipNewSessionTicket: true,
+ SkipChangeCipherSpec: true,
+ SkipFinished: true,
+ ExpectFalseStart: true,
+ },
+ },
+ flags: []string{
+ "-false-start",
+ "-handshake-never-done",
+ "-advertise-alpn", "\x03foo",
+ },
+ shimWritesFirst: true,
+ shouldFail: true,
+ expectedError: ":UNEXPECTED_RECORD:",
+ },
+ {
+ name: "FalseStart-SkipServerSecondLeg-Implicit",
+ config: Config{
+ CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
+ NextProtos: []string{"foo"},
+ Bugs: ProtocolBugs{
+ SkipNewSessionTicket: true,
+ SkipChangeCipherSpec: true,
+ SkipFinished: true,
+ },
+ },
+ flags: []string{
+ "-implicit-handshake",
+ "-false-start",
+ "-handshake-never-done",
+ "-advertise-alpn", "\x03foo",
+ },
+ shouldFail: true,
+ expectedError: ":UNEXPECTED_RECORD:",
+ },
+ {
+ testType: serverTest,
+ name: "FailEarlyCallback",
+ flags: []string{"-fail-early-callback"},
+ shouldFail: true,
+ expectedError: ":CONNECTION_REJECTED:",
+ expectedLocalError: "remote error: access denied",
+ },
+ {
+ name: "WrongMessageType",
+ config: Config{
+ Bugs: ProtocolBugs{
+ WrongCertificateMessageType: true,
+ },
+ },
+ shouldFail: true,
+ expectedError: ":UNEXPECTED_MESSAGE:",
+ expectedLocalError: "remote error: unexpected message",
+ },
+ {
+ protocol: dtls,
+ name: "WrongMessageType-DTLS",
+ config: Config{
+ Bugs: ProtocolBugs{
+ WrongCertificateMessageType: true,
+ },
+ },
+ shouldFail: true,
+ expectedError: ":UNEXPECTED_MESSAGE:",
+ expectedLocalError: "remote error: unexpected message",
+ },
+ {
+ protocol: dtls,
+ name: "FragmentMessageTypeMismatch-DTLS",
+ config: Config{
+ Bugs: ProtocolBugs{
+ MaxHandshakeRecordLength: 2,
+ FragmentMessageTypeMismatch: true,
+ },
+ },
+ shouldFail: true,
+ expectedError: ":FRAGMENT_MISMATCH:",
+ },
+ {
+ protocol: dtls,
+ name: "FragmentMessageLengthMismatch-DTLS",
+ config: Config{
+ Bugs: ProtocolBugs{
+ MaxHandshakeRecordLength: 2,
+ FragmentMessageLengthMismatch: true,
+ },
+ },
+ shouldFail: true,
+ expectedError: ":FRAGMENT_MISMATCH:",
+ },
+ {
+ protocol: dtls,
+ name: "SplitFragments-Header-DTLS",
+ config: Config{
+ Bugs: ProtocolBugs{
+ SplitFragments: 2,
+ },
+ },
+ shouldFail: true,
+ expectedError: ":UNEXPECTED_MESSAGE:",
+ },
+ {
+ protocol: dtls,
+ name: "SplitFragments-Boundary-DTLS",
+ config: Config{
+ Bugs: ProtocolBugs{
+ SplitFragments: dtlsRecordHeaderLen,
+ },
+ },
+ shouldFail: true,
+ expectedError: ":EXCESSIVE_MESSAGE_SIZE:",
+ },
+ {
+ protocol: dtls,
+ name: "SplitFragments-Body-DTLS",
+ config: Config{
+ Bugs: ProtocolBugs{
+ SplitFragments: dtlsRecordHeaderLen + 1,
+ },
+ },
+ shouldFail: true,
+ expectedError: ":EXCESSIVE_MESSAGE_SIZE:",
+ },
+ {
+ protocol: dtls,
+ name: "SendEmptyFragments-DTLS",
+ config: Config{
+ Bugs: ProtocolBugs{
+ SendEmptyFragments: true,
+ },
+ },
+ },
+ {
+ name: "UnsupportedCipherSuite",
+ config: Config{
+ CipherSuites: []uint16{TLS_RSA_WITH_RC4_128_SHA},
+ Bugs: ProtocolBugs{
+ IgnorePeerCipherPreferences: true,
+ },
+ },
+ flags: []string{"-cipher", "DEFAULT:!RC4"},
+ shouldFail: true,
+ expectedError: ":WRONG_CIPHER_RETURNED:",
+ },
+ {
+ name: "UnsupportedCurve",
+ config: Config{
+ CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
+ // BoringSSL implements P-224 but doesn't enable it by
+ // default.
+ CurvePreferences: []CurveID{CurveP224},
+ Bugs: ProtocolBugs{
+ IgnorePeerCurvePreferences: true,
+ },
+ },
+ shouldFail: true,
+ expectedError: ":WRONG_CURVE:",
+ },
+ {
+ name: "BadFinished",
+ config: Config{
+ Bugs: ProtocolBugs{
+ BadFinished: true,
+ },
+ },
+ shouldFail: true,
+ expectedError: ":DIGEST_CHECK_FAILED:",
+ },
+ {
+ name: "FalseStart-BadFinished",
+ config: Config{
+ CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
+ NextProtos: []string{"foo"},
+ Bugs: ProtocolBugs{
+ BadFinished: true,
+ ExpectFalseStart: true,
+ },
+ },
+ flags: []string{
+ "-false-start",
+ "-handshake-never-done",
+ "-advertise-alpn", "\x03foo",
+ },
+ shimWritesFirst: true,
+ shouldFail: true,
+ expectedError: ":DIGEST_CHECK_FAILED:",
+ },
+ {
+ name: "NoFalseStart-NoALPN",
+ config: Config{
+ CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
+ Bugs: ProtocolBugs{
+ ExpectFalseStart: true,
+ AlertBeforeFalseStartTest: alertAccessDenied,
+ },
+ },
+ flags: []string{
+ "-false-start",
+ },
+ shimWritesFirst: true,
+ shouldFail: true,
+ expectedError: ":TLSV1_ALERT_ACCESS_DENIED:",
+ expectedLocalError: "tls: peer did not false start: EOF",
+ },
+ {
+ name: "NoFalseStart-NoAEAD",
+ config: Config{
+ CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA},
+ NextProtos: []string{"foo"},
+ Bugs: ProtocolBugs{
+ ExpectFalseStart: true,
+ AlertBeforeFalseStartTest: alertAccessDenied,
+ },
+ },
+ flags: []string{
+ "-false-start",
+ "-advertise-alpn", "\x03foo",
+ },
+ shimWritesFirst: true,
+ shouldFail: true,
+ expectedError: ":TLSV1_ALERT_ACCESS_DENIED:",
+ expectedLocalError: "tls: peer did not false start: EOF",
+ },
+ {
+ name: "NoFalseStart-RSA",
+ config: Config{
+ CipherSuites: []uint16{TLS_RSA_WITH_AES_128_GCM_SHA256},
+ NextProtos: []string{"foo"},
+ Bugs: ProtocolBugs{
+ ExpectFalseStart: true,
+ AlertBeforeFalseStartTest: alertAccessDenied,
+ },
+ },
+ flags: []string{
+ "-false-start",
+ "-advertise-alpn", "\x03foo",
+ },
+ shimWritesFirst: true,
+ shouldFail: true,
+ expectedError: ":TLSV1_ALERT_ACCESS_DENIED:",
+ expectedLocalError: "tls: peer did not false start: EOF",
+ },
+ {
+ name: "NoFalseStart-DHE_RSA",
+ config: Config{
+ CipherSuites: []uint16{TLS_DHE_RSA_WITH_AES_128_GCM_SHA256},
+ NextProtos: []string{"foo"},
+ Bugs: ProtocolBugs{
+ ExpectFalseStart: true,
+ AlertBeforeFalseStartTest: alertAccessDenied,
+ },
+ },
+ flags: []string{
+ "-false-start",
+ "-advertise-alpn", "\x03foo",
+ },
+ shimWritesFirst: true,
+ shouldFail: true,
+ expectedError: ":TLSV1_ALERT_ACCESS_DENIED:",
+ expectedLocalError: "tls: peer did not false start: EOF",
+ },
+ {
+ testType: serverTest,
+ name: "NoSupportedCurves",
+ config: Config{
+ CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
+ Bugs: ProtocolBugs{
+ NoSupportedCurves: true,
+ },
+ },
+ },
+ {
+ testType: serverTest,
+ name: "NoCommonCurves",
+ config: Config{
+ CipherSuites: []uint16{
+ TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
+ TLS_DHE_RSA_WITH_AES_128_GCM_SHA256,
+ },
+ CurvePreferences: []CurveID{CurveP224},
+ },
+ expectedCipher: TLS_DHE_RSA_WITH_AES_128_GCM_SHA256,
+ },
+ {
+ protocol: dtls,
+ name: "SendSplitAlert-Sync",
+ config: Config{
+ Bugs: ProtocolBugs{
+ SendSplitAlert: true,
+ },
+ },
+ },
+ {
+ protocol: dtls,
+ name: "SendSplitAlert-Async",
+ config: Config{
+ Bugs: ProtocolBugs{
+ SendSplitAlert: true,
+ },
+ },
+ flags: []string{"-async"},
+ },
+ {
+ protocol: dtls,
+ name: "PackDTLSHandshake",
+ config: Config{
+ Bugs: ProtocolBugs{
+ MaxHandshakeRecordLength: 2,
+ PackHandshakeFragments: 20,
+ PackHandshakeRecords: 200,
+ },
+ },
+ },
+ {
+ testType: serverTest,
+ protocol: dtls,
+ name: "NoRC4-DTLS",
+ config: Config{
+ CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_RC4_128_SHA},
+ Bugs: ProtocolBugs{
+ EnableAllCiphersInDTLS: true,
+ },
+ },
+ shouldFail: true,
+ expectedError: ":NO_SHARED_CIPHER:",
+ },
+ {
+ name: "SendEmptyRecords-Pass",
+ sendEmptyRecords: 32,
+ },
+ {
+ name: "SendEmptyRecords",
+ sendEmptyRecords: 33,
+ shouldFail: true,
+ expectedError: ":TOO_MANY_EMPTY_FRAGMENTS:",
+ },
+ {
+ name: "SendEmptyRecords-Async",
+ sendEmptyRecords: 33,
+ flags: []string{"-async"},
+ shouldFail: true,
+ expectedError: ":TOO_MANY_EMPTY_FRAGMENTS:",
+ },
+ {
+ name: "SendWarningAlerts-Pass",
+ sendWarningAlerts: 4,
+ },
+ {
+ protocol: dtls,
+ name: "SendWarningAlerts-DTLS-Pass",
+ sendWarningAlerts: 4,
+ },
+ {
+ name: "SendWarningAlerts",
+ sendWarningAlerts: 5,
+ shouldFail: true,
+ expectedError: ":TOO_MANY_WARNING_ALERTS:",
+ },
+ {
+ name: "SendWarningAlerts-Async",
+ sendWarningAlerts: 5,
+ flags: []string{"-async"},
+ shouldFail: true,
+ expectedError: ":TOO_MANY_WARNING_ALERTS:",
+ },
+ {
+ name: "EmptySessionID",
+ config: Config{
+ SessionTicketsDisabled: true,
+ },
+ noSessionCache: true,
+ flags: []string{"-expect-no-session"},
+ },
+ {
+ name: "Unclean-Shutdown",
+ config: Config{
+ Bugs: ProtocolBugs{
+ NoCloseNotify: true,
+ ExpectCloseNotify: true,
+ },
+ },
+ shimShutsDown: true,
+ flags: []string{"-check-close-notify"},
+ shouldFail: true,
+ expectedError: "Unexpected SSL_shutdown result: -1 != 1",
+ },
+ {
+ name: "Unclean-Shutdown-Ignored",
+ config: Config{
+ Bugs: ProtocolBugs{
+ NoCloseNotify: true,
+ },
+ },
+ shimShutsDown: true,
+ },
+ {
+ name: "LargePlaintext",
+ config: Config{
+ Bugs: ProtocolBugs{
+ SendLargeRecords: true,
+ },
+ },
+ messageLen: maxPlaintext + 1,
+ shouldFail: true,
+ expectedError: ":DATA_LENGTH_TOO_LONG:",
+ },
+ {
+ protocol: dtls,
+ name: "LargePlaintext-DTLS",
+ config: Config{
+ Bugs: ProtocolBugs{
+ SendLargeRecords: true,
+ },
+ },
+ messageLen: maxPlaintext + 1,
+ shouldFail: true,
+ expectedError: ":DATA_LENGTH_TOO_LONG:",
+ },
+ {
+ name: "LargeCiphertext",
+ config: Config{
+ Bugs: ProtocolBugs{
+ SendLargeRecords: true,
+ },
+ },
+ messageLen: maxPlaintext * 2,
+ shouldFail: true,
+ expectedError: ":ENCRYPTED_LENGTH_TOO_LONG:",
+ },
+ {
+ protocol: dtls,
+ name: "LargeCiphertext-DTLS",
+ config: Config{
+ Bugs: ProtocolBugs{
+ SendLargeRecords: true,
+ },
+ },
+ messageLen: maxPlaintext * 2,
+ // Unlike the other four cases, DTLS drops records which
+ // are invalid before authentication, so the connection
+ // does not fail.
+ expectMessageDropped: true,
+ },
+ }
+ testCases = append(testCases, basicTests...)
+}
+
func addCipherSuiteTests() {
for _, suite := range testCipherSuites {
const psk = "12345"
@@ -1679,6 +1988,10 @@ func addCipherSuiteTests() {
"-psk", psk,
"-psk-identity", pskIdentity)
}
+ if hasComponent(suite.name, "NULL") {
+ // NULL ciphers must be explicitly enabled.
+ flags = append(flags, "-cipher", "DEFAULT:NULL-SHA")
+ }
for _, ver := range tlsVersions {
if ver.version < VersionTLS12 && isTLS12Only(suite.name) {
@@ -1752,6 +2065,47 @@ func addCipherSuiteTests() {
})
}
}
+
+ // Ensure both TLS and DTLS accept their maximum record sizes.
+ testCases = append(testCases, testCase{
+ name: suite.name + "-LargeRecord",
+ config: Config{
+ CipherSuites: []uint16{suite.id},
+ Certificates: []Certificate{cert},
+ PreSharedKey: []byte(psk),
+ PreSharedKeyIdentity: pskIdentity,
+ },
+ flags: flags,
+ messageLen: maxPlaintext,
+ })
+ testCases = append(testCases, testCase{
+ name: suite.name + "-LargeRecord-Extra",
+ config: Config{
+ CipherSuites: []uint16{suite.id},
+ Certificates: []Certificate{cert},
+ PreSharedKey: []byte(psk),
+ PreSharedKeyIdentity: pskIdentity,
+ Bugs: ProtocolBugs{
+ SendLargeRecords: true,
+ },
+ },
+ flags: append(flags, "-microsoft-big-sslv3-buffer"),
+ messageLen: maxPlaintext + 16384,
+ })
+ if isDTLSCipher(suite.name) {
+ testCases = append(testCases, testCase{
+ protocol: dtls,
+ name: suite.name + "-LargeRecord-DTLS",
+ config: Config{
+ CipherSuites: []uint16{suite.id},
+ Certificates: []Certificate{cert},
+ PreSharedKey: []byte(psk),
+ PreSharedKeyIdentity: pskIdentity,
+ },
+ flags: flags,
+ messageLen: maxPlaintext,
+ })
+ }
}
testCases = append(testCases, testCase{
@@ -1768,6 +2122,94 @@ func addCipherSuiteTests() {
shouldFail: true,
expectedError: "BAD_DH_P_LENGTH",
})
+
+ // versionSpecificCiphersTest specifies a test for the TLS 1.0 and TLS
+ // 1.1 specific cipher suite settings. A server is setup with the given
+ // cipher lists and then a connection is made for each member of
+ // expectations. The cipher suite that the server selects must match
+ // the specified one.
+ var versionSpecificCiphersTest = []struct {
+ ciphersDefault, ciphersTLS10, ciphersTLS11 string
+ // expectations is a map from TLS version to cipher suite id.
+ expectations map[uint16]uint16
+ }{
+ {
+ // Test that the null case (where no version-specific ciphers are set)
+ // works as expected.
+ "RC4-SHA:AES128-SHA", // default ciphers
+ "", // no ciphers specifically for TLS ≥ 1.0
+ "", // no ciphers specifically for TLS ≥ 1.1
+ map[uint16]uint16{
+ VersionSSL30: TLS_RSA_WITH_RC4_128_SHA,
+ VersionTLS10: TLS_RSA_WITH_RC4_128_SHA,
+ VersionTLS11: TLS_RSA_WITH_RC4_128_SHA,
+ VersionTLS12: TLS_RSA_WITH_RC4_128_SHA,
+ },
+ },
+ {
+ // With ciphers_tls10 set, TLS 1.0, 1.1 and 1.2 should get a different
+ // cipher.
+ "RC4-SHA:AES128-SHA", // default
+ "AES128-SHA", // these ciphers for TLS ≥ 1.0
+ "", // no ciphers specifically for TLS ≥ 1.1
+ map[uint16]uint16{
+ VersionSSL30: TLS_RSA_WITH_RC4_128_SHA,
+ VersionTLS10: TLS_RSA_WITH_AES_128_CBC_SHA,
+ VersionTLS11: TLS_RSA_WITH_AES_128_CBC_SHA,
+ VersionTLS12: TLS_RSA_WITH_AES_128_CBC_SHA,
+ },
+ },
+ {
+ // With ciphers_tls11 set, TLS 1.1 and 1.2 should get a different
+ // cipher.
+ "RC4-SHA:AES128-SHA", // default
+ "", // no ciphers specifically for TLS ≥ 1.0
+ "AES128-SHA", // these ciphers for TLS ≥ 1.1
+ map[uint16]uint16{
+ VersionSSL30: TLS_RSA_WITH_RC4_128_SHA,
+ VersionTLS10: TLS_RSA_WITH_RC4_128_SHA,
+ VersionTLS11: TLS_RSA_WITH_AES_128_CBC_SHA,
+ VersionTLS12: TLS_RSA_WITH_AES_128_CBC_SHA,
+ },
+ },
+ {
+ // With both ciphers_tls10 and ciphers_tls11 set, ciphers_tls11 should
+ // mask ciphers_tls10 for TLS 1.1 and 1.2.
+ "RC4-SHA:AES128-SHA", // default
+ "AES128-SHA", // these ciphers for TLS ≥ 1.0
+ "AES256-SHA", // these ciphers for TLS ≥ 1.1
+ map[uint16]uint16{
+ VersionSSL30: TLS_RSA_WITH_RC4_128_SHA,
+ VersionTLS10: TLS_RSA_WITH_AES_128_CBC_SHA,
+ VersionTLS11: TLS_RSA_WITH_AES_256_CBC_SHA,
+ VersionTLS12: TLS_RSA_WITH_AES_256_CBC_SHA,
+ },
+ },
+ }
+
+ for i, test := range versionSpecificCiphersTest {
+ for version, expectedCipherSuite := range test.expectations {
+ flags := []string{"-cipher", test.ciphersDefault}
+ if len(test.ciphersTLS10) > 0 {
+ flags = append(flags, "-cipher-tls10", test.ciphersTLS10)
+ }
+ if len(test.ciphersTLS11) > 0 {
+ flags = append(flags, "-cipher-tls11", test.ciphersTLS11)
+ }
+
+ testCases = append(testCases, testCase{
+ testType: serverTest,
+ name: fmt.Sprintf("VersionSpecificCiphersTest-%d-%x", i, version),
+ config: Config{
+ MaxVersion: version,
+ MinVersion: version,
+ CipherSuites: []uint16{TLS_RSA_WITH_RC4_128_SHA, TLS_RSA_WITH_AES_128_CBC_SHA, TLS_RSA_WITH_AES_256_CBC_SHA},
+ },
+ flags: flags,
+ expectedCipher: expectedCipherSuite,
+ })
+ }
+ }
}
func addBadECDSASignatureTests() {
@@ -1837,7 +2279,8 @@ func addCBCSplittingTests() {
MinVersion: VersionTLS10,
CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA},
},
- messageLen: -1, // read until EOF
+ messageLen: -1, // read until EOF
+ resumeSession: true,
flags: []string{
"-async",
"-write-different-record-sizes",
@@ -1882,8 +2325,8 @@ func addClientAuthTests() {
ClientCAs: certPool,
},
flags: []string{
- "-cert-file", rsaCertificateFile,
- "-key-file", rsaKeyFile,
+ "-cert-file", path.Join(*resourceDir, rsaCertificateFile),
+ "-key-file", path.Join(*resourceDir, rsaKeyFile),
},
})
testCases = append(testCases, testCase{
@@ -1917,8 +2360,8 @@ func addClientAuthTests() {
ClientCAs: certPool,
},
flags: []string{
- "-cert-file", ecdsaCertificateFile,
- "-key-file", ecdsaKeyFile,
+ "-cert-file", path.Join(*resourceDir, ecdsaCertificateFile),
+ "-key-file", path.Join(*resourceDir, ecdsaKeyFile),
},
})
}
@@ -2075,6 +2518,7 @@ func addStateMachineCoverageTests(async, splitHandshake bool, protocol protocol)
RenewTicketOnResume: true,
},
},
+ flags: []string{"-expect-ticket-renewal"},
resumeSession: true,
})
tests = append(tests, testCase{
@@ -2123,10 +2567,42 @@ func addStateMachineCoverageTests(async, splitHandshake bool, protocol protocol)
ClientAuth: RequireAnyClientCert,
},
flags: []string{
- "-cert-file", rsaCertificateFile,
- "-key-file", rsaKeyFile,
+ "-cert-file", path.Join(*resourceDir, rsaCertificateFile),
+ "-key-file", path.Join(*resourceDir, rsaKeyFile),
},
})
+ if async {
+ tests = append(tests, testCase{
+ testType: clientTest,
+ name: "ClientAuth-Client-AsyncKey",
+ config: Config{
+ ClientAuth: RequireAnyClientCert,
+ },
+ flags: []string{
+ "-cert-file", path.Join(*resourceDir, rsaCertificateFile),
+ "-key-file", path.Join(*resourceDir, rsaKeyFile),
+ "-use-async-private-key",
+ },
+ })
+ tests = append(tests, testCase{
+ testType: serverTest,
+ name: "Basic-Server-RSAAsyncKey",
+ flags: []string{
+ "-cert-file", path.Join(*resourceDir, rsaCertificateFile),
+ "-key-file", path.Join(*resourceDir, rsaKeyFile),
+ "-use-async-private-key",
+ },
+ })
+ tests = append(tests, testCase{
+ testType: serverTest,
+ name: "Basic-Server-ECDSAAsyncKey",
+ flags: []string{
+ "-cert-file", path.Join(*resourceDir, ecdsaCertificateFile),
+ "-key-file", path.Join(*resourceDir, ecdsaKeyFile),
+ "-use-async-private-key",
+ },
+ })
+ }
tests = append(tests, testCase{
testType: serverTest,
name: "ClientAuth-Server",
@@ -2171,6 +2647,57 @@ func addStateMachineCoverageTests(async, splitHandshake bool, protocol protocol)
flags: []string{"-psk", "secret"},
})
+ tests = append(tests, testCase{
+ testType: clientTest,
+ name: "OCSPStapling-Client",
+ flags: []string{
+ "-enable-ocsp-stapling",
+ "-expect-ocsp-response",
+ base64.StdEncoding.EncodeToString(testOCSPResponse),
+ "-verify-peer",
+ },
+ resumeSession: true,
+ })
+
+ tests = append(tests, testCase{
+ testType: serverTest,
+ name: "OCSPStapling-Server",
+ expectedOCSPResponse: testOCSPResponse,
+ flags: []string{
+ "-ocsp-response",
+ base64.StdEncoding.EncodeToString(testOCSPResponse),
+ },
+ resumeSession: true,
+ })
+
+ tests = append(tests, testCase{
+ testType: clientTest,
+ name: "CertificateVerificationSucceed",
+ flags: []string{
+ "-verify-peer",
+ },
+ })
+
+ tests = append(tests, testCase{
+ testType: clientTest,
+ name: "CertificateVerificationFail",
+ flags: []string{
+ "-verify-fail",
+ "-verify-peer",
+ },
+ shouldFail: true,
+ expectedError: ":CERTIFICATE_VERIFY_FAILED:",
+ })
+
+ tests = append(tests, testCase{
+ testType: clientTest,
+ name: "CertificateVerificationSoftFail",
+ flags: []string{
+ "-verify-fail",
+ "-expect-verify-result",
+ },
+ })
+
if protocol == tls {
tests = append(tests, testCase{
name: "Renegotiate-Client",
@@ -2292,7 +2819,7 @@ func addStateMachineCoverageTests(async, splitHandshake bool, protocol protocol)
config: Config{
RequestChannelID: true,
},
- flags: []string{"-send-channel-id", channelIDKeyFile},
+ flags: []string{"-send-channel-id", path.Join(*resourceDir, channelIDKeyFile)},
resumeSession: true,
expectChannelID: true,
})
@@ -2311,6 +2838,33 @@ func addStateMachineCoverageTests(async, splitHandshake bool, protocol protocol)
resumeSession: true,
expectChannelID: true,
})
+
+ // Bidirectional shutdown with the runner initiating.
+ tests = append(tests, testCase{
+ name: "Shutdown-Runner",
+ config: Config{
+ Bugs: ProtocolBugs{
+ ExpectCloseNotify: true,
+ },
+ },
+ flags: []string{"-check-close-notify"},
+ })
+
+ // Bidirectional shutdown with the shim initiating. The runner,
+ // in the meantime, sends garbage before the close_notify which
+ // the shim must ignore.
+ tests = append(tests, testCase{
+ name: "Shutdown-Shim",
+ config: Config{
+ Bugs: ProtocolBugs{
+ ExpectCloseNotify: true,
+ },
+ },
+ shimShutsDown: true,
+ sendEmptyRecords: 1,
+ sendWarningAlerts: 1,
+ flags: []string{"-check-close-notify"},
+ })
} else {
tests = append(tests, testCase{
name: "SkipHelloVerifyRequest",
@@ -2721,6 +3275,70 @@ func addExtensionTests() {
expectedNextProtoType: alpn,
resumeSession: true,
})
+ var emptyString string
+ testCases = append(testCases, testCase{
+ testType: clientTest,
+ name: "ALPNClient-EmptyProtocolName",
+ config: Config{
+ NextProtos: []string{""},
+ Bugs: ProtocolBugs{
+ // A server returning an empty ALPN protocol
+ // should be rejected.
+ ALPNProtocol: &emptyString,
+ },
+ },
+ flags: []string{
+ "-advertise-alpn", "\x03foo",
+ },
+ shouldFail: true,
+ expectedError: ":PARSE_TLSEXT:",
+ })
+ testCases = append(testCases, testCase{
+ testType: serverTest,
+ name: "ALPNServer-EmptyProtocolName",
+ config: Config{
+ // A ClientHello containing an empty ALPN protocol
+ // should be rejected.
+ NextProtos: []string{"foo", "", "baz"},
+ },
+ flags: []string{
+ "-select-alpn", "foo",
+ },
+ shouldFail: true,
+ expectedError: ":PARSE_TLSEXT:",
+ })
+ // Test that negotiating both NPN and ALPN is forbidden.
+ testCases = append(testCases, testCase{
+ name: "NegotiateALPNAndNPN",
+ config: Config{
+ NextProtos: []string{"foo", "bar", "baz"},
+ Bugs: ProtocolBugs{
+ NegotiateALPNAndNPN: true,
+ },
+ },
+ flags: []string{
+ "-advertise-alpn", "\x03foo",
+ "-select-next-proto", "foo",
+ },
+ shouldFail: true,
+ expectedError: ":NEGOTIATED_BOTH_NPN_AND_ALPN:",
+ })
+ testCases = append(testCases, testCase{
+ name: "NegotiateALPNAndNPN-Swapped",
+ config: Config{
+ NextProtos: []string{"foo", "bar", "baz"},
+ Bugs: ProtocolBugs{
+ NegotiateALPNAndNPN: true,
+ SwapNPNAndALPN: true,
+ },
+ },
+ flags: []string{
+ "-advertise-alpn", "\x03foo",
+ "-select-next-proto", "foo",
+ },
+ shouldFail: true,
+ expectedError: ":NEGOTIATED_BOTH_NPN_AND_ALPN:",
+ })
// Resume with a corrupt ticket.
testCases = append(testCases, testCase{
testType: serverTest,
@@ -2733,6 +3351,24 @@ func addExtensionTests() {
resumeSession: true,
expectResumeRejected: true,
})
+ // Test the ticket callback, with and without renewal.
+ testCases = append(testCases, testCase{
+ testType: serverTest,
+ name: "TicketCallback",
+ resumeSession: true,
+ flags: []string{"-use-ticket-callback"},
+ })
+ testCases = append(testCases, testCase{
+ testType: serverTest,
+ name: "TicketCallback-Renew",
+ config: Config{
+ Bugs: ProtocolBugs{
+ ExpectNewTicket: true,
+ },
+ },
+ flags: []string{"-use-ticket-callback", "-renew-ticket"},
+ resumeSession: true,
+ })
// Resume with an oversized session id.
testCases = append(testCases, testCase{
testType: serverTest,
@@ -2822,22 +3458,39 @@ func addExtensionTests() {
shouldFail: true,
expectedError: ":BAD_SRTP_PROTECTION_PROFILE_LIST:",
})
- // Test OCSP stapling and SCT list.
+ // Test SCT list.
testCases = append(testCases, testCase{
- name: "OCSPStapling",
+ name: "SignedCertificateTimestampList-Client",
+ testType: clientTest,
flags: []string{
- "-enable-ocsp-stapling",
- "-expect-ocsp-response",
- base64.StdEncoding.EncodeToString(testOCSPResponse),
+ "-enable-signed-cert-timestamps",
+ "-expect-signed-cert-timestamps",
+ base64.StdEncoding.EncodeToString(testSCTList),
},
+ resumeSession: true,
})
testCases = append(testCases, testCase{
- name: "SignedCertificateTimestampList",
+ name: "SignedCertificateTimestampList-Server",
+ testType: serverTest,
flags: []string{
- "-enable-signed-cert-timestamps",
- "-expect-signed-cert-timestamps",
+ "-signed-cert-timestamps",
base64.StdEncoding.EncodeToString(testSCTList),
},
+ expectedSCTList: testSCTList,
+ resumeSession: true,
+ })
+ testCases = append(testCases, testCase{
+ testType: clientTest,
+ name: "ClientHelloPadding",
+ config: Config{
+ Bugs: ProtocolBugs{
+ RequireClientHelloSize: 512,
+ },
+ },
+ // This hostname just needs to be long enough to push the
+ // ClientHello into F5's danger zone between 256 and 511 bytes
+ // long.
+ flags: []string{"-host-name", "01234567890123456789012345678901234567890123456789012345678901234567890123456789.com"},
})
}
@@ -2956,7 +3609,33 @@ func addRenegotiationTests() {
expectedError: ":NO_RENEGOTIATION:",
expectedLocalError: "remote error: no renegotiation",
})
- // TODO(agl): test the renegotiation info SCSV.
+ // The server shouldn't echo the renegotiation extension unless
+ // requested by the client.
+ testCases = append(testCases, testCase{
+ testType: serverTest,
+ name: "Renegotiate-Server-NoExt",
+ config: Config{
+ Bugs: ProtocolBugs{
+ NoRenegotiationInfo: true,
+ RequireRenegotiationInfo: true,
+ },
+ },
+ shouldFail: true,
+ expectedLocalError: "renegotiation extension missing",
+ })
+ // The renegotiation SCSV should be sufficient for the server to echo
+ // the extension.
+ testCases = append(testCases, testCase{
+ testType: serverTest,
+ name: "Renegotiate-Server-NoExt-SCSV",
+ config: Config{
+ Bugs: ProtocolBugs{
+ NoRenegotiationInfo: true,
+ SendRenegotiationSCSV: true,
+ RequireRenegotiationInfo: true,
+ },
+ },
+ })
testCases = append(testCases, testCase{
name: "Renegotiate-Client",
config: Config{
@@ -2989,8 +3668,7 @@ func addRenegotiationTests() {
expectedError: ":RENEGOTIATION_MISMATCH:",
})
testCases = append(testCases, testCase{
- name: "Renegotiate-Client-NoExt",
- renegotiate: true,
+ name: "Renegotiate-Client-NoExt",
config: Config{
Bugs: ProtocolBugs{
NoRenegotiationInfo: true,
@@ -3043,6 +3721,19 @@ func addRenegotiationTests() {
},
},
})
+ testCases = append(testCases, testCase{
+ name: "Renegotiate-FalseStart",
+ renegotiate: true,
+ config: Config{
+ CipherSuites: []uint16{TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256},
+ NextProtos: []string{"foo"},
+ },
+ flags: []string{
+ "-false-start",
+ "-select-next-proto", "foo",
+ },
+ shimWritesFirst: true,
+ })
}
func addDTLSReplayTests() {
@@ -3050,43 +3741,39 @@ func addDTLSReplayTests() {
testCases = append(testCases, testCase{
protocol: dtls,
name: "DTLS-Replay",
+ messageCount: 200,
replayWrites: true,
})
- // Test the outgoing sequence number skipping by values larger
+ // Test the incoming sequence number skipping by values larger
// than the retransmit window.
testCases = append(testCases, testCase{
protocol: dtls,
name: "DTLS-Replay-LargeGaps",
config: Config{
Bugs: ProtocolBugs{
- SequenceNumberIncrement: 127,
+ SequenceNumberMapping: func(in uint64) uint64 {
+ return in * 127
+ },
},
},
+ messageCount: 200,
replayWrites: true,
})
-}
-func addFastRadioPaddingTests() {
- testCases = append(testCases, testCase{
- protocol: tls,
- name: "FastRadio-Padding",
- config: Config{
- Bugs: ProtocolBugs{
- RequireFastradioPadding: true,
- },
- },
- flags: []string{"-fastradio-padding"},
- })
+ // Test the incoming sequence number changing non-monotonically.
testCases = append(testCases, testCase{
protocol: dtls,
- name: "FastRadio-Padding-DTLS",
+ name: "DTLS-Replay-NonMonotonic",
config: Config{
Bugs: ProtocolBugs{
- RequireFastradioPadding: true,
+ SequenceNumberMapping: func(in uint64) uint64 {
+ return in ^ 31
+ },
},
},
- flags: []string{"-fastradio-padding"},
+ messageCount: 200,
+ replayWrites: true,
})
}
@@ -3116,8 +3803,8 @@ func addSigningHashTests() {
},
},
flags: []string{
- "-cert-file", rsaCertificateFile,
- "-key-file", rsaKeyFile,
+ "-cert-file", path.Join(*resourceDir, rsaCertificateFile),
+ "-key-file", path.Join(*resourceDir, rsaKeyFile),
},
})
@@ -3147,8 +3834,8 @@ func addSigningHashTests() {
},
},
flags: []string{
- "-cert-file", rsaCertificateFile,
- "-key-file", rsaKeyFile,
+ "-cert-file", path.Join(*resourceDir, rsaCertificateFile),
+ "-key-file", path.Join(*resourceDir, rsaKeyFile),
},
})
@@ -3178,8 +3865,8 @@ func addSigningHashTests() {
},
},
flags: []string{
- "-cert-file", rsaCertificateFile,
- "-key-file", rsaKeyFile,
+ "-cert-file", path.Join(*resourceDir, rsaCertificateFile),
+ "-key-file", path.Join(*resourceDir, rsaKeyFile),
},
})
@@ -3235,6 +3922,73 @@ func addSigningHashTests() {
shouldFail: true,
expectedError: ":WRONG_SIGNATURE_TYPE:",
})
+
+ // Test that the agreed upon digest respects the client preferences and
+ // the server digests.
+ testCases = append(testCases, testCase{
+ name: "Agree-Digest-Fallback",
+ config: Config{
+ ClientAuth: RequireAnyClientCert,
+ SignatureAndHashes: []signatureAndHash{
+ {signatureRSA, hashSHA512},
+ {signatureRSA, hashSHA1},
+ },
+ },
+ flags: []string{
+ "-cert-file", path.Join(*resourceDir, rsaCertificateFile),
+ "-key-file", path.Join(*resourceDir, rsaKeyFile),
+ },
+ digestPrefs: "SHA256",
+ expectedClientCertSignatureHash: hashSHA1,
+ })
+ testCases = append(testCases, testCase{
+ name: "Agree-Digest-SHA256",
+ config: Config{
+ ClientAuth: RequireAnyClientCert,
+ SignatureAndHashes: []signatureAndHash{
+ {signatureRSA, hashSHA1},
+ {signatureRSA, hashSHA256},
+ },
+ },
+ flags: []string{
+ "-cert-file", path.Join(*resourceDir, rsaCertificateFile),
+ "-key-file", path.Join(*resourceDir, rsaKeyFile),
+ },
+ digestPrefs: "SHA256,SHA1",
+ expectedClientCertSignatureHash: hashSHA256,
+ })
+ testCases = append(testCases, testCase{
+ name: "Agree-Digest-SHA1",
+ config: Config{
+ ClientAuth: RequireAnyClientCert,
+ SignatureAndHashes: []signatureAndHash{
+ {signatureRSA, hashSHA1},
+ },
+ },
+ flags: []string{
+ "-cert-file", path.Join(*resourceDir, rsaCertificateFile),
+ "-key-file", path.Join(*resourceDir, rsaKeyFile),
+ },
+ digestPrefs: "SHA512,SHA256,SHA1",
+ expectedClientCertSignatureHash: hashSHA1,
+ })
+ testCases = append(testCases, testCase{
+ name: "Agree-Digest-Default",
+ config: Config{
+ ClientAuth: RequireAnyClientCert,
+ SignatureAndHashes: []signatureAndHash{
+ {signatureRSA, hashSHA256},
+ {signatureECDSA, hashSHA256},
+ {signatureRSA, hashSHA1},
+ {signatureECDSA, hashSHA1},
+ },
+ },
+ flags: []string{
+ "-cert-file", path.Join(*resourceDir, rsaCertificateFile),
+ "-key-file", path.Join(*resourceDir, rsaKeyFile),
+ },
+ expectedClientCertSignatureHash: hashSHA256,
+ })
}
// timeouts is the retransmit schedule for BoringSSL. It doubles and
@@ -3441,7 +4195,111 @@ func addTLSUniqueTests() {
}
}
-func worker(statusChan chan statusMsg, c chan *testCase, buildDir string, wg *sync.WaitGroup) {
+func addCustomExtensionTests() {
+ expectedContents := "custom extension"
+ emptyString := ""
+
+ for _, isClient := range []bool{false, true} {
+ suffix := "Server"
+ flag := "-enable-server-custom-extension"
+ testType := serverTest
+ if isClient {
+ suffix = "Client"
+ flag = "-enable-client-custom-extension"
+ testType = clientTest
+ }
+
+ testCases = append(testCases, testCase{
+ testType: testType,
+ name: "CustomExtensions-" + suffix,
+ config: Config{
+ Bugs: ProtocolBugs{
+ CustomExtension: expectedContents,
+ ExpectedCustomExtension: &expectedContents,
+ },
+ },
+ flags: []string{flag},
+ })
+
+ // If the parse callback fails, the handshake should also fail.
+ testCases = append(testCases, testCase{
+ testType: testType,
+ name: "CustomExtensions-ParseError-" + suffix,
+ config: Config{
+ Bugs: ProtocolBugs{
+ CustomExtension: expectedContents + "foo",
+ ExpectedCustomExtension: &expectedContents,
+ },
+ },
+ flags: []string{flag},
+ shouldFail: true,
+ expectedError: ":CUSTOM_EXTENSION_ERROR:",
+ })
+
+ // If the add callback fails, the handshake should also fail.
+ testCases = append(testCases, testCase{
+ testType: testType,
+ name: "CustomExtensions-FailAdd-" + suffix,
+ config: Config{
+ Bugs: ProtocolBugs{
+ CustomExtension: expectedContents,
+ ExpectedCustomExtension: &expectedContents,
+ },
+ },
+ flags: []string{flag, "-custom-extension-fail-add"},
+ shouldFail: true,
+ expectedError: ":CUSTOM_EXTENSION_ERROR:",
+ })
+
+ // If the add callback returns zero, no extension should be
+ // added.
+ skipCustomExtension := expectedContents
+ if isClient {
+ // For the case where the client skips sending the
+ // custom extension, the server must not “echo†it.
+ skipCustomExtension = ""
+ }
+ testCases = append(testCases, testCase{
+ testType: testType,
+ name: "CustomExtensions-Skip-" + suffix,
+ config: Config{
+ Bugs: ProtocolBugs{
+ CustomExtension: skipCustomExtension,
+ ExpectedCustomExtension: &emptyString,
+ },
+ },
+ flags: []string{flag, "-custom-extension-skip"},
+ })
+ }
+
+ // The custom extension add callback should not be called if the client
+ // doesn't send the extension.
+ testCases = append(testCases, testCase{
+ testType: serverTest,
+ name: "CustomExtensions-NotCalled-Server",
+ config: Config{
+ Bugs: ProtocolBugs{
+ ExpectedCustomExtension: &emptyString,
+ },
+ },
+ flags: []string{"-enable-server-custom-extension", "-custom-extension-fail-add"},
+ })
+
+ // Test an unknown extension from the server.
+ testCases = append(testCases, testCase{
+ testType: clientTest,
+ name: "UnknownExtension-Client",
+ config: Config{
+ Bugs: ProtocolBugs{
+ CustomExtension: expectedContents,
+ },
+ },
+ shouldFail: true,
+ expectedError: ":UNEXPECTED_EXTENSION:",
+ })
+}
+
+func worker(statusChan chan statusMsg, c chan *testCase, shimPath string, wg *sync.WaitGroup) {
defer wg.Done()
for test := range c {
@@ -3449,11 +4307,11 @@ func worker(statusChan chan statusMsg, c chan *testCase, buildDir string, wg *sy
if *mallocTest < 0 {
statusChan <- statusMsg{test: test, started: true}
- err = runTest(test, buildDir, -1)
+ err = runTest(test, shimPath, -1)
} else {
for mallocNumToFail := int64(*mallocTest); ; mallocNumToFail++ {
statusChan <- statusMsg{test: test, started: true}
- if err = runTest(test, buildDir, mallocNumToFail); err != errMoreMallocs {
+ if err = runTest(test, shimPath, mallocNumToFail); err != errMoreMallocs {
if err != nil {
fmt.Printf("\n\nmalloc test failed at %d: %s\n", mallocNumToFail, err)
}
@@ -3515,12 +4373,10 @@ func statusPrinter(doneChan chan *testOutput, statusChan chan statusMsg, total i
}
func main() {
- var flagTest *string = flag.String("test", "", "The name of a test to run, or empty to run all tests")
- var flagNumWorkers *int = flag.Int("num-workers", runtime.NumCPU(), "The number of workers to run in parallel.")
- var flagBuildDir *string = flag.String("build-dir", "../../../build", "The build directory to run the shim from.")
-
flag.Parse()
+ *resourceDir = path.Clean(*resourceDir)
+ addBasicTests()
addCipherSuiteTests()
addBadECDSASignatureTests()
addCBCPaddingTests()
@@ -3536,10 +4392,10 @@ func main() {
addRenegotiationTests()
addDTLSReplayTests()
addSigningHashTests()
- addFastRadioPaddingTests()
addDTLSRetransmitTests()
addExportKeyingMaterialTests()
addTLSUniqueTests()
+ addCustomExtensionTests()
for _, async := range []bool{false, true} {
for _, splitHandshake := range []bool{false, true} {
for _, protocol := range []protocol{tls, dtls} {
@@ -3550,21 +4406,19 @@ func main() {
var wg sync.WaitGroup
- numWorkers := *flagNumWorkers
-
- statusChan := make(chan statusMsg, numWorkers)
- testChan := make(chan *testCase, numWorkers)
+ statusChan := make(chan statusMsg, *numWorkers)
+ testChan := make(chan *testCase, *numWorkers)
doneChan := make(chan *testOutput)
go statusPrinter(doneChan, statusChan, len(testCases))
- for i := 0; i < numWorkers; i++ {
+ for i := 0; i < *numWorkers; i++ {
wg.Add(1)
- go worker(statusChan, testChan, *flagBuildDir, &wg)
+ go worker(statusChan, testChan, *shimPath, &wg)
}
for i := range testCases {
- if len(*flagTest) == 0 || *flagTest == testCases[i].name {
+ if len(*testToRun) == 0 || *testToRun == testCases[i].name {
testChan <- &testCases[i]
}
}
diff --git a/src/ssl/test/test_config.cc b/src/ssl/test/test_config.cc
index 363b6f3..1c42b2e 100644
--- a/src/ssl/test/test_config.cc
+++ b/src/ssl/test/test_config.cc
@@ -65,12 +65,9 @@ const Flag<bool> kBoolFlags[] = {
{ "-expect-session-miss", &TestConfig::expect_session_miss },
{ "-expect-extended-master-secret",
&TestConfig::expect_extended_master_secret },
- { "-allow-unsafe-legacy-renegotiation",
- &TestConfig::allow_unsafe_legacy_renegotiation },
{ "-enable-ocsp-stapling", &TestConfig::enable_ocsp_stapling },
{ "-enable-signed-cert-timestamps",
&TestConfig::enable_signed_cert_timestamps },
- { "-fastradio-padding", &TestConfig::fastradio_padding },
{ "-implicit-handshake", &TestConfig::implicit_handshake },
{ "-use-early-callback", &TestConfig::use_early_callback },
{ "-fail-early-callback", &TestConfig::fail_early_callback },
@@ -82,9 +79,27 @@ const Flag<bool> kBoolFlags[] = {
{ "-reject-peer-renegotiations", &TestConfig::reject_peer_renegotiations },
{ "-no-legacy-server-connect", &TestConfig::no_legacy_server_connect },
{ "-tls-unique", &TestConfig::tls_unique },
+ { "-use-async-private-key", &TestConfig::use_async_private_key },
+ { "-expect-ticket-renewal", &TestConfig::expect_ticket_renewal },
+ { "-expect-no-session", &TestConfig::expect_no_session },
+ { "-use-ticket-callback", &TestConfig::use_ticket_callback },
+ { "-renew-ticket", &TestConfig::renew_ticket },
+ { "-enable-client-custom-extension",
+ &TestConfig::enable_client_custom_extension },
+ { "-enable-server-custom-extension",
+ &TestConfig::enable_server_custom_extension },
+ { "-custom-extension-skip", &TestConfig::custom_extension_skip },
+ { "-custom-extension-fail-add", &TestConfig::custom_extension_fail_add },
+ { "-check-close-notify", &TestConfig::check_close_notify },
+ { "-shim-shuts-down", &TestConfig::shim_shuts_down },
+ { "-microsoft-big-sslv3-buffer", &TestConfig::microsoft_big_sslv3_buffer },
+ { "-verify-fail", &TestConfig::verify_fail },
+ { "-verify-peer", &TestConfig::verify_peer },
+ { "-expect-verify-result", &TestConfig::expect_verify_result }
};
const Flag<std::string> kStringFlags[] = {
+ { "-digest-prefs", &TestConfig::digest_prefs },
{ "-key-file", &TestConfig::key_file },
{ "-cert-file", &TestConfig::cert_file },
{ "-expect-server-name", &TestConfig::expected_server_name },
@@ -101,6 +116,8 @@ const Flag<std::string> kStringFlags[] = {
{ "-psk-identity", &TestConfig::psk_identity },
{ "-srtp-profiles", &TestConfig::srtp_profiles },
{ "-cipher", &TestConfig::cipher },
+ { "-cipher-tls10", &TestConfig::cipher_tls10 },
+ { "-cipher-tls11", &TestConfig::cipher_tls11 },
{ "-export-label", &TestConfig::export_label },
{ "-export-context", &TestConfig::export_context },
};
@@ -111,6 +128,8 @@ const Flag<std::string> kBase64Flags[] = {
{ "-expect-ocsp-response", &TestConfig::expected_ocsp_response },
{ "-expect-signed-cert-timestamps",
&TestConfig::expected_signed_cert_timestamps },
+ { "-ocsp-response", &TestConfig::ocsp_response },
+ { "-signed-cert-timestamps", &TestConfig::signed_cert_timestamps },
};
const Flag<int> kIntFlags[] = {
diff --git a/src/ssl/test/test_config.h b/src/ssl/test/test_config.h
index 5d753c8..9dea8e9 100644
--- a/src/ssl/test/test_config.h
+++ b/src/ssl/test/test_config.h
@@ -24,6 +24,7 @@ struct TestConfig {
bool is_dtls = false;
bool resume = false;
bool fallback_scsv = false;
+ std::string digest_prefs;
std::string key_file;
std::string cert_file;
std::string expected_server_name;
@@ -54,13 +55,11 @@ struct TestConfig {
bool expect_extended_master_secret = false;
std::string psk;
std::string psk_identity;
- bool allow_unsafe_legacy_renegotiation = false;
std::string srtp_profiles;
bool enable_ocsp_stapling = false;
std::string expected_ocsp_response;
bool enable_signed_cert_timestamps = false;
std::string expected_signed_cert_timestamps;
- bool fastradio_padding = false;
int min_version = 0;
int max_version = 0;
int mtu = 0;
@@ -71,6 +70,8 @@ struct TestConfig {
bool fail_ddos_callback = false;
bool fail_second_ddos_callback = false;
std::string cipher;
+ std::string cipher_tls10;
+ std::string cipher_tls11;
bool handshake_never_done = false;
int export_keying_material = 0;
std::string export_label;
@@ -79,6 +80,23 @@ struct TestConfig {
bool reject_peer_renegotiations = false;
bool no_legacy_server_connect = false;
bool tls_unique = false;
+ bool use_async_private_key = false;
+ bool expect_ticket_renewal = false;
+ bool expect_no_session = false;
+ bool use_ticket_callback = false;
+ bool renew_ticket = false;
+ bool enable_client_custom_extension = false;
+ bool enable_server_custom_extension = false;
+ bool custom_extension_skip = false;
+ bool custom_extension_fail_add = false;
+ std::string ocsp_response;
+ bool check_close_notify = false;
+ bool shim_shuts_down = false;
+ bool microsoft_big_sslv3_buffer = false;
+ bool verify_fail = false;
+ bool verify_peer = false;
+ bool expect_verify_result = false;
+ std::string signed_cert_timestamps;
};
bool ParseConfig(int argc, char **argv, TestConfig *out_config);
diff --git a/src/ssl/tls_record.c b/src/ssl/tls_record.c
new file mode 100644
index 0000000..36e31b4
--- /dev/null
+++ b/src/ssl/tls_record.c
@@ -0,0 +1,338 @@
+/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+ * All rights reserved.
+ *
+ * This package is an SSL implementation written
+ * by Eric Young (eay@cryptsoft.com).
+ * The implementation was written so as to conform with Netscapes SSL.
+ *
+ * This library is free for commercial and non-commercial use as long as
+ * the following conditions are aheared to. The following conditions
+ * apply to all code found in this distribution, be it the RC4, RSA,
+ * lhash, DES, etc., code; not just the SSL code. The SSL documentation
+ * included with this distribution is covered by the same copyright terms
+ * except that the holder is Tim Hudson (tjh@cryptsoft.com).
+ *
+ * Copyright remains Eric Young's, and as such any Copyright notices in
+ * the code are not to be removed.
+ * If this package is used in a product, Eric Young should be given attribution
+ * as the author of the parts of the library used.
+ * This can be in the form of a textual message at program startup or
+ * in documentation (online or textual) provided with the package.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * "This product includes cryptographic software written by
+ * Eric Young (eay@cryptsoft.com)"
+ * The word 'cryptographic' can be left out if the rouines from the library
+ * being used are not cryptographic related :-).
+ * 4. If you include any Windows specific code (or a derivative thereof) from
+ * the apps directory (application code) you must include an acknowledgement:
+ * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * The licence and distribution terms for any publically available version or
+ * derivative of this code cannot be changed. i.e. this code cannot simply be
+ * copied and put under another distribution licence
+ * [including the GNU Public Licence.]
+ */
+/* ====================================================================
+ * Copyright (c) 1998-2002 The OpenSSL Project. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. All advertising materials mentioning features or use of this
+ * software must display the following acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
+ *
+ * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
+ * endorse or promote products derived from this software without
+ * prior written permission. For written permission, please contact
+ * openssl-core@openssl.org.
+ *
+ * 5. Products derived from this software may not be called "OpenSSL"
+ * nor may "OpenSSL" appear in their names without prior written
+ * permission of the OpenSSL Project.
+ *
+ * 6. Redistributions of any form whatsoever must retain the following
+ * acknowledgment:
+ * "This product includes software developed by the OpenSSL Project
+ * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
+ * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This product includes cryptographic software written by Eric Young
+ * (eay@cryptsoft.com). This product includes software written by Tim
+ * Hudson (tjh@cryptsoft.com). */
+
+#include <openssl/ssl.h>
+
+#include <assert.h>
+
+#include <openssl/bytestring.h>
+#include <openssl/err.h>
+
+#include "internal.h"
+
+
+/* kMaxEmptyRecords is the number of consecutive, empty records that will be
+ * processed. Without this limit an attacker could send empty records at a
+ * faster rate than we can process and cause record processing to loop
+ * forever. */
+static const uint8_t kMaxEmptyRecords = 32;
+
+size_t ssl_record_prefix_len(const SSL *ssl) {
+ if (SSL_IS_DTLS(ssl)) {
+ return DTLS1_RT_HEADER_LENGTH +
+ SSL_AEAD_CTX_explicit_nonce_len(ssl->aead_read_ctx);
+ } else {
+ return SSL3_RT_HEADER_LENGTH +
+ SSL_AEAD_CTX_explicit_nonce_len(ssl->aead_read_ctx);
+ }
+}
+
+size_t ssl_seal_prefix_len(const SSL *ssl) {
+ if (SSL_IS_DTLS(ssl)) {
+ return DTLS1_RT_HEADER_LENGTH +
+ SSL_AEAD_CTX_explicit_nonce_len(ssl->aead_write_ctx);
+ } else {
+ size_t ret = SSL3_RT_HEADER_LENGTH +
+ SSL_AEAD_CTX_explicit_nonce_len(ssl->aead_write_ctx);
+ if (ssl->s3->need_record_splitting) {
+ ret += SSL3_RT_HEADER_LENGTH;
+ ret += ssl_cipher_get_record_split_len(ssl->aead_write_ctx->cipher);
+ }
+ return ret;
+ }
+}
+
+size_t ssl_max_seal_overhead(const SSL *ssl) {
+ if (SSL_IS_DTLS(ssl)) {
+ return DTLS1_RT_HEADER_LENGTH +
+ SSL_AEAD_CTX_max_overhead(ssl->aead_write_ctx);
+ } else {
+ size_t ret = SSL3_RT_HEADER_LENGTH +
+ SSL_AEAD_CTX_max_overhead(ssl->aead_write_ctx);
+ if (ssl->s3->need_record_splitting) {
+ ret *= 2;
+ }
+ return ret;
+ }
+}
+
+enum ssl_open_record_t tls_open_record(
+ SSL *ssl, uint8_t *out_type, uint8_t *out, size_t *out_len,
+ size_t *out_consumed, uint8_t *out_alert, size_t max_out, const uint8_t *in,
+ size_t in_len) {
+ CBS cbs;
+ CBS_init(&cbs, in, in_len);
+
+ /* Decode the record header. */
+ uint8_t type;
+ uint16_t version, ciphertext_len;
+ if (!CBS_get_u8(&cbs, &type) ||
+ !CBS_get_u16(&cbs, &version) ||
+ !CBS_get_u16(&cbs, &ciphertext_len)) {
+ *out_consumed = SSL3_RT_HEADER_LENGTH;
+ return ssl_open_record_partial;
+ }
+
+ /* Check the version. */
+ if ((ssl->s3->have_version && version != ssl->version) ||
+ (version >> 8) != SSL3_VERSION_MAJOR) {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_WRONG_VERSION_NUMBER);
+ *out_alert = SSL_AD_PROTOCOL_VERSION;
+ return ssl_open_record_error;
+ }
+
+ /* Check the ciphertext length. */
+ size_t extra = 0;
+ if (ssl->options & SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER) {
+ extra = SSL3_RT_MAX_EXTRA;
+ }
+ if (ciphertext_len > SSL3_RT_MAX_ENCRYPTED_LENGTH + extra) {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_ENCRYPTED_LENGTH_TOO_LONG);
+ *out_alert = SSL_AD_RECORD_OVERFLOW;
+ return ssl_open_record_error;
+ }
+
+ /* Extract the body. */
+ CBS body;
+ if (!CBS_get_bytes(&cbs, &body, ciphertext_len)) {
+ *out_consumed = SSL3_RT_HEADER_LENGTH + (size_t)ciphertext_len;
+ return ssl_open_record_partial;
+ }
+
+ if (ssl->msg_callback != NULL) {
+ ssl->msg_callback(0 /* read */, 0, SSL3_RT_HEADER, in,
+ SSL3_RT_HEADER_LENGTH, ssl, ssl->msg_callback_arg);
+ }
+
+ /* Decrypt the body. */
+ size_t plaintext_len;
+ if (!SSL_AEAD_CTX_open(ssl->aead_read_ctx, out, &plaintext_len, max_out,
+ type, version, ssl->s3->read_sequence, CBS_data(&body),
+ CBS_len(&body))) {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_DECRYPTION_FAILED_OR_BAD_RECORD_MAC);
+ *out_alert = SSL_AD_BAD_RECORD_MAC;
+ return ssl_open_record_error;
+ }
+ if (!ssl3_record_sequence_update(ssl->s3->read_sequence, 8)) {
+ *out_alert = SSL_AD_INTERNAL_ERROR;
+ return ssl_open_record_error;
+ }
+
+ /* Check the plaintext length. */
+ if (plaintext_len > SSL3_RT_MAX_PLAIN_LENGTH + extra) {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_DATA_LENGTH_TOO_LONG);
+ *out_alert = SSL_AD_RECORD_OVERFLOW;
+ return ssl_open_record_error;
+ }
+
+ /* Limit the number of consecutive empty records. */
+ if (plaintext_len == 0) {
+ ssl->s3->empty_record_count++;
+ if (ssl->s3->empty_record_count > kMaxEmptyRecords) {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_TOO_MANY_EMPTY_FRAGMENTS);
+ *out_alert = SSL_AD_UNEXPECTED_MESSAGE;
+ return ssl_open_record_error;
+ }
+ /* Apart from the limit, empty records are returned up to the caller. This
+ * allows the caller to reject records of the wrong type. */
+ } else {
+ ssl->s3->empty_record_count = 0;
+ }
+
+ *out_type = type;
+ *out_len = plaintext_len;
+ *out_consumed = in_len - CBS_len(&cbs);
+ return ssl_open_record_success;
+}
+
+static int do_seal_record(SSL *ssl, uint8_t *out, size_t *out_len,
+ size_t max_out, uint8_t type, const uint8_t *in,
+ size_t in_len) {
+ if (max_out < SSL3_RT_HEADER_LENGTH) {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_BUFFER_TOO_SMALL);
+ return 0;
+ }
+ /* Check the record header does not alias any part of the input.
+ * |SSL_AEAD_CTX_seal| will internally enforce other aliasing requirements. */
+ if (in < out + SSL3_RT_HEADER_LENGTH && out < in + in_len) {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_OUTPUT_ALIASES_INPUT);
+ return 0;
+ }
+
+ out[0] = type;
+
+ /* Some servers hang if initial ClientHello is larger than 256 bytes and
+ * record version number > TLS 1.0. */
+ uint16_t wire_version = ssl->version;
+ if (!ssl->s3->have_version && ssl->version > SSL3_VERSION) {
+ wire_version = TLS1_VERSION;
+ }
+ out[1] = wire_version >> 8;
+ out[2] = wire_version & 0xff;
+
+ size_t ciphertext_len;
+ if (!SSL_AEAD_CTX_seal(ssl->aead_write_ctx, out + SSL3_RT_HEADER_LENGTH,
+ &ciphertext_len, max_out - SSL3_RT_HEADER_LENGTH,
+ type, wire_version, ssl->s3->write_sequence, in,
+ in_len) ||
+ !ssl3_record_sequence_update(ssl->s3->write_sequence, 8)) {
+ return 0;
+ }
+
+ if (ciphertext_len >= 1 << 16) {
+ OPENSSL_PUT_ERROR(SSL, ERR_R_OVERFLOW);
+ return 0;
+ }
+ out[3] = ciphertext_len >> 8;
+ out[4] = ciphertext_len & 0xff;
+
+ *out_len = SSL3_RT_HEADER_LENGTH + ciphertext_len;
+
+ if (ssl->msg_callback) {
+ ssl->msg_callback(1 /* write */, 0, SSL3_RT_HEADER, out,
+ SSL3_RT_HEADER_LENGTH, ssl, ssl->msg_callback_arg);
+ }
+
+ return 1;
+}
+
+int tls_seal_record(SSL *ssl, uint8_t *out, size_t *out_len, size_t max_out,
+ uint8_t type, const uint8_t *in, size_t in_len) {
+ size_t frag_len = 0;
+ if (ssl->s3->need_record_splitting && type == SSL3_RT_APPLICATION_DATA &&
+ in_len > 1) {
+ /* |do_seal_record| will notice if it clobbers |in[0]|, but not if it
+ * aliases the rest of |in|. */
+ if (in + 1 <= out && out < in + in_len) {
+ OPENSSL_PUT_ERROR(SSL, SSL_R_OUTPUT_ALIASES_INPUT);
+ return 0;
+ }
+ /* Ensure |do_seal_record| does not write beyond |in[0]|. */
+ size_t frag_max_out = max_out;
+ if (out <= in + 1 && in + 1 < out + frag_max_out) {
+ frag_max_out = (size_t)(in + 1 - out);
+ }
+ if (!do_seal_record(ssl, out, &frag_len, frag_max_out, type, in, 1)) {
+ return 0;
+ }
+ in++;
+ in_len--;
+ out += frag_len;
+ max_out -= frag_len;
+
+ assert(SSL3_RT_HEADER_LENGTH +
+ ssl_cipher_get_record_split_len(ssl->aead_write_ctx->cipher) ==
+ frag_len);
+ }
+
+ if (!do_seal_record(ssl, out, out_len, max_out, type, in, in_len)) {
+ return 0;
+ }
+ *out_len += frag_len;
+ return 1;
+}
diff --git a/src/tool/CMakeLists.txt b/src/tool/CMakeLists.txt
index 74c1ac8..2d706ba 100644
--- a/src/tool/CMakeLists.txt
+++ b/src/tool/CMakeLists.txt
@@ -7,6 +7,7 @@ add_executable(
client.cc
const.cc
digest.cc
+ genrsa.cc
pkcs12.cc
rand.cc
server.cc
@@ -18,5 +19,10 @@ add_executable(
if (APPLE OR WIN32 OR ANDROID)
target_link_libraries(bssl ssl crypto)
else()
- target_link_libraries(bssl ssl crypto -lrt)
+ find_library(FOUND_LIBRT rt)
+ if (FOUND_LIBRT)
+ target_link_libraries(bssl ssl crypto -lrt)
+ else()
+ target_link_libraries(bssl ssl crypto)
+ endif()
endif()
diff --git a/src/tool/args.cc b/src/tool/args.cc
index a164476..9ec18a3 100644
--- a/src/tool/args.cc
+++ b/src/tool/args.cc
@@ -15,7 +15,9 @@
#include <string>
#include <vector>
+#include <limits.h>
#include <stdio.h>
+#include <stdlib.h>
#include <string.h>
#include "internal.h"
@@ -75,3 +77,28 @@ void PrintUsage(const struct argument *templates) {
fprintf(stderr, "%s\t%s\n", templ->name, templ->description);
}
}
+
+bool GetUnsigned(unsigned *out, const std::string &arg_name,
+ unsigned default_value,
+ const std::map<std::string, std::string> &args) {
+ const auto &it = args.find(arg_name);
+ if (it == args.end()) {
+ *out = default_value;
+ return true;
+ }
+
+ const std::string &value = it->second;
+ if (value.empty()) {
+ return false;
+ }
+
+ char *endptr;
+ unsigned long int num = strtoul(value.c_str(), &endptr, 10);
+ if (*endptr ||
+ num > UINT_MAX) {
+ return false;
+ }
+
+ *out = num;
+ return true;
+}
diff --git a/src/tool/client.cc b/src/tool/client.cc
index 1de0df2..cd8353b 100644
--- a/src/tool/client.cc
+++ b/src/tool/client.cc
@@ -70,6 +70,16 @@ static const struct argument kArguments[] = {
"The key to use for signing a channel ID",
},
{
+ "-false-start", kBooleanArgument,
+ "Enable False Start",
+ },
+ { "-session-in", kOptionalArgument,
+ "A file containing a session to resume.",
+ },
+ { "-session-out", kOptionalArgument,
+ "A file to write the negotiated session to.",
+ },
+ {
"", kOptionalArgument, "",
},
};
@@ -211,7 +221,10 @@ bool Client(const std::vector<std::string> &args) {
if (!pkey || !SSL_CTX_set1_tls_channel_id(ctx.get(), pkey.get())) {
return false;
}
- ctx->tlsext_channel_id_enabled_new = 1;
+ }
+
+ if (args_map.count("-false-start") != 0) {
+ SSL_CTX_set_mode(ctx.get(), SSL_MODE_ENABLE_FALSE_START);
}
int sock = -1;
@@ -226,6 +239,23 @@ bool Client(const std::vector<std::string> &args) {
SSL_set_tlsext_host_name(ssl.get(), args_map["-server-name"].c_str());
}
+ if (args_map.count("-session-in") != 0) {
+ ScopedBIO in(BIO_new_file(args_map["-session-in"].c_str(), "rb"));
+ if (!in) {
+ fprintf(stderr, "Error reading session\n");
+ ERR_print_errors_cb(PrintErrorCallback, stderr);
+ return false;
+ }
+ ScopedSSL_SESSION session(PEM_read_bio_SSL_SESSION(in.get(), nullptr,
+ nullptr, nullptr));
+ if (!session) {
+ fprintf(stderr, "Error reading session\n");
+ ERR_print_errors_cb(PrintErrorCallback, stderr);
+ return false;
+ }
+ SSL_set_session(ssl.get(), session.get());
+ }
+
SSL_set_bio(ssl.get(), bio.get(), bio.get());
bio.release();
@@ -240,6 +270,16 @@ bool Client(const std::vector<std::string> &args) {
fprintf(stderr, "Connected.\n");
PrintConnectionInfo(ssl.get());
+ if (args_map.count("-session-out") != 0) {
+ ScopedBIO out(BIO_new_file(args_map["-session-out"].c_str(), "wb"));
+ if (!out ||
+ !PEM_write_bio_SSL_SESSION(out.get(), SSL_get0_session(ssl.get()))) {
+ fprintf(stderr, "Error while saving session:\n");
+ ERR_print_errors_cb(PrintErrorCallback, stderr);
+ return false;
+ }
+ }
+
bool ok = TransferData(ssl.get(), sock);
return ok;
diff --git a/src/tool/const.cc b/src/tool/const.cc
index 5222667..7b7001e 100644
--- a/src/tool/const.cc
+++ b/src/tool/const.cc
@@ -15,9 +15,10 @@
#include <stddef.h>
#include <stdint.h>
-extern "C" {
+#include "internal.h"
-uint8_t kDERRSAPrivate2048[] = {
+
+const uint8_t kDERRSAPrivate2048[] = {
0x30, 0x82, 0x04, 0xa3, 0x02, 0x01, 0x00, 0x02, 0x82, 0x01, 0x01, 0x00,
0xd0, 0x02, 0xde, 0x5d, 0x19, 0x33, 0x48, 0x15, 0xc7, 0x86, 0xde, 0xa3,
0xec, 0x63, 0x89, 0x14, 0x63, 0x99, 0x30, 0x1f, 0x5d, 0x25, 0xb2, 0xfa,
@@ -120,9 +121,9 @@ uint8_t kDERRSAPrivate2048[] = {
0x77, 0xe6, 0xd3,
};
-size_t kDERRSAPrivate2048Len = sizeof(kDERRSAPrivate2048);
+const size_t kDERRSAPrivate2048Len = sizeof(kDERRSAPrivate2048);
-uint8_t kDERRSAPrivate4096[] = {
+const uint8_t kDERRSAPrivate4096[] = {
0x30, 0x82, 0x09, 0x28, 0x02, 0x01, 0x00, 0x02, 0x82, 0x02, 0x01, 0x00,
0xc3, 0x82, 0x01, 0xda, 0x03, 0xe1, 0x0d, 0x78, 0xf4, 0x86, 0xf1, 0x28,
0xf0, 0x4c, 0x34, 0xa6, 0x73, 0x0c, 0xfb, 0x22, 0xfa, 0x35, 0xc9, 0x3a,
@@ -321,6 +322,113 @@ uint8_t kDERRSAPrivate4096[] = {
0x59, 0x8e, 0xd7, 0x45, 0x87, 0x86, 0x05, 0x9d,
};
-size_t kDERRSAPrivate4096Len = sizeof(kDERRSAPrivate4096);
+const size_t kDERRSAPrivate4096Len = sizeof(kDERRSAPrivate4096);
+
+const uint8_t kDERRSAPrivate3Prime2048[] = {
+ 0x30, 0x82, 0x04, 0xd7, 0x02, 0x01, 0x01, 0x02, 0x82, 0x01, 0x00, 0x62,
+ 0x91, 0xe9, 0xea, 0xb3, 0x5d, 0x6c, 0x29, 0xae, 0x21, 0x83, 0xbb, 0xb5,
+ 0x82, 0xb1, 0x9e, 0xea, 0xe0, 0x64, 0x5b, 0x1e, 0x2f, 0x5e, 0x2c, 0x0a,
+ 0x80, 0x3d, 0x29, 0xd4, 0xfa, 0x9a, 0xe7, 0x44, 0xe6, 0x21, 0xbd, 0x98,
+ 0xc0, 0x3d, 0xe0, 0x53, 0x59, 0xae, 0xd3, 0x3e, 0xfe, 0xc4, 0xc2, 0xc4,
+ 0x5a, 0x5a, 0x89, 0x07, 0xf4, 0x4f, 0xdc, 0xb0, 0x6a, 0xd4, 0x3e, 0x99,
+ 0x7d, 0x7a, 0x97, 0x26, 0x4e, 0xe1, 0x93, 0xca, 0x6e, 0xed, 0x07, 0xfc,
+ 0xb4, 0xfa, 0x95, 0x1e, 0x73, 0x7b, 0x86, 0x08, 0x6a, 0xb9, 0xd4, 0x29,
+ 0xb0, 0x7e, 0x59, 0xb7, 0x9d, 0x7b, 0xeb, 0x67, 0x6e, 0xf0, 0xbb, 0x5e,
+ 0xcf, 0xb9, 0xcd, 0x58, 0x93, 0xf0, 0xe7, 0x88, 0x17, 0x6c, 0x0d, 0x76,
+ 0x1e, 0xb9, 0x27, 0x9a, 0x4d, 0x02, 0x16, 0xb6, 0x49, 0x6d, 0xa7, 0x83,
+ 0x23, 0x4d, 0x02, 0x48, 0x0c, 0x0c, 0x1f, 0x0e, 0x85, 0x21, 0xe3, 0x06,
+ 0x76, 0x0a, 0x73, 0xe6, 0xc1, 0x21, 0xfa, 0x30, 0x18, 0x78, 0x29, 0x5c,
+ 0x31, 0xd0, 0x29, 0xae, 0x6f, 0x7d, 0x87, 0xd8, 0x2f, 0x16, 0xfa, 0xbc,
+ 0x67, 0x8a, 0x94, 0x71, 0x59, 0x9b, 0xec, 0x22, 0x40, 0x55, 0x9f, 0xc2,
+ 0x94, 0xb5, 0xbd, 0x78, 0x01, 0xc9, 0xef, 0x18, 0xc8, 0x6d, 0x0d, 0xdc,
+ 0x53, 0x42, 0xb2, 0x5c, 0xab, 0x65, 0x05, 0xbd, 0x35, 0x08, 0x85, 0x1b,
+ 0xf8, 0xe9, 0x47, 0xbc, 0xfe, 0xc5, 0xae, 0x47, 0x29, 0x63, 0x44, 0x8e,
+ 0x4d, 0xb7, 0x47, 0xab, 0x0d, 0xd8, 0x76, 0x68, 0x4f, 0xc7, 0x07, 0x02,
+ 0xe4, 0x86, 0xb0, 0xcf, 0xd8, 0x19, 0xad, 0xf4, 0x85, 0x76, 0x8b, 0x3b,
+ 0x4e, 0x40, 0x8d, 0x29, 0x7a, 0x8a, 0x07, 0x36, 0xf3, 0x78, 0xae, 0x17,
+ 0xa6, 0x8f, 0x53, 0x58, 0x65, 0x4c, 0x86, 0x9e, 0xd7, 0x8b, 0xec, 0x38,
+ 0x4f, 0x99, 0xc7, 0x02, 0x01, 0x03, 0x02, 0x82, 0x01, 0x00, 0x41, 0xb6,
+ 0x9b, 0xf1, 0xcc, 0xe8, 0xf2, 0xc6, 0x74, 0x16, 0x57, 0xd2, 0x79, 0x01,
+ 0xcb, 0xbf, 0x47, 0x40, 0x42, 0xe7, 0x69, 0x74, 0xe9, 0x72, 0xb1, 0xaa,
+ 0xd3, 0x71, 0x38, 0xa7, 0x11, 0xef, 0x83, 0x44, 0x16, 0x7e, 0x65, 0xd5,
+ 0x7e, 0x95, 0x8c, 0xe6, 0x74, 0x8c, 0xd4, 0xa9, 0xd8, 0x81, 0xd8, 0x3c,
+ 0x3c, 0x5b, 0x5a, 0xa2, 0xdf, 0xe8, 0x75, 0x9c, 0x8d, 0x7f, 0x10, 0xfe,
+ 0x51, 0xba, 0x19, 0x89, 0xeb, 0xb7, 0xdc, 0x49, 0xf3, 0x5a, 0xa8, 0x78,
+ 0xa7, 0x0e, 0x14, 0x4c, 0xfd, 0x04, 0x05, 0x9c, 0x7b, 0xe2, 0xc5, 0xa3,
+ 0x04, 0xee, 0xd9, 0x4c, 0xfd, 0x7d, 0x47, 0xb0, 0x0d, 0x9b, 0x3d, 0x70,
+ 0x91, 0x81, 0x2c, 0xab, 0x2b, 0x87, 0xad, 0x11, 0x68, 0x24, 0xfc, 0x2b,
+ 0xd4, 0xee, 0x5e, 0x28, 0xeb, 0x6d, 0xab, 0xde, 0x0f, 0x77, 0x15, 0x58,
+ 0x76, 0x39, 0xc9, 0x59, 0x3a, 0x7f, 0x19, 0x9d, 0xc6, 0x7e, 0x86, 0xe4,
+ 0xd5, 0x38, 0x70, 0x9e, 0xae, 0xb9, 0xfb, 0x33, 0x33, 0xd1, 0x0c, 0x2d,
+ 0xab, 0x01, 0x20, 0xe1, 0x8b, 0x29, 0x99, 0xd3, 0xeb, 0x87, 0x05, 0x72,
+ 0xaa, 0x43, 0x58, 0x64, 0x8e, 0x9e, 0x31, 0xdb, 0x45, 0x9b, 0x2b, 0xac,
+ 0x58, 0x80, 0x5d, 0x33, 0xa2, 0x43, 0x05, 0x96, 0xcc, 0xca, 0x2d, 0x04,
+ 0x5f, 0xd6, 0xb7, 0x3d, 0x8b, 0x8f, 0x2d, 0xa3, 0xa5, 0xf8, 0x73, 0xf5,
+ 0xd7, 0xc0, 0x19, 0xff, 0x10, 0xe6, 0xee, 0x3a, 0x26, 0x2f, 0xe1, 0x64,
+ 0x3d, 0x11, 0xcd, 0x2d, 0xe4, 0x0a, 0x84, 0x27, 0xe3, 0xcb, 0x16, 0x62,
+ 0x19, 0xe7, 0xe3, 0x0d, 0x13, 0xe8, 0x09, 0x5a, 0x53, 0xd0, 0x20, 0x56,
+ 0x15, 0xf5, 0xb3, 0x67, 0xac, 0xa1, 0xb5, 0x94, 0x6b, 0xab, 0xdc, 0x71,
+ 0xc7, 0xbf, 0x0a, 0xde, 0x76, 0xf5, 0x03, 0xa0, 0x30, 0xd8, 0x27, 0x9d,
+ 0x00, 0x2b, 0x02, 0x57, 0x00, 0xf1, 0x4f, 0xc2, 0x86, 0x13, 0x06, 0x17,
+ 0xf7, 0x69, 0x7e, 0x37, 0xdf, 0x67, 0xc5, 0x32, 0xa0, 0x74, 0x1c, 0x32,
+ 0x69, 0x0f, 0x9f, 0x08, 0x88, 0x24, 0xb1, 0x51, 0xbc, 0xbc, 0x92, 0xba,
+ 0x73, 0x1f, 0x9c, 0x75, 0xc2, 0x14, 0x6d, 0x4f, 0xc4, 0x5a, 0xcf, 0xda,
+ 0x44, 0x35, 0x00, 0x6b, 0x42, 0x3b, 0x9f, 0x14, 0xf1, 0x05, 0xb3, 0x51,
+ 0x22, 0xb6, 0xbe, 0x9c, 0xe0, 0xc1, 0x5c, 0x48, 0x61, 0xdf, 0x4e, 0x4c,
+ 0x72, 0xb8, 0x05, 0x35, 0x7c, 0xac, 0xf1, 0xbb, 0xa0, 0x3b, 0x2a, 0xea,
+ 0xf7, 0x86, 0xe9, 0xd2, 0xff, 0x1e, 0x1d, 0x02, 0x56, 0x00, 0xca, 0xb1,
+ 0x39, 0xf6, 0xa2, 0xc6, 0x3b, 0x65, 0x45, 0x2f, 0x39, 0x00, 0xcd, 0x6e,
+ 0xd6, 0x55, 0xf7, 0x71, 0x37, 0x89, 0xc2, 0xe7, 0x7a, 0xc0, 0x1a, 0xa6,
+ 0x2f, 0xea, 0x17, 0x7c, 0xaa, 0x2a, 0x91, 0x8f, 0xd4, 0xc7, 0x50, 0x8b,
+ 0xab, 0x8e, 0x99, 0x3b, 0x33, 0x91, 0xbc, 0x02, 0x10, 0x58, 0x4b, 0x58,
+ 0x40, 0x9b, 0xc4, 0x8f, 0x48, 0x2b, 0xa7, 0x44, 0xfd, 0x07, 0x04, 0xf0,
+ 0x98, 0x67, 0x56, 0xea, 0x25, 0x92, 0x8b, 0x2e, 0x4b, 0x4a, 0xa1, 0xd3,
+ 0xc2, 0xa4, 0xb4, 0x9b, 0x59, 0x70, 0x32, 0xa6, 0xd8, 0x8b, 0xd9, 0x02,
+ 0x57, 0x00, 0xa0, 0xdf, 0xd7, 0x04, 0x0c, 0xae, 0xba, 0xa4, 0xf0, 0xfe,
+ 0xcf, 0xea, 0x45, 0x2e, 0x21, 0xc0, 0x4d, 0x68, 0x21, 0x9b, 0x5f, 0xbf,
+ 0x5b, 0x05, 0x6d, 0xcb, 0x8b, 0xd3, 0x28, 0x61, 0xd1, 0xa2, 0x15, 0x12,
+ 0xf9, 0x2c, 0x0d, 0x9e, 0x35, 0x2d, 0x91, 0xdf, 0xe6, 0xd8, 0x23, 0x55,
+ 0x9c, 0xd6, 0xd2, 0x6a, 0x0d, 0xf6, 0x03, 0xcc, 0xe0, 0xc1, 0xcf, 0x29,
+ 0xbd, 0xeb, 0x2b, 0x92, 0xda, 0xeb, 0xea, 0x34, 0x32, 0xf7, 0x25, 0x58,
+ 0xce, 0x53, 0x1d, 0xf6, 0x7d, 0x15, 0x7c, 0xc7, 0x47, 0x4f, 0xaf, 0x46,
+ 0x8c, 0xaa, 0x14, 0x13, 0x02, 0x56, 0x00, 0x87, 0x20, 0xd1, 0x4f, 0x17,
+ 0x2e, 0xd2, 0x43, 0x83, 0x74, 0xd0, 0xab, 0x33, 0x9f, 0x39, 0x8e, 0xa4,
+ 0xf6, 0x25, 0x06, 0x81, 0xef, 0xa7, 0x2a, 0xbc, 0x6e, 0xca, 0x9c, 0x0f,
+ 0xa8, 0x71, 0x71, 0xb6, 0x5f, 0xe3, 0x2f, 0x8b, 0x07, 0xc7, 0xb4, 0x66,
+ 0x27, 0x77, 0xb6, 0x7d, 0x56, 0xb5, 0x90, 0x32, 0x3a, 0xd5, 0xbd, 0x2d,
+ 0xb4, 0xda, 0xc7, 0xc4, 0xd8, 0xa8, 0xaf, 0x58, 0xa0, 0x65, 0x9a, 0x39,
+ 0xf1, 0x6e, 0x61, 0xb2, 0x1e, 0xdc, 0xdc, 0x6b, 0xe2, 0x81, 0xc3, 0x23,
+ 0x12, 0x3b, 0xa0, 0x21, 0xc4, 0x90, 0x5d, 0x3b, 0x02, 0x57, 0x00, 0xe6,
+ 0x8a, 0xaa, 0xb8, 0x6d, 0x2c, 0x81, 0x43, 0xb5, 0xd6, 0xa0, 0x2b, 0x42,
+ 0x49, 0xa9, 0x0a, 0x51, 0xfa, 0x18, 0xc8, 0x32, 0xea, 0x54, 0x18, 0xf3,
+ 0x60, 0xc2, 0xb5, 0x4a, 0x43, 0x05, 0x93, 0x9c, 0x01, 0xd9, 0x28, 0xed,
+ 0x73, 0xfa, 0x82, 0xbc, 0x12, 0x64, 0xcb, 0xc4, 0x24, 0xa9, 0x3e, 0xae,
+ 0x7c, 0x4b, 0x8f, 0x94, 0x57, 0x7b, 0x14, 0x10, 0x41, 0xdc, 0x62, 0x12,
+ 0x8c, 0xb2, 0x4a, 0x7c, 0xf6, 0x53, 0xd4, 0xc6, 0xe4, 0xda, 0xd1, 0xa2,
+ 0x00, 0x0e, 0x3d, 0x30, 0xf7, 0x05, 0x4f, 0x1d, 0x82, 0xbc, 0x52, 0xd9,
+ 0xb1, 0x30, 0x82, 0x01, 0x0a, 0x30, 0x82, 0x01, 0x06, 0x02, 0x56, 0x00,
+ 0x84, 0x12, 0x4f, 0xf7, 0x3b, 0x65, 0x53, 0x34, 0x6c, 0x6c, 0x4d, 0x77,
+ 0xdf, 0xfd, 0x1f, 0xb6, 0x16, 0xe2, 0x25, 0x15, 0xca, 0xc9, 0xc1, 0x41,
+ 0x9a, 0x50, 0xda, 0xeb, 0x88, 0x4f, 0x3d, 0xb3, 0x01, 0x00, 0x44, 0xc4,
+ 0xac, 0xe7, 0x14, 0x62, 0xa6, 0x56, 0xde, 0xc5, 0xb7, 0xc3, 0x1d, 0x07,
+ 0xbd, 0x7d, 0x64, 0xc5, 0x7e, 0x45, 0x25, 0x56, 0xed, 0x7a, 0xd2, 0x14,
+ 0xdb, 0x4e, 0x27, 0xd4, 0x1f, 0xf8, 0x94, 0xa7, 0xef, 0x07, 0xce, 0xdb,
+ 0x24, 0xb7, 0xdd, 0x71, 0x5c, 0x63, 0xc9, 0x33, 0xfe, 0xde, 0x40, 0x52,
+ 0xeb, 0x02, 0x55, 0x58, 0x0c, 0x35, 0x4f, 0x7c, 0xee, 0x37, 0x78, 0x48,
+ 0x48, 0x33, 0xa5, 0x3f, 0xfe, 0x15, 0x24, 0x0f, 0x41, 0x6e, 0x0e, 0x87,
+ 0x31, 0x2b, 0x81, 0x11, 0x8b, 0x3c, 0x9d, 0x05, 0x8a, 0x29, 0x22, 0x00,
+ 0xaa, 0xd8, 0x83, 0x1d, 0xef, 0x62, 0xec, 0x6e, 0xe4, 0x94, 0x83, 0xcf,
+ 0xd7, 0x68, 0xaf, 0xd3, 0xa8, 0xed, 0xd8, 0xfe, 0xd8, 0xc3, 0x8f, 0x48,
+ 0xfc, 0x8c, 0x0d, 0xe7, 0x89, 0x6f, 0xe2, 0xbf, 0xfb, 0x0d, 0xc5, 0x4a,
+ 0x05, 0x34, 0x92, 0x18, 0x7a, 0x93, 0xa0, 0xe8, 0x42, 0x86, 0x22, 0xa9,
+ 0xe9, 0x80, 0x37, 0x47, 0x02, 0x55, 0x60, 0x76, 0xab, 0xde, 0x2b, 0xf5,
+ 0xa2, 0x2c, 0xaa, 0x0c, 0x99, 0x81, 0xee, 0x72, 0x2c, 0x7d, 0x22, 0x59,
+ 0x2a, 0x35, 0xea, 0x50, 0x4e, 0x47, 0x6b, 0x92, 0x2d, 0x30, 0xa1, 0x01,
+ 0xa5, 0x9e, 0x26, 0x6e, 0x27, 0xca, 0xf5, 0xf2, 0x87, 0x5d, 0x31, 0xaf,
+ 0xe9, 0x32, 0xcd, 0x10, 0xfd, 0x4d, 0xdb, 0xf9, 0x86, 0x05, 0x12, 0x1b,
+ 0x01, 0x84, 0x55, 0x97, 0x5f, 0xe2, 0x78, 0x27, 0xd9, 0xe4, 0x26, 0x7d,
+ 0xab, 0x0e, 0xe0, 0x1b, 0x6f, 0xcb, 0x4b, 0x14, 0xdd, 0xdc, 0xdc, 0x8b,
+ 0xe8, 0x9f, 0xd0, 0x62, 0x96, 0xca, 0xcf,
+};
-}
+const size_t kDERRSAPrivate3Prime2048Len = sizeof(kDERRSAPrivate3Prime2048);
diff --git a/src/tool/genrsa.cc b/src/tool/genrsa.cc
new file mode 100644
index 0000000..4b39401
--- /dev/null
+++ b/src/tool/genrsa.cc
@@ -0,0 +1,69 @@
+/* Copyright (c) 2015, Google Inc.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
+ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
+
+#include <openssl/bio.h>
+#include <openssl/bn.h>
+#include <openssl/err.h>
+#include <openssl/pem.h>
+#include <openssl/rsa.h>
+
+#include "../crypto/test/scoped_types.h"
+#include "internal.h"
+
+
+static const struct argument kArguments[] = {
+ {
+ "-nprimes", kOptionalArgument,
+ "The number of primes to generate (default: 2)",
+ },
+ {
+ "-bits", kOptionalArgument,
+ "The number of bits in the modulus (default: 2048)",
+ },
+ {
+ "", kOptionalArgument, "",
+ },
+};
+
+bool GenerateRSAKey(const std::vector<std::string> &args) {
+ std::map<std::string, std::string> args_map;
+
+ if (!ParseKeyValueArguments(&args_map, args, kArguments)) {
+ PrintUsage(kArguments);
+ return false;
+ }
+
+ unsigned bits, nprimes = 0;
+ if (!GetUnsigned(&bits, "-bits", 2048, args_map) ||
+ !GetUnsigned(&nprimes, "-nprimes", 2, args_map)) {
+ PrintUsage(kArguments);
+ return false;
+ }
+
+ ScopedRSA rsa(RSA_new());
+ ScopedBIGNUM e(BN_new());
+ ScopedBIO bio(BIO_new_fp(stdout, BIO_NOCLOSE));
+
+ if (!BN_set_word(e.get(), RSA_F4) ||
+ !RSA_generate_multi_prime_key(rsa.get(), bits, nprimes, e.get(), NULL) ||
+ !PEM_write_bio_RSAPrivateKey(bio.get(), rsa.get(), NULL /* cipher */,
+ NULL /* key */, 0 /* key len */,
+ NULL /* password callback */,
+ NULL /* callback arg */)) {
+ ERR_print_errors_fp(stderr);
+ return false;
+ }
+
+ return true;
+}
diff --git a/src/tool/internal.h b/src/tool/internal.h
index 277d099..84f8c4d 100644
--- a/src/tool/internal.h
+++ b/src/tool/internal.h
@@ -15,6 +15,8 @@
#ifndef OPENSSL_HEADER_TOOL_INTERNAL_H
#define OPENSSL_HEADER_TOOL_INTERNAL_H
+#include <openssl/base.h>
+
#include <string>
#include <vector>
@@ -49,5 +51,17 @@ bool ParseKeyValueArguments(std::map<std::string, std::string> *out_args, const
void PrintUsage(const struct argument *templates);
+bool GetUnsigned(unsigned *out, const std::string &arg_name,
+ unsigned default_value,
+ const std::map<std::string, std::string> &args);
+
+// These values are DER encoded, RSA private keys.
+extern const uint8_t kDERRSAPrivate2048[];
+extern const size_t kDERRSAPrivate2048Len;
+extern const uint8_t kDERRSAPrivate4096[];
+extern const size_t kDERRSAPrivate4096Len;
+extern const uint8_t kDERRSAPrivate3Prime2048[];
+extern const size_t kDERRSAPrivate3Prime2048Len;
+
#endif /* !OPENSSL_HEADER_TOOL_INTERNAL_H */
diff --git a/src/tool/server.cc b/src/tool/server.cc
index 164d6a5..abc71cf 100644
--- a/src/tool/server.cc
+++ b/src/tool/server.cc
@@ -35,10 +35,54 @@ static const struct argument kArguments[] = {
"Private-key file to use (default is server.pem)",
},
{
+ "-ocsp-response", kOptionalArgument,
+ "OCSP response file to send",
+ },
+ {
"", kOptionalArgument, "",
},
};
+static bool LoadOCSPResponse(SSL_CTX *ctx, const char *filename) {
+ void *data = NULL;
+ bool ret = false;
+ size_t bytes_read;
+ long length;
+
+ FILE *f = fopen(filename, "rb");
+
+ if (f == NULL ||
+ fseek(f, 0, SEEK_END) != 0) {
+ goto out;
+ }
+
+ length = ftell(f);
+ if (length < 0) {
+ goto out;
+ }
+
+ data = malloc(length);
+ if (data == NULL) {
+ goto out;
+ }
+ rewind(f);
+
+ bytes_read = fread(data, 1, length, f);
+ if (ferror(f) != 0 ||
+ bytes_read != (size_t)length ||
+ !SSL_CTX_set_ocsp_response(ctx, (uint8_t*)data, bytes_read)) {
+ goto out;
+ }
+
+ ret = true;
+out:
+ if (f != NULL) {
+ fclose(f);
+ }
+ free(data);
+ return ret;
+}
+
bool Server(const std::vector<std::string> &args) {
if (!InitSocketLibrary()) {
return false;
@@ -74,6 +118,12 @@ bool Server(const std::vector<std::string> &args) {
return false;
}
+ if (args_map.count("-ocsp-response") != 0 &&
+ !LoadOCSPResponse(ctx, args_map["-ocsp-response"].c_str())) {
+ fprintf(stderr, "Failed to load OCSP response: %s\n", args_map["-ocsp-response"].c_str());
+ return false;
+ }
+
int sock = -1;
if (!Accept(&sock, args_map["-accept"])) {
return false;
diff --git a/src/tool/speed.cc b/src/tool/speed.cc
index ab17c2f..307b0b9 100644
--- a/src/tool/speed.cc
+++ b/src/tool/speed.cc
@@ -36,16 +36,9 @@
#endif
#include "../crypto/test/scoped_types.h"
+#include "internal.h"
-extern "C" {
-// These values are DER encoded, RSA private keys.
-extern const uint8_t kDERRSAPrivate2048[];
-extern size_t kDERRSAPrivate2048Len;
-extern const uint8_t kDERRSAPrivate4096[];
-extern size_t kDERRSAPrivate4096Len;
-}
-
// TimeResults represents the results of benchmarking a function.
struct TimeResults {
// num_calls is the number of function calls done in the time period.
@@ -414,9 +407,9 @@ bool Speed(const std::vector<std::string> &args) {
selected = args[0];
}
- RSA *key = NULL;
- const uint8_t *inp = kDERRSAPrivate2048;
- if (NULL == d2i_RSAPrivateKey(&key, &inp, kDERRSAPrivate2048Len)) {
+ RSA *key = RSA_private_key_from_bytes(kDERRSAPrivate2048,
+ kDERRSAPrivate2048Len);
+ if (key == NULL) {
fprintf(stderr, "Failed to parse RSA key.\n");
ERR_print_errors_fp(stderr);
return false;
@@ -427,10 +420,22 @@ bool Speed(const std::vector<std::string> &args) {
}
RSA_free(key);
- key = NULL;
+ key = RSA_private_key_from_bytes(kDERRSAPrivate3Prime2048,
+ kDERRSAPrivate3Prime2048Len);
+ if (key == NULL) {
+ fprintf(stderr, "Failed to parse RSA key.\n");
+ ERR_print_errors_fp(stderr);
+ return false;
+ }
- inp = kDERRSAPrivate4096;
- if (NULL == d2i_RSAPrivateKey(&key, &inp, kDERRSAPrivate4096Len)) {
+ if (!SpeedRSA("RSA 2048 (3 prime, e=3)", key, selected)) {
+ return false;
+ }
+
+ RSA_free(key);
+ key = RSA_private_key_from_bytes(kDERRSAPrivate4096,
+ kDERRSAPrivate4096Len);
+ if (key == NULL) {
fprintf(stderr, "Failed to parse 4096-bit RSA key.\n");
ERR_print_errors_fp(stderr);
return 1;
diff --git a/src/tool/tool.cc b/src/tool/tool.cc
index 4bd7d1a..e4d5201 100644
--- a/src/tool/tool.cc
+++ b/src/tool/tool.cc
@@ -27,16 +27,17 @@
bool Client(const std::vector<std::string> &args);
-bool Server(const std::vector<std::string> &args);
+bool DoPKCS12(const std::vector<std::string> &args);
+bool GenerateRSAKey(const std::vector<std::string> &args);
bool MD5Sum(const std::vector<std::string> &args);
+bool Rand(const std::vector<std::string> &args);
bool SHA1Sum(const std::vector<std::string> &args);
bool SHA224Sum(const std::vector<std::string> &args);
bool SHA256Sum(const std::vector<std::string> &args);
bool SHA384Sum(const std::vector<std::string> &args);
bool SHA512Sum(const std::vector<std::string> &args);
-bool DoPKCS12(const std::vector<std::string> &args);
+bool Server(const std::vector<std::string> &args);
bool Speed(const std::vector<std::string> &args);
-bool Rand(const std::vector<std::string> &args);
typedef bool (*tool_func_t)(const std::vector<std::string> &args);
@@ -46,19 +47,20 @@ struct Tool {
};
static const Tool kTools[] = {
- { "speed", Speed },
- { "pkcs12", DoPKCS12 },
{ "client", Client },
+ { "genrsa", GenerateRSAKey },
+ { "md5sum", MD5Sum },
+ { "pkcs12", DoPKCS12 },
+ { "rand", Rand },
{ "s_client", Client },
- { "server", Server },
{ "s_server", Server },
- { "md5sum", MD5Sum },
+ { "server", Server },
{ "sha1sum", SHA1Sum },
{ "sha224sum", SHA224Sum },
{ "sha256sum", SHA256Sum },
{ "sha384sum", SHA384Sum },
{ "sha512sum", SHA512Sum },
- { "rand", Rand },
+ { "speed", Speed },
{ "", nullptr },
};
diff --git a/src/tool/transport_common.cc b/src/tool/transport_common.cc
index 3f5e631..98f0f95 100644
--- a/src/tool/transport_common.cc
+++ b/src/tool/transport_common.cc
@@ -169,6 +169,8 @@ void PrintConnectionInfo(const SSL *ssl) {
const SSL_CIPHER *cipher = SSL_get_current_cipher(ssl);
fprintf(stderr, " Version: %s\n", SSL_get_version(ssl));
+ fprintf(stderr, " Resumed session: %s\n",
+ SSL_session_reused(ssl) ? "yes" : "no");
fprintf(stderr, " Cipher: %s\n", SSL_CIPHER_get_name(cipher));
fprintf(stderr, " Secure renegotiation: %s\n",
SSL_get_secure_renegotiation_support(ssl) ? "yes" : "no");
diff --git a/src/util/all_tests.go b/src/util/all_tests.go
index 49954df..566c3f7 100644
--- a/src/util/all_tests.go
+++ b/src/util/all_tests.go
@@ -41,63 +41,6 @@ var (
type test []string
-var tests = []test{
- {"crypto/base64/base64_test"},
- {"crypto/bio/bio_test"},
- {"crypto/bn/bn_test"},
- {"crypto/bytestring/bytestring_test"},
- {"crypto/cipher/aead_test", "aes-128-gcm", "crypto/cipher/test/aes_128_gcm_tests.txt"},
- {"crypto/cipher/aead_test", "aes-128-key-wrap", "crypto/cipher/test/aes_128_key_wrap_tests.txt"},
- {"crypto/cipher/aead_test", "aes-256-gcm", "crypto/cipher/test/aes_256_gcm_tests.txt"},
- {"crypto/cipher/aead_test", "aes-256-key-wrap", "crypto/cipher/test/aes_256_key_wrap_tests.txt"},
- {"crypto/cipher/aead_test", "chacha20-poly1305", "crypto/cipher/test/chacha20_poly1305_tests.txt"},
- {"crypto/cipher/aead_test", "rc4-md5-tls", "crypto/cipher/test/rc4_md5_tls_tests.txt"},
- {"crypto/cipher/aead_test", "rc4-sha1-tls", "crypto/cipher/test/rc4_sha1_tls_tests.txt"},
- {"crypto/cipher/aead_test", "aes-128-cbc-sha1-tls", "crypto/cipher/test/aes_128_cbc_sha1_tls_tests.txt"},
- {"crypto/cipher/aead_test", "aes-128-cbc-sha1-tls-implicit-iv", "crypto/cipher/test/aes_128_cbc_sha1_tls_implicit_iv_tests.txt"},
- {"crypto/cipher/aead_test", "aes-128-cbc-sha256-tls", "crypto/cipher/test/aes_128_cbc_sha256_tls_tests.txt"},
- {"crypto/cipher/aead_test", "aes-256-cbc-sha1-tls", "crypto/cipher/test/aes_256_cbc_sha1_tls_tests.txt"},
- {"crypto/cipher/aead_test", "aes-256-cbc-sha1-tls-implicit-iv", "crypto/cipher/test/aes_256_cbc_sha1_tls_implicit_iv_tests.txt"},
- {"crypto/cipher/aead_test", "aes-256-cbc-sha256-tls", "crypto/cipher/test/aes_256_cbc_sha256_tls_tests.txt"},
- {"crypto/cipher/aead_test", "aes-256-cbc-sha384-tls", "crypto/cipher/test/aes_256_cbc_sha384_tls_tests.txt"},
- {"crypto/cipher/aead_test", "des-ede3-cbc-sha1-tls", "crypto/cipher/test/des_ede3_cbc_sha1_tls_tests.txt"},
- {"crypto/cipher/aead_test", "des-ede3-cbc-sha1-tls-implicit-iv", "crypto/cipher/test/des_ede3_cbc_sha1_tls_implicit_iv_tests.txt"},
- {"crypto/cipher/aead_test", "rc4-md5-ssl3", "crypto/cipher/test/rc4_md5_ssl3_tests.txt"},
- {"crypto/cipher/aead_test", "rc4-sha1-ssl3", "crypto/cipher/test/rc4_sha1_ssl3_tests.txt"},
- {"crypto/cipher/aead_test", "aes-128-cbc-sha1-ssl3", "crypto/cipher/test/aes_128_cbc_sha1_ssl3_tests.txt"},
- {"crypto/cipher/aead_test", "aes-256-cbc-sha1-ssl3", "crypto/cipher/test/aes_256_cbc_sha1_ssl3_tests.txt"},
- {"crypto/cipher/aead_test", "des-ede3-cbc-sha1-ssl3", "crypto/cipher/test/des_ede3_cbc_sha1_ssl3_tests.txt"},
- {"crypto/cipher/aead_test", "aes-128-ctr-hmac-sha256", "crypto/cipher/test/aes_128_ctr_hmac_sha256.txt"},
- {"crypto/cipher/aead_test", "aes-256-ctr-hmac-sha256", "crypto/cipher/test/aes_256_ctr_hmac_sha256.txt"},
- {"crypto/cipher/cipher_test", "crypto/cipher/test/cipher_test.txt"},
- {"crypto/cmac/cmac_test"},
- {"crypto/constant_time_test"},
- {"crypto/dh/dh_test"},
- {"crypto/digest/digest_test"},
- {"crypto/dsa/dsa_test"},
- {"crypto/ec/ec_test"},
- {"crypto/ec/example_mul"},
- {"crypto/ecdsa/ecdsa_test"},
- {"crypto/err/err_test"},
- {"crypto/evp/evp_extra_test"},
- {"crypto/evp/evp_test", "crypto/evp/evp_tests.txt"},
- {"crypto/evp/evp_test", "crypto/hmac/hmac_tests.txt"},
- {"crypto/evp/pbkdf_test"},
- {"crypto/hkdf/hkdf_test"},
- {"crypto/hmac/hmac_test", "crypto/hmac/hmac_tests.txt"},
- {"crypto/lhash/lhash_test"},
- {"crypto/modes/gcm_test"},
- {"crypto/pkcs8/pkcs12_test"},
- {"crypto/refcount_test"},
- {"crypto/rsa/rsa_test"},
- {"crypto/thread_test"},
- {"crypto/x509/pkcs7_test"},
- {"crypto/x509v3/tab_test"},
- {"crypto/x509v3/v3name_test"},
- {"ssl/pqueue/pqueue_test"},
- {"ssl/ssl_test"},
-}
-
// testOutput is a representation of Chromium's JSON test result format. See
// https://www.chromium.org/developers/the-json-test-results-format
type testOutput struct {
@@ -254,8 +197,43 @@ func shortTestName(test test) string {
return strings.Join(args, " ")
}
+// setWorkingDirectory walks up directories as needed until the current working
+// directory is the top of a BoringSSL checkout.
+func setWorkingDirectory() {
+ for i := 0; i < 64; i++ {
+ if _, err := os.Stat("BUILDING.md"); err == nil {
+ return
+ }
+ os.Chdir("..")
+ }
+
+ panic("Couldn't find BUILDING.md in a parent directory!")
+}
+
+func parseTestConfig(filename string) ([]test, error) {
+ in, err := os.Open(filename)
+ if err != nil {
+ return nil, err
+ }
+ defer in.Close()
+
+ decoder := json.NewDecoder(in)
+ var result []test
+ if err := decoder.Decode(&result); err != nil {
+ return nil, err
+ }
+ return result, nil
+}
+
func main() {
flag.Parse()
+ setWorkingDirectory()
+
+ tests, err := parseTestConfig("util/all_tests.json")
+ if err != nil {
+ fmt.Printf("Failed to parse input: %s\n", err)
+ os.Exit(1)
+ }
testOutput := newTestOutput()
var failed []test
diff --git a/src/util/all_tests.json b/src/util/all_tests.json
new file mode 100644
index 0000000..a6daa2f
--- /dev/null
+++ b/src/util/all_tests.json
@@ -0,0 +1,58 @@
+[
+ ["crypto/aes/aes_test"],
+ ["crypto/base64/base64_test"],
+ ["crypto/bio/bio_test"],
+ ["crypto/bn/bn_test"],
+ ["crypto/bytestring/bytestring_test"],
+ ["crypto/cipher/aead_test", "aes-128-gcm", "crypto/cipher/test/aes_128_gcm_tests.txt"],
+ ["crypto/cipher/aead_test", "aes-128-key-wrap", "crypto/cipher/test/aes_128_key_wrap_tests.txt"],
+ ["crypto/cipher/aead_test", "aes-256-gcm", "crypto/cipher/test/aes_256_gcm_tests.txt"],
+ ["crypto/cipher/aead_test", "aes-256-key-wrap", "crypto/cipher/test/aes_256_key_wrap_tests.txt"],
+ ["crypto/cipher/aead_test", "chacha20-poly1305", "crypto/cipher/test/chacha20_poly1305_tests.txt"],
+ ["crypto/cipher/aead_test", "rc4-md5-tls", "crypto/cipher/test/rc4_md5_tls_tests.txt"],
+ ["crypto/cipher/aead_test", "rc4-sha1-tls", "crypto/cipher/test/rc4_sha1_tls_tests.txt"],
+ ["crypto/cipher/aead_test", "aes-128-cbc-sha1-tls", "crypto/cipher/test/aes_128_cbc_sha1_tls_tests.txt"],
+ ["crypto/cipher/aead_test", "aes-128-cbc-sha1-tls-implicit-iv", "crypto/cipher/test/aes_128_cbc_sha1_tls_implicit_iv_tests.txt"],
+ ["crypto/cipher/aead_test", "aes-128-cbc-sha256-tls", "crypto/cipher/test/aes_128_cbc_sha256_tls_tests.txt"],
+ ["crypto/cipher/aead_test", "aes-256-cbc-sha1-tls", "crypto/cipher/test/aes_256_cbc_sha1_tls_tests.txt"],
+ ["crypto/cipher/aead_test", "aes-256-cbc-sha1-tls-implicit-iv", "crypto/cipher/test/aes_256_cbc_sha1_tls_implicit_iv_tests.txt"],
+ ["crypto/cipher/aead_test", "aes-256-cbc-sha256-tls", "crypto/cipher/test/aes_256_cbc_sha256_tls_tests.txt"],
+ ["crypto/cipher/aead_test", "aes-256-cbc-sha384-tls", "crypto/cipher/test/aes_256_cbc_sha384_tls_tests.txt"],
+ ["crypto/cipher/aead_test", "des-ede3-cbc-sha1-tls", "crypto/cipher/test/des_ede3_cbc_sha1_tls_tests.txt"],
+ ["crypto/cipher/aead_test", "des-ede3-cbc-sha1-tls-implicit-iv", "crypto/cipher/test/des_ede3_cbc_sha1_tls_implicit_iv_tests.txt"],
+ ["crypto/cipher/aead_test", "rc4-md5-ssl3", "crypto/cipher/test/rc4_md5_ssl3_tests.txt"],
+ ["crypto/cipher/aead_test", "rc4-sha1-ssl3", "crypto/cipher/test/rc4_sha1_ssl3_tests.txt"],
+ ["crypto/cipher/aead_test", "aes-128-cbc-sha1-ssl3", "crypto/cipher/test/aes_128_cbc_sha1_ssl3_tests.txt"],
+ ["crypto/cipher/aead_test", "aes-256-cbc-sha1-ssl3", "crypto/cipher/test/aes_256_cbc_sha1_ssl3_tests.txt"],
+ ["crypto/cipher/aead_test", "des-ede3-cbc-sha1-ssl3", "crypto/cipher/test/des_ede3_cbc_sha1_ssl3_tests.txt"],
+ ["crypto/cipher/aead_test", "aes-128-ctr-hmac-sha256", "crypto/cipher/test/aes_128_ctr_hmac_sha256.txt"],
+ ["crypto/cipher/aead_test", "aes-256-ctr-hmac-sha256", "crypto/cipher/test/aes_256_ctr_hmac_sha256.txt"],
+ ["crypto/cipher/cipher_test", "crypto/cipher/test/cipher_test.txt"],
+ ["crypto/cmac/cmac_test"],
+ ["crypto/constant_time_test"],
+ ["crypto/dh/dh_test"],
+ ["crypto/digest/digest_test"],
+ ["crypto/dsa/dsa_test"],
+ ["crypto/ec/ec_test"],
+ ["crypto/ec/example_mul"],
+ ["crypto/ecdsa/ecdsa_test"],
+ ["crypto/err/err_test"],
+ ["crypto/evp/evp_extra_test"],
+ ["crypto/evp/evp_test", "crypto/evp/evp_tests.txt"],
+ ["crypto/evp/pbkdf_test"],
+ ["crypto/hkdf/hkdf_test"],
+ ["crypto/hmac/hmac_test", "crypto/hmac/hmac_tests.txt"],
+ ["crypto/lhash/lhash_test"],
+ ["crypto/modes/gcm_test"],
+ ["crypto/pkcs8/pkcs8_test"],
+ ["crypto/pkcs8/pkcs12_test"],
+ ["crypto/poly1305/poly1305_test", "crypto/poly1305/poly1305_test.txt"],
+ ["crypto/refcount_test"],
+ ["crypto/rsa/rsa_test"],
+ ["crypto/thread_test"],
+ ["crypto/x509/pkcs7_test"],
+ ["crypto/x509v3/tab_test"],
+ ["crypto/x509v3/v3name_test"],
+ ["ssl/pqueue/pqueue_test"],
+ ["ssl/ssl_test"]
+]
diff --git a/src/util/doc.go b/src/util/doc.go
index 540d6ca..23cd5f4 100644
--- a/src/util/doc.go
+++ b/src/util/doc.go
@@ -48,9 +48,8 @@ type HeaderSection struct {
// Preamble contains a comment for a group of functions.
Preamble []string
Decls []HeaderDecl
- // Num is just the index of the section. It's included in order to help
- // text/template generate anchors.
- Num int
+ // Anchor, if non-empty, is the URL fragment to use in anchor tags.
+ Anchor string
// IsPrivate is true if the section contains private functions (as
// indicated by its name).
IsPrivate bool
@@ -65,10 +64,8 @@ type HeaderDecl struct {
Name string
// Decl contains the preformatted C declaration itself.
Decl string
- // Num is an index for the declaration, but the value is unique for all
- // declarations in a HeaderFile. It's included in order to help
- // text/template generate anchors.
- Num int
+ // Anchor, if non-empty, is the URL fragment to use in anchor tags.
+ Anchor string
}
const (
@@ -192,14 +189,6 @@ func extractDecl(lines []string, lineNo int) (decl string, rest []string, restLi
return
}
-func skipPast(s, skip string) string {
- i := strings.Index(s, skip)
- if i > 0 {
- return s[i:]
- }
- return s
-}
-
func skipLine(s string) string {
i := strings.Index(s, "\n")
if i > 0 {
@@ -227,8 +216,9 @@ func getNameFromDecl(decl string) (string, bool) {
}
return decl[:i], true
}
- decl = skipPast(decl, "STACK_OF(")
- decl = skipPast(decl, "LHASH_OF(")
+ decl = strings.TrimPrefix(decl, "OPENSSL_EXPORT ")
+ decl = strings.TrimPrefix(decl, "STACK_OF(")
+ decl = strings.TrimPrefix(decl, "LHASH_OF(")
i := strings.Index(decl, "(")
if i < 0 {
return "", false
@@ -243,6 +233,10 @@ func getNameFromDecl(decl string) (string, bool) {
return decl[j+1 : i], true
}
+func sanitizeAnchor(name string) string {
+ return strings.Replace(name, " ", "-", -1)
+}
+
func (config *Config) parseHeader(path string) (*HeaderFile, error) {
headerPath := filepath.Join(config.BaseDirectory, path)
@@ -314,7 +308,7 @@ func (config *Config) parseHeader(path string) (*HeaderFile, error) {
}
}
- var sectionNumber, declNumber int
+ allAnchors := make(map[string]struct{})
for {
// Start of a section.
@@ -330,10 +324,7 @@ func (config *Config) parseHeader(path string) (*HeaderFile, error) {
return nil, fmt.Errorf("blank line at start of section on line %d", lineNo)
}
- section := HeaderSection{
- Num: sectionNumber,
- }
- sectionNumber++
+ var section HeaderSection
if strings.HasPrefix(line, commentStart) {
comment, rest, restLineNo, err := extractComment(lines, lineNo)
@@ -341,8 +332,17 @@ func (config *Config) parseHeader(path string) (*HeaderFile, error) {
return nil, err
}
if len(rest) > 0 && len(rest[0]) == 0 {
+ anchor := sanitizeAnchor(firstSentence(comment))
+ if len(anchor) > 0 {
+ if _, ok := allAnchors[anchor]; ok {
+ return nil, fmt.Errorf("duplicate anchor: %s", anchor)
+ }
+ allAnchors[anchor] = struct{}{}
+ }
+
section.Preamble = comment
section.IsPrivate = len(comment) > 0 && strings.HasPrefix(comment[0], "Private functions")
+ section.Anchor = anchor
lines = rest[1:]
lineNo = restLineNo + 1
}
@@ -381,13 +381,18 @@ func (config *Config) parseHeader(path string) (*HeaderFile, error) {
if last := len(section.Decls) - 1; len(name) == 0 && len(comment) == 0 && last >= 0 {
section.Decls[last].Decl += "\n" + decl
} else {
+ anchor := sanitizeAnchor(name)
+ // TODO(davidben): Enforce uniqueness. This is
+ // skipped because #ifdefs currently result in
+ // duplicate table-of-contents entries.
+ allAnchors[anchor] = struct{}{}
+
section.Decls = append(section.Decls, HeaderDecl{
Comment: comment,
Name: name,
Decl: decl,
- Num: declNumber,
+ Anchor: anchor,
})
- declNumber++
}
if len(lines) > 0 && len(lines[0]) == 0 {
@@ -451,7 +456,7 @@ again:
if end > 0 {
end += start
w := strings.ToLower(string(s[start:end]))
- if w == "a" || w == "an" || w == "deprecated:" {
+ if w == "a" || w == "an" {
start = end + 1
goto again
}
@@ -495,9 +500,9 @@ func generate(outPath string, config *Config) (map[string]string, error) {
<ol>
{{range .Sections}}
{{if not .IsPrivate}}
- {{if .Preamble}}<li class="header"><a href="#section-{{.Num}}">{{.Preamble | firstSentence | html | markupPipeWords}}</a></li>{{end}}
+ {{if .Anchor}}<li class="header"><a href="#{{.Anchor}}">{{.Preamble | firstSentence | html | markupPipeWords}}</a></li>{{end}}
{{range .Decls}}
- {{if .Name}}<li><a href="#decl-{{.Num}}"><tt>{{.Name}}</tt></a></li>{{end}}
+ {{if .Anchor}}<li><a href="#{{.Anchor}}"><tt>{{.Name}}</tt></a></li>{{end}}
{{end}}
{{end}}
{{end}}
@@ -508,7 +513,7 @@ func generate(outPath string, config *Config) (map[string]string, error) {
<div class="section">
{{if .Preamble}}
<div class="sectionpreamble">
- <a name="section-{{.Num}}">
+ <a{{if .Anchor}} name="{{.Anchor}}"{{end}}>
{{range .Preamble}}<p>{{. | html | markupPipeWords}}</p>{{end}}
</a>
</div>
@@ -516,7 +521,7 @@ func generate(outPath string, config *Config) (map[string]string, error) {
{{range .Decls}}
<div class="decl">
- <a name="decl-{{.Num}}">
+ <a{{if .Anchor}} name="{{.Anchor}}"{{end}}>
{{range .Comment}}
<p>{{. | html | markupPipeWords | newlinesToBR | markupFirstWord}}</p>
{{end}}
@@ -605,6 +610,14 @@ func generateIndex(outPath string, config *Config, headerDescriptions map[string
return nil
}
+func copyFile(outPath string, inFilePath string) error {
+ bytes, err := ioutil.ReadFile(inFilePath)
+ if err != nil {
+ return err
+ }
+ return ioutil.WriteFile(filepath.Join(outPath, filepath.Base(inFilePath)), bytes, 0666)
+}
+
func main() {
var (
configFlag *string = flag.String("config", "doc.config", "Location of config file")
@@ -645,4 +658,9 @@ func main() {
fmt.Printf("Failed to generate index: %s\n", err)
os.Exit(1)
}
+
+ if err := copyFile(*outputDir, "doc.css"); err != nil {
+ fmt.Printf("Failed to copy static file: %s\n", err)
+ os.Exit(1)
+ }
}
diff --git a/src/util/generate_build_files.py b/src/util/generate_build_files.py
index e534a56..2eae98a 100644
--- a/src/util/generate_build_files.py
+++ b/src/util/generate_build_files.py
@@ -19,6 +19,7 @@
import os
import subprocess
import sys
+import json
# OS_ARCH_COMBOS maps from OS and platform to the OpenSSL assembly "style" for
@@ -68,7 +69,9 @@ class Chromium(object):
gypi.write(self.header + '{\n \'variables\': {\n')
self.PrintVariableSection(
- gypi, 'boringssl_lib_sources', files['crypto'] + files['ssl'])
+ gypi, 'boringssl_ssl_sources', files['ssl'])
+ self.PrintVariableSection(
+ gypi, 'boringssl_crypto_sources', files['crypto'])
for ((osname, arch), asm_files) in asm_outputs:
self.PrintVariableSection(gypi, 'boringssl_%s_%s_sources' %
@@ -133,6 +136,9 @@ class Android(object):
"""
+ def ExtraFiles(self):
+ return ['android_compat_hacks.c', 'android_compat_keywrap.c']
+
def PrintVariableSection(self, out, name, files):
out.write('%s := \\\n' % name)
for f in sorted(files):
@@ -143,8 +149,7 @@ class Android(object):
with open('sources.mk', 'w+') as makefile:
makefile.write(self.header)
- files['crypto'].append('android_compat_hacks.c')
- files['crypto'].append('android_compat_keywrap.c')
+ files['crypto'].extend(self.ExtraFiles())
self.PrintVariableSection(makefile, 'crypto_sources', files['crypto'])
self.PrintVariableSection(makefile, 'ssl_sources', files['ssl'])
self.PrintVariableSection(makefile, 'tool_sources', files['tool'])
@@ -154,6 +159,127 @@ class Android(object):
makefile, '%s_%s_sources' % (osname, arch), asm_files)
+class AndroidStandalone(Android):
+ """AndroidStandalone is for Android builds outside of the Android-system, i.e.
+
+ for applications that wish wish to ship BoringSSL.
+ """
+
+ def ExtraFiles(self):
+ return []
+
+
+class Bazel(object):
+ """Bazel outputs files suitable for including in Bazel files."""
+
+ def __init__(self):
+ self.firstSection = True
+ self.header = \
+"""# This file is created by generate_build_files.py. Do not edit manually.
+
+"""
+
+ def PrintVariableSection(self, out, name, files):
+ if not self.firstSection:
+ out.write('\n')
+ self.firstSection = False
+
+ out.write('%s = [\n' % name)
+ for f in sorted(files):
+ out.write(' "%s",\n' % f)
+ out.write(']\n')
+
+ def WriteFiles(self, files, asm_outputs):
+ with open('BUILD.generated', 'w+') as out:
+ out.write(self.header)
+
+ self.PrintVariableSection(out, 'ssl_headers', files['ssl_headers'])
+ self.PrintVariableSection(
+ out, 'ssl_internal_headers', files['ssl_internal_headers'])
+ self.PrintVariableSection(out, 'ssl_sources', files['ssl'])
+ self.PrintVariableSection(out, 'crypto_headers', files['crypto_headers'])
+ self.PrintVariableSection(
+ out, 'crypto_internal_headers', files['crypto_internal_headers'])
+ self.PrintVariableSection(out, 'crypto_sources', files['crypto'])
+ self.PrintVariableSection(out, 'tool_sources', files['tool'])
+
+ for ((osname, arch), asm_files) in asm_outputs:
+ if osname is not 'linux':
+ continue
+ self.PrintVariableSection(
+ out, 'crypto_sources_%s' % arch, asm_files)
+
+ with open('BUILD.generated_tests', 'w+') as out:
+ out.write(self.header)
+
+ out.write('test_support_sources = [\n')
+ for filename in files['test_support']:
+ if os.path.basename(filename) == 'malloc.cc':
+ continue
+ out.write(' "%s",\n' % filename)
+ out.write('] + glob(["src/crypto/test/*.h"])\n\n')
+
+ name_counts = {}
+ for test in files['tests']:
+ name = os.path.basename(test[0])
+ name_counts[name] = name_counts.get(name, 0) + 1
+
+ first = True
+ for test in files['tests']:
+ name = os.path.basename(test[0])
+ if name_counts[name] > 1:
+ if '/' in test[1]:
+ name += '_' + os.path.splitext(os.path.basename(test[1]))[0]
+ else:
+ name += '_' + test[1].replace('-', '_')
+
+ if not first:
+ out.write('\n')
+ first = False
+
+ src_prefix = 'src/' + test[0]
+ for src in files['test']:
+ if src.startswith(src_prefix):
+ src = src
+ break
+ else:
+ raise ValueError("Can't find source for %s" % test[0])
+
+ out.write('cc_test(\n')
+ out.write(' name = "%s",\n' % name)
+ out.write(' size = "small",\n')
+ out.write(' srcs = ["%s"] + test_support_sources,\n' % src)
+
+ data_files = []
+ if len(test) > 1:
+
+ out.write(' args = [\n')
+ for arg in test[1:]:
+ if '/' in arg:
+ out.write(' "$(location src/%s)",\n' % arg)
+ data_files.append('src/%s' % arg)
+ else:
+ out.write(' "%s",\n' % arg)
+ out.write(' ],\n')
+
+ out.write(' copts = boringssl_copts,\n')
+
+ if len(data_files) > 0:
+ out.write(' data = [\n')
+ for filename in data_files:
+ out.write(' "%s",\n' % filename)
+ out.write(' ],\n')
+
+ if 'ssl/' in test[0]:
+ out.write(' deps = [\n')
+ out.write(' ":crypto",\n')
+ out.write(' ":ssl",\n')
+ out.write(' ],\n')
+ else:
+ out.write(' deps = [":crypto"],\n')
+ out.write(')\n')
+
+
def FindCMakeFiles(directory):
"""Returns list of all CMakeLists.txt files recursively in directory."""
cmakefiles = []
@@ -188,6 +314,10 @@ def AllFiles(dent, is_dir):
return True
+def SSLHeaderFiles(dent, is_dir):
+ return dent in ['ssl.h', 'tls1.h', 'ssl23.h', 'ssl3.h', 'dtls1.h']
+
+
def FindCFiles(directory, filter_func):
"""Recurses through directory and returns a list of paths to all the C source
files that pass filter_func."""
@@ -208,6 +338,21 @@ def FindCFiles(directory, filter_func):
return cfiles
+def FindHeaderFiles(directory, filter_func):
+ """Recurses through directory and returns a list of paths to all the header files that pass filter_func."""
+ hfiles = []
+
+ for (path, dirnames, filenames) in os.walk(directory):
+ for filename in filenames:
+ if not filename.endswith('.h'):
+ continue
+ if not filter_func(filename, False):
+ continue
+ hfiles.append(os.path.join(path, filename))
+
+ return hfiles
+
+
def ExtractPerlAsmFromCMakeFile(cmakefile):
"""Parses the contents of the CMakeLists.txt file passed as an argument and
returns a list of all the perlasm() directives found in the file."""
@@ -289,6 +434,9 @@ def WriteAsmFiles(perlasms):
if not output.startswith('src'):
raise ValueError('output missing src: %s' % output)
output = os.path.join(outDir, output[4:])
+ if output.endswith('-armx.${ASM_EXT}'):
+ output = output.replace('-armx',
+ '-armx64' if arch == 'aarch64' else '-armx32')
output = output.replace('${ASM_EXT}', asm_ext)
if arch in ArchForAsmFilename(filename):
@@ -302,7 +450,7 @@ def WriteAsmFiles(perlasms):
return asmfiles
-def main(platform):
+def main(platforms):
crypto_c_files = FindCFiles(os.path.join('src', 'crypto'), NoTests)
ssl_c_files = FindCFiles(os.path.join('src', 'ssl'), NoTests)
tool_cc_files = FindCFiles(os.path.join('src', 'tool'), NoTests)
@@ -320,36 +468,80 @@ def main(platform):
test_c_files = FindCFiles(os.path.join('src', 'crypto'), OnlyTests)
test_c_files += FindCFiles(os.path.join('src', 'ssl'), OnlyTests)
+ ssl_h_files = (
+ FindHeaderFiles(
+ os.path.join('src', 'include', 'openssl'),
+ SSLHeaderFiles))
+
+ def NotSSLHeaderFiles(filename, is_dir):
+ return not SSLHeaderFiles(filename, is_dir)
+ crypto_h_files = (
+ FindHeaderFiles(
+ os.path.join('src', 'include', 'openssl'),
+ NotSSLHeaderFiles))
+
+ ssl_internal_h_files = FindHeaderFiles(os.path.join('src', 'ssl'), NoTests)
+ crypto_internal_h_files = FindHeaderFiles(
+ os.path.join('src', 'crypto'), NoTests)
+
+ with open('src/util/all_tests.json', 'r') as f:
+ tests = json.load(f)
+ test_binaries = set([test[0] for test in tests])
+ test_sources = set([
+ test.replace('.cc', '').replace('.c', '').replace(
+ 'src/',
+ '')
+ for test in test_c_files])
+ if test_binaries != test_sources:
+ print 'Test sources and configured tests do not match'
+ a = test_binaries.difference(test_sources)
+ if len(a) > 0:
+ print 'These tests are configured without sources: ' + str(a)
+ b = test_sources.difference(test_binaries)
+ if len(b) > 0:
+ print 'These test sources are not configured: ' + str(b)
+
files = {
'crypto': crypto_c_files,
+ 'crypto_headers': crypto_h_files,
+ 'crypto_internal_headers': crypto_internal_h_files,
'ssl': ssl_c_files,
+ 'ssl_headers': ssl_h_files,
+ 'ssl_internal_headers': ssl_internal_h_files,
'tool': tool_cc_files,
'test': test_c_files,
'test_support': test_support_cc_files,
+ 'tests': tests,
}
asm_outputs = sorted(WriteAsmFiles(ReadPerlAsmOperations()).iteritems())
- platform.WriteFiles(files, asm_outputs)
+ for platform in platforms:
+ platform.WriteFiles(files, asm_outputs)
return 0
def Usage():
- print 'Usage: python %s [chromium|android]' % sys.argv[0]
+ print 'Usage: python %s [chromium|android|android-standalone|bazel]' % sys.argv[0]
sys.exit(1)
if __name__ == '__main__':
- if len(sys.argv) != 2:
- Usage()
-
- platform = None
- if sys.argv[1] == 'chromium':
- platform = Chromium()
- elif sys.argv[1] == 'android':
- platform = Android()
- else:
+ if len(sys.argv) < 2:
Usage()
- sys.exit(main(platform))
+ platforms = []
+ for s in sys.argv[1:]:
+ if s == 'chromium' or s == 'gyp':
+ platforms.append(Chromium())
+ elif s == 'android':
+ platforms.append(Android())
+ elif s == 'android-standalone':
+ platforms.append(AndroidStandalone())
+ elif s == 'bazel':
+ platforms.append(Bazel())
+ else:
+ Usage()
+
+ sys.exit(main(platforms))
diff --git a/src/util/make_errors.go b/src/util/make_errors.go
index dc8039a..cc35409 100644
--- a/src/util/make_errors.go
+++ b/src/util/make_errors.go
@@ -25,7 +25,6 @@ import (
"sort"
"strconv"
"strings"
- "unicode"
)
// ssl.h reserves values 1000 and above for error codes corresponding to
@@ -61,12 +60,11 @@ func makeErrors(reset bool) error {
}
prefix := strings.ToUpper(lib)
- functions, reasons, err := parseHeader(prefix, headerFile)
+ reasons, err := parseHeader(prefix, headerFile)
headerFile.Close()
if reset {
err = nil
- functions = make(map[string]int)
// Retain any reason codes above reservedReasonCode.
newReasons := make(map[string]int)
for key, value := range reasons {
@@ -97,12 +95,11 @@ func makeErrors(reset bool) error {
continue
}
- if err := addFunctionsAndReasons(functions, reasons, name, prefix); err != nil {
+ if err := addReasons(reasons, name, prefix); err != nil {
return err
}
}
- assignNewValues(functions, -1)
assignNewValues(reasons, reservedReasonCode)
headerFile, err = os.Open(headerPath)
@@ -117,7 +114,7 @@ func makeErrors(reset bool) error {
}
defer newHeaderFile.Close()
- if err := writeHeaderFile(newHeaderFile, headerFile, prefix, functions, reasons); err != nil {
+ if err := writeHeaderFile(newHeaderFile, headerFile, prefix, reasons); err != nil {
return err
}
os.Rename(headerPath+".tmp", headerPath)
@@ -127,8 +124,7 @@ func makeErrors(reset bool) error {
return err
}
- outputStrings(dataFile, lib, typeFunctions, functions)
- outputStrings(dataFile, lib, typeReasons, reasons)
+ outputStrings(dataFile, lib, reasons)
dataFile.Close()
return nil
@@ -136,16 +132,16 @@ func makeErrors(reset bool) error {
func findToplevel() (path string, err error) {
path = ".."
- buildingPath := filepath.Join(path, "BUILDING")
+ buildingPath := filepath.Join(path, "BUILDING.md")
_, err = os.Stat(buildingPath)
if err != nil && os.IsNotExist(err) {
path = filepath.Join("..", path)
- buildingPath = filepath.Join(path, "BUILDING")
+ buildingPath = filepath.Join(path, "BUILDING.md")
_, err = os.Stat(buildingPath)
}
if err != nil {
- return "", errors.New("Cannot find BUILDING file at the top-level")
+ return "", errors.New("Cannot find BUILDING.md file at the top-level")
}
return path, nil
}
@@ -183,7 +179,7 @@ func outputAssignments(w io.Writer, assignments map[string]int) {
}
}
-func parseDefineLine(line, lib string) (typ int, key string, value int, ok bool) {
+func parseDefineLine(line, lib string) (key string, value int, ok bool) {
if !strings.HasPrefix(line, "#define ") {
return
}
@@ -193,16 +189,8 @@ func parseDefineLine(line, lib string) (typ int, key string, value int, ok bool)
return
}
- funcPrefix := lib + "_F_"
- reasonPrefix := lib + "_R_"
-
key = fields[1]
- switch {
- case strings.HasPrefix(key, funcPrefix):
- typ = typeFunctions
- case strings.HasPrefix(key, reasonPrefix):
- typ = typeReasons
- default:
+ if !strings.HasPrefix(key, lib+"_R_") {
return
}
@@ -215,7 +203,7 @@ func parseDefineLine(line, lib string) (typ int, key string, value int, ok bool)
return
}
-func writeHeaderFile(w io.Writer, headerFile io.Reader, lib string, functions, reasons map[string]int) error {
+func writeHeaderFile(w io.Writer, headerFile io.Reader, lib string, reasons map[string]int) error {
var last []byte
var haveLast, sawDefine bool
newLine := []byte("\n")
@@ -223,7 +211,7 @@ func writeHeaderFile(w io.Writer, headerFile io.Reader, lib string, functions, r
scanner := bufio.NewScanner(headerFile)
for scanner.Scan() {
line := scanner.Text()
- _, _, _, ok := parseDefineLine(line, lib)
+ _, _, ok := parseDefineLine(line, lib)
if ok {
sawDefine = true
continue
@@ -247,7 +235,6 @@ func writeHeaderFile(w io.Writer, headerFile io.Reader, lib string, functions, r
return err
}
- outputAssignments(w, functions)
outputAssignments(w, reasons)
w.Write(newLine)
@@ -259,14 +246,9 @@ func writeHeaderFile(w io.Writer, headerFile io.Reader, lib string, functions, r
return nil
}
-const (
- typeFunctions = iota
- typeReasons
-)
-
-func outputStrings(w io.Writer, lib string, ty int, assignments map[string]int) {
+func outputStrings(w io.Writer, lib string, assignments map[string]int) {
lib = strings.ToUpper(lib)
- prefixLen := len(lib + "_F_")
+ prefixLen := len(lib + "_R_")
keys := make([]string, 0, len(assignments))
for key := range assignments {
@@ -275,11 +257,7 @@ func outputStrings(w io.Writer, lib string, ty int, assignments map[string]int)
sort.Strings(keys)
for _, key := range keys {
- typeString := "function"
- if ty == typeReasons {
- typeString = "reason"
- }
- fmt.Fprintf(w, "%s,%s,%d,%s\n", lib, typeString, assignments[key], key[prefixLen:])
+ fmt.Fprintf(w, "%s,%d,%s\n", lib, assignments[key], key[prefixLen:])
}
}
@@ -339,7 +317,7 @@ func handleDeclareMacro(line, join, macroName string, m map[string]int) {
}
}
-func addFunctionsAndReasons(functions, reasons map[string]int, filename, prefix string) error {
+func addReasons(reasons map[string]int, filename, prefix string) error {
file, err := os.Open(filename)
if err != nil {
return err
@@ -347,45 +325,15 @@ func addFunctionsAndReasons(functions, reasons map[string]int, filename, prefix
defer file.Close()
reasonPrefix := prefix + "_R_"
- var currentFunction string
scanner := bufio.NewScanner(file)
for scanner.Scan() {
line := scanner.Text()
- if len(line) > 0 && unicode.IsLetter(rune(line[0])) {
- /* Function start */
- fields := strings.Fields(line)
- for _, field := range fields {
- if i := strings.Index(field, "("); i != -1 {
- f := field[:i]
- // The return type of some functions is
- // a macro that contains a "(".
- if f == "STACK_OF" {
- continue
- }
- currentFunction = f
- for len(currentFunction) > 0 && currentFunction[0] == '*' {
- currentFunction = currentFunction[1:]
- }
- break
- }
- }
- }
-
- // Do not include cross-module error lines.
- if strings.Contains(line, "OPENSSL_PUT_ERROR(" + prefix + ",") {
- functionToken := prefix + "_F_" + currentFunction
- if _, ok := functions[functionToken]; !ok {
- functions[functionToken] = -1
- }
- }
-
handleDeclareMacro(line, "_R_", "OPENSSL_DECLARE_ERROR_REASON(", reasons)
- handleDeclareMacro(line, "_F_", "OPENSSL_DECLARE_ERROR_FUNCTION(", functions)
for len(line) > 0 {
- i := strings.Index(line, prefix + "_")
+ i := strings.Index(line, prefix+"_")
if i == -1 {
break
}
@@ -413,25 +361,17 @@ func addFunctionsAndReasons(functions, reasons map[string]int, filename, prefix
return scanner.Err()
}
-func parseHeader(lib string, file io.Reader) (functions, reasons map[string]int, err error) {
- functions = make(map[string]int)
+func parseHeader(lib string, file io.Reader) (reasons map[string]int, err error) {
reasons = make(map[string]int)
scanner := bufio.NewScanner(file)
for scanner.Scan() {
- typ, key, value, ok := parseDefineLine(scanner.Text(), lib)
+ key, value, ok := parseDefineLine(scanner.Text(), lib)
if !ok {
continue
}
- switch typ {
- case typeFunctions:
- functions[key] = value
- case typeReasons:
- reasons[key] = value
- default:
- panic("internal error")
- }
+ reasons[key] = value
}
err = scanner.Err()